00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef cmplr_segmented_array_INCLUDED
00044 #define cmplr_segmented_array_INCLUDED
00045
00046 #ifndef __SGI_STL_ALGO_H
00047
00048 #if defined(defs_INCLUDED) && !defined(USE_STANDARD_TYPES)
00049 #undef short // get around bogus type defs.
00050 #undef int
00051 #undef long
00052 #endif // defined(defs_INCLUDED) && !defined(USE_STANDARD_TYPES)
00053
00054 #ifndef __GNUC__
00055 #include <CC/algorithm>
00056 #else
00057 #include <algorithm>
00058 #endif
00059
00060 #endif // __SGI_STL_ALGO_H
00061
00062 #ifndef __SGI_STL_VECTOR_H
00063
00064 #if defined(defs_INCLUDED) && !defined(USE_STANDARD_TYPES)
00065 #undef short // get around bogus type defs.
00066 #undef int
00067 #undef long
00068 #endif // defined(defs_INCLUDED) && !defined(USE_STANDARD_TYPES)
00069
00070 #ifndef __GNUC__
00071 #include <CC/vector>
00072 #else
00073 #include <vector>
00074 #endif
00075
00076 #endif // __SGI_STL_VECTOR_H
00077
00078 #ifndef __SGI_STL_SLIST_H
00079
00080 #if defined(defs_INCLUDED) && !defined(USE_STANDARD_TYPES)
00081 #undef short // get around bogus type defs.
00082 #undef int
00083 #undef long
00084 #endif // defined(defs_INCLUDED) && !defined(USE_STANDARD_TYPES)
00085
00086 #include <ext/slist>
00087 #endif // __SGI_STL_LIST_H
00088
00089
00090 #ifndef ERRORS_INCLUDED
00091 #include "errors.h"
00092 #endif // ERRORS_INCLUDED
00093
00094 #ifndef mempool_INCLUDED
00095 #include "mempool.h"
00096 #endif // mempool_INCLUDED
00097
00098 #ifndef segmented_array_INCLUDED
00099 #include "segmented_array.h"
00100 #endif // segmented_array_INCLUDED
00101
00102 #ifndef mempool_allocator_INCLUDED
00103 #include "mempool_allocator.h"
00104 #endif
00105
00106 using std::find;
00107 using __gnu_cxx::slist;
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 class growing_table {
00171 protected:
00172 UINT size;
00173
00174 private:
00175 typedef slist<growing_table *> kids_type;
00176
00177 kids_type kids;
00178
00179 virtual void Construct_new_entry(void) = 0;
00180 virtual void Construct_new_entry(UINT n) = 0;
00181 virtual void Delete_last(void) = 0;
00182 virtual void Delete_last(UINT n) = 0;
00183
00184 protected:
00185
00186
00187
00188
00189
00190 void Decrease_kids_size(void)
00191 {
00192 for (kids_type::iterator kid = kids.begin();
00193 kid != kids.end();
00194 ++kid) {
00195 (*kid)->Delete_last();
00196 }
00197 }
00198
00199 void Decrease_kids_size(UINT n)
00200 {
00201 for (kids_type::iterator kid = kids.begin();
00202 kid != kids.end();
00203 ++kid) {
00204 (*kid)->Delete_last(n);
00205 }
00206 }
00207
00208 void Increase_kids_size(void)
00209 {
00210 for (kids_type::iterator kid = kids.begin();
00211 kid != kids.end();
00212 ++kid) {
00213 (*kid)->Construct_new_entry();
00214 }
00215 }
00216
00217 void Increase_kids_size(UINT n)
00218 {
00219 for (kids_type::iterator kid = kids.begin();
00220 kid != kids.end();
00221 ++kid) {
00222 (*kid)->Construct_new_entry(n);
00223 }
00224 }
00225
00226 public:
00227
00228
00229
00230 void Register(growing_table &kid)
00231 {
00232
00233 FmtAssert(kid.size <= size,
00234 ("growing_table::Register: child must not be larger "
00235 "than parent"));
00236
00237 while (kid.size < size) {
00238 kid.Construct_new_entry();
00239 }
00240
00241
00242 kids.push_front(&kid);
00243 }
00244
00245 void Un_register(growing_table &kid)
00246 {
00247 kids_type::iterator kid_ptr = find(kids.begin(), kids.end(), &kid);
00248 if (kid_ptr != kids.end()) {
00249 kids.erase(kid_ptr);
00250 }
00251 else {
00252 Fail_FmtAssertion("RELATED_SEGMENTED_ARRAY: Cannot un-register "
00253 "an unregistered kid");
00254 }
00255 }
00256 };
00257
00258 template <class T, UINT block_size = 128>
00259 class RELATED_SEGMENTED_ARRAY : public growing_table {
00260 private:
00261 typedef std::pair<T *, BOOL> thingy;
00262 std::vector<thingy, mempool_allocator<thingy> > map;
00263 MEM_POOL *pool;
00264 UINT max_size;
00265 INT block_base;
00266
00267
00268 UINT next_block_size;
00269 T *block;
00270
00271 private:
00272
00273 typedef RELATED_SEGMENTED_ARRAY<T, block_size> self;
00274
00275 public:
00276 typedef T base_type;
00277
00278 typedef T value_type;
00279 typedef value_type* pointer;
00280 typedef const value_type* const_pointer;
00281 typedef value_type& reference;
00282 typedef const value_type& const_reference;
00283 typedef UINT size_type;
00284 typedef INT difference_type;
00285
00286 typedef SEGMENTED_ARRAY_ITERATOR<self*, T, pointer, reference>
00287 iterator;
00288 typedef SEGMENTED_ARRAY_ITERATOR<const self*, T,
00289 const_pointer, const_reference>
00290 const_iterator;
00291
00292 private:
00293
00294
00295 virtual void Construct_new_entry(void)
00296 {
00297 if (size == max_size) Allocate();
00298 Increase_kids_size();
00299 new(&block[size++ - block_base]) T();
00300
00301
00302
00303
00304 }
00305
00306 virtual void Construct_new_entry(UINT n)
00307 {
00308
00309
00310 for (; n > 0; n--) {
00311 Construct_new_entry();
00312 }
00313 }
00314
00315 UINT Round_up (UINT s) {
00316 UINT mask = block_size - 1;
00317 return (s + mask) & ~mask;
00318 }
00319
00320 void Update_Map (T *marker, UINT new_size, BOOL own_memory);
00321
00322 void Pop_Map ();
00323
00324
00325 void Allocate ();
00326
00327 T& New_entry () {
00328 if (size == max_size) Allocate ();
00329 Increase_kids_size();
00330 return block[size++ - block_base];
00331 }
00332
00333
00334 void Copy (const T* x, UINT n) {
00335 std::copy(x, x + n, block + (size - block_base));
00336 size += n;
00337 Increase_kids_size(n);
00338 }
00339
00340
00341
00342 UINT next_block_idx(UINT block_idx) const {
00343 for ( ; block_idx + 1 < map.size() &&
00344 map[block_idx].first + block_size == map[block_idx + 1].first;
00345 ++block_idx)
00346 {}
00347 return block_idx + 1;
00348 }
00349
00350 public:
00351
00352 RELATED_SEGMENTED_ARRAY(MEM_POOL *m = Malloc_Mem_Pool) :
00353 pool (m), map(m) {
00354 size = max_size = next_block_size = 0;
00355 block_base = -1;
00356 block = 0;
00357 }
00358
00359 ~RELATED_SEGMENTED_ARRAY() {
00360
00361
00362 for (typename std::vector<thingy, mempool_allocator<thingy> >::iterator
00363 entry = map.begin();
00364 entry != map.end();
00365 ++entry) {
00366
00367 if (entry->second) {
00368 MEM_POOL_FREE(pool, entry->first);
00369 }
00370 }
00371 }
00372
00373 UINT Block_size () const { return block_size; }
00374
00375 UINT Size () const { return growing_table::size; }
00376
00377 T& Entry (UINT idx) {
00378 Is_True (idx < size, ("Array subscript out of bound"));
00379 return map[idx / block_size].first[idx % block_size];
00380 }
00381
00382 const T& Entry (UINT idx) const {
00383 Is_True (idx < size, ("Array subscript out of bound"));
00384 return map[idx / block_size].first[idx % block_size];
00385 }
00386
00387
00388 T& operator[] (UINT idx) { return Entry(idx); }
00389 const T& operator[] (UINT idx) const { return Entry(idx); }
00390
00391 iterator begin () {
00392 return iterator (this, map[0].first, Block_end (0), 0);
00393 }
00394
00395 iterator end () {
00396 return iterator (this, block + (size - block_base),
00397 block + (max_size - block_base), size);
00398 }
00399
00400 const_iterator begin () const {
00401 return const_iterator (this, map[0].first, Block_end (0), 0);
00402 }
00403
00404 const_iterator end () const {
00405 return const_iterator (this, block + (size - block_base),
00406 block + (max_size - block_base), size);
00407 }
00408
00409 T& New_entry (UINT& idx) { idx = size; return New_entry (); }
00410
00411 UINT Insert (const T& x);
00412
00413 virtual void Delete_last () {
00414 size--;
00415 Decrease_kids_size();
00416 if (size == block_base)
00417 Pop_Map ();
00418 }
00419
00420 virtual void Delete_last (UINT n);
00421
00422
00423 UINT Insert (const T* x, UINT n_elemt);
00424
00425
00426 UINT Transfer (T* x, UINT n_elemt);
00427
00428
00429
00430 void Reserve (UINT n_elemt) {
00431 if (max_size - size + next_block_size < n_elemt)
00432 next_block_size = n_elemt - (max_size - size);
00433 }
00434
00435
00436 UINT Get_block_size (UINT idx) const {
00437 UINT block_idx = idx / block_size;
00438 return std::min(next_block_idx(block_idx) * block_size, size) - idx;
00439 }
00440
00441 UINT Block_index (UINT idx) const { return idx / block_size; }
00442
00443
00444 UINT Block_index_end () const { return map.size(); }
00445
00446 T* Block_begin (UINT block_idx) { return map[block_idx].first; }
00447 const T* Block_begin (UINT block_idx) const { return map[block_idx].first; }
00448
00449 T* Block_end(UINT block_idx) {
00450 return Block_begin(block_idx) +
00451 (next_block_idx(block_idx) - block_idx) * block_size;
00452 }
00453
00454 const T* Block_end(UINT block_idx) const {
00455 return Block_begin(block_idx) +
00456 (next_block_idx(block_idx) - block_idx) * block_size;
00457 }
00458
00459 void Clear(void);
00460 };
00461
00462 template <class T, UINT block_size>
00463 inline void
00464 RELATED_SEGMENTED_ARRAY<T,block_size>::Update_Map(T *marker,
00465 UINT new_size,
00466 BOOL own_memory)
00467 {
00468 do {
00469 map.push_back(pair<T*, BOOL>(marker, own_memory));
00470 new_size -= block_size;
00471 marker += block_size;
00472 own_memory += false;
00473
00474 } while (new_size);
00475 }
00476
00477
00478
00479 template <class T, UINT block_size>
00480 void
00481 RELATED_SEGMENTED_ARRAY<T,block_size>::Pop_Map ()
00482 {
00483 next_block_size += max_size - block_base;
00484 MEM_POOL_FREE (pool, block);
00485
00486 T *last_map_entry;
00487 do {
00488 last_map_entry = (map.end() - 1)->first;
00489 map.pop_back ();
00490 } while (last_map_entry != block);
00491
00492 max_size = size;
00493 if (size > 0) {
00494 Is_True(size >= block_size,
00495 ("RELATED_SEGMENTED_ARRAY: size in limbo"));
00496 block_base = size - block_size;
00497 UINT idx = block_base / block_size;
00498 block = map[idx].first;
00499 while (idx > 0 && map[idx - 1].first + block_size == block) {
00500 block = map[--idx].first;
00501 block_base -= block_size;
00502 }
00503 }
00504 else {
00505 Is_True(map.begin() == map.end(),
00506 ("RELATED_SEGMENTED_ARRAY::Pop_Map: Map should be empty"));
00507 block_base = -1;
00508 block = NULL;
00509 }
00510 }
00511
00512
00513 template <class T, UINT block_size>
00514 void
00515 RELATED_SEGMENTED_ARRAY<T,block_size>::Allocate ()
00516 {
00517 Is_True (size == max_size, ("Invalid internal state in segmented array"));
00518
00519 UINT new_size;
00520
00521 if (next_block_size == 0)
00522 new_size = block_size;
00523 else {
00524 new_size = Round_up (next_block_size);
00525 next_block_size = 0;
00526 }
00527
00528 block = (T *) MEM_POOL_Alloc (pool, new_size * sizeof(T));
00529 max_size += new_size;
00530 block_base = size;
00531
00532 Update_Map (block, new_size, TRUE);
00533 }
00534
00535
00536 template <class T, UINT block_size>
00537 void
00538 RELATED_SEGMENTED_ARRAY<T,block_size>::Delete_last (UINT n)
00539 {
00540 while (n >= size - block_base) {
00541 n -= size - block_base;
00542 size = block_base;
00543 Pop_Map ();
00544 }
00545 size -= n;
00546 Decrease_kids_size(n);
00547 }
00548
00549
00550 template <class T, UINT block_size>
00551 inline UINT
00552 RELATED_SEGMENTED_ARRAY<T,block_size>::Insert (const T& x)
00553 {
00554 UINT idx = size;
00555 T &entry = New_entry ();
00556
00557 entry = x;
00558 return idx;
00559 }
00560
00561
00562 template <class T, UINT block_size>
00563 UINT
00564 RELATED_SEGMENTED_ARRAY<T,block_size>::Insert (const T* x, UINT n_elemt)
00565 {
00566 UINT result = size;
00567 if (size + n_elemt <= max_size) {
00568 Copy (x, n_elemt);
00569 return result;
00570 }
00571
00572 UINT space_left = max_size - size;
00573 Copy (x, space_left);
00574 n_elemt -= space_left;
00575
00576 Reserve (n_elemt);
00577 Allocate ();
00578 Copy (x + space_left, n_elemt);
00579
00580 return result;
00581 }
00582
00583
00584 template <class T, UINT block_size>
00585 UINT
00586 RELATED_SEGMENTED_ARRAY<T,block_size>::Transfer (T* x, UINT n_elemt)
00587 {
00588 UINT result = size;
00589
00590 if (size + n_elemt <= max_size) {
00591 Copy (x, n_elemt);
00592 return result;
00593 }
00594
00595 UINT space_left = max_size - size;
00596 if (space_left > 0) {
00597 Copy (x, space_left);
00598 n_elemt -= space_left;
00599 x += space_left;
00600 }
00601
00602 if (n_elemt >= block_size) {
00603 UINT reused_size = n_elemt & ~(block_size - 1);
00604 block = x;
00605 Update_Map (block, reused_size, FALSE);
00606 block_base = size;
00607 size += reused_size;
00608 max_size += reused_size;
00609 n_elemt -= reused_size;
00610 x += reused_size;
00611 if (next_block_size > reused_size)
00612 next_block_size -= reused_size;
00613 else
00614 next_block_size = 0;
00615 }
00616
00617 if (n_elemt > 0) {
00618 Allocate ();
00619 Copy (x, n_elemt);
00620 }
00621
00622 return result;
00623 }
00624
00625
00626
00627 template <class T, UINT block_size>
00628 void
00629 RELATED_SEGMENTED_ARRAY<T,block_size>::Clear(void)
00630 {
00631 if (growing_table::size > 0) {
00632 Delete_last(growing_table::size);
00633 }
00634 Is_True(map.begin() == map.end(),
00635 ("RELATED_SEGMENTED_ARRAY::Clear: Map should be empty"));
00636 }
00637
00638 template <class T, UINT block_size, class OP>
00639 inline void
00640 For_all_entries (RELATED_SEGMENTED_ARRAY<T, block_size>& array,
00641 const OP &op,
00642 UINT32 first = 0)
00643 {
00644 UINT last = array.Size ();
00645
00646 while (first < last) {
00647 T *block = &array[first];
00648 UINT size = array.Get_block_size (first);
00649 for (UINT j = 0; j < size; ++j, ++block)
00650 op (first + j, block);
00651 first += size;
00652 }
00653 }
00654
00655
00656
00657
00658 #if 0
00659
00660 template <class T, UINT block_size, class OP>
00661 inline void
00662 For_all_entries (const RELATED_SEGMENTED_ARRAY<T, block_size>& array,
00663 const OP &op,
00664 UINT32 first = 0)
00665 {
00666 UINT last = array.Size ();
00667
00668 while (first < last) {
00669 const T *block = &array[first];
00670 UINT size = array.Get_block_size (first);
00671 for (UINT j = 0; j < size; ++j, ++block)
00672 op (first + j, block);
00673 first += size;
00674 }
00675 }
00676
00677 #endif
00678
00679 template <class T, UINT block_size, class OP>
00680 inline void
00681 For_all_blocks (RELATED_SEGMENTED_ARRAY<T, block_size>& array, const OP &op)
00682 {
00683 UINT max_size = array.Size ();
00684 UINT i = 0;
00685
00686 while (i < max_size) {
00687 T *block = &array[i];
00688 UINT size = array.Get_block_size (i);
00689 op (i, block, size);
00690 i += size;
00691 }
00692 }
00693
00694
00695 #define NOT_FOUND ((UINT) -1)
00696
00697 template <class T, UINT block_size, class PREDICATE>
00698 inline UINT
00699 Find_entry_if (const RELATED_SEGMENTED_ARRAY<T, block_size>& array,
00700 const PREDICATE& pred, UINT i = 0)
00701 {
00702 UINT max_size = array.Size ();
00703
00704 while (i < max_size) {
00705 const T *block = &array[i];
00706 UINT size = array.Get_block_size (i);
00707 for (UINT j = 0; j < size; ++j, ++block)
00708 if (pred (i+j, block))
00709 return i + j;
00710 i += size;
00711 }
00712
00713 return (UINT) NOT_FOUND;
00714 }
00715
00716
00717
00718
00719
00720 template <class T, UINT block_size>
00721 UINT32
00722 Copy_array_range (const RELATED_SEGMENTED_ARRAY<T, block_size>& from_array,
00723 RELATED_SEGMENTED_ARRAY<T, block_size>& to_array,
00724 UINT32 first_idx = 0, UINT32 last_idx = (UINT32) -1)
00725 {
00726 if (last_idx > from_array.Size ())
00727 last_idx = from_array.Size ();
00728
00729 Is_True (last_idx >= first_idx, ("Invalid copy range"));
00730
00731 UINT32 entries = last_idx - first_idx;
00732
00733 to_array.Reserve (entries);
00734
00735 while (first_idx < last_idx) {
00736 const T* block = &from_array[first_idx];
00737 UINT32 size = from_array.Get_block_size (first_idx);
00738 if (size > last_idx - first_idx)
00739 size = last_idx - first_idx;
00740
00741 to_array.Insert (block, size);
00742 first_idx += size;
00743 }
00744
00745 return entries;
00746 }
00747
00748
00749
00750
00751
00752 template <class T, UINT block_size>
00753 void
00754 Delete_array_item (const RELATED_SEGMENTED_ARRAY<T, block_size>& from_array,
00755 RELATED_SEGMENTED_ARRAY<T, block_size>& to_array,
00756 UINT32 first_idx = 0, UINT32 last_idx = (UINT32) -1)
00757 {
00758 UINT32 index;
00759 index = to_array.Size() - from_array.Size();
00760
00761 while ( index < to_array.Size()) {
00762 T* block = &to_array[index];
00763 if (block->name_idx !=0 )
00764 block->name_idx = 0;
00765 index ++;
00766 }
00767 }
00768
00769 #endif // cmplr_segmented_array_INCLUDED