home *** CD-ROM | disk | FTP | other *** search
- /* (C) Copyright 1984,85,86,87 Walter L. Peacock All Rights Reserved */
- /* THIS PROGRAM BELONGS TO WALTER L. PEACOCK. IT IS CONSIDERED A TRADE */
- /* SECRET AND IS NOT TO BE DIVULGED OR USED BY PARTIES WHO HAVE NOT */
- /* RECEIVED WRITTEN AUTHORIZATION FROM THE OWNER. */
-
- /*-----------------------------------------------------------------------
- The utility ckbtree performs integrity checks on the specified b+tree
- index file. It verifies that all index nodes and data nodes are properly
- linked and sequenced. It also checks the order of keys within each node.
- -------------------------------------------------------------------------*/
- /* 09/11/87 C K B T R E E . C check btree pointers and keys */
-
- #include <stdio.h>
- #include "cbtree.h"
- /* btfio.h *must* be included when bt_open() is used */
- #include "btfio.h"
-
- #if CI | DC
- #else
- #include <ctype.h>
- #endif
-
- long keyicnt, idxdcnt, idxtcnt;
- int ckkeyans;
- char *lastkey;
-
- void main(argc, argv)
- int argc;
- char **argv;
- {
- extern char *strcpy(), *calloc(), *strcat();
- extern int strlen(), exit(), atoi(), cklvlptr();
- extern void free();
- extern long getroot();
- long rootptr, savlvlpt, savlvl, depth;
- struct btcommo btstruct;
- BTIDXBLK *idxblk;
- int fdidx;
- register int i;
-
- wopen("CON:0/0/640/200/Ckbtree");
-
- scr_clr(); /* clear the screen */
- scr_curs(1,24);
- printf("CHECK B+TREE STRUCTURE");
- scr_curs(3, 3);
- printf("o Reads each index block and verifies that internal pointers");
- scr_curs(4, 3);
- printf("o are consistent. Also verifies that keys are in proper sequence");
- scr_curs(5, 3);
- printf("o and accumulates the total key count at the leaf node.");
-
- getbname(argc, argv, &btstruct);
-
- scr_curs(9, 3);
- printf(" Beginning check of index page pointers. ");
-
- ckkeyans = 1; /* check key sequences */
-
- /* open btstruct.idx file */
- if( (fdidx = bt_open(btstruct.idxname, O_RDONLY) ) == ERR)
- ckerror(- CK_OPEN, "ckbtree");
-
- i = sizeof(BTIDXBLK) + btstruct.btcells * sizeof(BTIDX);
- if( !(idxblk = (BTIDXBLK *) calloc(i, SZCHAR) ))
- ckerror(- CK_NOMEM, "cbtrseq: idxblk");
-
- if( !(lastkey = (char *) calloc(btstruct.btkeylen + 1, 1) ))
- ckerror(- CK_NOMEM, "ckbtree: lastkey");
-
- keyicnt = idxdcnt = idxtcnt = 0L;
- depth = 1L;
- idxblk->blkalloc = 0;
-
- rootptr = getroot(fdidx, btstruct.findroot); /* get ptr to idx root node */
-
- getidxr(fdidx, rootptr, idxblk, btstruct.btidxlen, btstruct.btkeylen);
- savlvl = idxblk->btpage[0].btptr;
-
- scr_curs(11, 16);
- printf("Depth Node Key Count", rootptr);
- scr_curs(12, 16);
- printf("%3ld %7ld ", depth++, rootptr);
-
- strcpy(lastkey, ""); /* initialize at each level */
-
- if (cklvlptr(fdidx, rootptr, idxblk, btstruct.btidxlen, btstruct.btkeylen,ckkeyans) < 1){
- printf("\nB+tree error detected!!! Rebuild index before continuing.");
- goto ckb_0exit;
- }
-
- while(!idxblk->blktype && savlvl){ /* until data block type = 1 located */
- getidxr(fdidx, savlvl, idxblk, btstruct.btidxlen, btstruct.btkeylen);
- savlvlpt = idxblk->btpage[0].btptr;
-
- scr_curs(12, 16);
- printf("%3ld %7ld ", depth++, savlvl);
-
- strcpy(lastkey, ""); /* initialize at each level */
-
- if (cklvlptr(fdidx, savlvl, idxblk, btstruct.btidxlen, btstruct.btkeylen,ckkeyans) < 1){
- printf("\nB+tree error detected!!! Rebuild index before continuing.");
- goto ckb_0exit;
- }
- savlvl = savlvlpt;
- }
-
- /* keyicnt includes the null cell 7F */
- printf("\n\n%s checks out O.K.",btstruct.btname);
- printf("\nKey count = %ld", keyicnt-1);
- printf("\nData nodes = %ld Index nodes = %ld Total nodes in tree = %ld ",
- idxdcnt, idxtcnt - idxdcnt, idxtcnt);
- printf("\nPercent full data nodes = %u %%", (100 * keyicnt)/(idxdcnt * btstruct.btcells) );
- printf("\nAverage cells per node = %u ", keyicnt/idxdcnt);
- printf("\tMaximum cells per node = %u\n", btstruct.btcells);
-
- /************************
- printf("\n\nPercent full entire tree= %4.2f; Average cells per node = %6.2f; ",
- (double) ((double) (keyicnt/idxtcnt)/btstruct.btcells) * 100, (double) (keyicnt/idxtcnt));
- *********************/
-
- ckb_0exit:
- FREE(lastkey);
- freekeys(idxblk);
- FREE(idxblk);
- close(fdidx);
- btrterm(&btstruct);
- wclose(); /* close Amiga window */
- }
-
- /* check each node for proper forward and backward pointers */
-
- int cklvlptr(fd, idxptr, idxblk, idxlen, keylen, ckkeyfl)
- int fd, ckkeyfl;
- long idxptr;
- unsigned idxlen, keylen;
- struct btidxblk *idxblk;
- {
- int moreidx = 1, ckkeys();
- long savcurpt, savfwdpt;
-
- savcurpt = idxptr;
- idxtcnt++;
-
- if(idxblk->bwdpage > 1L){ /* the bwdpage for the first node should be 0 */
- printf("\nFirst backward pointer is invalid.");
- return(-1);
- }
-
- keyicnt = idxdcnt = 0L;
-
- while(moreidx){
- if(idxblk->blktype){ /* count keys on leaf node */
- idxdcnt++; /* count leaf nodes */
- keyicnt += idxblk->cellicnt; /* accumulate key count */
- scr_curs(12, 30);
- printf("%8ld", keyicnt - 1);
- }
-
- if(ckkeyfl) /* check keys within index block */
- if (ckkeys(idxblk, keylen) < 1)
- return(-1);
-
- if( (savfwdpt = idxblk->fwdpage) > 1L)
- {
- getidxr(fd, idxblk->fwdpage, idxblk, idxlen, keylen);
-
- scr_curs(12, 21);
- printf("%7ld", idxblk->fwdpage);
-
- idxtcnt++;
-
- if(idxblk->bwdpage != savcurpt){ /* doesn't point back */
- printf("\nBackward pointer is invalid.");
- return(-1);
- }
-
- savcurpt = savfwdpt; /* save the new current position */
- }
- else
- moreidx = 0;
- }
-
- return(1);
- }
-
- /* check index block keys for proper sequence */
-
- int ckkeys(idxblk, keylen)
- struct btidxblk *idxblk;
- unsigned int keylen;
- {
- extern char *strcpy();
- register int m;
-
- if (strcmp(lastkey,idxblk->btpage[0].skeynme) > 0){
- printf("\nKeys out of sequence between index pages.");
- return(-1); /* keys out of sequence between index pages */
- }
-
- if (strlen(idxblk->btpage[0].skeynme) > keylen){
- printf("\nKey is not properly null terminated.");
- return(-1); /* key is not properly null terminated */
- }
-
- for(m = 1; m < idxblk->cellicnt; m++){
- if (strcmp(idxblk->btpage[m-1].skeynme,idxblk->btpage[m].skeynme) > 0){
- printf("\nKeys out of sequence between index pages.");
- return(-1); /* keys out of sequence */
- }
-
- if (strlen(idxblk->btpage[m].skeynme) > keylen){
- printf("\nKey is not properly null terminated.");
- return(-1); /* key is not properly null terminated */
- }
- }
-
- strcpy(lastkey, idxblk->btpage[idxblk->cellicnt - 1].skeynme);
-
- scr_curs(14, 28);
- printf("%-12.12s ", lastkey);
-
- return(1);
- }
-