StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StiFactory.h
1 #ifndef StiFactory_H
2 #define StiFactory_H
3 #include <cassert>
4 #include <stdexcept>
5 #include <string.h>
6 #include <typeinfo>
7 #include "Sti/Base/Factory.h"
19 //______________________________________________________________________________
20 template<class Object>
21 class StiHolder {
22 public:
23  StiHolder();
24 union {
25  StiHolder *fNext;
26  long fLong;
27  char fChar[1];
28 };
29  Object fObj;
30 };
31 
32 //______________________________________________________________________________
33 template<class Object>
34 class StiBlock {
35 public:
36 enum {kSize=100};
37  StiBlock(StiBlock **bTop,StiHolder<Object> **hTop,char *buf);
38 void reset(StiBlock **bTop,StiHolder<Object> **hTop);
39 int getSize() const {return kSize;}
40 
41 StiBlock *fNext;
42 char *fBuff;
43 StiHolder<Object> fArr[kSize];
44 };
45 
46 
47 //______________________________________________________________________________
48 template <class Concrete, class Abstract>
49 class StiFactory : public Factory<Abstract>
50 {
51 public:
52 void free(Abstract *obj);
53 void free(void *obj) { free((Abstract*)obj);}
55 void clear();
56 
58 void reset();
59 
61 Abstract* getInstance();
62 static StiFactory* myInstance();
63 
64 private:
65  StiFactory();
66  ~StiFactory(){clear();}
67 StiBlock<Concrete> *fBTop;
68 StiHolder<Concrete> *fHTop;
69 
70 };
71 //______________________________________________________________________________
72 //______________________________________________________________________________
73 //______________________________________________________________________________
74 template <class Object>
76 {
77  fBuff=buf;
78  reset(bTop,hTop);
79 }
80 template <class Object>
82 {
83  fNext=*bTop; *bTop=this;
84  for (int i=0;i<kSize;i++) {
85  fArr[i].fNext = *hTop;
86  *hTop = fArr+i;
87  }
88 }
89 //______________________________________________________________________________
90 //______________________________________________________________________________
91 template <class Object>
93 {
94  memset(fChar,0,((char*)&fObj)-fChar);
95 }
96 //______________________________________________________________________________
97 //______________________________________________________________________________
98 template <class Concrete, class Abstract>
100 {
101  fHTop=0;fBTop=0;
102  this->setName(typeid(*this).name());
103  printf("*** Factory created *** %s\n",this->getName().c_str());
104 }
105 template <class Concrete, class Abstract>
107 {
108  static StiFactory* my=0;
109  if (!my) my = new StiFactory;
110  return my;
111 }
112 //______________________________________________________________________________
113 template <class Concrete, class Abstract>
115 {
116  enum {FENCE = sizeof(double)+2*sizeof(long)+1};
117  if (!fHTop) {
118  assert(this->fCurCount < this->fMaxCount);
119  if (this->fFastDel) {
120  int nBuf = sizeof(StiBlock<Concrete>) + FENCE;
121  char *cBuf = new char[nBuf];
122  cBuf[nBuf-1]=46;
123  new((StiBlock<Concrete>*)cBuf) StiBlock<Concrete>(&fBTop,&fHTop,cBuf);
124  assert(cBuf[nBuf-1]==46);
125  } else {
126  new StiBlock<Concrete>(&fBTop,&fHTop, 0);
127  }
128  this->fCurCount += fBTop->getSize();
129  this->fgTotal += sizeof(StiBlock<Concrete>)*1e-6;
130  }
131  this->fInstCount++;
132  StiHolder<Concrete> *h = fHTop;
133  fHTop = h->fNext;
134  h->fNext=0;
135  h->fObj.reset();
136  this->fUseCount++;
137  h->fLong= ((long)this)+1; //set factory addres+1
138  return &h->fObj;
139 }
140 //______________________________________________________________________________
141 template <class Concrete, class Abstract>
143 {
144  static const int shift = (char*)(&(((StiHolder<Concrete>*)1)->fObj))-(char*)1;
145  obj->unset();
146  StiHolder<Concrete>* h = (StiHolder<Concrete>*)((char*)obj-shift);
147  assert((h->fLong-1)== (long)this);
148  h->fNext = fHTop; fHTop=h; this->fUseCount--; this->fFreeCount++;
149 }
150 
151 //______________________________________________________________________________
152 template <class Concrete, class Abstract>
154 {
155  double sz=0;
156  StiBlock<Concrete>* b = fBTop;
157  while (b) {
158  StiBlock<Concrete>* d = b;
159  b=b->fNext;
160  if (this->fFastDel) {delete [] d->fBuff;} else { delete d;}
161  sz += sizeof(StiBlock<Concrete>);
162  this->fgTotal -= sizeof(StiBlock<Concrete>)*1e-6;
163  }
164  fBTop=0; fHTop=0; this->fCurCount=0; this->fUseCount=0;
165  printf("*** %s::clear() %g MegaBytes Total %g Inst/Free=%d %d\n"
166  ,this->getName().c_str(),sz*1e-6
167  ,this->fgTotal,this->fInstCount,this->fFreeCount);
168  this->fInstCount=0; this->fFreeCount=0;
169 }
170 //______________________________________________________________________________
171 template <class Concrete, class Abstract>
173 {
174  if (!this->fUseCount) return;
175 
176  typedef StiBlock<Concrete> B_t;
177  B_t* b = fBTop;
178  fBTop=0;fHTop=0;
179  while (b) {
180  B_t* n = b->fNext;
181  b->reset(&fBTop,&fHTop);
182  b=n;
183  }
184  this->fUseCount=0;
185 }
186 #endif
void reset()
Reset this factory.
Definition: StiFactory.h:172
void free(Abstract *obj)
Free an object for reuse.
Definition: StiFactory.h:142
void clear()
Clear/delete all objects owned by this factory.
Definition: StiFactory.h:153
void free(void *obj)
Free an object for reuse.
Definition: StiFactory.h:53
Abstract * getInstance()
Get a pointer to instance of objects served by this factory.
Definition: StiFactory.h:114
void setName(const string &newName)
Set the name of the object.
Definition: Named.cxx:15
const string & getName() const
Get the name of the object.
Definition: Named.cxx:22