Ejemplo n.º 1
0
 /// <summary>
 /// insert key/position entry in self 
 /// </summary>
 /// <param name="key">Key to associate with the leaf</param>
 /// <param name="position">position associated with key in external structur</param>
 /// <param name="splitString">if not null then the smallest key in the new split leaf</param>
 /// <param name="splitNode">if not null then the node was split and this is the leaf to the right.</param>
 /// <returns>null unless the smallest key under this node has changed, in which case it returns the smallest key.</returns>
 public string Insert(string key, long position, out string splitString, out BplusNode splitNode)
 {
     if (this.isLeaf)
     {
         return this.InsertLeaf(key, position, out splitString, out splitNode);
     }
     splitString = null;
     splitNode = null;
     int insertposition = this.FindAtOrNextPosition(key, false, true);
     long insertBufferNumber = this.ChildBufferNumbers[insertposition];
     if (insertBufferNumber==BplusTreeLong.NULLBUFFERNUMBER)
     {
         throw new BplusTreeException("key not followed by buffer number in non-leaf");
     }
     // insert in subtree
     BplusNode InsertChild = this.MaterializeNodeAtIndex(insertposition);
     BplusNode childSplit;
     string childSplitString;
     string childInsert = InsertChild.Insert(key, position, out childSplitString, out childSplit);
     // if there was a split the node must expand
     if (childSplit!=null)
     {
         // insert the child
         this.Soil(); // redundant -- a child will have a change so this node will need to be copied
         int newChildPosition = insertposition+1;
         bool dosplit = false;
         // if there is no free space we must do a split
         if (this.ChildBufferNumbers[this.Size]!=BplusTreeLong.NULLBUFFERNUMBER)
         {
             dosplit = true;
             this.PrepareForSplit();
         }
         // bubble over the current values to make space for new child
         for (int i=this.ChildKeys.Length-2; i>=newChildPosition-1; i--)
         {
             int i1 = i+1;
             int i2 = i1+1;
             this.ChildKeys[i1] = this.ChildKeys[i];
             this.ChildBufferNumbers[i2] = this.ChildBufferNumbers[i1];
             BplusNode childNode = this.MaterializedChildNodes[i2] = this.MaterializedChildNodes[i1];
         }
         // record the new child
         this.ChildKeys[newChildPosition-1] = childSplitString;
         //this.MaterializedChildNodes[newChildPosition] = childSplit;
         //this.ChildBufferNumbers[newChildPosition] = childSplit.myBufferNumber;
         childSplit.Reparent(this, newChildPosition);
         // split, if needed
         if (dosplit)
         {
             int splitpoint = this.MaterializedChildNodes.Length/2-1;
             splitString = this.ChildKeys[splitpoint];
             splitNode = new BplusNode(this.owner, this.parent, -1, this.isLeaf);
             // make copy of expanded node structure
             BplusNode[] materialized = this.MaterializedChildNodes;
             long[] buffernumbers = this.ChildBufferNumbers;
             string[] keys = this.ChildKeys;
             // repair the expanded node
             this.ChildKeys = new string[this.Size];
             this.MaterializedChildNodes = new BplusNode[this.Size+1];
             this.ChildBufferNumbers = new long[this.Size+1];
             this.Clear();
             Array.Copy(materialized, 0, this.MaterializedChildNodes, 0, splitpoint+1);
             Array.Copy(buffernumbers, 0, this.ChildBufferNumbers, 0, splitpoint+1);
             Array.Copy(keys, 0, this.ChildKeys, 0, splitpoint);
             // initialize the new node
             splitNode.Clear(); // redundant.
             int remainingKeys = this.Size-splitpoint;
             Array.Copy(materialized, splitpoint+1, splitNode.MaterializedChildNodes, 0, remainingKeys+1);
             Array.Copy(buffernumbers, splitpoint+1, splitNode.ChildBufferNumbers, 0, remainingKeys+1);
             Array.Copy(keys, splitpoint+1, splitNode.ChildKeys, 0, remainingKeys);
             // fix pointers in materialized children of splitnode
             splitNode.reParentAllChildren();
             // store the new node
             splitNode.DumpToFreshBuffer();
             splitNode.CheckIfTerminal();
             splitNode.Soil();
             this.CheckIfTerminal();
         }
         // fix pointers in children
         this.reParentAllChildren();
     }
     if (insertposition==0)
     {
         // the smallest key may have changed
         return childInsert;
     }
     return null;  // no change in smallest key
 }
Ejemplo n.º 2
0
 /// <summary>
 /// insert key/position entry in self 
 /// </summary>
 /// <param name="key">Key to associate with the leaf</param>
 /// <param name="position">position associated with key in external structur</param>
 /// <param name="splitString">if not null then the smallest key in the new split leaf</param>
 /// <param name="splitNode">if not null then the node was split and this is the leaf to the right.</param>
 /// <returns>null unless the smallest key under this node has changed, in which case it returns the smallest key.</returns>
 public string Insert(string key, long position, out string splitString, out BplusNode splitNode)
 {
     if (IsLeaf)
     {
         return InsertLeaf(key, position, out splitString, out splitNode);
     }
     splitString = null;
     splitNode = null;
     var insertposition = FindAtOrNextPosition(key, false);
     var insertBufferNumber = m_childBufferNumbers[insertposition];
     if (insertBufferNumber==BplusTreeLong.Nullbuffernumber)
     {
         throw new BplusTreeException("key not followed by buffer number in non-leaf");
     }
     // insert in subtree
     var insertChild = MaterializeNodeAtIndex(insertposition);
     BplusNode childSplit;
     string childSplitString;
     var childInsert = insertChild.Insert(key, position, out childSplitString, out childSplit);
     // if there was a split the node must expand
     if (childSplit!=null)
     {
         // insert the child
         Soil(); // redundant -- a child will have a change so this node will need to be copied
         var newChildPosition = insertposition+1;
         var dosplit = false;
         // if there is no free space we must do a split
         if (m_childBufferNumbers[m_size]!=BplusTreeLong.Nullbuffernumber)
         {
             dosplit = true;
             PrepareForSplit();
         }
         // bubble over the current values to make space for new child
         for (var i=m_childKeys.Length-2; i>=newChildPosition-1; i--)
         {
             var i1 = i+1;
             var i2 = i1+1;
             m_childKeys[i1] = m_childKeys[i];
             m_childBufferNumbers[i2] = m_childBufferNumbers[i1];
             var childNode = m_materializedChildNodes[i2] = m_materializedChildNodes[i1];
         }
         // record the new child
         m_childKeys[newChildPosition-1] = childSplitString;
         //this.MaterializedChildNodes[newChildPosition] = childSplit;
         //this.ChildBufferNumbers[newChildPosition] = childSplit.myBufferNumber;
         childSplit.Reparent(this, newChildPosition);
         // split, if needed
         if (dosplit)
         {
             var splitpoint = m_materializedChildNodes.Length/2-1;
             splitString = m_childKeys[splitpoint];
             splitNode = new BplusNode(m_owner, m_parent, -1, IsLeaf);
             // make copy of expanded node structure
             var materialized = m_materializedChildNodes;
             var buffernumbers = m_childBufferNumbers;
             var keys = m_childKeys;
             // repair the expanded node
             m_childKeys = new string[m_size];
             m_materializedChildNodes = new BplusNode[m_size+1];
             m_childBufferNumbers = new long[m_size+1];
             Clear();
             Array.Copy(materialized, 0, m_materializedChildNodes, 0, splitpoint+1);
             Array.Copy(buffernumbers, 0, m_childBufferNumbers, 0, splitpoint+1);
             Array.Copy(keys, 0, m_childKeys, 0, splitpoint);
             // initialize the new node
             splitNode.Clear(); // redundant.
             var remainingKeys = m_size-splitpoint;
             Array.Copy(materialized, splitpoint+1, splitNode.m_materializedChildNodes, 0, remainingKeys+1);
             Array.Copy(buffernumbers, splitpoint+1, splitNode.m_childBufferNumbers, 0, remainingKeys+1);
             Array.Copy(keys, splitpoint+1, splitNode.m_childKeys, 0, remainingKeys);
             // fix pointers in materialized children of splitnode
             splitNode.ReParentAllChildren();
             // store the new node
             splitNode.DumpToFreshBuffer();
             splitNode.CheckIfTerminal();
             splitNode.Soil();
             CheckIfTerminal();
         }
         // fix pointers in children
         ReParentAllChildren();
     }
     if (insertposition==0)
     {
         // the smallest key may have changed
         return childInsert;
     }
     return null;  // no change in smallest key
 }