コード例 #1
0
ファイル: BplusTreeLong.cs プロジェクト: katnegermis/BTree
 /// <summary>
 /// insert key/position entry in self (as leaf)
 /// </summary>
 /// <param name="key">Key to associate with the leaf</param>
 /// <param name="position">position associated with key in external structure</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>smallest key value in keys, or null if no change</returns>
 public string InsertLeaf(string key, long position, out string splitString, out BplusNode splitNode)
 {
     splitString = null;
     splitNode = null;
     bool dosplit = false;
     if (!this.isLeaf)
     {
         throw new BplusTreeException("bad call to InsertLeaf: this is not a leaf");
     }
     this.Soil();
     int insertposition = this.FindAtOrNextPosition(key, false, true);
     if (insertposition>=this.Size)
     {
         //throw new BplusTreeException("key too big and leaf is full");
         dosplit = true;
         this.PrepareForSplit();
     }
     else
     {
         // if it's already there then change the value at the current location (duplicate entries not supported).
         if (this.ChildKeys[insertposition]==null || this.owner.Compare(this.ChildKeys[insertposition], key, true)==0) // this.ChildKeys[insertposition].Equals(key)
         {
             this.ChildBufferNumbers[insertposition] = position;
             this.ChildKeys[insertposition] = key;
             if (insertposition==0)
             {
                 return key;
             }
             else
             {
                 return null;
             }
         }
     }
     // check for a null position
     int nullindex = insertposition;
     while (nullindex<this.ChildKeys.Length && this.ChildKeys[nullindex]!=null)
     {
         nullindex++;
     }
     if (nullindex>=this.ChildKeys.Length)
     {
         if (dosplit)
         {
             throw new BplusTreeException("can't split twice!!");
         }
         //throw new BplusTreeException("no space in leaf");
         dosplit = true;
         this.PrepareForSplit();
     }
     // bubble in the new info XXXX THIS SHOULD BUBBLE BACKWARDS
     string nextkey = this.ChildKeys[insertposition];
     long nextposition = this.ChildBufferNumbers[insertposition];
     this.ChildKeys[insertposition] = key;
     this.ChildBufferNumbers[insertposition] = position;
     while (nextkey!=null)
     {
         key = nextkey;
         position = nextposition;
         insertposition++;
         nextkey = this.ChildKeys[insertposition];
         nextposition = this.ChildBufferNumbers[insertposition];
         this.ChildKeys[insertposition] = key;
         this.ChildBufferNumbers[insertposition] = position;
     }
     // split if needed
     if (dosplit)
     {
         int splitpoint = this.ChildKeys.Length/2;
         int splitlength = this.ChildKeys.Length - splitpoint;
         splitNode = new BplusNode(this.owner, this.parent, -1, this.isLeaf);
         // copy the split info into the splitNode
         Array.Copy(this.ChildBufferNumbers, splitpoint, splitNode.ChildBufferNumbers, 0, splitlength);
         Array.Copy(this.ChildKeys, splitpoint, splitNode.ChildKeys, 0, splitlength);
         Array.Copy(this.MaterializedChildNodes, splitpoint, splitNode.MaterializedChildNodes, 0, splitlength);
         splitString = splitNode.ChildKeys[0];
         // archive the new node
         splitNode.DumpToFreshBuffer();
         // store the node data temporarily
         long[] buffernumbers = this.ChildBufferNumbers;
         string[] keys = this.ChildKeys;
         BplusNode[] nodes = this.MaterializedChildNodes;
         // repair current node, copy in the other part of the split
         this.ChildBufferNumbers = new long[this.Size+1];
         this.ChildKeys = new string[this.Size];
         this.MaterializedChildNodes = new BplusNode[this.Size+1];
         Array.Copy(buffernumbers, 0, this.ChildBufferNumbers, 0, splitpoint);
         Array.Copy(keys, 0, this.ChildKeys, 0, splitpoint);
         Array.Copy(nodes, 0, this.MaterializedChildNodes, 0, splitpoint);
         for (int i=splitpoint; i<this.ChildKeys.Length; i++)
         {
             this.ChildKeys[i] = null;
             this.ChildBufferNumbers[i] = BplusTreeLong.NULLBUFFERNUMBER;
             this.MaterializedChildNodes[i] = null;
         }
         // store the new node
         //splitNode.DumpToFreshBuffer();
         this.owner.RecordTerminalNode(splitNode);
         splitNode.Soil();
     }
     //return this.ChildKeys[0];
     if (insertposition==0)
     {
         return key; // smallest key changed.
     }
     else
     {
         return null; // no change in smallest key
     }
 }
コード例 #2
0
ファイル: BplusTreeLong.cs プロジェクト: petlof/BplusDotNet
 /// <summary>
 /// insert key/position entry in self (as leaf)
 /// </summary>
 /// <param name="key">Key to associate with the leaf</param>
 /// <param name="position">position associated with key in external structure</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>smallest key value in keys, or null if no change</returns>
 public string InsertLeaf(string key, long position, out string splitString, out BplusNode splitNode)
 {
     splitString = null;
     splitNode = null;
     var dosplit = false;
     if (!IsLeaf)
     {
         throw new BplusTreeException("bad call to InsertLeaf: this is not a leaf");
     }
     Soil();
     var insertposition = FindAtOrNextPosition(key, false);
     if (insertposition>=m_size)
     {
         //throw new BplusTreeException("key too big and leaf is full");
         dosplit = true;
         PrepareForSplit();
     }
     else
     {
         // if it's already there then change the value at the current location (duplicate entries not supported).
         if (m_childKeys[insertposition]==null || m_owner.Compare(m_childKeys[insertposition], key)==0) // this.ChildKeys[insertposition].Equals(key)
         {
             m_childBufferNumbers[insertposition] = position;
             m_childKeys[insertposition] = key;
             if (insertposition==0)
             {
                 return key;
             }
             else
             {
                 return null;
             }
         }
     }
     // check for a null position
     var nullindex = insertposition;
     while (nullindex<m_childKeys.Length && m_childKeys[nullindex]!=null)
     {
         nullindex++;
     }
     if (nullindex>=m_childKeys.Length)
     {
         if (dosplit)
         {
             throw new BplusTreeException("can't split twice!!");
         }
         //throw new BplusTreeException("no space in leaf");
         dosplit = true;
         PrepareForSplit();
     }
     // bubble in the new info XXXX THIS SHOULD BUBBLE BACKWARDS
     var nextkey = m_childKeys[insertposition];
     var nextposition = m_childBufferNumbers[insertposition];
     m_childKeys[insertposition] = key;
     m_childBufferNumbers[insertposition] = position;
     while (nextkey!=null)
     {
         key = nextkey;
         position = nextposition;
         insertposition++;
         nextkey = m_childKeys[insertposition];
         nextposition = m_childBufferNumbers[insertposition];
         m_childKeys[insertposition] = key;
         m_childBufferNumbers[insertposition] = position;
     }
     // split if needed
     if (dosplit)
     {
         var splitpoint = m_childKeys.Length/2;
         var splitlength = m_childKeys.Length - splitpoint;
         splitNode = new BplusNode(m_owner, m_parent, -1, IsLeaf);
         // copy the split info into the splitNode
         Array.Copy(m_childBufferNumbers, splitpoint, splitNode.m_childBufferNumbers, 0, splitlength);
         Array.Copy(m_childKeys, splitpoint, splitNode.m_childKeys, 0, splitlength);
         Array.Copy(m_materializedChildNodes, splitpoint, splitNode.m_materializedChildNodes, 0, splitlength);
         splitString = splitNode.m_childKeys[0];
         // archive the new node
         splitNode.DumpToFreshBuffer();
         // store the node data temporarily
         var buffernumbers = m_childBufferNumbers;
         var keys = m_childKeys;
         var nodes = m_materializedChildNodes;
         // repair current node, copy in the other part of the split
         m_childBufferNumbers = new long[m_size+1];
         m_childKeys = new string[m_size];
         m_materializedChildNodes = new BplusNode[m_size+1];
         Array.Copy(buffernumbers, 0, m_childBufferNumbers, 0, splitpoint);
         Array.Copy(keys, 0, m_childKeys, 0, splitpoint);
         Array.Copy(nodes, 0, m_materializedChildNodes, 0, splitpoint);
         for (var i=splitpoint; i<m_childKeys.Length; i++)
         {
             m_childKeys[i] = null;
             m_childBufferNumbers[i] = BplusTreeLong.Nullbuffernumber;
             m_materializedChildNodes[i] = null;
         }
         // store the new node
         //splitNode.DumpToFreshBuffer();
         m_owner.RecordTerminalNode(splitNode);
         splitNode.Soil();
     }
     //return this.ChildKeys[0];
     if (insertposition==0)
     {
         return key; // smallest key changed.
     }
     else
     {
         return null; // no change in smallest key
     }
 }
コード例 #3
0
ファイル: BplusTreeLong.cs プロジェクト: katnegermis/BTree
 /// <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
 }
コード例 #4
0
ファイル: BplusTreeLong.cs プロジェクト: petlof/BplusDotNet
 /// <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
 }