#include <stdio.h>
#include <stdlib.h>
#include "btree.h"
#include "btree_consts.h"
bool
operator ==(uPtr u1, uPtr u2) {
return (u1.offset == u2.offset);
} // overloaded operator ==
bTree::bTree(char * filename, uInt32 nodeSize, treeTypes tt, bTreeVFS * virtualFS) {
filename = filename;
nodeSize = nodeSize;
tt = tt;
vfs = virtualFS;
return;
} // bTree::bTree
int
bTree::align(int keyLength) {
return ((sizeof(uPtr) + keyLength + 7) >> 3) << 3;
} // bTree::align
uPtr
bTree::allocEmptyNode(void) {
struct TbNode * newNode = NULL;
uPtr result;
saveSuperBlock();
setNull(result);
if (!isNull(getFirstDeleted())) {
newNode = loadPage(getFirstDeleted());
if (newNode == NULL) return result;
setFirstDeleted(newNode->parent);
} else {
newNode = static_cast<TbNode *>(calloc(1, info->bNodeSize));
setNodes(getNodes() + 1);
newNode->tag = getNodes();
} // else
newNode->magic = B_NODE_LEAF;
newNode->numKeys = 1;
newNode->size = (int)&newNode->data - (int)newNode;
// these should really be setNull() calls, but gcc doesn't support it.
// GNU bastards. Die. Die. Die.
newNode->left.offset = 0;
newNode->right.offset = 0;
newNode->parent.offset = 0;
newNode->reserved.offset = 0;
result = getAddress(newNode);
savePage(newNode);
discardPage(newNode);
return result;
} // bTree::allocEmptyNode
int
bTree::calcSize(TbNode * node) {
int size;
TbNodeData * dataNode;
if (node == NULL) return 0;
dataNode = &node->data;
size = (int)dataNode - (int)node;
for (unsigned int curNode = 1; curNode <= node->numKeys; curNode++) {
size += align(keySize(&dataNode->key));
//mjikaboom dataNode += align(keySize(&dataNode->key)));
} // for curNode
return size;
} // bTree::calcSize
void
bTree::discardPage(TbNode *) {
} // bTree::discardPage
bool
bTree::isNull(uPtr u) {
return (u.offset == 0);
} // bTree::isNull
uPtr
bTree::getAddress(TbNode * node) {
uPtr u;
setNull(u);
if (memoryTree)
u.bPtr = node;
else
u.offset = node->tag;
return u;
} // bTree::getAddress
uPtr
bTree::getFirstDeleted(void) {
if (!memoryTree) {
if (!vfs->fSeek((int)&info->firstDeleted - (int)info)) exit(42);
if (!vfs->fRead(&info->firstDeleted, sizeof(info->firstDeleted))) exit(42);
} // if not memoryTree
return info->firstDeleted;
} // bTree::getFirstDeleted
uInt32
bTree::getNodes(void) {
if (!memoryTree) {
if (!vfs->fSeek((int)&info->nodes - (int)info)) exit(42);
if (!vfs->fRead(&info->nodes, sizeof(info->nodes))) exit(42);
} // if not memoryTree
return info->nodes;
} // bTree::getNodes
uInt32
bTree::getHeight(void) {
if (!memoryTree) {
if (!vfs->fSeek((int)&info->height - (int)info)) exit(42);
if (!vfs->fRead(&info->height, sizeof(info->height))) exit(42);
} // if not memoryTree
return info->height;
} // bTree::getHeight
uInt32
bTree::getKeys(void) {
if (!memoryTree) {
if (!vfs->fSeek((int)&info->keys - (int)info)) exit(42);
if (!vfs->fRead(&info->keys, sizeof(info->keys))) exit(42);
} // if not memoryTree
return info->keys;
} // bTree::getKeys
uPtr
bTree::getRoot(void) {
if (info == NULL) {
uPtr result;
setNull(result);
return result;
} // if info == NULL
if (!memoryTree) {
if (!vfs->fSeek((int)&info->root - (int)info)) exit(42);
if (!vfs->fRead(&info->root, sizeof(info->root))) exit(42);
} // if not memoryTree
return info->root;
} // bTree::getRoot
TbNode *
bTree::loadPage(uPtr u) {
TbNode * node;
if (isNull(u)) return NULL;
if (memoryTree)
node = u.bPtr;
else {
if (!vfs->fSeek((int)u.offset * info->bNodeSize)) exit(42);
node = (TbNode *)malloc(info->bNodeSize);
if (node == NULL) return NULL;
if (!vfs->fRead(node, info->bNodeSize)) exit(42);
} // else
return node;
} // bTree::loadPage
void
bTree::loadSuperBlock(void) {
if (memoryTree) return;
if (!vfs->fSeek(0)) exit(42);
if (!vfs->fRead(info, sizeof(bTreeInfo))) exit(42);
} // bTree::loadSuperBlock
void
bTree::savePage(TbNode * node) {
if (memoryTree) return;
if (node == NULL) return;
if (!vfs->fSeek((int)node->tag * info->bNodeSize)) exit(42);
if (!vfs->fWrite(node, info->bNodeSize)) exit(42);
} // bTree::savePage
void
bTree::saveSuperBlock(void) {
if (memoryTree) return;
if (!vfs->fSeek(0)) exit(42);
if (!vfs->fWrite(info, sizeof(bTreeInfo))) exit(42);
} // bTree::saveSuperBlock
void
bTree::setFirstDeleted(uPtr value) {
info->firstDeleted = value;
if (memoryTree) return;
if (!vfs->fSeek((int)&info->firstDeleted - (int)info)) exit(42);
if (!vfs->fWrite(&info->firstDeleted, sizeof(info->firstDeleted))) exit(42);
} // bTree::setFirstDeleted
void
bTree::setNodes(uInt32 value) {
info->nodes = value;
if (memoryTree) return;
if (!vfs->fSeek((int)&info->nodes - (int)info)) exit(42);
if (!vfs->fWrite(&info->nodes, sizeof(info->nodes))) exit(42);
} // bTree::setNodes
void
bTree::setHeight(uInt32 value) {
info->height = value;
if (memoryTree) return;
if (!vfs->fSeek((int)&info->height - (int)info)) exit(42);
if (!vfs->fWrite(&info->height, sizeof(info->height))) exit(42);
} // bTree::setHeight
void
bTree::setKeys(uInt32 value) {
info->keys = value;
if (memoryTree) return;
if (!vfs->fSeek((int)&info->keys - (int)info)) exit(42);
if (!vfs->fWrite(&info->keys, sizeof(info->keys))) exit(42);
} // bTree::getKeys
void
bTree::setLeft(uPtr u, uPtr newPtr) {
TbNode * node = loadPage(u);
if (node == NULL) return;
node->left = newPtr;
savePage(node);
discardPage(node);
} // bTree::setLeft
void
bTree::setParent(uPtr u, uPtr newPtr) {
TbNode * node = loadPage(u);
if (node == NULL) return;
node->parent = newPtr;
savePage(node);
discardPage(node);
} // bTree::setParent
void
bTree::setRight(uPtr u, uPtr newPtr) {
TbNode * node = loadPage(u);
if (node == NULL) return;
node->right = newPtr;
savePage(node);
discardPage(node);
} // bTree::setRight
void
bTree::setRoot(uPtr value) {
info->root = value;
if (memoryTree) return;
if (!vfs->fSeek((int)&info->root - (int)info)) exit(42);
if (!vfs->fWrite(&info->root, sizeof(info->root))) exit(42);
} // bTree::setRoot
void
bTree::setNull(uPtr & u) {
u.offset = 0;
} // bTree::setNull
void
bTree::InstallUserFunctions(compareKeyFunc cmpFunc, copyKeyProc copyProc, keySizeFunc ksFunc) {
compareKey = cmpFunc;
copyKey = copyProc;
keySize = ksFunc;
return;
} // bTree::InstallUserFunctions
bTree::~bTree(void) {
return;
} // bTree::~bTree