/***********************************************************************\
-| Find location for data |
+| Find leaf node in which data nodes can be found |
\***********************************************************************/
/********************** top level lookup **********************/
Nptr bplus_Lookup(Tree *B, keyT key)
{
- Nptr findNode;
+ Nptr leafNode;
#ifdef DEBUG_BTREE
sprintf(B->message, "LOOKUP: key %s.\n", key.name);
#endif
setfunkey(B, key); /* set search key */
- findNode = descendToLeaf(B, getroot(B)); /* start search from root node */
+ leafNode = descendToLeaf(B, getroot(B)); /* start search from root node */
#ifdef DEBUG_BTREE
- if (findNode) {
+ if (leafNode) {
int slot;
Nptr dataNode;
dataT data;
- slot = getSlot(B, findNode);
+ slot = getSlot(B, leafNode);
if (slot <= BTERROR)
return NONODE;
- dataNode = getnode(findNode, slot);
+ dataNode = getnode(leafNode, slot);
data = getdatavalue(dataNode);
sprintf(B->message, "LOOKUP: %s found on page %d value (%d.%d.%d).\n",
key.name,
- getnodenumber(B, findNode),
+ getnodenumber(B, leafNode),
data.fid.volume,
data.fid.vnode,
data.fid.unique);
OutputDebugString(B->message);
#endif
- return findNode;
+ return leafNode;
}
/********************** `recurse' down B+tree **********************/
curr = getfirstnode(curr);
else if (slot > 0)
curr = getnode(curr, slot);
- else /* BTERROR */ {
+ else /* BTERROR, BTLOWER, BTUPPER */ {
curr = NONODE;
break;
}
#ifdef DEBUG_BTREE
if (findslot == BTERROR) {
- sprintf(B->message, "Bad key ordering on node %d\n", getnodenumber(B, curr));
- OutputDebugString(B->message);
+ sprintf(B->message, "FINDKEY: (lo %d hi %d) Bad key ordering on node %d (0x%p)\n",
+ lo, hi, getnodenumber(B, curr), curr);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
}
#endif
} else {
findslot = findKey(B, curr, mid + 1, hi);
break;
case BTERROR:
- sprintf(B->message, "Bad key ordering on node %d\n", getnodenumber(B, curr));
- OutputDebugString(B->message);
+ sprintf(B->message, "FINDKEY: (lo %d hi %d) Bad key ordering on node %d (0x%p)\n",
+ lo, hi, getnodenumber(B, curr), curr);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
}
}
+
+ if (isleaf(curr) && findslot == 0)
+ {
+ sprintf(B->message, "FINDKEY: (lo %d hi %d) findslot %d is invalid for leaf nodes, bad key ordering on node %d (0x%p)\n",
+ lo, hi, findslot, getnodenumber(B, curr), curr);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
+ }
return findslot;
}
/************ comparison of key with a target key slot *************/
static int bestMatch(Tree *B, Nptr curr, int slot)
{
- int diff, comp, findslot;
+ int diff, comp=2, findslot;
diff = comparekeys(B)(getfunkey(B), getkey(curr, slot), 0);
if (diff == 0) {
findslot = slot;
- } else
- if (diff < 0) { /* also check previous slot */
- if ((slot == 1) ||
- ((comp = comparekeys(B)(getfunkey(B), getkey(curr, slot - 1), 0)) >= 0))
- {
+ } else if (diff < 0) { /* also check previous slot */
+ if (slot == 1) {
+ if (isleaf(curr))
+ findslot = BTLOWER; /* not found in the tree */
+ else
+ findslot = 0;
+ }
+ else if ((comp = comparekeys(B)(getfunkey(B), getkey(curr, slot - 1), 0)) >= 0) {
findslot = slot - 1;
- }
- else if (comp < diff) {
+ } else if (comp < diff) {
findslot = BTERROR; /* inconsistent ordering of keys */
#ifdef DEBUG_BTREE
DebugBreak();
#endif
- }
- else {
+ } else {
findslot = BTLOWER; /* key must be below in node ordering */
}
} else { /* or check following slot */
- if ((slot == numentries(curr)) ||
- ((comp = comparekeys(B)(getfunkey(B), getkey(curr, slot + 1), 0)) < 0))
- {
+ if (slot == numentries(curr)) {
+ if (isleaf(curr) && numentries(curr) == getfanout(B))
+ findslot = BTUPPER;
+ else
+ findslot = slot;
+ } else if ((comp = comparekeys(B)(getfunkey(B), getkey(curr, slot + 1), 0)) < 0) {
findslot = slot;
- }
- else if (comp == 0) {
+ } else if (comp == 0) {
findslot = slot + 1;
- }
- else if (comp > diff) {
+ } else if (comp > diff) {
findslot = BTERROR; /* inconsistent ordering of keys */
#ifdef DEBUG_BTREE
DebugBreak();
#endif
- }
- else {
+ } else {
findslot = BTUPPER; /* key must be above in node ordering */
}
}
+
+ if (findslot == BTERROR || isleaf(curr) && findslot == 0)
+ {
+ sprintf(B->message, "BESTMATCH: node %d (0x%p) slot %d diff %d comp %d findslot %d\n",
+ getnodenumber(B, curr), curr, slot, diff, comp, findslot);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
+ }
return findslot;
}
#ifdef DEBUG_BTREE
sprintf(B->message, "INSERT: key %s.\n", key.name);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
#endif
setfunkey(B, key); /* set insertion key */
setsplitpath(B, curr); /* indicates where nodes must split */
slot = getSlot(B, curr); /* is null only if the root is empty */
- if (slot <= BTERROR)
+ if (slot == BTERROR)
return NONODE;
+
+ if (isleaf(curr)) {
+ if (slot == BTLOWER)
+ slot = 0;
+ else if (slot == BTUPPER)
+ slot = getfanout(B);
+ }
+
if (isinternal(curr)) { /* continue recursion to leaves */
if (slot == 0)
downNode = descendSplit(B, getfirstnode(curr));
#ifdef DEBUG_BTREE
sprintf(B->message, "INSERT: slot %d, down node %d.\n", slot, getnodenumber(B, downPtr));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
#endif
if (sibling == NONODE) { /* no split occurred */
#ifdef DEBUG_BTREE
sprintf(B->message, "DELETE: key %s.\n", key.name);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
#endif
setfunkey(B, key); /* set deletion key */
if (isnode(newNode)) {
#ifdef DEBUG_BTREE
sprintf(B->message, "DELETE: collapsing node %d", getnodenumber(B, newNode));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
#endif
collapseRoot(B, getroot(B), newNode); /* remove root when superfluous */
}
#ifdef DEBUG_BTREE
sprintf(B->message, "COLLAPSE: old %d, new %d.\n", getnodenumber(B, oldRoot), getnodenumber(B, newRoot));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
showNode(B, "collapseRoot oldRoot", oldRoot);
showNode(B, "collapseRoot newRoot", newRoot);
#endif
lAnc ? getnodenumber(B, lAnc) : -1,
rAnc ? getnodenumber(B, rAnc) : -1,
parent ? getnodenumber(B, parent) : -1);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
#endif
if (!isfew(curr))
setmergepath(B, curr); /* mark which nodes may need rebalancing */
slot = getSlot(B, curr);
- if (slot <= BTERROR)
+ if (slot == BTERROR)
return NONODE;
+ if (isleaf(curr)) {
+ if (slot == BTLOWER)
+ slot = 0;
+ else if (slot == BTUPPER)
+ slot = getfanout(B);
+ }
+
if (isinternal(curr)) /* set up next recursion call's parameters */
{
if (slot == 0) {
if (newMe != NONODE) { /* this node removal doesn't consider duplicates */
#ifdef DEBUG_BTREE
sprintf(B->message, "descendBalance DELETE: slot %d, node %d.\n", slot, getnodenumber(B, curr));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
#endif
removeEntry(B, curr, slot + (newMe != newNode)); /* removes one of two */
#ifdef DEBUG_BTREE
sprintf(B->message, "descendBalance returns %d\n", getnodenumber(B, newNode));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
#endif
return newNode;
}
#ifdef DEBUG_BTREE
sprintf(B->message, "MERGE: left %d, right %d.\n", getnodenumber(B, left), getnodenumber(B, right));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
showNode(B, "pre-merge anchor", anchor);
showNode(B, "pre-merge left", left);
showNode(B, "pre-merge right", right);
getnodenumber(B, left),
getnodenumber(B, right),
getnodenumber(B, anchor));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
showNode(B, "pre-shift anchor", anchor);
showNode(B, "pre-shift left", left);
showNode(B, "pre-shift right", right);
pushentry(right, z, y);
setfunkey(B, getkey(left, x)); /* set new anchor key value */
- z = getSlot(B, anchor) + 1;
+ z = getSlot(B, anchor);
if (z <= BTERROR)
return NONODE;
+ z += 1;
+
if (i) {
decentries(left);
incentries(right);
#ifdef DEBUG_BTREE
sprintf(B->message, "SHIFT: left %d, right %d.\n", getnodenumber(B, left), getnodenumber(B, right));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
showNode(B, "post-shift anchor", anchor);
showNode(B, "post-shift left", left);
showNode(B, "post-shift right", right);
int x;
sprintf(B->message, "- -- -- -- -- -- -- -- -- -- -- -- -\n");
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| %-20s |\n", where);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| node %6d ", getnodenumber(B, n));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, " magic %4x |\n", getmagic(n));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "- -- -- -- -- -- -- -- -- -- -- -- -\n");
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| flags %1d%1d%1d%1d ", isfew(n), isfull(n), isroot(n), isleaf(n));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| keys = %5d ", numentries(n));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| node = %6d |\n", getnodenumber(B, getfirstnode(n)));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
for (x = 1; x <= numentries(n); x++) {
sprintf(B->message, "| entry %6d ", x);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| key = %6s ", getkey(n, x).name);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| node = %6d |\n", getnodenumber(B, getnode(n, x)));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
}
sprintf(B->message, "- -- -- -- -- -- -- -- -- -- -- -- -\n");
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
}
/****************** B+tree class variable printer ******************/
void showBtree(Tree *B)
{
sprintf(B->message, "- -- -- -- -- -- -\n");
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| B+tree %10p |\n", (void *) B);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "- -- -- -- -- -- -\n");
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| root %6d |\n", getnodenumber(B, getroot(B)));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| leaf %6d |\n", getnodenumber(B, getleaf(B)));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| fanout %3d |\n", getfanout(B) + 1);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| minfanout %3d |\n", getminfanout(B, getroot(B)) + 1);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| height %3d |\n", gettreeheight(B));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| freenode %6d |\n", getnodenumber(B, getfirstfreenode(B)));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| theKey %6s |\n", getfunkey(B).name);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "| theData %d.%d.%d |\n", getfundata(B).volume,
getfundata(B).vnode, getfundata(B).unique);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
sprintf(B->message, "- -- -- -- -- -- -\n");
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
}
void
if (isntnode(node)) {
sprintf(B->message, "%s - NoNode!!!\n");
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
return;
}
sprintf(B->message, "%s - data node %d (%d.%d.%d)\n",
parent_desc, getnodenumber(B, node),
data.fid.volume, data.fid.vnode, data.fid.unique);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
return;
} else
showNode(B, parent_desc, node);
if ( isinternal(node) || isroot(node) ) {
sprintf(thisnode, "parent %6d", getnodenumber(B , node));
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
for ( i= isinternal(node) ? 0 : 1; i <= numentries(node); i++ ) {
listBtreeNodes(B, thisnode, i == 0 ? getfirstnode(node) : getnode(node, i));
}
for (slot = 1; (n != NONODE) && num && numentries(n); num--) {
if (comparekeys(B)(getkey(n, slot),prev, 0) < 0) {
sprintf(B->message, "BOMB %8s\n", getkey(n, slot).name);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
DebugBreak();
}
prev = getkey(n, slot);
data = getdatavalue(getnode(n, slot));
sprintf(B->message, "%8s (%d.%d.%d)\n",
prev.name, data.fid.volume, data.fid.vnode, data.fid.unique);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
if (++slot > numentries(n))
n = getnextnode(n), slot = 1;
}
sprintf(B->message, "\n\n");
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
}
/******************** entire B+tree data printer *******************/
for (slot = 1; (n != NONODE) && num && numentries(n); num--) {
if (comparekeys(B)(getkey(n, slot),prev, 0) < 0) {
sprintf(B->message,"BOMB %8s\n", getkey(n, slot).name);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
#ifdef DEBUG_BTREE
DebugBreak();
#endif
sprintf(B->message,"BOMB %8s cannot be found\n", prev.name);
else
sprintf(B->message,"BOMB lookup(%8s) finds wrong node\n", prev.name);
- OutputDebugString(B->message);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message));
#ifdef DEBUG_BTREE
DebugBreak();
#endif
slot = getSlot(op->scp->dirBplus, leafNode);
if (slot <= BTERROR) {
op->scp->dirDataVersion = 0;
- rc = EINVAL;
+ rc = (slot == BTERROR ? EINVAL : ENOENT);
goto done;
}
firstDataNode = getnode(leafNode, slot);
long rc = 0;
char buffer[512];
- OutputDebugString("cm_BPlusDirEnumerate start");
+ osi_Log0(afsd_logp, "cm_BPlusDirEnumerate start");
/* Read lock the bplus tree so the data can't change */
if (!locked)
lock_ObtainRead(&scp->dirlock);
if (scp->dirBplus == NULL) {
- OutputDebugString("cm_BPlusDirEnumerate No BPlus Tree");
+ osi_Log0(afsd_logp, "cm_BPlusDirEnumerate No BPlus Tree");
goto done;
}
}
sprintf(buffer, "BPlusTreeEnumerate count = %d", count);
- OutputDebugString(buffer);
+ osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, buffer));
/* Allocate the enumeration object */
enump = cm_BPlusEnumAlloc(count);
if (enump == NULL) {
- OutputDebugString("cm_BPlusDirEnumerate Alloc failed");
+ osi_Log0(afsd_logp, "cm_BPlusDirEnumerate Alloc failed");
rc = ENOMEM;
goto done;
}
}
if (name == NULL) {
- OutputDebugString("cm_BPlusDirEnumerate strdup failed");
+ osi_Log0(afsd_logp, "cm_BPlusDirEnumerate strdup failed");
rc = ENOMEM;
goto done;
}
/* if we failed, cleanup any mess */
if (rc != 0) {
- OutputDebugString("cm_BPlusDirEnumerate rc != 0");
+ osi_Log0(afsd_logp, "cm_BPlusDirEnumerate rc != 0");
if (enump) {
for ( count = 0; count < enump->count && enump->entry[count].name; count++ ) {
free(enump->entry[count].name);
}
}
- OutputDebugString("cm_BPlusDirEnumerate end");
+ osi_Log0(afsd_logp, "cm_BPlusDirEnumerate end");
*enumpp = enump;
return rc;
}
if (enump == NULL || entrypp == NULL || enump->next > enump->count) {
if (entrypp)
*entrypp = NULL;
- OutputDebugString("cm_BPlusDirNextEnumEntry invalid input");
+ osi_Log0(afsd_logp, "cm_BPlusDirNextEnumEntry invalid input");
return CM_ERROR_INVAL; \
}
*entrypp = &enump->entry[enump->next++];
if ( enump->next == enump->count ) {
- OutputDebugString("cm_BPlusDirNextEnumEntry STOPNOW");
+ osi_Log0(afsd_logp, "cm_BPlusDirNextEnumEntry STOPNOW");
return CM_ERROR_STOPNOW;
}
else {
- OutputDebugString("cm_BPlusDirNextEnumEntry SUCCESS");
+ osi_Log0(afsd_logp, "cm_BPlusDirNextEnumEntry SUCCESS");
return 0;
}
}
{
afs_uint32 count;
- OutputDebugString("cm_BPlusDirFreeEnumeration");
+ osi_Log0(afsd_logp, "cm_BPlusDirFreeEnumeration");
if (enump) {
for ( count = 0; count < enump->count && enump->entry[count].name; count++ ) {
cm_direnum_entry_t * entryp;
long code;
- OutputDebugString("cm_BPlusDirEnumTest start");
+ osi_Log0(afsd_logp, "cm_BPlusDirEnumTest start");
for (code = cm_BPlusDirEnumerate(dscp, locked, NULL, &enump); code == 0; ) {
code = cm_BPlusDirNextEnumEntry(enump, &entryp);
type,
dv);
- OutputDebugString(buffer);
+ osi_Log0(afsd_logp, osi_LogSaveString(afsd_logp, buffer));
}
}
if (enump)
cm_BPlusDirFreeEnumeration(enump);
- OutputDebugString("cm_BPlusDirEnumTest end");
+ osi_Log0(afsd_logp, "cm_BPlusDirEnumTest end");
return 0;
}