]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Reve/Plex.h
9de25b87a39cca939db2814675f248dd5a56f0da
[u/mrichter/AliRoot.git] / EVE / Reve / Plex.h
1 // $Header$
2
3 #ifndef REVE_PLEX_H
4 #define REVE_PLEX_H
5
6 #include <Reve/Reve.h>
7
8 #include <TObject.h>
9 #include <TArrayC.h>
10
11 #include <vector>
12
13 namespace Reve {
14
15 /**************************************************************************/
16 // VoidCPlex
17 /**************************************************************************/
18
19 class VoidCPlex
20 {
21 private:
22   VoidCPlex(const VoidCPlex&);            // Not implemented
23   VoidCPlex& operator=(const VoidCPlex&); // Not implemented
24
25 protected:
26   Int_t fS;        // Size of atom
27   Int_t fN;        // Number of atoms in a chunk
28
29   Int_t fSize;     // Size of container, number of atoms
30   Int_t fVecSize;  // Number of allocated chunks
31   Int_t fCapacity; // Available capacity within the chunks
32
33   std::vector<TArrayC*> fChunks; // Memory blocks
34
35   void ReleaseChunks();
36
37 public:
38   VoidCPlex();
39   VoidCPlex(Int_t atom_size, Int_t chunk_size);
40   virtual ~VoidCPlex();
41
42   void Reset(Int_t atom_size, Int_t chunk_size);
43   void Refit();
44
45   Int_t    S() const { return fS; }
46   Int_t    N() const { return fN; }
47   
48   Int_t    Size()     const { return fSize; }
49   Int_t    VecSize()  const { return fVecSize; }
50   Int_t    Capacity() const { return fCapacity; }
51
52   Char_t* Atom(Int_t idx)   const { return fChunks[idx/fN]->fArray + idx%fN*fS; }
53   Char_t* Chunk(Int_t chk)  const { return fChunks[chk]->fArray; }
54   Int_t   NAtoms(Int_t chk) const { return (chk < fVecSize-1) ? fN : (fSize-1)%fN + 1; }
55
56   Char_t* NewAtom();
57   Char_t* NewChunk();
58
59
60   // Iterators
61
62   struct iterator
63   {
64     VoidCPlex *fPlex;
65     Char_t    *fCurrent;
66     Int_t      fAtomIndex;
67     Int_t      fNextChunk;
68     Int_t      fAtomsToGo;
69
70     iterator(VoidCPlex* p) :
71       fPlex(p),  fCurrent(0), fAtomIndex(-1), fNextChunk(0), fAtomsToGo(0) {}
72     iterator(VoidCPlex& p) :
73       fPlex(&p), fCurrent(0), fAtomIndex(-1), fNextChunk(0), fAtomsToGo(0) {}
74
75     Bool_t  next();
76     void    reset() { fCurrent = 0; fNextChunk = fAtomsToGo = 0; }
77
78     Char_t* operator()() { return fCurrent; }
79     Char_t* operator*()  { return fCurrent; }
80     Int_t   index()      { return fAtomIndex; }
81   };
82
83   ClassDef(VoidCPlex, 1); // Vector-like container with chunked memory allocation.
84 };
85
86
87 /******************************************************************************/
88
89 inline Char_t* VoidCPlex::NewAtom()
90 {
91   Char_t *a = (fSize >= fCapacity) ? NewChunk() : Atom(fSize);
92   ++fSize;
93   return a;
94 }
95
96 inline Bool_t VoidCPlex::iterator::next()
97 {
98   if (fAtomsToGo <= 0) {
99     if (fNextChunk < fPlex->fVecSize) {
100       fCurrent   = fPlex->Chunk(fNextChunk);
101       fAtomsToGo = fPlex->NAtoms(fNextChunk);
102       ++fNextChunk;
103     } else {
104       return kFALSE;
105     }
106   } else {
107     fCurrent += fPlex->fS;
108   }
109   ++fAtomIndex;
110   --fAtomsToGo;
111   return kTRUE;
112 }
113
114
115 /**************************************************************************/
116 // Templated some-class CPlex
117 /**************************************************************************/
118
119 template<class T>
120 class CPlex : public VoidCPlex
121 {
122 private:
123   CPlex(const CPlex&);            // Not implemented
124   CPlex& operator=(const CPlex&); // Not implemented
125
126 public:
127   CPlex()                 : VoidCPlex() {}
128   CPlex(Int_t chunk_size) : VoidCPlex(sizeof(T), chunk_size) {}
129   virtual ~CPlex() {}
130
131   void Reset(Int_t chunk_size) { Reset(sizeof(T), chunk_size); }
132
133   T* At(Int_t idx)  { return reinterpret_cast<T*>(Atom(idx)); }
134   T& Ref(Int_t idx) { return *At(idx); }
135
136   ClassDef(CPlex, 1); // Templated class for specific atom classes (given as template argument).
137 }; // endclass CPlex
138
139 }
140
141 #endif