BTreeAccessBase.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/btree/BTreeAccessBase.cpp#9 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-2009 The Eigenbase Project
00005 // Copyright (C) 2005-2009 SQLstream, Inc.
00006 // Copyright (C) 2005-2009 LucidEra, Inc.
00007 // Portions Copyright (C) 1999-2009 John V. Sichi
00008 //
00009 // This program is free software; you can redistribute it and/or modify it
00010 // under the terms of the GNU General Public License as published by the Free
00011 // Software Foundation; either version 2 of the License, or (at your option)
00012 // any later version approved by The Eigenbase Project.
00013 //
00014 // This program is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with this program; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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     // TODO:  fine-tuning (in some cases fixed-width may be better for short
00043     // variable-width tuples, and indirection may be good for long fixed-width
00044     // tuples)
00045 
00046     // supported leaf accessor types
00047     typedef BTreeKeyedNodeAccessor<
00048         BTreeHeapNodeAccessor,TupleAccessor>
00049         VarNonLeafNodeAccessor;
00050     typedef BTreeKeyedNodeAccessor<
00051         BTreeCompactNodeAccessor,TupleAccessor>
00052         FixedNonLeafNodeAccessor;
00053 
00054     // supported non-leaf accessor types
00055     typedef BTreeKeyedNodeAccessor<
00056         BTreeHeapNodeAccessor,TupleProjectionAccessor>
00057         VarLeafNodeAccessor;
00058     typedef BTreeKeyedNodeAccessor<
00059         BTreeCompactNodeAccessor,TupleProjectionAccessor>
00060         FixedLeafNodeAccessor;
00061 
00062     // REVIEW:  These are just for deciding between fixed and var.  Add an
00063     // isFixedWidth() method to TupleDescriptor instead?
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     // TODO:  make PageId storage type selection automatic
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 // End BTreeAccessBase.cpp

Generated on Mon Jun 22 04:00:13 2009 for Fennel by  doxygen 1.5.1