void freenode(long t) { node nod; readnode(t, &nod); nod.ptr[0] = freelist; freelist = t; writenode(t, &nod); }
void wrstart(void) { start[0] = root; start[1] = freelist; if (fseek(fptree, 0L, SEEK_SET)) error("fseek in wrstart"); if (fwrite(start, sizeof(long), 2, fptree) == 0) error("fwrite in wrstart"); if (root != NIL) writenode(root, &rootnode); }
long getnode(void) { long t; node nod; if (freelist == NIL) { if (fseek(fptree, 0L, SEEK_END)) error("fseek in getnode"); t = ftell(fptree); writenode(t, &nod); } /* Allocate space on disk */ else{ t = freelist; readnode(t, &nod); /* To update freelist */ freelist = nod.ptr[0]; } return(t); }
void writenode(genpt p){ genpt temp=p; if(temp->tag==data){ printf("%c",temp->u.c); } printf("("); for(temp=temp->link;temp!=NULL;temp=temp->link){ if(temp->tag==data) printf("%c",temp->u.c); else{ genpt temp_list=temp->u.list; writenode(temp_list); } if(temp->link!=NULL) printf(","); } printf(")"); }
/* Driver function for node insertion, called only in the main function. Most of the work is delegated to 'ins'. */ status insert(char *index, long value) { long tnew, u; btuple_t x; strcpy(x.index,index); x.value = value; btuple_t xnew; status code = ins(x, root, &xnew, &tnew); if (code == DUPLICATEKEY) printf("Duplicate uid %s ignored \n", x.index); else if (code == INSERTNOTCOMPLETE){ u = getnode(); rootnode.cnt = 1; rootnode.tuple[0] = xnew; rootnode.ptr[0] = root; rootnode.ptr[1] = tnew; root = u; writenode(u, &rootnode); code = SUCCESS; } return(code); /* return index: SUCCESS of DUPLICATEKEY */ }
void writetree(genpt p){ genpt temp=p->u.list; writenode(temp); }
/* Delete item x in B-tree with root t. Return index: SUCCESS, NOTFOUND, OR UNDERFLOW */ status del(btuple_t x, long t) { int i, j, *n, *nleft, *nright, borrowleft=0, nq; btuple_t *k, *ltuple, *rtuple, *item, *addr; status code; long *p, left, right, *lptr, *rptr, q, q1; node nod, nod1, nod2, nodL, nodR; if (t == NIL) return(NOTFOUND); readnode(t, &nod); n = & nod.cnt; k = nod.tuple; p=nod.ptr; i=binsearch(x, k, *n); /* *t is a leaf */ if (p[0] == NIL){ if (i == *n || strcmp(x.index,k[i].index) < 0) return NOTFOUND; /* x is now equal to k[i], located in a leaf: */ for (j=i+1; j < *n; j++){ k[j-1] = k[j]; p[j] = p[j+1]; } --*n; writenode(t, &nod); return(*n >= (t==root ? 1 : M) ? SUCCESS : UNDERFLOW); } /* t is an interior node (not a leaf): */ item = k+i; left = p[i]; readnode(left, &nod1); nleft = & nod1.cnt; /* x found in interior node. Go to left child *p[i] and then follow a path all the way to a leaf, using rightmost branches: */ if (i < *n && strcmp(x.index,item->index) == 0){ q = p[i]; readnode(q, &nod1); nq = nod1.cnt; while (q1 = nod1.ptr[nq], q1!= NIL){ q = q1; readnode(q, &nod1); nq = nod1.cnt; } /* Exchange k[i] with the rightmost item in that leaf: */ addr = nod1.tuple + nq -1; *item = *addr; *addr = x; writenode(t, &nod); writenode(q, &nod1); } /* Delete x in subtree with root p[i]: */ code = del(x, left); if (code != UNDERFLOW) return code; /* Underflow, borrow, and , if necessary, merge: */ if (i < *n) readnode(p[i+1], &nodR); if (i == *n || nodR.cnt == M){ if (i > 0){ readnode(p[i-1], &nodL); if (i == *n || nodL.cnt > M) borrowleft = 1; } } /* borrow from left sibling */ if (borrowleft){ item = k+i-1; left = p[i-1]; right = p[i]; nod1 = nodL; readnode(right, &nod2); nleft = & nod1.cnt; }else{ right = p[i+1]; /* borrow from right sibling */ readnode(left, &nod1); nod2 = nodR; } nright = & nod2.cnt; ltuple = nod1.tuple; rtuple = nod2.tuple; lptr = nod1.ptr; rptr = nod2.ptr; if (borrowleft){ rptr[*nright + 1] = rptr[*nright]; for (j=*nright; j>0; j--){ rtuple[j] = rtuple[j-1]; rptr[j] = rptr[j-1]; } ++*nright; rtuple[0] = *item; rptr[0] = lptr[*nleft]; *item = ltuple[*nleft - 1]; if (--*nleft >= M){ writenode(t, &nod); writenode(left, &nod1); writenode(right, &nod2); return SUCCESS; } }else /* borrow from right sibling */ if (*nright > M){ ltuple[M-1] = *item; lptr[M] = rptr[0]; *item = rtuple[0]; ++*nleft; --*nright; for (j=0; j < *nright; j++){ rptr[j] = rptr[j+1]; rtuple[j] = rtuple[j+1]; } rptr[*nright] = rptr[*nright + 1]; writenode(t, &nod); writenode(left, &nod1); writenode(right, &nod2); return(SUCCESS); } /* Merge */ ltuple[M-1] = *item; lptr[M] = rptr[0]; for (j=0; j<M; j++){ ltuple[M+j] = rtuple[j]; lptr[M+j+1] = rptr[j+1]; } *nleft = MM; freenode(right); for (j=i+1; j < *n; j++){ k[j-1] = k[j]; p[j] = p[j+1]; } --*n; writenode(t, &nod); writenode(left, &nod1); return( *n >= (t==root ? 1 : M) ? SUCCESS : UNDERFLOW); }
/* Insert x in B-tree with root t. If not completely successful, the integer *y and the pointer *u remain to be inserted. */ status ins(btuple_t x, long t, btuple_t *y, long *u) { long tnew, p_final, *p; int i, j, *n; btuple_t *k; btuple_t xnew, k_final; status code; node nod, newnod; /* Examine whether t is a pointer member in a leaf */ if (t == NIL){ *u = NIL; *y = x; return(INSERTNOTCOMPLETE); } readnode(t, &nod); n = & nod.cnt; k = nod.tuple; p = nod.ptr; /* Select pointer p[i] and try to insert x in the subtree of whichp[i] is the root: */ i = binsearch(x, k, *n); if (i < *n && strcmp(x.index,k[i].index) == 0) return(DUPLICATEKEY); code = ins(x, p[i], &xnew, &tnew); if (code != INSERTNOTCOMPLETE) return code; /* Insertion in subtree did not completely succeed; try to insert xnew and tnew in the current node: */ if (*n < MM){ i = binsearch(xnew, k, *n); for (j = *n; j > i; j--){ k[j] = k[j-1]; p[j+1] = p[j]; } k[i] = xnew; p[i+1] = tnew; ++*n; writenode(t, &nod); return(SUCCESS); } /* The current node was already full, so split it. Pass item k[M] in the middle of the augmented sequence back through parameter y, so that it can move upward in the tree. Also, pass a pointer to the newly created node back through u. Return INSERTNOTCOMPLETE, to report that insertion was not completed: */ if (i == MM){ k_final = xnew; p_final = tnew; }else{ k_final = k[MM-1]; p_final = p[MM]; for (j=MM-1; j>i; j--){ k[j] = k[j-1]; p[j+1] = p[j]; } k[i] = xnew; p[i+1] = tnew; } *y = k[M]; *n = M; *u = getnode(); newnod.cnt = M; for (j=0; j< M-1; j++){ newnod.tuple[j] = k[j+M+1]; newnod.ptr[j] = p[j+M+1]; } newnod.ptr[M-1] = p[MM]; newnod.tuple[M-1] = k_final; newnod.ptr[M] = p_final; writenode(t, &nod); writenode(*u, &newnod); return(INSERTNOTCOMPLETE); }