Exemple #1
0
        /// <summary>
        /// Splits a leaf node and adds the <paramref name="newEntry"/>
        /// </summary>
        /// <param name="node"></param>
        /// <param name="newEntry"></param>
        private void Split(MNode <int> node, MNodeEntry <int> newEntry)
        {
            var         nodeIsRoot       = node == this.Root;
            MNode <int> parent           = null;
            var         parentEntryIndex = -1;

            if (!nodeIsRoot)
            {
                // keep reference to parent node
                parent           = node.ParentEntry.EnclosingNode;
                parentEntryIndex = parent.Entries.IndexOf(node.ParentEntry);
                //if we are not the root, the get the parent of the current node.
            }

            // Create local copy of entries
            var entries = node.Entries.ToList();

            entries.Add(newEntry);

            var newNode = new MNode <int> {
                Capacity = this.Capacity
            };
            var promotionResult = this.Promote(entries.ToArray(), node.IsInternalNode);

            // TODO: Does not need to be an array
            node.Entries    = promotionResult.FirstPartition;
            newNode.Entries = promotionResult.SecondPartition;

            // Set child nodes of promotion objects
            promotionResult.FirstPromotionObject.ChildNode  = node;
            promotionResult.SecondPromotionObject.ChildNode = newNode;

            if (nodeIsRoot)
            {
                // if we are the root node, then create a new root and assign the promoted objects to them
                var newRoot = new MNode <int> {
                    ParentEntry = null, Capacity = this.Capacity
                };
                newRoot.AddRange(
                    new List <MNodeEntry <int> >
                {
                    promotionResult.FirstPromotionObject,
                    promotionResult.SecondPromotionObject
                });

                this.Root = newRoot;
            }
            else // we are not the root
            {
                // Set distance from parent
                if (parent == this.Root)
                {
                    promotionResult.FirstPromotionObject.DistanceFromParent = -1;
                }
                else
                {
                    promotionResult.FirstPromotionObject.DistanceFromParent =
                        this.Metric(this.internalArray[promotionResult.FirstPromotionObject.Value], this.internalArray[parent.ParentEntry.Value]);
                }

                parent.SetEntryAtIndex(parentEntryIndex, promotionResult.FirstPromotionObject);
                if (parent.IsFull)
                {
                    this.Split(parent, promotionResult.SecondPromotionObject);
                }
                else
                {
                    // Set distance from parent
                    if (parent == this.Root)
                    {
                        promotionResult.SecondPromotionObject.DistanceFromParent = -1;
                    }
                    else
                    {
                        promotionResult.SecondPromotionObject.DistanceFromParent =
                            this.Metric(this.internalArray[promotionResult.SecondPromotionObject.Value], this.internalArray[parent.ParentEntry.Value]);
                    }

                    parent.Add(promotionResult.SecondPromotionObject);
                }
            }
        }