//recordPosition : optional parameter holding position of record to be deleted
        public void Delete(SimpleBTreeNode x, Record record, int recordPosition=-1)
        {
            int position=(recordPosition==-1)?0:recordPosition;
            int cmp=-1;
            bool RecordPresentInNode = false;

            //traverse through all elements in current node until we either find the required record
            // or find a record with key greater than required key (which means the current node
            //does not contain the required key)
            while( (position < x.NumKeys) && (cmp = record.GetKey().CompareTo(x.records[position].GetKey())) <=0 )
            {
                if (cmp == 0)
                {
                    RecordPresentInNode = true;
                    break;
                }
                position++;
            }
            //after execution of the loop, if cmp is 0, it means the required key was found; position variable
            //would contain the position of the required key.

            if (RecordPresentInNode)
            {
                if (x.IsLeaf)
                {
                    DeleteFromLeafNode(x, position);
                }
                else
                {
                    DeleteFromInternalNode(x, position);
                }
            }
            else
            {
                if (x.IsLeaf)
                {
                    //reached the leaf node of the tree and required key was found anwhere in the tree.
                    //record not present in the tree; deletion is a no-op. return
                    return;
                }
                else
                {
                    DeleteFromSubTree(x, record, position);
                }
            }
        }
 public void Insert(Record record)
 {
 }
 public void Delete(Record record)
 {
     Delete(root, record);
 }
 public void Insert(SimpleBTreeNode x, Record record)
 {
     int i = x.NumKeys;
     if (x.IsLeaf)
     {
         while (i >= 0)
         {
             int cmp = record.GetKey().CompareTo(x.records[i].GetKey());
             if (cmp > 0)
                 break;
             x.records[i + 1] = x.records[i];
             i--;
         }
         x.records[i+1] = record;
         x.NumKeys++;
     }
     else
     {
         while (i >= 0)
         {
             int cmp = record.GetKey().CompareTo(x.records[i].GetKey());
             if (cmp > 0)
                 break;
             i--;
         }
         //the loop would have i point to the first key in the node that is smaller than the new record's key
         //link to the right of this key would point to the node where the new record would have to be inserted
         //so we increment i to point to the appropriate child to traverse to.
         i = i + 1;
         SimpleBTreeNode child = x.child[i];
         if (child.IsFull())
         {
             SplitChild(x,i,child);
             //i will now have new key after split
             int cmp = record.GetKey().CompareTo(x.records[i].GetKey());
             //if the record's key is more than newly added key in current node,
             //the new record will have to go to the child to the right of the new key
             //so increment i by 1
             if (cmp > 0)
             {
                 i = i + 1;
             }
         }
         Insert(x.child[i],record);
     }
 }
 public void Insert(Record record)
 {
     if (root.IsFull())
     {
         SimpleBTreeNode newroot = new SimpleBTreeNode(MinDegree, false);
         newroot.child[0] = root;
         root = newroot;
         SplitChild(root, 0, root.child[0]);
         Insert(root, record);
     }
     else
         Insert(root, record);
 }
        //position : position of the child that would contain the record to be deleted
        //if at all the record is present in the tree
        public void DeleteFromSubTree(SimpleBTreeNode x, Record record, int position)
        {
            SimpleBTreeNode childToDescendTo = x.child[position];

            //if the node to descend to has t-1 children, make adjustments to ensure
            //it has at least t keys before we descend to it
            if (childToDescendTo.NumKeys == MinDegree - 1)
            {
                SimpleBTreeNode LeftSibling = (position-1>=0)?x.child[position - 1]:null;
                SimpleBTreeNode RightSibling = (position+1<x.NumKeys)?x.child[position + 1]:null;

                //if left sibling has at least t elements
                if( (LeftSibling!=null)  && (LeftSibling.NumKeys >= MinDegree))
                {
                    //get handle of record in between the child and its left sibling
                    Record recordFromParent = x.records[position - 1];

                    //get handle of predecessor of record from parent. this will be moved to parent
                    Record recordFromLeftSibling = LeftSibling.records[LeftSibling.NumKeys - 1];
                    LeftSibling.records[LeftSibling.NumKeys - 1] = null;

                    //get handle of last child of left sibling
                    SimpleBTreeNode LastChildFromLeftSibling = LeftSibling.child[LeftSibling.NumKeys];
                    LeftSibling.child[LeftSibling.NumKeys] = null;

                    for (int i = childToDescendTo.NumKeys; i >0 ; i--)
                    {
                        childToDescendTo.records[i] = childToDescendTo.records[i - 1];
                    }

                    for (int i = childToDescendTo.NumKeys+1; i > 0; i--)
                    {
                        childToDescendTo.child[i + 1] = childToDescendTo.child[i];
                    }

                    childToDescendTo.records[0] = recordFromParent;
                    x.records[position -1]=recordFromLeftSibling;
                    childToDescendTo.child[0] = LastChildFromLeftSibling;

                    childToDescendTo.NumKeys++;
                    LeftSibling.NumKeys--;

                }
                //if right sibling has at least t elements
                else if ( (RightSibling!=null) && (RightSibling.NumKeys >= MinDegree) )
                {

                    //get handle of record in between the child and its right sibling
                    Record recordFromParent = x.records[position + 1];

                    //get handle of successor of record from parent. this will be moved to parent
                    Record recordFromRightSibling = RightSibling.records[0];

                    //get handle of first child of right sibling
                    SimpleBTreeNode FirstChildFromRightSibling = RightSibling.child[0];

                    for (int i = 0; i < childToDescendTo.NumKeys; i++)
                    {
                        RightSibling.records[i] = RightSibling.records[i + 1];
                    }

                    for (int i = 0; i < childToDescendTo.NumKeys + 1; i++)
                    {
                        RightSibling.child[i] = RightSibling.child[i+1];
                    }
                    RightSibling.NumKeys--;

                    childToDescendTo.records[childToDescendTo.NumKeys] = recordFromParent;
                    childToDescendTo.NumKeys++;
                    x.records[position + 1] = recordFromRightSibling;
                    childToDescendTo.child[childToDescendTo.NumKeys+1] = FirstChildFromRightSibling;

                }
                //if neither siblings have at least t elements
                else
                {
                    if (RightSibling != null)
                    {
                        childToDescendTo.records[childToDescendTo.NumKeys] = x.records[position + 1];
                        childToDescendTo.NumKeys++;
                        for (int i = 0; i < RightSibling.NumKeys; i++)
                        {
                            childToDescendTo.records[childToDescendTo.NumKeys + i] = RightSibling.records[i];
                        }

                        for (int i = 0; i < RightSibling.NumKeys + 1; i++)
                        {
                            childToDescendTo.child[childToDescendTo.NumKeys + i] = RightSibling.child[i];
                        }
                        childToDescendTo.NumKeys += RightSibling.NumKeys;

                        for (int i = position; i < x.NumKeys-1; i++)
                        {
                            x.records[i] = x.records[i + 1];
                        }
                        for (int i = position + 1; i < x.NumKeys; i++)
                        {
                            x.child[i] = x.child[i + 1];
                        }
                        x.NumKeys--;
                    }
                    else if (LeftSibling != null)
                    {

                        LeftSibling.records[LeftSibling.NumKeys] = x.records[position - 1];
                        LeftSibling.NumKeys++;
                        for (int i = 0; i < childToDescendTo.NumKeys; i++)
                        {
                            LeftSibling.records[LeftSibling.NumKeys + i] = childToDescendTo.records[i];
                        }

                        for (int i = 0; i < childToDescendTo.NumKeys + 1; i++)
                        {
                            LeftSibling.child[LeftSibling.NumKeys + i] = childToDescendTo.child[i];
                        }
                        LeftSibling.NumKeys += childToDescendTo.NumKeys;

                        for (int i = position-1; i < x.NumKeys - 1; i++)
                        {
                            x.records[i] = x.records[i + 1];
                        }
                        for (int i = position; i < x.NumKeys; i++)
                        {
                            x.child[i] = x.child[i + 1];
                        }
                        x.NumKeys--;

                        childToDescendTo = LeftSibling;
                    }
                }
            }

            Delete(childToDescendTo, record);
        }