00001
00002
00003
00004
00005
00006
00007 #ifndef __B_PLUS_TREE_CPP
00008 #define __B_PLUS_TREE_CPP
00009
00010 #include "DS_MemoryPool.h"
00011 #include "DS_Queue.h"
00012 #include <stdio.h>
00013 #include "Export.h"
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #pragma warning( push )
00026 #endif
00027
00028 #include "RakMemoryOverride.h"
00029
00032 namespace DataStructures
00033 {
00036 template <class KeyType, class DataType, int order>
00037 struct RAK_DLL_EXPORT Page
00038 {
00039
00040
00041
00042 bool isLeaf;
00043
00044
00045
00046
00047 int size;
00048
00049
00050 KeyType keys[order];
00051
00052
00053 DataType data[order];
00054 Page<KeyType, DataType, order> *next;
00055 Page<KeyType, DataType, order> *previous;
00056
00057
00058 Page *children[order+1];
00059 };
00060
00063 template <class KeyType, class DataType, int order>
00064 class RAK_DLL_EXPORT BPlusTree
00065 {
00066 public:
00067 struct ReturnAction
00068 {
00069 KeyType key1;
00070 KeyType key2;
00071 enum
00072 {
00073 NO_ACTION,
00074 REPLACE_KEY1_WITH_KEY2,
00075 PUSH_KEY_TO_PARENT,
00076 SET_BRANCH_KEY,
00077 } action;
00078 };
00079
00080 BPlusTree();
00081 ~BPlusTree();
00082 void SetPoolPageSize(int size);
00083 bool Get(const KeyType key, DataType &out) const;
00084 bool Delete(const KeyType key);
00085 bool Delete(const KeyType key, DataType &out);
00086 bool Insert(const KeyType key, const DataType &data);
00087 void Clear(void);
00088 unsigned Size(void) const;
00089 bool IsEmpty(void) const;
00090 Page<KeyType, DataType, order> *GetListHead(void) const;
00091 DataType GetDataHead(void) const;
00092 void PrintLeaves(void);
00093 void ForEachLeaf(void (*func)(Page<KeyType, DataType, order> * leaf, int index));
00094 void ForEachData(void (*func)(DataType input, int index));
00095 void PrintGraph(void);
00096 protected:
00097 void ValidateTreeRecursive(Page<KeyType, DataType, order> *cur);
00098 void DeleteFromPageAtIndex(const int index, Page<KeyType, DataType, order> *cur);
00099 static void PrintLeaf(Page<KeyType, DataType, order> * leaf, int index);
00100 void FreePages(void);
00101 bool GetIndexOf(const KeyType key, Page<KeyType, DataType, order> *page, int *out) const;
00102 void ShiftKeysLeft(Page<KeyType, DataType, order> *cur);
00103 bool CanRotateLeft(Page<KeyType, DataType, order> *cur, int childIndex);
00104 bool CanRotateRight(Page<KeyType, DataType, order> *cur, int childIndex);
00105 void RotateRight(Page<KeyType, DataType, order> *cur, int childIndex, ReturnAction *returnAction);
00106 void RotateLeft(Page<KeyType, DataType, order> *cur, int childIndex, ReturnAction *returnAction);
00107 Page<KeyType, DataType, order>* InsertIntoNode(const KeyType key, const DataType &childData, int insertionIndex, Page<KeyType, DataType, order> *nodeData, Page<KeyType, DataType, order> *cur, ReturnAction* returnAction);
00108 Page<KeyType, DataType, order>* InsertBranchDown(const KeyType key, const DataType &data,Page<KeyType, DataType, order> *cur, ReturnAction* returnAction, bool *success);
00109 Page<KeyType, DataType, order>* GetLeafFromKey(const KeyType key) const;
00110 bool FindDeleteRebalance(const KeyType key, Page<KeyType, DataType, order> *cur, bool *underflow, KeyType rightRootKey, ReturnAction *returnAction, DataType &out);
00111 bool FixUnderflow(int branchIndex, Page<KeyType, DataType, order> *cur, KeyType rightRootKey, ReturnAction *returnAction);
00112 void ShiftNodeLeft(Page<KeyType, DataType, order> *cur);
00113 void ShiftNodeRight(Page<KeyType, DataType, order> *cur);
00114
00115 MemoryPool<Page<KeyType, DataType, order> > pagePool;
00116 Page<KeyType, DataType, order> *root, *leftmostLeaf;
00117 };
00118
00119 template<class KeyType, class DataType, int order>
00120 BPlusTree<KeyType, DataType, order>::BPlusTree ()
00121 {
00122 RakAssert(order>1);
00123 root=0;
00124 leftmostLeaf=0;
00125 }
00126 template<class KeyType, class DataType, int order>
00127 BPlusTree<KeyType, DataType, order>::~BPlusTree ()
00128 {
00129 Clear();
00130 }
00131 template<class KeyType, class DataType, int order>
00132 void BPlusTree<KeyType, DataType, order>::SetPoolPageSize(int size)
00133 {
00134 pagePool.SetPageSize(size);
00135 }
00136 template<class KeyType, class DataType, int order>
00137 bool BPlusTree<KeyType, DataType, order>::Get(const KeyType key, DataType &out) const
00138 {
00139 if (root==0)
00140 return false;
00141
00142 Page<KeyType, DataType, order>* leaf = GetLeafFromKey(key);
00143 int childIndex;
00144
00145 if (GetIndexOf(key, leaf, &childIndex))
00146 {
00147 out=leaf->data[childIndex];
00148 return true;
00149 }
00150 return false;
00151 }
00152 template<class KeyType, class DataType, int order>
00153 void BPlusTree<KeyType, DataType, order>::DeleteFromPageAtIndex(const int index, Page<KeyType, DataType, order> *cur)
00154 {
00155 int i;
00156 for (i=index; i < cur->size-1; i++)
00157 cur->keys[i]=cur->keys[i+1];
00158 if (cur->isLeaf)
00159 {
00160 for (i=index; i < cur->size-1; i++)
00161 cur->data[i]=cur->data[i+1];
00162 }
00163 else
00164 {
00165 for (i=index; i < cur->size-1; i++)
00166 cur->children[i+1]=cur->children[i+2];
00167 }
00168 cur->size--;
00169 }
00170 template<class KeyType, class DataType, int order>
00171 bool BPlusTree<KeyType, DataType, order>::Delete(const KeyType key)
00172 {
00173 DataType temp;
00174 return Delete(key, temp);
00175 }
00176 template<class KeyType, class DataType, int order>
00177 bool BPlusTree<KeyType, DataType, order>::Delete(const KeyType key, DataType &out)
00178 {
00179 if (root==0)
00180 return false;
00181
00182 ReturnAction returnAction;
00183 returnAction.action=ReturnAction::NO_ACTION;
00184 int childIndex;
00185 bool underflow=false;
00186 if (root==leftmostLeaf)
00187 {
00188 if (GetIndexOf(key, root, &childIndex)==false)
00189 return false;
00190 out=root->data[childIndex];
00191 DeleteFromPageAtIndex(childIndex,root);
00192 if (root->size==0)
00193 {
00194 pagePool.Release(root, __FILE__,__LINE__);
00195 root=0;
00196 leftmostLeaf=0;
00197 }
00198 return true;
00199 }
00200 else if (FindDeleteRebalance(key, root, &underflow,root->keys[0], &returnAction, out)==false)
00201 return false;
00202
00203
00204
00205 if (underflow && root->size==0)
00206 {
00207
00208 Page<KeyType, DataType, order> *oldRoot=root;
00209 root=root->children[0];
00210 pagePool.Release(oldRoot, __FILE__,__LINE__);
00211
00212 }
00213
00214 return true;
00215 }
00216 template<class KeyType, class DataType, int order>
00217 bool BPlusTree<KeyType, DataType, order>::FindDeleteRebalance(const KeyType key, Page<KeyType, DataType, order> *cur, bool *underflow, KeyType rightRootKey, ReturnAction *returnAction, DataType &out)
00218 {
00219
00220 int branchIndex, childIndex;
00221 if (GetIndexOf(key, cur, &childIndex))
00222 branchIndex=childIndex+1;
00223 else
00224 branchIndex=childIndex;
00225
00226
00227 if (cur->children[branchIndex]->isLeaf==false)
00228 {
00229 if (branchIndex<cur->size)
00230 rightRootKey=cur->keys[branchIndex];
00231 else
00232 rightRootKey=cur->keys[branchIndex-1];
00233
00234 if (FindDeleteRebalance(key, cur->children[branchIndex], underflow, rightRootKey, returnAction, out)==false)
00235 return false;
00236
00237
00238 if (branchIndex<cur->size)
00239 rightRootKey=cur->keys[branchIndex];
00240 else
00241 rightRootKey=cur->keys[branchIndex-1];
00242
00243 if (returnAction->action==ReturnAction::SET_BRANCH_KEY && branchIndex!=childIndex)
00244 {
00245 returnAction->action=ReturnAction::NO_ACTION;
00246 cur->keys[childIndex]=returnAction->key1;
00247
00248 if (branchIndex<cur->size)
00249 rightRootKey=cur->keys[branchIndex];
00250 else
00251 rightRootKey=cur->keys[branchIndex-1];
00252 }
00253 }
00254 else
00255 {
00256
00257 if (GetIndexOf(key, cur->children[branchIndex], &childIndex)==false)
00258 return false;
00259
00260
00261
00262 out=cur->children[branchIndex]->data[childIndex];
00263 DeleteFromPageAtIndex(childIndex, cur->children[branchIndex]);
00264
00265 if (childIndex==0)
00266 {
00267 if (branchIndex>0)
00268 cur->keys[branchIndex-1]=cur->children[branchIndex]->keys[0];
00269
00270 if (branchIndex==0)
00271 {
00272 returnAction->action=ReturnAction::SET_BRANCH_KEY;
00273 returnAction->key1=cur->children[0]->keys[0];
00274 }
00275 }
00276
00277 if (cur->children[branchIndex]->size < order/2)
00278 *underflow=true;
00279 else
00280 *underflow=false;
00281 }
00282
00283
00284 if (*underflow)
00285 {
00286 *underflow=FixUnderflow(branchIndex, cur, rightRootKey, returnAction);
00287 }
00288
00289 return true;
00290 }
00291 template<class KeyType, class DataType, int order>
00292 bool BPlusTree<KeyType, DataType, order>::FixUnderflow(int branchIndex, Page<KeyType, DataType, order> *cur, KeyType rightRootKey, ReturnAction *returnAction)
00293 {
00294
00295 Page<KeyType, DataType, order> *source;
00296 Page<KeyType, DataType, order> *dest;
00297
00298 if (branchIndex>0 && cur->children[branchIndex-1]->size > order/2)
00299 {
00300 dest=cur->children[branchIndex];
00301 source=cur->children[branchIndex-1];
00302
00303
00304 ShiftNodeRight(dest);
00305 if (dest->isLeaf)
00306 {
00307 dest->keys[0]=source->keys[source->size-1];
00308 dest->data[0]=source->data[source->size-1];
00309 }
00310 else
00311 {
00312 dest->children[0]=source->children[source->size];
00313 dest->keys[0]=cur->keys[branchIndex-1];
00314 }
00315
00316 cur->keys[branchIndex-1]=source->keys[source->size-1];
00317 source->size--;
00318
00319
00320
00321
00322
00323
00324
00325
00326 return false;
00327 }
00328 else if (branchIndex<cur->size && cur->children[branchIndex+1]->size > order/2)
00329 {
00330 dest=cur->children[branchIndex];
00331 source=cur->children[branchIndex+1];
00332
00333
00334 if (dest->isLeaf)
00335 {
00336 dest->keys[dest->size]=source->keys[0];
00337 dest->data[dest->size]=source->data[0];
00338
00339
00340 cur->keys[branchIndex]=source->keys[1];
00341
00342 #ifdef _MSC_VER
00343 #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
00344 #endif
00345 if (order<=3 && dest->size==0)
00346 {
00347 if (branchIndex==0)
00348 {
00349 returnAction->action=ReturnAction::SET_BRANCH_KEY;
00350 returnAction->key1=dest->keys[0];
00351 }
00352 else
00353 cur->keys[branchIndex-1]=cur->children[branchIndex]->keys[0];
00354 }
00355 }
00356 else
00357 {
00358 if (returnAction->action==ReturnAction::NO_ACTION)
00359 {
00360 returnAction->action=ReturnAction::SET_BRANCH_KEY;
00361 returnAction->key1=dest->keys[0];
00362 }
00363
00364 dest->keys[dest->size]=rightRootKey;
00365 dest->children[dest->size+1]=source->children[0];
00366
00367
00368 cur->keys[branchIndex]=source->keys[0];
00369 }
00370
00371
00372 dest->size++;
00373 ShiftNodeLeft(source);
00374
00375
00376
00377
00378
00379
00380
00381 return false;
00382 }
00383 else
00384 {
00385 int sourceIndex;
00386
00387
00388
00389
00390
00391
00392 if (branchIndex<cur->size)
00393 {
00394
00395 dest=cur->children[branchIndex];
00396 source=cur->children[branchIndex+1];
00397 }
00398 else
00399 {
00400
00401 dest=cur->children[branchIndex-1];
00402 source=cur->children[branchIndex];
00403 }
00404
00405
00406 if (dest->isLeaf)
00407 {
00408 for (sourceIndex=0; sourceIndex<source->size; sourceIndex++)
00409 {
00410 dest->keys[dest->size]=source->keys[sourceIndex];
00411 dest->data[dest->size++]=source->data[sourceIndex];
00412 }
00413 }
00414 else
00415 {
00416
00417 dest->keys[dest->size]=rightRootKey;
00418 dest->children[dest->size++ + 1]=source->children[0];
00419 for (sourceIndex=0; sourceIndex<source->size; sourceIndex++)
00420 {
00421 dest->keys[dest->size]=source->keys[sourceIndex];
00422 dest->children[dest->size++ + 1]=source->children[sourceIndex + 1];
00423 }
00424 }
00425
00426 #ifdef _MSC_VER
00427 #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
00428 #endif
00429 if (order<=3 && branchIndex>0 && cur->children[branchIndex]->isLeaf)
00430 cur->keys[branchIndex-1]=cur->children[branchIndex]->keys[0];
00431
00432 if (branchIndex<cur->size)
00433 {
00434
00435 DeleteFromPageAtIndex(branchIndex, cur);
00436 }
00437 else
00438 {
00439 if (branchIndex>0)
00440 {
00441
00442 DeleteFromPageAtIndex(branchIndex-1, cur);
00443 }
00444 }
00445
00446 if (branchIndex==0 && dest->isLeaf)
00447 {
00448 returnAction->action=ReturnAction::SET_BRANCH_KEY;
00449 returnAction->key1=dest->keys[0];
00450 }
00451
00452 if (source==leftmostLeaf)
00453 leftmostLeaf=source->next;
00454
00455 if (source->isLeaf)
00456 {
00457 if (source->previous)
00458 source->previous->next=source->next;
00459 if (source->next)
00460 source->next->previous=source->previous;
00461 }
00462
00463
00464 pagePool.Release(source, __FILE__,__LINE__);
00465
00466
00467
00468 return cur->size < order/2;
00469 }
00470 }
00471 template<class KeyType, class DataType, int order>
00472 void BPlusTree<KeyType, DataType, order>::ShiftNodeRight(Page<KeyType, DataType, order> *cur)
00473 {
00474 int i;
00475 for (i=cur->size; i>0; i--)
00476 cur->keys[i]=cur->keys[i-1];
00477 if (cur->isLeaf)
00478 {
00479 for (i=cur->size; i>0; i--)
00480 cur->data[i]=cur->data[i-1];
00481 }
00482 else
00483 {
00484 for (i=cur->size+1; i>0; i--)
00485 cur->children[i]=cur->children[i-1];
00486 }
00487
00488 cur->size++;
00489 }
00490 template<class KeyType, class DataType, int order>
00491 void BPlusTree<KeyType, DataType, order>::ShiftNodeLeft(Page<KeyType, DataType, order> *cur)
00492 {
00493 int i;
00494 for (i=0; i < cur->size-1; i++)
00495 cur->keys[i]=cur->keys[i+1];
00496 if (cur->isLeaf)
00497 {
00498 for (i=0; i < cur->size; i++)
00499 cur->data[i]=cur->data[i+1];
00500 }
00501 else
00502 {
00503 for (i=0; i < cur->size; i++)
00504 cur->children[i]=cur->children[i+1];
00505 }
00506 cur->size--;
00507 }
00508 template<class KeyType, class DataType, int order>
00509 Page<KeyType, DataType, order>* BPlusTree<KeyType, DataType, order>::InsertIntoNode(const KeyType key, const DataType &leafData, int insertionIndex, Page<KeyType, DataType, order> *nodeData, Page<KeyType, DataType, order> *cur, ReturnAction* returnAction)
00510 {
00511 int i;
00512 if (cur->size < order)
00513 {
00514 for (i=cur->size; i > insertionIndex; i--)
00515 cur->keys[i]=cur->keys[i-1];
00516 if (cur->isLeaf)
00517 {
00518 for (i=cur->size; i > insertionIndex; i--)
00519 cur->data[i]=cur->data[i-1];
00520 }
00521 else
00522 {
00523 for (i=cur->size+1; i > insertionIndex+1; i--)
00524 cur->children[i]=cur->children[i-1];
00525 }
00526 cur->keys[insertionIndex]=key;
00527 if (cur->isLeaf)
00528 cur->data[insertionIndex]=leafData;
00529 else
00530 cur->children[insertionIndex+1]=nodeData;
00531
00532 cur->size++;
00533 }
00534 else
00535 {
00536 Page<KeyType, DataType, order>* newPage = pagePool.Allocate( __FILE__, __LINE__ );
00537 newPage->isLeaf=cur->isLeaf;
00538 if (cur->isLeaf)
00539 {
00540 newPage->next=cur->next;
00541 if (cur->next)
00542 cur->next->previous=newPage;
00543 newPage->previous=cur;
00544 cur->next=newPage;
00545 }
00546
00547 int destIndex, sourceIndex;
00548
00549 if (insertionIndex>=(order+1)/2)
00550 {
00551 destIndex=0;
00552 sourceIndex=order/2;
00553
00554 for (; sourceIndex < insertionIndex; sourceIndex++, destIndex++)
00555 {
00556 newPage->keys[destIndex]=cur->keys[sourceIndex];
00557 }
00558 newPage->keys[destIndex++]=key;
00559 for (; sourceIndex < order; sourceIndex++, destIndex++)
00560 {
00561 newPage->keys[destIndex]=cur->keys[sourceIndex];
00562 }
00563
00564 destIndex=0;
00565 sourceIndex=order/2;
00566 if (cur->isLeaf)
00567 {
00568 for (; sourceIndex < insertionIndex; sourceIndex++, destIndex++)
00569 {
00570 newPage->data[destIndex]=cur->data[sourceIndex];
00571 }
00572 newPage->data[destIndex++]=leafData;
00573 for (; sourceIndex < order; sourceIndex++, destIndex++)
00574 {
00575 newPage->data[destIndex]=cur->data[sourceIndex];
00576 }
00577 }
00578 else
00579 {
00580
00581 for (; sourceIndex < insertionIndex; sourceIndex++, destIndex++)
00582 {
00583 newPage->children[destIndex]=cur->children[sourceIndex+1];
00584 }
00585 newPage->children[destIndex++]=nodeData;
00586
00587
00588
00589 for (; sourceIndex+1 < cur->size+1; sourceIndex++, destIndex++)
00590 {
00591 newPage->children[destIndex]=cur->children[sourceIndex+1];
00592 }
00593
00594
00595 returnAction->action=ReturnAction::PUSH_KEY_TO_PARENT;
00596 returnAction->key1=newPage->keys[0];
00597 for (int i=0; i < destIndex-1; i++)
00598 newPage->keys[i]=newPage->keys[i+1];
00599
00600 }
00601 cur->size=order/2;
00602 }
00603 else
00604 {
00605 destIndex=0;
00606 sourceIndex=(order+1)/2-1;
00607 for (; sourceIndex < order; sourceIndex++, destIndex++)
00608 newPage->keys[destIndex]=cur->keys[sourceIndex];
00609 destIndex=0;
00610 if (cur->isLeaf)
00611 {
00612 sourceIndex=(order+1)/2-1;
00613 for (; sourceIndex < order; sourceIndex++, destIndex++)
00614 newPage->data[destIndex]=cur->data[sourceIndex];
00615 }
00616 else
00617 {
00618 sourceIndex=(order+1)/2;
00619 for (; sourceIndex < order+1; sourceIndex++, destIndex++)
00620 newPage->children[destIndex]=cur->children[sourceIndex];
00621
00622
00623 returnAction->action=ReturnAction::PUSH_KEY_TO_PARENT;
00624 returnAction->key1=newPage->keys[0];
00625 for (int i=0; i < destIndex-1; i++)
00626 newPage->keys[i]=newPage->keys[i+1];
00627 }
00628 cur->size=(order+1)/2-1;
00629 if (cur->size)
00630 {
00631 bool b = GetIndexOf(key, cur, &insertionIndex);
00632 (void) b;
00633 RakAssert(b==false);
00634 }
00635 else
00636 insertionIndex=0;
00637 InsertIntoNode(key, leafData, insertionIndex, nodeData, cur, returnAction);
00638 }
00639
00640 newPage->size=destIndex;
00641
00642 return newPage;
00643 }
00644
00645 return 0;
00646 }
00647
00648 template<class KeyType, class DataType, int order>
00649 bool BPlusTree<KeyType, DataType, order>::CanRotateLeft(Page<KeyType, DataType, order> *cur, int childIndex)
00650 {
00651 return childIndex>0 && cur->children[childIndex-1]->size<order;
00652 }
00653
00654 template<class KeyType, class DataType, int order>
00655 void BPlusTree<KeyType, DataType, order>::RotateLeft(Page<KeyType, DataType, order> *cur, int childIndex, ReturnAction *returnAction)
00656 {
00657 Page<KeyType, DataType, order> *dest = cur->children[childIndex-1];
00658 Page<KeyType, DataType, order> *source = cur->children[childIndex];
00659 returnAction->key1=source->keys[0];
00660 dest->keys[dest->size]=source->keys[0];
00661 dest->data[dest->size]=source->data[0];
00662 dest->size++;
00663 for (int i=0; i < source->size-1; i++)
00664 {
00665 source->keys[i]=source->keys[i+1];
00666 source->data[i]=source->data[i+1];
00667 }
00668 source->size--;
00669 cur->keys[childIndex-1]=source->keys[0];
00670 returnAction->key2=source->keys[0];
00671 }
00672
00673 template<class KeyType, class DataType, int order>
00674 bool BPlusTree<KeyType, DataType, order>::CanRotateRight(Page<KeyType, DataType, order> *cur, int childIndex)
00675 {
00676 return childIndex < cur->size && cur->children[childIndex+1]->size<order;
00677 }
00678
00679 template<class KeyType, class DataType, int order>
00680 void BPlusTree<KeyType, DataType, order>::RotateRight(Page<KeyType, DataType, order> *cur, int childIndex, ReturnAction *returnAction)
00681 {
00682 Page<KeyType, DataType, order> *dest = cur->children[childIndex+1];
00683 Page<KeyType, DataType, order> *source = cur->children[childIndex];
00684 returnAction->key1=dest->keys[0];
00685 for (int i= dest->size; i > 0; i--)
00686 {
00687 dest->keys[i]=dest->keys[i-1];
00688 dest->data[i]=dest->data[i-1];
00689 }
00690 dest->keys[0]=source->keys[source->size-1];
00691 dest->data[0]=source->data[source->size-1];
00692 dest->size++;
00693 source->size--;
00694
00695 cur->keys[childIndex]=dest->keys[0];
00696 returnAction->key2=dest->keys[0];
00697 }
00698 template<class KeyType, class DataType, int order>
00699 Page<KeyType, DataType, order>* BPlusTree<KeyType, DataType, order>::GetLeafFromKey(const KeyType key) const
00700 {
00701 Page<KeyType, DataType, order>* cur = root;
00702 int childIndex;
00703 while (cur->isLeaf==false)
00704 {
00705
00706 if (GetIndexOf(key, cur, &childIndex))
00707 childIndex++;
00708 cur = cur->children[childIndex];
00709 }
00710 return cur;
00711 }
00712
00713 template<class KeyType, class DataType, int order>
00714 Page<KeyType, DataType, order>* BPlusTree<KeyType, DataType, order>::InsertBranchDown(const KeyType key, const DataType &data,Page<KeyType, DataType, order> *cur, ReturnAction *returnAction, bool *success)
00715 {
00716 int childIndex;
00717 int branchIndex;
00718 if (GetIndexOf(key, cur, &childIndex))
00719 branchIndex=childIndex+1;
00720 else
00721 branchIndex=childIndex;
00722 Page<KeyType, DataType, order>* newPage;
00723 if (cur->isLeaf==false)
00724 {
00725 if (cur->children[branchIndex]->isLeaf==true && cur->children[branchIndex]->size==order)
00726 {
00727 if (branchIndex==childIndex+1)
00728 {
00729 *success=false;
00730 return 0;
00731 }
00732
00733 if (CanRotateLeft(cur, branchIndex))
00734 {
00735 returnAction->action=ReturnAction::REPLACE_KEY1_WITH_KEY2;
00736 if (key > cur->children[branchIndex]->keys[0])
00737 {
00738 RotateLeft(cur, branchIndex, returnAction);
00739
00740 int insertionIndex;
00741 GetIndexOf(key, cur->children[branchIndex], &insertionIndex);
00742 InsertIntoNode(key, data, insertionIndex, 0, cur->children[branchIndex], 0);
00743 }
00744 else
00745 {
00746
00747 Page<KeyType, DataType, order>* dest=cur->children[branchIndex-1];
00748 Page<KeyType, DataType, order>* source=cur->children[branchIndex];
00749 returnAction->key1=source->keys[0];
00750 returnAction->key2=key;
00751 dest->keys[dest->size]=source->keys[0];
00752 dest->data[dest->size]=source->data[0];
00753 dest->size++;
00754 source->keys[0]=key;
00755 source->data[0]=data;
00756 }
00757 cur->keys[branchIndex-1]=cur->children[branchIndex]->keys[0];
00758
00759 return 0;
00760 }
00761 else if (CanRotateRight(cur, branchIndex))
00762 {
00763 returnAction->action=ReturnAction::REPLACE_KEY1_WITH_KEY2;
00764
00765 if (key < cur->children[branchIndex]->keys[cur->children[branchIndex]->size-1])
00766 {
00767 RotateRight(cur, branchIndex, returnAction);
00768
00769 int insertionIndex;
00770 GetIndexOf(key, cur->children[branchIndex], &insertionIndex);
00771 InsertIntoNode(key, data, insertionIndex, 0, cur->children[branchIndex], 0);
00772
00773 }
00774 else
00775 {
00776
00777 returnAction->key1=cur->children[branchIndex+1]->keys[0];
00778 InsertIntoNode(key, data, 0, 0, cur->children[branchIndex+1], 0);
00779 returnAction->key2=key;
00780 }
00781 cur->keys[branchIndex]=cur->children[branchIndex+1]->keys[0];
00782 return 0;
00783 }
00784 }
00785
00786 newPage=InsertBranchDown(key,data,cur->children[branchIndex], returnAction, success);
00787 if (returnAction->action==ReturnAction::REPLACE_KEY1_WITH_KEY2)
00788 {
00789 if (branchIndex>0 && cur->keys[branchIndex-1]==returnAction->key1)
00790 cur->keys[branchIndex-1]=returnAction->key2;
00791 }
00792 if (newPage)
00793 {
00794 if (newPage->isLeaf==false)
00795 {
00796 RakAssert(returnAction->action==ReturnAction::PUSH_KEY_TO_PARENT);
00797 newPage->size--;
00798 return InsertIntoNode(returnAction->key1, data, branchIndex, newPage, cur, returnAction);
00799 }
00800 else
00801 {
00802 return InsertIntoNode(newPage->keys[0], data, branchIndex, newPage, cur, returnAction);
00803 }
00804 }
00805 }
00806 else
00807 {
00808 if (branchIndex==childIndex+1)
00809 {
00810 *success=false;
00811 return 0;
00812 }
00813 else
00814 {
00815 return InsertIntoNode(key, data, branchIndex, 0, cur, returnAction);
00816 }
00817 }
00818
00819 return 0;
00820 }
00821 template<class KeyType, class DataType, int order>
00822 bool BPlusTree<KeyType, DataType, order>::Insert(const KeyType key, const DataType &data)
00823 {
00824 if (root==0)
00825 {
00826
00827 root = pagePool.Allocate( __FILE__, __LINE__ );
00828 root->isLeaf=true;
00829 leftmostLeaf=root;
00830 root->size=1;
00831 root->keys[0]=key;
00832 root->data[0]=data;
00833 root->next=0;
00834 root->previous=0;
00835 }
00836 else
00837 {
00838 bool success=true;
00839 ReturnAction returnAction;
00840 returnAction.action=ReturnAction::NO_ACTION;
00841 Page<KeyType, DataType, order>* newPage = InsertBranchDown(key, data, root, &returnAction, &success);
00842 if (success==false)
00843 return false;
00844 if (newPage)
00845 {
00846 KeyType newKey;
00847 if (newPage->isLeaf==false)
00848 {
00849
00850 RakAssert(returnAction.action==ReturnAction::PUSH_KEY_TO_PARENT);
00851 newKey=returnAction.key1;
00852 newPage->size--;
00853 }
00854 else
00855 newKey = newPage->keys[0];
00856
00857 Page<KeyType, DataType, order>* newRoot = pagePool.Allocate( __FILE__, __LINE__ );
00858 newRoot->isLeaf=false;
00859 newRoot->size=1;
00860 newRoot->keys[0]=newKey;
00861 newRoot->children[0]=root;
00862 newRoot->children[1]=newPage;
00863 root=newRoot;
00864 }
00865 }
00866
00867 return true;
00868 }
00869 template<class KeyType, class DataType, int order>
00870 void BPlusTree<KeyType, DataType, order>::ShiftKeysLeft(Page<KeyType, DataType, order> *cur)
00871 {
00872 int i;
00873 for (i=0; i < cur->size; i++)
00874 cur->keys[i]=cur->keys[i+1];
00875 }
00876 template<class KeyType, class DataType, int order>
00877 void BPlusTree<KeyType, DataType, order>::Clear(void)
00878 {
00879 if (root)
00880 {
00881 FreePages();
00882 leftmostLeaf=0;
00883 root=0;
00884 }
00885 pagePool.Clear(__FILE__, __LINE__);
00886 }
00887 template<class KeyType, class DataType, int order>
00888 unsigned BPlusTree<KeyType, DataType, order>::Size(void) const
00889 {
00890 int count=0;
00891 DataStructures::Page<KeyType, DataType, order> *cur = GetListHead();
00892 while (cur)
00893 {
00894 count+=cur->size;
00895 cur=cur->next;
00896 }
00897 return count;
00898 }
00899 template<class KeyType, class DataType, int order>
00900 bool BPlusTree<KeyType, DataType, order>::IsEmpty(void) const
00901 {
00902 return root==0;
00903 }
00904 template<class KeyType, class DataType, int order>
00905 bool BPlusTree<KeyType, DataType, order>::GetIndexOf(const KeyType key, Page<KeyType, DataType, order> *page, int *out) const
00906 {
00907 RakAssert(page->size>0);
00908 int index, upperBound, lowerBound;
00909 upperBound=page->size-1;
00910 lowerBound=0;
00911 index = page->size/2;
00912
00913 #ifdef _MSC_VER
00914 #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
00915 #endif
00916 while (1)
00917 {
00918 if (key==page->keys[index])
00919 {
00920 *out=index;
00921 return true;
00922 }
00923 else if (key<page->keys[index])
00924 upperBound=index-1;
00925 else
00926 lowerBound=index+1;
00927
00928 index=lowerBound+(upperBound-lowerBound)/2;
00929
00930 if (lowerBound>upperBound)
00931 {
00932 *out=lowerBound;
00933 return false;
00934 }
00935 }
00936 }
00937 template<class KeyType, class DataType, int order>
00938 void BPlusTree<KeyType, DataType, order>::FreePages(void)
00939 {
00940 DataStructures::Queue<DataStructures::Page<KeyType, DataType, order> *> queue;
00941 DataStructures::Page<KeyType, DataType, order> *ptr;
00942 int i;
00943 queue.Push(root, __FILE__, __LINE__ );
00944 while (queue.Size())
00945 {
00946 ptr=queue.Pop();
00947 if (ptr->isLeaf==false)
00948 {
00949 for (i=0; i < ptr->size+1; i++)
00950 queue.Push(ptr->children[i], __FILE__, __LINE__ );
00951 }
00952 pagePool.Release(ptr, __FILE__,__LINE__);
00953
00954 };
00955 }
00956 template<class KeyType, class DataType, int order>
00957 Page<KeyType, DataType, order> *BPlusTree<KeyType, DataType, order>::GetListHead(void) const
00958 {
00959 return leftmostLeaf;
00960 }
00961 template<class KeyType, class DataType, int order>
00962 DataType BPlusTree<KeyType, DataType, order>::GetDataHead(void) const
00963 {
00964 return leftmostLeaf->data[0];
00965 }
00966 template<class KeyType, class DataType, int order>
00967 void BPlusTree<KeyType, DataType, order>::ForEachLeaf(void (*func)(Page<KeyType, DataType, order> * leaf, int index))
00968 {
00969 int count=0;
00970 DataStructures::Page<KeyType, DataType, order> *cur = GetListHead();
00971 while (cur)
00972 {
00973 func(cur, count++);
00974 cur=cur->next;
00975 }
00976 }
00977 template<class KeyType, class DataType, int order>
00978 void BPlusTree<KeyType, DataType, order>::ForEachData(void (*func)(DataType input, int index))
00979 {
00980 int count=0,i;
00981 DataStructures::Page<KeyType, DataType, order> *cur = GetListHead();
00982 while (cur)
00983 {
00984 for (i=0; i < cur->size; i++)
00985 func(cur->data[i], count++);
00986 cur=cur->next;
00987 }
00988 }
00989 template<class KeyType, class DataType, int order>
00990 void BPlusTree<KeyType, DataType, order>::PrintLeaf(Page<KeyType, DataType, order> * leaf, int index)
00991 {
00992 int i;
00993 RAKNET_DEBUG_PRINTF("%i] SELF=%p\n", index+1, leaf);
00994 for (i=0; i < leaf->size; i++)
00995 RAKNET_DEBUG_PRINTF(" %i. %i\n", i+1, leaf->data[i]);
00996 }
00997 template<class KeyType, class DataType, int order>
00998 void BPlusTree<KeyType, DataType, order>::PrintLeaves(void)
00999 {
01000 ForEachLeaf(PrintLeaf);
01001 }
01002
01003 template<class KeyType, class DataType, int order>
01004 void BPlusTree<KeyType, DataType, order>::ValidateTreeRecursive(Page<KeyType, DataType, order> *cur)
01005 {
01006 RakAssert(cur==root || cur->size>=order/2);
01007
01008 if (cur->children[0]->isLeaf)
01009 {
01010 RakAssert(cur->children[0]->keys[0] < cur->keys[0]);
01011 for (int i=0; i < cur->size; i++)
01012 {
01013 RakAssert(cur->children[i+1]->keys[0]==cur->keys[i]);
01014 }
01015 }
01016 else
01017 {
01018 for (int i=0; i < cur->size+1; i++)
01019 ValidateTreeRecursive(cur->children[i]);
01020 }
01021 }
01022
01023 template<class KeyType, class DataType, int order>
01024 void BPlusTree<KeyType, DataType, order>::PrintGraph(void)
01025 {
01026 DataStructures::Queue<DataStructures::Page<KeyType, DataType, order> *> queue;
01027 queue.Push(root,__FILE__,__LINE__);
01028 queue.Push(0,__FILE__,__LINE__);
01029 DataStructures::Page<KeyType, DataType, order> *ptr;
01030 int i,j;
01031 if (root)
01032 {
01033 RAKNET_DEBUG_PRINTF("%p(", root);
01034 for (i=0; i < root->size; i++)
01035 {
01036 RAKNET_DEBUG_PRINTF("%i ", root->keys[i]);
01037 }
01038 RAKNET_DEBUG_PRINTF(") ");
01039 RAKNET_DEBUG_PRINTF("\n");
01040 }
01041 while (queue.Size())
01042 {
01043 ptr=queue.Pop();
01044 if (ptr==0)
01045 RAKNET_DEBUG_PRINTF("\n");
01046 else if (ptr->isLeaf==false)
01047 {
01048 for (i=0; i < ptr->size+1; i++)
01049 {
01050 RAKNET_DEBUG_PRINTF("%p(", ptr->children[i]);
01051
01052 for (j=0; j < ptr->children[i]->size; j++)
01053 RAKNET_DEBUG_PRINTF("%i ", ptr->children[i]->keys[j]);
01054 RAKNET_DEBUG_PRINTF(") ");
01055 queue.Push(ptr->children[i],__FILE__,__LINE__);
01056 }
01057 queue.Push(0,__FILE__,__LINE__);
01058 RAKNET_DEBUG_PRINTF(" -- ");
01059 }
01060 }
01061 RAKNET_DEBUG_PRINTF("\n");
01062 }
01063 }
01064 #ifdef _MSC_VER
01065 #pragma warning( pop )
01066 #endif
01067
01068 #endif
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146