OOFILE  1.9
oofarray.cpp
Go to the documentation of this file.
1 // COPYRIGHT 1997 A.D. Software, All rights reserved
2 
3 // array classes for OOFILE database
4 
5 // NOTE inline definitions included at end of this header file
6 
7 #include "oofpch_c.h" // for precompilation of core files
8 
9 #ifndef H_OOFARRAY
10  #include "oofarray.h"
11 #endif
12 
13 #ifdef OOF_MEM_DEBUG_LAST_INCLUDE
14  #include OOF_MEM_DEBUG_LAST_INCLUDE
15 #endif
16 
17 #ifndef OOF_NO_STDLIB
18  #ifndef std
19  using namespace std;
20  #endif
21 #endif
22 
23 // -------------------------------------------------------
24 // O O F _ E x p a n d a b l e L o n g A r r a y
25 // -------------------------------------------------------
27  unsigned long defaultValue,
28  unsigned long numSlots,
29  unsigned int expandBySlots
30 ) :
31  mBits(0),
32  mDefaultValue(defaultValue),
33  mInternalIter(0),
34  mNextFreeEntry(0),
35  mNumSlots(0),
36  mExpansionChunk(expandBySlots)
37 {
38  if (mExpansionChunk<1)
39  mExpansionChunk = 1;
40  if (numSlots) {
41  mNumSlots = ((numSlots-1) / expandBySlots + 1) * expandBySlots;
42  mBits = new unsigned long[mNumSlots];
43  assert(mBits);
44  for (unsigned long i=0; i<mNumSlots; i++)
45  mBits[i] = defaultValue;
46  }
47 }
48 
49 
51  mBits(0),
52  mDefaultValue(rhs.mDefaultValue),
53  mNextFreeEntry(rhs.mNextFreeEntry),
54  mNumSlots(rhs.mNumSlots),
55  mInternalIter(0),
56  mExpansionChunk(rhs.mExpansionChunk)
57 {
58  CopyBits(rhs);
59 }
60 
61 
64 {
65  if ((this == &rhs) || (mBits == rhs.mBits))
66  return *this;
67 
70  mNumSlots = rhs.mNumSlots;
71  mInternalIter = 0;
73  CopyBits(rhs);
74  return *this;
75 }
76 
77 
79 {
80  DeleteBits();
81 }
82 
83 
84 #ifndef OOF_NO_STDLIB
85 void
87 {
88  os << this << ": " << endl;
89  const unsigned long numBits = count();
90  for(unsigned long i=0; i<numBits; i++)
91  {
92  os << value(i) << ", " ;
93 
94  }
95  os << endl;
96 }
97 #endif
98 
99 
100 void
102 {
103  delete[] mBits;
104  mBits = 0; // in case we get called other than at destruction
105  mNumSlots = 0;
106 }
107 
108 
109 void
111 {
112  if (mBits)
113  DeleteBits();
114  const unsigned long newSlots = rhs.mNumSlots;
115  if (newSlots==0)
116  mBits = 0;
117  else {
118  mBits = new unsigned long[newSlots];
119  mNumSlots = newSlots;
120  assert(mBits);
121  memcpy(mBits, rhs.mBits, newSlots*sizeof(unsigned long));
122  #ifdef OOF_MEM_DEBUG_FORCE_POOL_CHECK
124  #endif
125  }
126  assert(Invariant());
127 }
128 
129 
130 void
131 OOF_ExpandableLongArray::append(unsigned long aBit) {
132  (*this)[mNextFreeEntry] = aBit;
133 }
134 
135 
136 void
138 #ifdef OOF_MEM_DEBUG_FORCE_POOL_CHECK
140 #endif
141  for (unsigned long i=index; i<mNextFreeEntry; i++)
142  mBits[i] = mBits[i+1];
143 #ifdef OOF_MEM_DEBUG_FORCE_POOL_CHECK
145 #endif
146  mNextFreeEntry--;
148 }
149 
150 
151 void
153 {
154  unsigned long foundIndex;
155  if (find(schValue, foundIndex))
156  deleteItem(foundIndex);
157 }
158 
159 
160 void
162 {
163  for (unsigned long i=0; i<mNextFreeEntry;) { // relies on mNextFreeEntry being decremented by deleteItem
164  if (value(i) == schValue)
165  deleteItem(i); // and don't advance
166  else
167  i++;
168  }
169 // NOT YET IMPLEMENTED - make smarter for large collections, incorporate delete
170 }
171 
172 
173 bool
174 OOF_ExpandableLongArray::contains(unsigned long schValue) const
175 {
176  const unsigned long numEntries = mNextFreeEntry;
177  for (unsigned long i=0; i<numEntries; i++) {
178  if (value(i)==schValue) {
179  return true;
180  }
181  }
182  return false;
183 }
184 
185 
186 bool
187 OOF_ExpandableLongArray::find(unsigned long schValue, unsigned long& foundAt) const
188 {
189  const unsigned long numEntries = mNextFreeEntry;
190  for (unsigned long i=0; i<numEntries; i++) {
191  if (value(i)==schValue) {
192  foundAt = i;
193  return true;
194  }
195  }
196  return false;
197 }
198 
199 
200 unsigned long
201 OOF_ExpandableLongArray::countOccurrences(unsigned long schValue) const
202 {
203  unsigned long ret = 0;
204  const unsigned long numEntries = mNextFreeEntry;
205  for (unsigned long i=0; i<numEntries; i++) {
206  if (value(i)==schValue)
207  ret++;
208  }
209  return ret;
210 }
211 
212 
218 void
219 OOF_ExpandableLongArray::deleteAllCells(bool alwaysDeleteStorage) {
220  mNextFreeEntry=0;
221  if (alwaysDeleteStorage)
222  DeleteBits() ;
223  assert(Invariant());
224 }
225 
226 
227 unsigned long&
229 {
230  assert(mNextFreeEntry <= mNumSlots);
231 #ifdef OOF_MEM_DEBUG_FORCE_POOL_CHECK
233 #endif
234  if (index >= mNumSlots)
235  ExpandToInclude(index);
236  if (index >= mNextFreeEntry)
237  mNextFreeEntry = index+1;
238  return mBits[index];
239 }
240 
241 
242 unsigned long
243 OOF_ExpandableLongArray::value(unsigned long index) const
244 {
245  unsigned long ret;
246  if (index >= mNextFreeEntry)
247  ret = mDefaultValue;
248  else
249  ret = mBits[index];
250  return ret;
251 }
252 
253 
257 void
258 OOF_ExpandableLongArray::ExpandToInclude(unsigned long indexToCover)
259 {
260 // expand the storage to include the specified index
261 // (ie: expand to the next chunk multiple >= indexToCover
262  const unsigned long newSize = (indexToCover / mExpansionChunk + 1) * mExpansionChunk;
263  unsigned long* newBits = new unsigned long[newSize];
264 // NOT YET IMPLEMENTED - need error handling here
265 
266  assert(newBits);
267  if (mBits) {
268  const unsigned long numEntries = mNextFreeEntry;
269  for (unsigned long i=0; i<numEntries; i++)
270  newBits[i] = mBits[i];
271  delete[] mBits;
272  }
273  mBits = newBits;
274 #ifdef OOF_MEM_DEBUG_FORCE_POOL_CHECK
276 #endif
277  for (unsigned long i=mNextFreeEntry; i<newSize; i++)
278  mBits[i] = mDefaultValue;
279  mNumSlots = newSize;
280 #ifdef OOF_MEM_DEBUG_FORCE_POOL_CHECK
282 #endif
283 }
284 
285 
286 // -------------------------------------------------------
287 // o o f A r r a y
288 // -------------------------------------------------------
290  unsigned long slotSize,
291  unsigned long /*numSlots*/,
292  unsigned int expandBySlots
293 ) :
294  mUserStorage(0), // user may init in subclass's ctor
295  mBits(0),
296  mNextFreeEntry(0),
297  mNumSlots(0),
298  mSlotSize(slotSize),
299  mExpansionChunk(expandBySlots)
300 {
301  if (mExpansionChunk<1)
302  mExpansionChunk = 1;
303 // unlike OOF_ExpandableLongArray we use virtual allocators
304 // therefore cannot allocate space in this base ctor
305  }
306 
307 
309  mUserStorage(0), // user may init in subclass's ctor
310  mNextFreeEntry(rhs.mNextFreeEntry),
311  mNumSlots(rhs.mNumSlots),
312  mInternalIter(0),
313  mExpansionChunk(rhs.mExpansionChunk)
314 {
315  mBits = rhs.CloneBits(); // rhs is actual subclass so can invoke virtual
316 }
317 
318 
320 {
321  delete[] (char*)mBits; // user must set to zero if have DeleteBits
322  // and use their own dtor!!!
323 }
324 
325 
326 oofArray&
328 {
329  if ((this == &rhs) || (mBits == rhs.mBits))
330  return *this;
331 
333  mNumSlots = rhs.mNumSlots;
334  mInternalIter = 0;
336 
337  DeleteBits(true /* copying */);
338  mBits = rhs.CloneBits(); // rhs is actual subclass so can invoke virtual
339  if (mUserStorage)
340  *mUserStorage = mBits;
341 #ifdef OOF_MEM_DEBUG_FORCE_POOL_CHECK
343 #endif
344  assert(Invariant());
345  return *this;
346 }
347 
348 
349 void*
351 {
352  // default implementation based on bit-level copy of contents
353  // you may have to implement your own copy loop
354  // using actual user array slot types
355  void* ret = AllocBits(mNumSlots);
356  const unsigned long numBytes = mNumSlots*mSlotSize;
357  memcpy(ret, mBits, numBytes);
358 #ifdef OOF_MEM_DEBUG_FORCE_POOL_CHECK
360 #endif
361  return ret;
362 }
363 
364 
365 unsigned long
367 {
368 #ifdef OOF_MEM_DEBUG_FORCE_POOL_CHECK
370 #endif
371  const unsigned long ret = mNextFreeEntry;
372  if (ret >= mNumSlots || !mBits) // on init, next is 0 but have no storage
373  ExpandToInclude(ret);
374  mNextFreeEntry++;
375  return ret;
376 }
377 
378 
379 void
380 oofArray::ExpandToInclude(unsigned long indexToCover)
381 {
382 // expand the storage to include the specified index
383 // (ie: expand to the next chunk multiple >= indexToCover
384  const unsigned long newSize = (indexToCover / mExpansionChunk + 1) * mExpansionChunk;
385  void* newBits = AllocBits(newSize);
386 // NOT YET IMPLEMENTED - need error handling here
387 
388  assert(newBits);
389  if (mBits) {
390  const unsigned long bytesToCopy = mNextFreeEntry*mSlotSize;
391  memcpy(newBits, mBits, bytesToCopy);
392  DeleteBits(true /* copying */);
393  }
394  mBits = newBits;
395  if (mUserStorage)
396  *mUserStorage = newBits; // update their pointer
397 #ifdef OOF_MEM_DEBUG_FORCE_POOL_CHECK
399 #endif
400  mNumSlots = newSize;
401  assert(Invariant());
402 }
403 
unsigned long mInternalIter
Definition: oofarray.h:105
unsigned long mDefaultValue
Definition: oofarray.h:62
void ExpandToInclude(unsigned long indexToCover)
Definition: oofarray.cpp:380
precompilation header.
void ** mUserStorage
Definition: oofarray.h:103
unsigned long * mBits
Definition: oofarray.h:61
virtual void * CloneBits() const
Definition: oofarray.cpp:350
void CopyBits(const OOF_ExpandableLongArray &rhs)
Definition: oofarray.cpp:110
bool find(unsigned long value, unsigned long &foundAt) const
Definition: oofarray.cpp:187
virtual ~OOF_ExpandableLongArray()
Definition: oofarray.cpp:78
unsigned long count() const
Definition: oofarray.h:126
bool Invariant() const
Guarantee members managing storage are consistent.
Definition: oofarray.h:119
OOF_ExpandableLongArray(unsigned long defaultValue=0, unsigned long numSlots=0, unsigned int expandBySlots=4)
Definition: oofarray.cpp:26
virtual ~oofArray()
Definition: oofarray.cpp:319
unsigned long mNextFreeEntry
Definition: oofarray.h:63
unsigned long countOccurrences(unsigned long) const
Definition: oofarray.cpp:201
void deleteAllCells(bool alwaysDeleteStorage=false)
Effectively delete cells by resetting mNextFreeEntry cursor.
Definition: oofarray.cpp:219
bool contains(unsigned long value) const
Definition: oofarray.cpp:174
void deleteItem(unsigned long index)
Definition: oofarray.cpp:137
void describe(std::ostream &) const
Definition: oofarray.cpp:86
unsigned long mNextFreeEntry
Definition: oofarray.h:105
OOF_ExpandableLongArray & operator=(const OOF_ExpandableLongArray &)
Definition: oofarray.cpp:63
virtual void DeleteBits(bool becauseExpanding)=0
oofArray & operator=(const oofArray &)
Definition: oofarray.cpp:327
void * mBits
Definition: oofarray.h:104
Array of longs which expands automatically as you write to cells.
Definition: oofarray.h:21
virtual void * AllocBits(unsigned long) const =0
unsigned long mNumSlots
Definition: oofarray.h:105
unsigned long mNumSlots
Definition: oofarray.h:63
void append(unsigned long)
Definition: oofarray.cpp:131
base class for user arrays.
Definition: oofarray.h:76
unsigned long mInternalIter
Definition: oofarray.h:63
#define OOF_MEM_DEBUG_FORCE_POOL_CHECK
Definition: doxyoof.h:408
unsigned int mExpansionChunk
Definition: oofarray.h:106
unsigned long mSlotSize
Definition: oofarray.h:105
unsigned long AllocSlot()
Definition: oofarray.cpp:366
void ExpandToInclude(unsigned long indexToCover)
Definition: oofarray.cpp:258
bool Invariant() const
Guarantee members managing storage are consistent.
Definition: oofarray.h:183
oofArray(unsigned long slotSize, unsigned long numSlots=0, unsigned int expandBySlots=4)
Definition: oofarray.cpp:289
void deleteFirstMatching(unsigned long value)
Definition: oofarray.cpp:152
void deleteAllMatching(unsigned long value)
Definition: oofarray.cpp:161
unsigned long & operator[](unsigned long index)
Definition: oofarray.cpp:228
unsigned long index() const
Definition: oofarray.h:133
unsigned long value(unsigned long index) const
Definition: oofarray.cpp:243
unsigned int mExpansionChunk
Definition: oofarray.h:64