I have a B-tree which already exists in the database. Now the following piece of code which is written by some other programmer tries to traverse the B-Tree. However, I am unable to understand as to what is the use of the functions: readInner1(page,slot) and readInnerPage(page,slot). Can someone help me in understanding what the code does by using these 2 functions?
static inline unsigned readUint32Aligned(const unsigned char* data) { return toHost(*reinterpret_cast<const uint32_t*>(data)); }
/// The page remains accessible during the lifetime of the BufferReference object.
class BufferReference
{
public:
/// The size of a page
static const unsigned pageSize = 16384;
/// A page buffer
struct PageBuffer { char data[pageSize]; };
private:
/// The buffer frame
const BufferFrame* frame;
/// No copying of references
BufferReference(const BufferReference&);
void operator=(const BufferReference&);
public:
/// Constructor
BufferReference();
/// Constructor from a request
BufferReference(const BufferRequest& request);
/// Destructor
/// Access the page
const void* getPage() const;
/// Get the page number
unsigned getPageNo() const;
};
Info1(unsigned root,unsigned value1)
{
// Traverse the B-Tree
#define readInner1(page,slot) readUint32Aligned(page+24+8*(slot))
#define readInnerPage(page,slot) readUint32Aligned(page+24+8*(slot)+4)
BufferReference ref;
ref=readShared(root);
while (true) {
const unsigned char* page=static_cast<const unsigned char*>(ref.getPage());
// Inner node?
if (readUint32Aligned(page+8)==0xFFFFFFFF) {
// Perform a binary search. The test is more complex as we only have the upper bound for ranges
unsigned left=0,right=readUint32Aligned(page+16);
cout<<"\n right="<<right<<"\n";
while (left!=right) {
unsigned middle=(left+right)/2;
printf("\n MIDDLE=%d",middle);
unsigned middle1=readInner1(page,middle);
cout<<"\n middle1="<<middle1<<"\t value1="<<value1<<"\n";
if (value1>middle1) {
left=middle+1;
cout<<"\n left="<<left<<"\n";
} else if ((!middle)||(value1>readInner1(page,middle-1))) {
ref=readShared(readInnerPage(page,middle));
break;
} else {
right=middle;
cout<<"\n right="<<right<<"\n";
}
}
// Unsuccessful search?
if (left==right) {
ref.reset();
return false;
}
} else {
// A leaf node
break;
}
}
#undef readInnerPage
#undef readInner1
}
Also it will be great if someone could explain the code?
The code in general is performing a binary search.
Thus
leftandrightare bounds to the search, and this halves every iteration until they hold the same value.The data seems to be arranged in pages of 16K bytes, and there is probably some header information within those pages, which are probably sorted and thus it is checking these values then readjusting the search.
If you are allowed to modify the code may I suggest you replace the macros with inline functions.