protected virtual void AdjustTree(Node node1, Node node2, Int32 level)
 {
     if (node1.Address.Equals(Root))
     {
         Cache.WritePageData(node1);
         return;
     }
     if (Root.Equals(Address.Empty))
     {
         Type childType = node1 is Leaf ? typeof(Leaf) : typeof(Node);
         Node rootNode = new Node(Address.Empty, childType);
         Root = rootNode.Address;
         node1.Parent = Root;
         node2.Parent = Root;
         Cache.WritePageData(rootNode);
         TreeHeight++;
     }
     Node parent = Cache.LookupNode(node1.Parent);
     NodeEntry entryToUpdate = null;
     foreach (NodeEntry entry in parent.NodeEntries)
         if (entry.Child.Equals(node1.Address))
             entryToUpdate = entry;
     if (entryToUpdate == null)
         parent.AddNodeEntry(new NodeEntry(node1.CalculateMinimumBoundingBox(), node1.Address));
     else
         entryToUpdate.MinimumBoundingBox = node1.CalculateMinimumBoundingBox();
     Cache.WritePageData(node1);
     if (node2 != null)
     {
         parent.AddNodeEntry(new NodeEntry(node2.CalculateMinimumBoundingBox(), node2.Address));
         Cache.WritePageData(node2);
         if (parent.NodeEntries.Count > Constants.MAXIMUM_ENTRIES_PER_NODE)
         {
             List<Node> splitNodes = OverFlowTreatment(parent, level - 1);
             if (splitNodes != null)
             {
                 if (parent.Address.Equals(Root))
                     Root = Address.Empty;
                 RemoveFromParent(parent);
                 AdjustTree(splitNodes[0], splitNodes[1], level - 1);
             }
             return;
         }
     }
     AdjustTree(parent, null, level - 1);
 }
 protected virtual void ReInsert(Node node, Int32 level)
 {
     MinimumBoundingBox nodeBox = node.CalculateMinimumBoundingBox();
     PriorityQueue<NodeEntry, Single> distances = new PriorityQueue<NodeEntry, Single>(),
     reInsertions = new PriorityQueue<NodeEntry, Single>();
     foreach (NodeEntry entry in node.NodeEntries)
         distances.Enqueue(entry, GetCenterDistance(nodeBox, entry.MinimumBoundingBox) * -1);
     for (int i = 0; i < Constants.NODES_FOR_REINSERT; i++)
         reInsertions.Enqueue(distances.Peek().Value, distances.Dequeue().Priority * -1);
     foreach (PriorityQueueItem<NodeEntry, Single> entry in reInsertions)
         node.RemoveNodeEntry(entry.Value);
     AdjustTree(node, level);
     while(reInsertions.Count > 0)
         Insert(reInsertions.Dequeue().Value, level);
 }
 protected virtual Single GetMargin(Node node)
 {
     MinimumBoundingBox box = node.CalculateMinimumBoundingBox();
     return (box.MaxX - box.MinX) + (box.MaxY - box.MinY);
 }
 protected virtual Single GetOverlap(Node node1, Node node2)
 {
     MinimumBoundingBox overlapArea =
         IntersectMinimumBoundingBoxes(node1.CalculateMinimumBoundingBox(), node2.CalculateMinimumBoundingBox());
     return
         (overlapArea.MaxX - overlapArea.MinX) *
         (overlapArea.MaxY - overlapArea.MinY);
 }
 protected override void Insert(Node newNode, Node node)
 {
     MinimumBoundingBox mbb = newNode.CalculateMinimumBoundingBox();
     IndexUnit indexUnit = new IndexUnit(node.Address, newNode.Address, mbb, Operation.Insert);
     NodeTranslationTable.Add(indexUnit);
     node.AddNodeEntry(new NodeEntry(mbb, newNode.Address));
     newNode.Parent = node.Address;
     Cache.WritePageData(newNode);
 }
 protected override Node ChooseNode(Node node)
 {
     NodeEntry nodeEntry = new NodeEntry(node.CalculateMinimumBoundingBox(), node.Address);
     return ChooseNode(nodeEntry, TreeHeight - CalculateHeight(node) + 1);
 }
        protected override void CondenseTree(Node node)
        {
            List<Node> eliminatedNodes = new List<Node>();
            while (!node.Address.Equals(Root))
            {

                if (node.NodeEntries.Count < Constants.MINIMUM_ENTRIES_PER_NODE)
                {
                    RemoveFromParent(node);
                    eliminatedNodes.Add(node);
                }
                else
                    NodeTranslationTable.Add(new IndexUnit(node.Parent, node.Address, node.CalculateMinimumBoundingBox(), Operation.Update));
                node = Cache.LookupNode(node.Parent);
            }
            foreach(Node eliminatedNode in eliminatedNodes)
            {
                if (eliminatedNode is Leaf)
                    foreach (LeafEntry leafEntry in eliminatedNode.NodeEntries)
                        InsertRecord(new BufferItem(leafEntry, Operation.Insert));
                else
                    foreach (NodeEntry entry in eliminatedNode.NodeEntries)
                        Insert(Cache.LookupNode(entry.Child));
            }
        }
 protected override void AdjustTree(Node node1, Node node2)
 {
     if (node1.Address.Equals(Root))
         return;
     if (Root.Equals(Address.Empty))
     {
         Type childType = node1 is Leaf ? typeof(Leaf) : typeof(Node);
         Node rootNode = new Node(Address.Empty, childType);
         Root = rootNode.Address;
         node1.Parent = Root;
         node2.Parent = Root;
         rootNode.AddNodeEntry(new NodeEntry(node1.CalculateMinimumBoundingBox(), node1.Address));
         rootNode.AddNodeEntry(new NodeEntry(node2.CalculateMinimumBoundingBox(), node2.Address));
         Cache.WritePageData(rootNode);
         //Node temp = Cache.LookupNode(rootNode.Address);
         Cache.WritePageData(node1);
         Cache.WritePageData(node2);
         TreeHeight++;
         return;
     }
     Node parent = Cache.LookupNode(node1.Parent);
     NodeEntry entryToUpdate = null;
     foreach (NodeEntry entry in parent.NodeEntries)
         if (entry.Child.Equals(node1.Address))
             entryToUpdate = entry;
     if (entryToUpdate == null)
     {
         MinimumBoundingBox mbb = node1.CalculateMinimumBoundingBox();
         IndexUnit indexUnit = new IndexUnit(parent.Address, node1.Address, mbb, Operation.Insert);
         NodeTranslationTable.Add(indexUnit);
         parent.AddNodeEntry(new NodeEntry(mbb, node1.Address));
     }
     else
     {
         MinimumBoundingBox mbb = node1.CalculateMinimumBoundingBox();
         IndexUnit indexUnit = new IndexUnit(parent.Address, entryToUpdate.Child, mbb, Operation.Update);
         NodeTranslationTable.Add(indexUnit);
         entryToUpdate.MinimumBoundingBox = mbb;
     }
     if (node2 != null)
     {
         MinimumBoundingBox mbb = node2.CalculateMinimumBoundingBox();
         IndexUnit indexUnit = new IndexUnit(parent.Address, node2.Address, mbb, Operation.Insert);
         NodeTranslationTable.Add(indexUnit);
         parent.AddNodeEntry(new NodeEntry(mbb, node2.Address));
         Cache.WritePageData(node2);
         Cache.WritePageData(node1);
         if (parent.NodeEntries.Count > Constants.MAXIMUM_ENTRIES_PER_NODE)
         {
             List<Node> splitNodes = Split(parent);
             if (parent.Address.Equals(Root))
                 Root = Address.Empty;
             RemoveFromParent(parent);
             AdjustTree(splitNodes[0], splitNodes[1]);
             return;
         }
     }
     AdjustTree(parent, null);
 }
 protected virtual void Insert(Node newNode, Node node)
 {
     node.AddNodeEntry(new NodeEntry(newNode.CalculateMinimumBoundingBox(), newNode.Address));
     newNode.Parent = node.Address;
     Cache.WritePageData(node);
     Cache.WritePageData(newNode);
 }
 protected virtual void CondenseTree(Node node)
 {
     List<Node> eliminatedNodes = new List<Node>();
     while (!node.Address.Equals(Root))
     {
         Node parent = Cache.LookupNode(node.Parent);
         NodeEntry nodeEntry = null;
         foreach (NodeEntry entry in parent.NodeEntries)
             if (entry.Child.Equals(node.Address))
                 nodeEntry = entry;
         if (node.NodeEntries.Count < Constants.MINIMUM_ENTRIES_PER_NODE)
         {
             parent.RemoveNodeEntry(nodeEntry);
             eliminatedNodes.Add(node);
             Cache.DeletePageData(node);
         }
         else
             nodeEntry.MinimumBoundingBox = node.CalculateMinimumBoundingBox();
         Cache.WritePageData(parent);
         node = parent;
     }
     for (int i = 0; i < eliminatedNodes.Count; i++)
     {
         Node eliminatedNode = eliminatedNodes[i];
         if (eliminatedNode is Leaf)
             foreach (LeafEntry leafEntry in eliminatedNode.NodeEntries)
                 Insert(Cache.LookupRecord(leafEntry.Child));
         else
             foreach (NodeEntry entry in eliminatedNode.NodeEntries)
                 Insert(Cache.LookupNode(entry.Child));
     }
 }
 protected virtual Node ChooseNode(Node node)
 {
     Node insertionNode = Cache.LookupNode(Root);
     MinimumBoundingBox nodeBoundingBox = node.CalculateMinimumBoundingBox();
     Int32 nodeHeight = CalculateHeight(node), currentDepth = 1;
     while (currentDepth + nodeHeight < TreeHeight)
     {
         NodeEntry minEnlargment = insertionNode.NodeEntries[0];
         Single minEnlargedArea = GetFutureSize(nodeBoundingBox, minEnlargment.MinimumBoundingBox) - minEnlargment.MinimumBoundingBox.GetArea();
         foreach (NodeEntry nodeEntry in insertionNode.NodeEntries)
         {
             Single enlargment = GetFutureSize(nodeBoundingBox, nodeEntry.MinimumBoundingBox) - nodeEntry.MinimumBoundingBox.GetArea();
             if ((enlargment == minEnlargedArea && nodeEntry.MinimumBoundingBox.GetArea() < minEnlargment.MinimumBoundingBox.GetArea()) ||
                 enlargment < minEnlargedArea)
             {
                 minEnlargedArea = enlargment;
                 minEnlargment = nodeEntry;
             }
         }
         insertionNode = Cache.LookupNode(minEnlargment.Child);
         currentDepth++;
     }
     return insertionNode;
 }