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/BTreeAccessBaseImpl.h"
00026 #include "fennel/btree/BTreeCompactNodeAccessor.h"
00027 #include "fennel/btree/BTreeHeapNodeAccessor.h"
00028 #include "fennel/btree/BTreeKeyedNodeAccessor.h"
00029 #include "fennel/cache/CacheAccessor.h"
00030 #include "fennel/tuple/StandardTypeDescriptor.h"
00031 #include "fennel/tuple/TupleOverflowExcn.h"
00032
00033 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/btree/BTreeAccessBase.cpp#9 $");
00034
00035 BTreeAccessBase::BTreeAccessBase(BTreeDescriptor const &treeDescriptorInit)
00036 : treeDescriptor(treeDescriptorInit)
00037 {
00038 keyDescriptor.projectFrom(
00039 treeDescriptor.tupleDescriptor,
00040 treeDescriptor.keyProjection);
00041
00042
00043
00044
00045
00046
00047 typedef BTreeKeyedNodeAccessor<
00048 BTreeHeapNodeAccessor,TupleAccessor>
00049 VarNonLeafNodeAccessor;
00050 typedef BTreeKeyedNodeAccessor<
00051 BTreeCompactNodeAccessor,TupleAccessor>
00052 FixedNonLeafNodeAccessor;
00053
00054
00055 typedef BTreeKeyedNodeAccessor<
00056 BTreeHeapNodeAccessor,TupleProjectionAccessor>
00057 VarLeafNodeAccessor;
00058 typedef BTreeKeyedNodeAccessor<
00059 BTreeCompactNodeAccessor,TupleProjectionAccessor>
00060 FixedLeafNodeAccessor;
00061
00062
00063
00064 TupleAccessor tmpLeafAccessor;
00065 tmpLeafAccessor.compute(treeDescriptor.tupleDescriptor);
00066 TupleAccessor tmpNonLeafAccessor;
00067 tmpNonLeafAccessor.compute(keyDescriptor);
00068
00069 if (tmpLeafAccessor.isFixedWidth()) {
00070 FixedLeafNodeAccessor *pLeafNodeAccessorImpl =
00071 new FixedLeafNodeAccessor();
00072 pLeafNodeAccessor.reset(pLeafNodeAccessorImpl);
00073 pLeafNodeAccessorImpl->pKeyAccessor = &leafKeyAccessor;
00074 } else {
00075 VarLeafNodeAccessor *pLeafNodeAccessorImpl =
00076 new VarLeafNodeAccessor();
00077 pLeafNodeAccessor.reset(pLeafNodeAccessorImpl);
00078 pLeafNodeAccessorImpl->pKeyAccessor = &leafKeyAccessor;
00079 }
00080
00081 if (tmpNonLeafAccessor.isFixedWidth()) {
00082 FixedNonLeafNodeAccessor *pNonLeafNodeAccessorImpl =
00083 new FixedNonLeafNodeAccessor();
00084 pNonLeafNodeAccessor.reset(pNonLeafNodeAccessorImpl);
00085 pNonLeafNodeAccessorImpl->pKeyAccessor =
00086 &(pNonLeafNodeAccessor->tupleAccessor);
00087 } else {
00088 VarNonLeafNodeAccessor *pNonLeafNodeAccessorImpl =
00089 new VarNonLeafNodeAccessor();
00090 pNonLeafNodeAccessor.reset(pNonLeafNodeAccessorImpl);
00091 pNonLeafNodeAccessorImpl->pKeyAccessor =
00092 &(pNonLeafNodeAccessor->tupleAccessor);
00093 }
00094
00095 pLeafNodeAccessor->tupleDescriptor = treeDescriptor.tupleDescriptor;
00096
00097 pNonLeafNodeAccessor->tupleDescriptor = keyDescriptor;
00098 StandardTypeDescriptorFactory stdTypeFactory;
00099
00100
00101 assert(sizeof(PageId) == sizeof(uint64_t));
00102 TupleAttributeDescriptor pageIdDesc(
00103 stdTypeFactory.newDataType(STANDARD_TYPE_UINT_64));
00104 pNonLeafNodeAccessor->tupleDescriptor.push_back(pageIdDesc);
00105
00106 pLeafNodeAccessor->onInit();
00107 pNonLeafNodeAccessor->onInit();
00108
00109 pChildAccessor = &(
00110 pNonLeafNodeAccessor->tupleAccessor.getAttributeAccessor(
00111 getKeyProjection().size()));
00112
00113 leafKeyAccessor.bind(
00114 pLeafNodeAccessor->tupleAccessor,
00115 getKeyProjection());
00116
00117 cbTupleMax =
00118 ((getSegment()->getUsablePageSize() - sizeof(BTreeNode)) / 2)
00119 - pLeafNodeAccessor->getEntryByteCount(0);
00120 }
00121
00122 BTreeAccessBase::~BTreeAccessBase()
00123 {
00124 }
00125
00126 PageId BTreeAccessBase::getFirstChild(PageId parentPageId)
00127 {
00128 BTreePageLock pageLock(treeDescriptor.segmentAccessor);
00129 while (parentPageId != NULL_PAGE_ID) {
00130 pageLock.lockShared(parentPageId);
00131 BTreeNode const &node = pageLock.getNodeForRead();
00132 assert(node.height);
00133 if (node.nEntries) {
00134 return getChild(node,0);
00135 }
00136 parentPageId = node.rightSibling;
00137 }
00138 return NULL_PAGE_ID;
00139 }
00140
00141 void BTreeAccessBase::setRootPageId(PageId rootPageId)
00142 {
00143 treeDescriptor.rootPageId = rootPageId;
00144 }
00145
00146 void BTreeAccessBase::validateTupleSize(TupleAccessor const &tupleAccessor)
00147 {
00148 uint cbTuple = tupleAccessor.getCurrentByteCount();
00149 if (cbTuple > cbTupleMax) {
00150 TupleData tupleData(getTupleDescriptor());
00151 tupleAccessor.unmarshal(tupleData);
00152 throw TupleOverflowExcn(
00153 getTupleDescriptor(),
00154 tupleData,
00155 cbTuple,
00156 cbTupleMax);
00157 }
00158 }
00159
00160 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/btree/BTreeAccessBase.cpp#9 $");
00161
00162