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: <null>" << 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<PConstBuffer>(&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