19 #ifndef LINEAR_POOL_HPP
20 #define LINEAR_POOL_HPP
22 #include <Bitmask.hpp>
23 #include "SuperPool.hpp"
66 #include "SuperPool.hpp"
68 template <
class T, U
int32 LogBase = 8>
70 typedef SuperPool::PtrI PtrI;
73 STATIC_CONST( Base = 1 << LogBase );
76 STATIC_CONST( DigitMask = Base - 1 );
79 STATIC_CONST( MaxLevels = (32 + LogBase - 1) / LogBase );
82 STATIC_CONST( BitmaskSize = (Base + 31) / 32 );
93 Uint32 m_bitmask[BitmaskSize];
115 void release(
Ptr<T>& ptr);
126 void get_map(
Ptr<Map>& map_ptr, Uint32 index);
138 void add_entry(
Ptr<Map> map_ptr, Uint32 digit, PtrI ptr_i);
141 void remove_entry(
Ptr<Map> map_ptr, Uint32 digit);
150 void remove_avail(
Ptr<Map> map_ptr);
156 void verify_map(
Ptr<Map> map_ptr, Uint32
level, Uint32* count);
162 PtrI m_avail[MaxLevels];
165 template <
class T, U
int32 LogBase>
174 for (n = 0; n < MaxLevels; n++)
178 template <
class T, U
int32 LogBase>
184 template <
class T, U
int32 LogBase>
188 Uint32
index = ptr.i;
191 get_map(map_ptr, index);
194 Uint32 digit = index & DigitMask;
196 rec_ptr.i = map_ptr.p->m_entry[digit];
197 m_records.getPtr(rec_ptr);
201 template <
class T, U
int32 LogBase>
209 while (n < m_levels) {
210 if ((map_ptr.i = m_avail[n]) != RNIL)
214 if (map_ptr.i == RNIL) {
218 assert(n < m_levels);
219 map_ptr.i = m_avail[
n];
221 m_maps.getPtr(map_ptr);
227 digit = map_ptr.p->m_firstfree;
231 if (! add_map(child_ptr, map_ptr, digit)) {
232 if (new_ptr.i != RNIL)
241 assert(map_ptr.p->m_level == 0);
243 if (! m_records.seize(rec_ptr)) {
244 if (new_ptr.i != RNIL)
248 add_entry(map_ptr, digit, rec_ptr.i);
249 ptr.i = digit + (map_ptr.p->m_index << LogBase);
254 template <
class T, U
int32 LogBase>
259 Uint32 digits[MaxLevels];
263 digits[
n] = tmp & DigitMask;
265 }
while (++n < m_levels || tmp != 0);
267 while (n > m_levels) {
274 m_maps.getPtr(map_ptr);
286 map_ptr.i = map_ptr.p->m_entry[digit];
287 m_maps.getPtr(map_ptr);
290 if (! add_map(child_ptr, map_ptr, digit)) {
291 if (new_ptr.i != RNIL)
299 assert(map_ptr.p->m_level == 0);
301 if (used || ! m_records.seize(rec_ptr)) {
302 if (new_ptr.i != RNIL)
304 return used ? -1 :
false;
306 add_entry(map_ptr, digit, rec_ptr.i);
307 assert(index == digit + (map_ptr.p->m_index << LogBase));
313 template <
class T, U
int32 LogBase>
317 Uint32 index = ptr.i;
320 get_map(map_ptr, index);
323 Uint32 digit = index & DigitMask;
324 rec_ptr.i = map_ptr.p->m_entry[digit];
325 m_records.release(rec_ptr);
327 remove_entry(map_ptr, digit);
333 template <
class T, U
int32 LogBase>
338 Uint32 count1 = sp.getRecUseCount(m_records.m_recInfo);
342 template <
class T, U
int32 LogBase>
347 if (m_root == RNIL) {
348 assert(m_levels == 0);
351 assert(m_levels != 0);
354 m_maps.getPtr(map_ptr);
355 Uint32 count1 = count();
357 verify_map(map_ptr, m_levels - 1, &count2);
358 assert(count1 == count2);
363 template <
class T, U
int32 LogBase>
370 m_maps.getPtr(tmp_ptr);
371 assert(tmp_ptr.p->m_level + 1 == m_levels);
373 Uint32 digits[MaxLevels];
376 digits[
n] = index & DigitMask;
378 }
while (++n < m_levels);
382 tmp_ptr.i = tmp_ptr.p->m_entry[digits[
n]];
383 m_maps.getPtr(tmp_ptr);
386 assert(tmp_ptr.p->m_level == 0);
390 template <
class T, U
int32 LogBase>
396 if (! m_maps.seize(map_ptr))
398 Uint32 n = m_levels++;
399 assert(n < MaxLevels);
401 map_ptr.p->m_level =
n;
402 map_ptr.p->m_parent = RNIL;
403 map_ptr.p->m_index = 0;
409 m_maps.getPtr(old_ptr);
410 assert(old_ptr.p->m_parent == RNIL);
411 old_ptr.p->m_parent = map_ptr.i;
412 add_entry(map_ptr, 0, old_ptr.i);
419 template <
class T, U
int32 LogBase>
423 if (! m_maps.seize(map_ptr))
425 assert(parent_ptr.p->m_level != 0);
427 map_ptr.p->m_level = parent_ptr.p->m_level - 1;
428 map_ptr.p->m_parent = parent_ptr.i;
429 map_ptr.p->m_index = digit + (parent_ptr.p->m_index << LogBase);
431 add_entry(parent_ptr, digit, map_ptr.i);
435 template <
class T, U
int32 LogBase>
439 map_ptr.p->m_occup = 0;
440 map_ptr.p->m_firstfree = 0;
444 for (j = 0; j < Base - 1; j++) {
445 map_ptr.p->m_entry[j] = back | ((j + 1) << 16);
448 map_ptr.p->m_entry[j] = back | (ZNIL << 16);
455 template <
class T, U
int32 LogBase>
459 assert(map_ptr.p->m_occup < Base && digit < Base);
462 Uint32 val = map_ptr.p->m_entry[digit];
463 Uint16 back = val & ZNIL;
464 Uint16 forw = val >> 16;
467 map_ptr.p->m_entry[back] &= ZNIL;
468 map_ptr.p->m_entry[back] |= (forw << 16);
472 map_ptr.p->m_entry[forw] &= (ZNIL << 16);
473 map_ptr.p->m_entry[forw] |= back;
476 map_ptr.p->m_firstfree = forw;
479 map_ptr.p->m_entry[digit] = ptr_i;
480 map_ptr.p->m_occup++;
482 if (map_ptr.p->m_occup == Base)
483 remove_avail(map_ptr);
486 template <
class T, U
int32 LogBase>
490 assert(map_ptr.p->m_occup != 0 && digit < Base);
493 Uint32 firstfree = map_ptr.p->m_firstfree;
494 map_ptr.p->m_entry[digit] = ZNIL | (firstfree << 16);
495 if (firstfree != ZNIL) {
496 assert(firstfree < Base);
497 map_ptr.p->m_entry[firstfree] &= (ZNIL << 16);
498 map_ptr.p->m_entry[firstfree] |= digit;
500 map_ptr.p->m_firstfree = digit;
501 map_ptr.p->m_occup--;
503 if (map_ptr.p->m_occup + 1 == Base)
505 else if (map_ptr.p->m_occup == 0)
509 template <
class T, U
int32 LogBase>
513 assert(map_ptr.p->m_occup == 0);
514 remove_avail(map_ptr);
516 parent_ptr.i = map_ptr.p->m_parent;
517 Uint32 digit = map_ptr.p->m_index & DigitMask;
518 PtrI map_ptr_i = map_ptr.i;
519 m_maps.release(map_ptr);
520 if (m_root == map_ptr_i) {
521 assert(parent_ptr.i == RNIL);
522 Uint32 used = count();
527 if (parent_ptr.i != RNIL) {
528 m_maps.getPtr(parent_ptr);
530 remove_entry(parent_ptr, digit);
534 template <
class T, U
int32 LogBase>
538 Uint32 n = map_ptr.p->m_level;
539 assert(n < m_levels);
540 map_ptr.p->m_nextavail = m_avail[
n];
541 if (map_ptr.p->m_nextavail != RNIL) {
543 next_ptr.i = map_ptr.p->m_nextavail;
544 m_maps.getPtr(next_ptr);
545 next_ptr.p->m_prevavail = map_ptr.i;
547 map_ptr.p->m_prevavail = RNIL;
548 m_avail[
n] = map_ptr.i;
551 template <
class T, U
int32 LogBase>
555 Uint32 n = map_ptr.p->m_level;
556 assert(n < m_levels);
557 if (map_ptr.p->m_nextavail != RNIL) {
559 next_ptr.i = map_ptr.p->m_nextavail;
560 m_maps.getPtr(next_ptr);
561 next_ptr.p->m_prevavail = map_ptr.p->m_prevavail;
563 if (map_ptr.p->m_prevavail != RNIL) {
565 prev_ptr.i = map_ptr.p->m_prevavail;
566 m_maps.getPtr(prev_ptr);
567 prev_ptr.p->m_nextavail = map_ptr.p->m_nextavail;
569 if (map_ptr.p->m_prevavail == RNIL) {
570 m_avail[
n] = map_ptr.p->m_nextavail;
572 map_ptr.p->m_nextavail = RNIL;
573 map_ptr.p->m_prevavail = RNIL;
576 template <
class T, U
int32 LogBase>
581 for (Uint32 n = 0; n < MaxLevels; n++) {
583 map_ptr.i = m_avail[
n];
585 while (map_ptr.i != RNIL) {
586 m_maps.getPtr(map_ptr);
587 assert(map_ptr.p->m_occup < Base);
588 assert(back == map_ptr.p->m_prevavail);
590 map_ptr.i = map_ptr.p->m_nextavail;
595 template <
class T, U
int32 LogBase>
599 assert(level < MaxLevels);
600 assert(map_ptr.p->m_level == level);
604 assert(nused <= Base);
605 assert(map_ptr.p->m_occup == nused);
607 Uint32 j = map_ptr.p->m_firstfree;
612 Uint32 val = map_ptr.p->m_entry[j];
613 assert(back == (val & ZNIL));
618 assert(nused + nfree == Base);
622 for (Uint32 j = 0; j < Base; j++) {
628 child_ptr.i = map_ptr.p->m_entry[j];
629 m_maps.getPtr(child_ptr);
630 assert(child_ptr.p->m_parent == map_ptr.i);
631 assert(child_ptr.p->m_index == j + (map_ptr.p->m_index << LogBase));
632 verify_map(child_ptr, level - 1, count);
635 rec_ptr.i = map_ptr.p->m_entry[j];
636 m_records.getPtr(rec_ptr);
644 avail_ptr.i = m_avail[map_ptr.p->m_level];
646 while (avail_ptr.i != RNIL) {
647 if (avail_ptr.i == map_ptr.i) {
651 m_maps.getPtr(avail_ptr);
652 avail_ptr.i = avail_ptr.p->m_nextavail;
654 assert(found == (map_ptr.p->m_occup < Base));