Fennel: /home/pub/open/dev/fennel/btree/BTreeNodeAccessor.cpp Source File (original) (raw)

00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 #include "fennel/common/CommonPreamble.h" 00025 #include "fennel/btree/BTreeNodeAccessor.h" 00026 #include "fennel/tuple/TuplePrinter.h" 00027 00028 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/btree/BTreeNodeAccessor.cpp#12 $"); 00029 00030 BTreeNodeAccessor::~BTreeNodeAccessor() 00031 { 00032 } 00033 00034 void BTreeNodeAccessor::clearNode(BTreeNode &node,uint cbPage) 00035 { 00036 node.rightSibling = NULL_PAGE_ID; 00037 node.nEntries = 0; 00038 node.height = 0; 00039 node.cbTotalFree = cbPage - sizeof(BTreeNode); 00040 node.cbCompactFree = MAXU; 00041 } 00042 00043 void BTreeNodeAccessor::onInit() 00044 { 00045 tupleAccessor.compute(tupleDescriptor); 00046 tupleData.compute(tupleDescriptor); 00047 } 00048 00049 void BTreeNodeAccessor::dumpNode( 00050 std::ostream &os,BTreeNode const &node,PageId pageId) 00051 { 00052 os << "PageId: " << pageId << std::endl; 00053 if (node.rightSibling == NULL_PAGE_ID) { 00054 os << "rightSibling: " << std::endl; 00055 } else { 00056 os << "rightSibling: " << node.rightSibling << std::endl; 00057 } 00058 os << "nEntries: " << node.nEntries << std::endl; 00059 os << "height: " << node.height << std::endl; 00060 os << "cbTotalFree: " << node.cbTotalFree << std::endl; 00061 if (isMAXU(node.cbCompactFree)) { 00062 os << "cbCompactFree: " << node.cbCompactFree << std::endl; 00063 } 00064 os << std::endl; 00065 TuplePrinter tuplePrinter; 00066
00067 for (uint i = 0; i < node.nEntries; ++i) { 00068 PConstBuffer pEntry = getEntryForRead(node,i); 00069 os << "offset = " 00070 << pEntry - reinterpret_cast(&node) << std::endl; 00071 tupleAccessor.setCurrentTupleBuf(pEntry); 00072 tupleAccessor.unmarshal(tupleData); 00073 tuplePrinter.print(os,tupleDescriptor,tupleData); 00074 os << std::endl; 00075 } 00076 os << std::endl; 00077 } 00078 00079 00080 00081 00082 void BTreeNodeAccessor::compactNode(BTreeNode &node,BTreeNode &scratchNode) 00083 { 00084 assert(!scratchNode.nEntries); 00085 for (uint i = 0; i < node.nEntries; ++i) { 00086 accessTuple(node,i); 00087 uint cbTuple = tupleAccessor.getCurrentByteCount(); 00088 PBuffer pBuffer = allocateEntry(scratchNode,i,cbTuple); 00089 memcpy(pBuffer,tupleAccessor.getCurrentTupleBuf(),cbTuple); 00090 } 00091 00092 if (isMAXU(node.cbCompactFree)) { 00093 node.cbCompactFree = node.cbTotalFree; 00094 } 00095 memcpy(&scratchNode,&node,sizeof(BTreeNode)); 00096 } 00097 00098 00099 00100 00101 00102 00103 00104 void BTreeNodeAccessor::splitNode( 00105 BTreeNode &node,BTreeNode &newNode, 00106 uint cbNewTuple, 00107 bool monotonic) 00108 { 00109 assert(!newNode.nEntries); 00110 assert(node.nEntries > 1); 00111 newNode.height = node.height; 00112 00113
00114
00115
00116
00117
00118
00119 if (monotonic && node.height == 0) { 00120 return; 00121 } 00122 00123
00124 uint cbNeeded = getEntryByteCount(cbNewTuple); 00125 uint cbBalance = cbNeeded; 00126 if (!monotonic) { 00127 cbBalance = (node.cbTotalFree + newNode.cbTotalFree - cbNeeded) / 2; 00128 cbBalance = std::max(cbNeeded,cbBalance); 00129 } 00130 00131
00132 uint cbFreeAfterSplit = node.cbTotalFree; 00133 uint iSplitTuple = node.nEntries; 00134 while (cbFreeAfterSplit < cbBalance) { 00135 --iSplitTuple; 00136 accessTuple(node,iSplitTuple); 00137 uint cbTuple = tupleAccessor.getCurrentByteCount(); 00138 cbFreeAfterSplit += getEntryByteCount(cbTuple); 00139 } 00140 00141
00142 for (uint i = iSplitTuple; i < node.nEntries; ++i) { 00143 accessTuple(node,i); 00144 uint cbTuple = tupleAccessor.getCurrentByteCount(); 00145 PBuffer pNewEntry = allocateEntry(newNode,newNode.nEntries,cbTuple); 00146 memcpy(pNewEntry,tupleAccessor.getCurrentTupleBuf(),cbTuple); 00147 } 00148 00149
00150
00151
00152 node.nEntries = iSplitTuple; 00153 node.cbTotalFree = cbFreeAfterSplit; 00154 } 00155 00156 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/btree/BTreeNodeAccessor.cpp#12 $"); 00157 00158