00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef Fennel_BTreeKeyedNodeAccessor_Included
00025 #define Fennel_BTreeKeyedNodeAccessor_Included
00026
00027 #include "fennel/btree/BTreeNodeAccessor.h"
00028
00029 FENNEL_BEGIN_NAMESPACE
00030
00031
00032
00038 template <class NodeAccessor,class KeyAccessor>
00039 class BTreeKeyedNodeAccessor : public NodeAccessor
00040 {
00041 public:
00042 KeyAccessor *pKeyAccessor;
00043
00044 virtual void accessTupleInline(BTreeNode const &node,uint iEntry)
00045 {
00046 assert(iEntry < node.nEntries);
00047 NodeAccessor::tupleAccessor.setCurrentTupleBuf(
00048 NodeAccessor::getEntryForReadInline(node,iEntry));
00049 }
00050
00051 virtual void accessTuple(BTreeNode const &node,uint iEntry)
00052 {
00053 return accessTupleInline(node,iEntry);
00054 }
00055
00056 virtual void unmarshalKey(TupleData &keyData)
00057 {
00058 pKeyAccessor->unmarshal(keyData);
00059 }
00060
00061 virtual uint binarySearch(
00062 BTreeNode const &node,
00063 TupleDescriptor const &keyDescriptor,
00064 TupleData const &searchKey,
00065 DuplicateSeek dupSeek,
00066 bool leastUpper,
00067 TupleData &scratchKey,
00068 bool &found)
00069 {
00070 uint probe = 0;
00071 uint base = probe;
00072 found = false;
00073 int nKeys = NodeAccessor::getKeyCount(node);
00074 while (nKeys > 0) {
00075 uint split = nKeys >> 1;
00076 probe = base + split;
00077 accessTupleInline(node,probe);
00078 pKeyAccessor->unmarshal(scratchKey);
00079 int j = keyDescriptor.compareTuples(
00080 searchKey,scratchKey);
00081 if (j == 0) {
00082 found = true;
00083 switch (dupSeek) {
00084 case DUP_SEEK_ANY:
00085 return probe;
00086 case DUP_SEEK_BEGIN:
00087 j = -1;
00088 break;
00089 case DUP_SEEK_END:
00090 j = 1;
00091 break;
00092 default:
00093 permAssert(false);
00094 }
00095 }
00096 if (j < 0) {
00097 nKeys = split;
00098 } else {
00099 base = probe + 1;
00100 nKeys -= (split + 1);
00101 }
00102 }
00103 if (!found && !leastUpper && (base > 0)) {
00104 base--;
00105 }
00106 if (((base != probe) && (base < node.nEntries)) ||
00107 ((node.nEntries == 1) && (node.height != 0)))
00108 {
00109
00110 accessTupleInline(node,base);
00111 }
00112 return base;
00113 }
00114
00115 virtual int compareFirstKey(
00116 BTreeNode const &node,
00117 TupleDescriptor const &keyDescriptor,
00118 TupleData const &searchKey,
00119 TupleData &scratchKey)
00120 {
00121 int nKeys = NodeAccessor::getKeyCount(node);
00122 if (nKeys == 0) {
00123 return -1;
00124 }
00125 accessTupleInline(node, 0);
00126 pKeyAccessor->unmarshal(scratchKey);
00127 int compareResult = keyDescriptor.compareTuples(searchKey, scratchKey);
00128 return compareResult;
00129 }
00130
00131 virtual PConstBuffer getEntryForRead(BTreeNode const &node,uint iEntry)
00132 {
00133 return NodeAccessor::getEntryForReadInline(node,iEntry);
00134 }
00135 };
00136
00137 FENNEL_END_NAMESPACE
00138
00139 #endif
00140
00141