// Source code example for "A Practical Introduction // to Data Structures and Algorithm Analysis" // by Clifford A. Shaffer, Prentice Hall, 1998. // Copyright 1998 by Clifford A. Shaffer import java.io.*; // Driver class for testing syntactic correctness of B+ tree pseudocode public class BPtreemain { static final int THRESHOLD = 30; static final int MAXREC = 100; int binaryle(Pair[] recarray, int a, int b) {return 0;} void putinarray(Pair[] recarray, int a, Pair t) {} void removerec(Pair[] recarray, int a, int t) {} void merge_nodes(BPNode a, BPNode b) {} void shuffle_nodes(BPNode a, BPNode b) {} BPNode splitnode(BPNode r, int c, Pair t) {return null;}Elem findhelp(BPNode root, int K) { // function binaryle(A, n, K) returns the greatest value // less than or equal to K in array A containing n records. int currec = binaryle(root.recarray, root.numrec, K); if (root.isLeaf()) // If its a leaf node... if (root.recarray[currec].key() == K) // Children are Elems return (Elem)root.recarray[currec].pointer; else return null; // K not in this node else return findhelp((BPNode)root.recarray[currec].pointer, K); // Process child } // B+-tree pseudocode: insert // putinarray(A, pos, pair) places pair in array A at position pos. // Function splitnode(rt, pos, pair) places pair in rt at pos. // But, in the process, rt is split into two nodes, each node // taking half of the records, and the new node is returned. Pair inserthelp(BPNode root, Elem rec) { Pair temp; // Hold a key/pointer pair int currec = binaryle(root.recarray, root.numrec, rec.key()); if (root.isLeaf()) { // Leaf node -- set up values to insert Assert.notFalse(root.recarray[currec].key() != rec.key(), "Duplicates are not allowed"); temp = new Pair(rec.key(), rec); } else { // internal node temp = inserthelp((BPNode)root.recarray[currec].pointer, rec); if (temp == null) return null; // Child did not split, so no } // insert into current node // Now, do the insert to the current node. Split if necessary if (!root.isFull()) putinarray(root.recarray, currec, temp); else { BPNode tp = splitnode(root, currec, temp); return new Pair(tp.recarray[0].key(), tp); } return null; } // removehelp returns position of the child node adjusted, if any. // If the child node did not underflow or change its first record, // then return -1, to indicate the parent shouldn't be modified. // Function removerec(A, n, c) removes the record at position c from // array A containing n records. // Function merge_nodes(N1, N2) merges together the record arrays of // BPNodes N1 and N2. // Function shuffle_nodes(N1, N2) copies records as necessary within // BPnodes N1 and N2, so that both have equal number of records. int removehelp(BPNode root, int K, int thispos) { int currec = binaryle(root.recarray, root.numrec, K); if (root.isLeaf()) if (root.recarray[currec].key() != K) return -1;// K not found else { // Delete from child currec = removehelp((BPNode)root.recarray[currec].pointer, K, currec); if (currec == -1) // Child did not underflow return -1; else if(((BPNode)root.recarray[currec].pointer).numrec != 0) { // Child was shuffled -- adust key value root.recarray[currec].key = ((BPNode)root.recarray[currec].pointer).recarray[0].key; return -1; // Child did not underflow } } // Now, remove record at position currec removerec(root.recarray, root.numrec--, currec); if (root.numrec > THRESHOLD) // Enough records, just remove it return -1; else { // Underflow if (root.leftptr == null) // No left neighbor if (root.numrec + root.rightptr.numrec <= MAXREC) { merge_nodes(root, root.rightptr); return thispos+1; // Right neighbor is now empty } else { shuffle_nodes(root, root.rightptr); return thispos+1; // Right neighbor has new first record } else if (root.numrec + root.leftptr.numrec <= MAXREC) { merge_nodes(root.leftptr, root); return thispos; // This node is now empty } else { shuffle_nodes(root.leftptr, root); return thispos; // This node has new first record } } } // Main routine for B+ tree syntax check public static void main(String args[]) throws IOException { System.in.read(); } }