/// <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); } } }