00001 #ifndef TREESTORAGESCHEMES_H
00002 #define TREESTORAGESCHEMES_H
00003
00004 #include <stack>
00005 #include <assert.h>
00006
00007
00008 template <typename DataType>
00009 class HeapStorage
00010 {
00011 public:
00012 typedef PriorityQueueSizeType SizeType;
00013 HeapStorage( DataType* pool, const SizeType& height):m_pool(pool)
00014 {
00015 }
00016
00017 ~HeapStorage()
00018 {
00019 }
00020
00021 DataType* getRootAddr() const
00022 {
00023 return m_pool;
00024 }
00025
00026 DataType* getBfsIndexAddress( const SizeType& bfsIndex)
00027 {
00028 return m_pool + bfsIndex - 1;
00029 }
00030
00031 DataType* getLeftChildAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00032 {
00033 return ptr + bfsIndex;
00034 }
00035
00036 SizeType getMemoryUsage() const
00037 {
00038 return sizeof( DataType*);
00039 }
00040
00041 DataType* getRightChildAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00042 {
00043 return ptr + bfsIndex + 1;
00044 }
00045
00046 DataType* getParentAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00047 {
00048 return (bfsIndex & 1) ? ptr - ((bfsIndex >> 1) + 1) : ptr - (bfsIndex >> 1);
00049 }
00050
00051 private:
00052 DataType* m_pool;
00053 };
00054
00055
00056 template <typename DataType>
00057 class VebStorage
00058 {
00059 public:
00060 typedef PriorityQueueSizeType SizeType;
00061 VebStorage( DataType* pool, const SizeType& height):m_pool(pool),m_height(height)
00062 {
00063 upperLevels = new SizeType[ height + 1];
00064 lowerLevels = new SizeType[ height + 1];
00065 treeSize = new SizeType[ height + 1];
00066
00067 calculateTransitionValues( height);
00068 }
00069
00070 ~VebStorage()
00071 {
00072 delete [] upperLevels;
00073 delete [] lowerLevels;
00074 delete [] treeSize;
00075 }
00076
00077 DataType* getRootAddr() const
00078 {
00079 return m_pool;
00080 }
00081
00082 DataType* getBfsIndexAddress( const SizeType& bfsIndex)
00083 {
00084 return m_pool + getVebFromBfs( bfsIndex);
00085 }
00086
00087 DataType* getLeftChildAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00088 {
00089 if( upperLevels[height] == 1) return ptr + 1;
00090 return ptr + getLeftStep( bfsIndex, height);
00091 }
00092
00093 SizeType getMemoryUsage() const
00094 {
00095 return sizeof( DataType*);
00096 }
00097
00098 DataType* getRightChildAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00099 {
00100 if( upperLevels[height] == 1) return ptr + 2;
00101 return ptr + getRightStep( bfsIndex, height);
00102 }
00103
00104 DataType* getParentAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00105 {
00106 if( upperLevels[height + 1] == 1)
00107 {
00108 return ptr - (1 + (bfsIndex & 1));
00109 }
00110 if( bfsIndex & 1)
00111 {
00112 return ptr - getRightStep( bfsIndex >> 1, height + 1);
00113 }
00114 else
00115 {
00116 return ptr - getLeftStep( bfsIndex >> 1, height + 1);
00117 }
00118 }
00119
00120 const SizeType& getRightStep( const SizeType bfsIndex, const SizeType height)
00121 {
00122 levels = upperLevels[height];
00123 childIndex = (bfsIndex << 1);
00124 siblings = (childIndex & treeSize[levels]) + 1;
00125 sum = (1 << levels) + ( (siblings) << lowerLevels[ height]) - (siblings << 1);
00126
00127 while( levels > 1)
00128 {
00129 upper = (levels >> 1) + (levels & 1);
00130 levels = (levels >> 1);
00131 fatherIndex = bfsIndex >> (levels - 1);
00132 sum += (fatherIndex & treeSize[upper]);
00133 sum -= treeSize[upper];
00134 }
00135 return sum;
00136 }
00137
00138 const SizeType& getLeftStep(const SizeType& bfsIndex, const SizeType& height)
00139 {
00140 levels = upperLevels[height];
00141
00142 childIndex = (bfsIndex << 1);
00143 siblings = (childIndex & treeSize[levels]);
00144 sum = (1<<levels) - 1 + (siblings << lowerLevels[height]) - (siblings << 1);
00145
00146 while( levels > 1)
00147 {
00148 upper = (levels >> 1) + (levels & 1);
00149 levels = (levels >> 1);
00150 fatherIndex = bfsIndex >> (levels - 1);
00151 sum += (fatherIndex & treeSize[upper]);
00152 sum -= treeSize[upper];
00153 }
00154 return sum;
00155 }
00156
00157 private:
00158 DataType* m_pool;
00159
00160 SizeType* upperLevels;
00161 SizeType* lowerLevels;
00162 SizeType* treeSize;
00163
00164 SizeType m_height;
00165
00166 SizeType sum,upper,levels;
00167 SizeType siblings, fatherIndex, childIndex;
00168
00169
00170 void calculateTransitionValues( const SizeType& height)
00171 {
00172 std::stack< std::pair<SizeType,SizeType> > S;
00173
00174 S.push( std::pair<SizeType,SizeType>( 0, height + 1));
00175 SizeType subTreeLevels;
00176 SizeType middleLevel;
00177 std::pair<SizeType,SizeType> levelRange;
00178
00179
00180 while( !S.empty())
00181 {
00182 levelRange = S.top();
00183
00184 S.pop();
00185 subTreeLevels = levelRange.second - levelRange.first;
00186
00187 for( SizeType h = 0; h <= height; h++)
00188 {
00189 treeSize[ h] = (1<<h) - 1;
00190 }
00191
00192 if( subTreeLevels > 1)
00193 {
00194
00195
00196 middleLevel = levelRange.first + (subTreeLevels >> 1);
00197
00198
00199
00200
00201
00202
00203 lowerLevels[ middleLevel] = middleLevel - levelRange.first;
00204
00205 upperLevels[ middleLevel] = levelRange.second - middleLevel;
00206
00207 S.push( std::pair<SizeType,SizeType>( middleLevel, levelRange.second));
00208 S.push( std::pair<SizeType,SizeType>( levelRange.first, middleLevel));
00209 }
00210
00211 }
00212
00213 upperLevels[height] = 1;
00214
00215 lowerLevels[0] = 0;
00216 upperLevels[0] = 1;
00217
00218 }
00219
00220 const SizeType& getVebFromBfs( const SizeType& bfsIndex)
00221 {
00222 sum = 0;
00223 if (bfsIndex == 1) return sum;
00224
00225 childIndex = bfsIndex;
00226 SizeType height = m_height - floorLog2( childIndex);
00227
00228 while( childIndex != 1)
00229 {
00230 sum += ( childIndex & ((1 << upperLevels[height + 1]) - 1)) * treeSize[ lowerLevels[ height + 1]];
00231 sum += treeSize[ upperLevels[height + 1]];
00232 childIndex >>= upperLevels[height + 1];
00233 height += upperLevels[height + 1];
00234 }
00235 return sum;
00236 }
00237 };
00238
00239
00240
00241
00242 template <typename DataType>
00243 class ExplicitNodePointers
00244 {
00245 public:
00246 DataType* leftChild;
00247 DataType* rightChild;
00248 DataType* parent;
00249 };
00250
00251
00252 template <typename DataType>
00253 class ExplicitHeapStorage
00254 {
00255 public:
00256 typedef PriorityQueueSizeType SizeType;
00257 typedef ExplicitNodePointers<DataType> PointerType;
00258
00259 ExplicitHeapStorage( DataType* pool, const SizeType& height):m_pool(pool)
00260 {
00261 m_explicit = new PointerType[ (1<<(height + 1))];
00262 calculateTransitionValues( height);
00263 }
00264
00265 ~ExplicitHeapStorage()
00266 {
00267 delete [] m_explicit;
00268 }
00269
00270 DataType* getRootAddr() const
00271 {
00272 return m_pool;
00273 }
00274
00275 DataType* getBfsIndexAddress( const SizeType& bfsIndex)
00276 {
00277 return m_pool + bfsIndex - 1;
00278 }
00279
00280 DataType* getLeftChildAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00281 {
00282 assert( m_explicit[ptr-m_pool].leftChild == ptr + bfsIndex);
00283 return m_explicit[ptr-m_pool].leftChild;
00284 }
00285
00286 SizeType getMemoryUsage() const
00287 {
00288 return sizeof( DataType*);
00289 }
00290
00291 DataType* getRightChildAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00292 {
00293
00294 assert( m_explicit[ptr-m_pool].rightChild == ptr + bfsIndex + 1);
00295 return m_explicit[ptr-m_pool].rightChild;
00296 }
00297
00298 DataType* getParentAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00299 {
00300 return m_explicit[ptr-m_pool].parent;
00301 }
00302
00303 private:
00304 DataType* m_pool;
00305 PointerType* m_explicit;
00306
00307 void calculateTransitionValues( const SizeType& height)
00308 {
00309 for( unsigned int i = 1; i < ( (unsigned int)1<< (height+1)); ++i)
00310 {
00311 if( i != 1)
00312 {
00313 m_explicit[i - 1].parent = m_pool + (i>>1) - 1;
00314 }
00315
00316 if( (unsigned int)floorLog2(i) != height)
00317 {
00318 m_explicit[i - 1].leftChild = m_pool + ( i<<1) - 1;
00319
00320 m_explicit[i - 1].rightChild = m_pool + ((i<<1) + 1) - 1;
00321 }
00322 }
00323 }
00324
00325 };
00326
00327
00328 template <typename DataType>
00329 class ExplicitVebStorage
00330 {
00331 public:
00332 typedef PriorityQueueSizeType SizeType;
00333 typedef ExplicitNodePointers<DataType> PointerType;
00334
00335 ExplicitVebStorage( DataType* pool, const SizeType& height):m_pool(pool),m_height(height)
00336 {
00337 upperLevels = new SizeType[ height + 1];
00338 lowerLevels = new SizeType[ height + 1];
00339 treeSize = new SizeType[ height + 1];
00340 bfsToVeb = new SizeType[ (1<<(height + 1))];
00341
00342 m_explicit = new PointerType[ (1<<(height + 1))];
00343 calculateTransitionValues( height);
00344 }
00345
00346 ~ExplicitVebStorage()
00347 {
00348 delete [] upperLevels;
00349 delete [] lowerLevels;
00350 delete [] treeSize;
00351 delete [] bfsToVeb;
00352 delete [] m_explicit;
00353 }
00354
00355 DataType* getRootAddr() const
00356 {
00357 return m_pool;
00358 }
00359
00360 DataType* getBfsIndexAddress( const SizeType& bfsIndex)
00361 {
00362 return m_pool + bfsToVeb[ bfsIndex];
00363 }
00364
00365 DataType* getLeftChildAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00366 {
00367 return m_explicit[ptr-m_pool].leftChild;
00368 }
00369
00370 SizeType getMemoryUsage() const
00371 {
00372 return sizeof( DataType*);
00373 }
00374
00375 DataType* getRightChildAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00376 {
00377 return m_explicit[ptr-m_pool].rightChild;
00378 }
00379
00380 DataType* getParentAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00381 {
00382 return m_explicit[ptr-m_pool].parent;
00383 }
00384
00385 private:
00386 DataType* m_pool;
00387
00388 SizeType m_height, sum, childIndex;
00389
00390 SizeType* upperLevels;
00391 SizeType* lowerLevels;
00392 SizeType* treeSize;
00393 SizeType* bfsToVeb;
00394 PointerType* m_explicit;
00395
00396 void calculateTransitionValues( const SizeType& height)
00397 {
00398 std::stack< std::pair<SizeType,SizeType> > S;
00399
00400 S.push( std::pair<SizeType,SizeType>( 0, height + 1));
00401 SizeType subTreeLevels;
00402 SizeType middleLevel;
00403 std::pair<SizeType,SizeType> levelRange;
00404
00405
00406
00407 while( !S.empty())
00408 {
00409 levelRange = S.top();
00410
00411 S.pop();
00412 subTreeLevels = levelRange.second - levelRange.first;
00413
00414 for( SizeType h = 0; h <= height; h++)
00415 {
00416 treeSize[ h] = (1<<h) - 1;
00417 }
00418
00419 if( subTreeLevels > 1)
00420 {
00421
00422
00423 middleLevel = levelRange.first + (subTreeLevels >> 1) + (subTreeLevels & 1);
00424
00425
00426
00427
00428
00429
00430 lowerLevels[ middleLevel] = middleLevel - levelRange.first;
00431
00432 upperLevels[ middleLevel] = levelRange.second - middleLevel;
00433
00434 S.push( std::pair<SizeType,SizeType>( middleLevel, levelRange.second));
00435 S.push( std::pair<SizeType,SizeType>( levelRange.first, middleLevel));
00436 }
00437
00438 }
00439
00440 upperLevels[height] = 1;
00441
00442 lowerLevels[0] = 0;
00443 upperLevels[0] = 1;
00444
00445 for( unsigned int i = 1; i < ((unsigned int) 1<< (height+1)); ++i)
00446 {
00447 bfsToVeb[i] = getVebFromBfs(i);
00448
00449 if( i != 1)
00450 {
00451 m_explicit[ getVebFromBfs(i)].parent = m_pool + getVebFromBfs(i>>1);
00452 }
00453
00454 if( (unsigned int)floorLog2(i) != height)
00455 {
00456 m_explicit[ getVebFromBfs(i)].leftChild = m_pool + getVebFromBfs( i<<1);
00457 m_explicit[ getVebFromBfs(i)].rightChild = m_pool + getVebFromBfs( (i<<1) + 1);
00458 }
00459 }
00460 }
00461
00462 const SizeType& getVebFromBfs( const SizeType& bfsIndex)
00463 {
00464 sum = 0;
00465 if (bfsIndex == 1) return sum;
00466
00467 childIndex = bfsIndex;
00468 SizeType height = m_height - floorLog2( childIndex);
00469
00470 while( childIndex != 1)
00471 {
00472 sum += ( childIndex & ((1 << upperLevels[height + 1]) - 1)) * treeSize[ lowerLevels[ height + 1]];
00473 sum += treeSize[ upperLevels[height + 1]];
00474 childIndex >>= upperLevels[height + 1];
00475 height += upperLevels[height + 1];
00476 }
00477 return sum;
00478 }
00479 };
00480
00481
00482 template <typename DataType>
00483 class ExplicitPowerVebStorage
00484 {
00485 public:
00486 typedef PriorityQueueSizeType SizeType;
00487 typedef ExplicitNodePointers<DataType> PointerType;
00488
00489 ExplicitPowerVebStorage( DataType* pool, const SizeType& height):m_pool(pool),m_height(height)
00490 {
00491 upperLevels = new SizeType[ height + 1];
00492 lowerLevels = new SizeType[ height + 1];
00493 treeSize = new SizeType[ height + 1];
00494 bfsToVeb = new SizeType[ (1<<(height + 1))];
00495
00496 m_explicit = new PointerType[ (1<<(height + 1))];
00497 calculateTransitionValues( height);
00498 }
00499
00500 ~ExplicitPowerVebStorage()
00501 {
00502 delete [] upperLevels;
00503 delete [] lowerLevels;
00504 delete [] treeSize;
00505 delete [] bfsToVeb;
00506 delete [] m_explicit;
00507 }
00508
00509 DataType* getRootAddr() const
00510 {
00511 return m_pool;
00512 }
00513
00514 DataType* getBfsIndexAddress( const SizeType& bfsIndex)
00515 {
00516 return m_pool + bfsToVeb[ bfsIndex];
00517 }
00518
00519 DataType* getLeftChildAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00520 {
00521 return m_explicit[ptr-m_pool].leftChild;
00522 }
00523
00524 SizeType getMemoryUsage() const
00525 {
00526 return sizeof( DataType*);
00527 }
00528
00529 DataType* getRightChildAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00530 {
00531 return m_explicit[ptr-m_pool].rightChild;
00532 }
00533
00534 DataType* getParentAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00535 {
00536 return m_explicit[ptr-m_pool].parent;
00537 }
00538
00539 private:
00540 DataType* m_pool;
00541
00542 SizeType m_height, sum, childIndex;
00543
00544 SizeType* upperLevels;
00545 SizeType* lowerLevels;
00546 SizeType* treeSize;
00547 SizeType* bfsToVeb;
00548 PointerType* m_explicit;
00549
00550 void calculateTransitionValues( const SizeType& height)
00551 {
00552 std::stack< std::pair<SizeType,SizeType> > S;
00553
00554 S.push( std::pair<SizeType,SizeType>( 0, height + 1));
00555 SizeType subTreeLevels;
00556 SizeType middleLevel;
00557 std::pair<SizeType,SizeType> levelRange;
00558
00559
00560
00561 while( !S.empty())
00562 {
00563 levelRange = S.top();
00564
00565 S.pop();
00566 subTreeLevels = levelRange.second - levelRange.first;
00567
00568 for( SizeType h = 0; h <= height; h++)
00569 {
00570 treeSize[ h] = (1<<h) - 1;
00571 }
00572
00573 if( subTreeLevels > 1)
00574 {
00575
00576
00577 if (!isPowerOf2(subTreeLevels))
00578 {
00579 subTreeLevels = nextPowerOf2( subTreeLevels) >> 1;
00580 }
00581 else
00582 {
00583 subTreeLevels >>= 1;
00584 }
00585
00586
00587 middleLevel = levelRange.first + subTreeLevels;
00588
00589
00590
00591
00592
00593
00594 lowerLevels[ middleLevel] = middleLevel - levelRange.first;
00595
00596 upperLevels[ middleLevel] = levelRange.second - middleLevel;
00597
00598 S.push( std::pair<SizeType,SizeType>( middleLevel, levelRange.second));
00599 S.push( std::pair<SizeType,SizeType>( levelRange.first, middleLevel));
00600 }
00601
00602 }
00603
00604 upperLevels[height] = 1;
00605
00606 lowerLevels[0] = 0;
00607 upperLevels[0] = 1;
00608
00609 for( unsigned int i = 1; i < ( (unsigned int)1<< (height+1)); ++i)
00610 {
00611 bfsToVeb[i] = getVebFromBfs(i);
00612
00613 if( i != 1)
00614 {
00615 m_explicit[ getVebFromBfs(i)].parent = m_pool + getVebFromBfs(i>>1);
00616 }
00617
00618 if( (unsigned int)floorLog2(i) != height)
00619 {
00620 m_explicit[ getVebFromBfs(i)].leftChild = m_pool + getVebFromBfs( i<<1);
00621 m_explicit[ getVebFromBfs(i)].rightChild = m_pool + getVebFromBfs( (i<<1) + 1);
00622 }
00623 }
00624 }
00625
00626 const SizeType& getVebFromBfs( const SizeType& bfsIndex)
00627 {
00628 sum = 0;
00629 if (bfsIndex == 1) return sum;
00630
00631 childIndex = bfsIndex;
00632 SizeType height = m_height - floorLog2( childIndex);
00633
00634 while( childIndex != 1)
00635 {
00636 sum += ( childIndex & ((1 << upperLevels[height + 1]) - 1)) * treeSize[ lowerLevels[ height + 1]];
00637 sum += treeSize[ upperLevels[height + 1]];
00638 childIndex >>= upperLevels[height + 1];
00639 height += upperLevels[height + 1];
00640 }
00641 return sum;
00642 }
00643 };
00644
00645
00646 template <typename DataType>
00647 class SplitStorage
00648 {
00649 public:
00650 typedef PriorityQueueSizeType SizeType;
00651 SplitStorage( DataType* pool, const SizeType& height):m_pool(pool)
00652 {
00653 m_L2Ltransitions = new SizeType[ height + 1];
00654 m_L2Rtransitions = new SizeType[ height + 1];
00655 m_R2Ltransitions = new SizeType[ height + 1];
00656 m_R2Rtransitions = new SizeType[ height + 1];
00657 calculateTransitionValues( height);
00658 }
00659
00660 ~SplitStorage()
00661 {
00662 delete[] m_L2Ltransitions;
00663 delete[] m_L2Rtransitions;
00664 delete[] m_R2Ltransitions;
00665 delete[] m_R2Rtransitions;
00666 }
00667
00668 DataType* getRootAddr() const
00669 {
00670 return m_pool;
00671 }
00672
00673 DataType* getLeftChildAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00674 {
00675 return (bfsIndex & 1)? ptr + m_R2Ltransitions[height] : ptr + m_L2Ltransitions[height];
00676 }
00677
00678 DataType* getRightChildAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00679 {
00680 return (bfsIndex & 1)? ptr + m_R2Rtransitions[height] : ptr + m_L2Rtransitions[height];
00681 }
00682
00683 DataType* getParentAddress( DataType* ptr, const SizeType& bfsIndex, const SizeType& height)
00684 {
00685 if(bfsIndex & 1)
00686 {
00687 return ( (bfsIndex >> 1) & 1 )? ptr - m_R2Rtransitions[ height + 1]: ptr - m_L2Rtransitions[ height + 1];
00688 }
00689 else
00690 {
00691 return ( (bfsIndex >> 1) & 1 )? ptr - m_R2Ltransitions[ height + 1]: ptr - m_L2Ltransitions[ height + 1];
00692 }
00693 }
00694
00695 private:
00696 DataType* m_pool;
00697
00701 SizeType* m_L2Ltransitions;
00702
00706 SizeType* m_L2Rtransitions;
00707
00711 SizeType* m_R2Ltransitions;
00712
00716 SizeType* m_R2Rtransitions;
00717
00718 void calculateTransitionValues( const SizeType& height)
00719 {
00720 m_L2Ltransitions[height] = 1;
00721 m_R2Ltransitions[height] = 1;
00722 if( modulusPow2(height,2))
00723 {
00724 m_L2Rtransitions[height] = 2;
00725 m_R2Rtransitions[height] = 2;
00726 }
00727 else
00728 {
00729 m_L2Rtransitions[height] = (1 << height);
00730 m_R2Rtransitions[height] = (1 << height);
00731 }
00732
00733 for( SizeType h = 1; h < height; h++)
00734 {
00735 if( modulusPow2( h, 2))
00736 {
00737 m_L2Ltransitions[h] = 1;
00738 m_R2Ltransitions[h] = 1;
00739 m_L2Rtransitions[h] = 2;
00740 m_R2Rtransitions[h] = 2;
00741 }
00742 else
00743 {
00744 m_L2Ltransitions[h] = 2;
00745 m_R2Ltransitions[h] = pow2( h + 1) -1;
00746 m_L2Rtransitions[h] = pow2( h) + 1;
00747 m_R2Rtransitions[h] = pow2( h + 1) + pow2( h) - 2;
00748 }
00749 }
00750
00751 m_L2Ltransitions[0] = 0;
00752 m_R2Ltransitions[0] = 0;
00753 m_L2Rtransitions[0] = 0;
00754 m_R2Rtransitions[0] = 0;
00755 }
00756 };
00757
00758
00759 #endif //TREESTORAGESCHEMES_H