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 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 override void AdjustTree(Node node1, Node node2) { AdjustTree(node1, node2, TreeHeight - CalculateHeight(node1) + 1); }
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 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 node1, Node node2) { return GetMargin(node1) + GetMargin(node2); }
protected virtual Single GetOverlap(NodeEntry insertionEntry, Node node) { return GetOverlap(insertionEntry, insertionEntry.MinimumBoundingBox, node); }
protected virtual List<Record> Search(KNearestNeighborQuery kNN, Node node) { PriorityQueue<NodeEntry, Single> proximityQueue = new PriorityQueue<NodeEntry, Single>(); List<Record> results = new List<Record>(kNN.K); EnqueNodeEntries(kNN, node, proximityQueue); while (results.Count < kNN.K && proximityQueue.Count > 0) { NodeEntry closestEntry = proximityQueue.Dequeue().Value; if (closestEntry is LeafEntry) { Record closestRecord = Cache.LookupRecord(closestEntry.Child); results.Add(closestRecord); } else { Node closestNode = Cache.LookupNode(closestEntry.Child); EnqueNodeEntries(kNN, closestNode, proximityQueue); } } for(int i = 0; i < results.Count; i++) for(int j = i; j < results.Count; j++) { if (results[i].BoundingBox.MinX == results[j].BoundingBox.MinX && results[i].BoundingBox.MinY == results[j].BoundingBox.MinY && results[i].BoundingBox.MaxX == results[j].BoundingBox.MaxX && results[i].BoundingBox.MaxY == results[j].BoundingBox.MaxY) { if (results[i].RecordID.CompareTo(results[j].RecordID) > 0) { Record temp = results[i]; results[i] = results[j]; results[j] = temp; } } else break; } return results; }
protected virtual List<Node> Split(Node nodeToBeSplit) { List<NodeEntry> entries = new List<NodeEntry>(nodeToBeSplit.NodeEntries); List<NodeEntry> seeds = PickSeeds(entries); entries.Remove(seeds[0]); entries.Remove(seeds[1]); Node node1, node2; if (nodeToBeSplit is Leaf) { node1 = new Leaf(nodeToBeSplit.Parent); node2 = new Leaf(nodeToBeSplit.Parent); } else { node1 = new Node(nodeToBeSplit.Parent, nodeToBeSplit.ChildType); node2 = new Node(nodeToBeSplit.Parent, nodeToBeSplit.ChildType); } node1.AddNodeEntry(seeds[0]); node2.AddNodeEntry(seeds[1]); if (!(seeds[0] is LeafEntry)) { Node child = Cache.LookupNode(seeds[0].Child); child.Parent = node1.Address; Cache.WritePageData(child); } if (!(seeds[1] is LeafEntry)) { Node child = Cache.LookupNode(seeds[1].Child); child.Parent = node2.Address; Cache.WritePageData(child); } while (entries.Count > 0) { if (node1.NodeEntries.Count + entries.Count == Constants.MINIMUM_ENTRIES_PER_NODE) { foreach (NodeEntry entry in entries) { node1.AddNodeEntry(entry); if(!(entry is LeafEntry)) { Node child = Cache.LookupNode(entry.Child); child.Parent = node1.Address; Cache.WritePageData(child); } } break; } else if (node2.NodeEntries.Count + entries.Count == Constants.MINIMUM_ENTRIES_PER_NODE) { foreach (NodeEntry entry in entries) { node2.AddNodeEntry(entry); if (!(entry is LeafEntry)) { Node child = Cache.LookupNode(entry.Child); child.Parent = node2.Address; Cache.WritePageData(child); } } break; } MinimumBoundingBox minimumBoundingBox1 = node1.CalculateMinimumBoundingBox(), minimumBoundingBox2 = node2.CalculateMinimumBoundingBox(); NodeEntry nextEntry = PickNext(entries, minimumBoundingBox1, minimumBoundingBox2); entries.Remove(nextEntry); Node nodeToEnter; if (GetFutureSize(nextEntry.MinimumBoundingBox, minimumBoundingBox1) == GetFutureSize(nextEntry.MinimumBoundingBox, minimumBoundingBox2)) { if (minimumBoundingBox1.GetArea() == minimumBoundingBox2.GetArea()) if (node1.NodeEntries.Count <= node2.NodeEntries.Count) nodeToEnter = node1; else nodeToEnter = node2; else if (minimumBoundingBox1.GetArea() < minimumBoundingBox2.GetArea()) nodeToEnter = node1; else nodeToEnter = node2; } else if (GetFutureSize(nextEntry.MinimumBoundingBox, minimumBoundingBox1) < GetFutureSize(nextEntry.MinimumBoundingBox, minimumBoundingBox2)) nodeToEnter = node1; else nodeToEnter = node2; nodeToEnter.AddNodeEntry(nextEntry); if (!(nextEntry is LeafEntry)) { Node child = Cache.LookupNode(nextEntry.Child); child.Parent = nodeToEnter.Address; Cache.WritePageData(child); } } List<Node> newNodes = new List<Node>(); newNodes.Add(node1); newNodes.Add(node2); return newNodes; }
protected virtual void RemoveFromParent(Node node) { if (!node.Parent.Equals(Address.Empty)) { Node parent = Cache.LookupNode(node.Parent); NodeEntry entryToRemove = null; foreach (NodeEntry entry in parent.NodeEntries) if (entry.Child.Equals(node.Address)) entryToRemove = entry; parent.RemoveNodeEntry(entryToRemove); Cache.WritePageData(parent); } else Root = Address.Empty; Cache.DeletePageData(node); }
protected virtual List<Record> Search(RegionQuery window, Node node) { List<Record> records = new List<Record>(); foreach (NodeEntry nodeEntry in node.NodeEntries) { if (window is RangeQuery && Overlaps((RangeQuery)window, nodeEntry.MinimumBoundingBox) || window is WindowQuery && Overlaps((WindowQuery)window, nodeEntry.MinimumBoundingBox)) if (nodeEntry is LeafEntry) records.Add(Cache.LookupRecord(nodeEntry.Child)); else records.AddRange(Search(window, Cache.LookupNode(nodeEntry.Child))); } return records; }
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 Leaf FindLeaf(Record record, Node node) { if (node is Leaf) { foreach (LeafEntry entry in node.NodeEntries) if (entry.Child.Equals(record.Address)) return node as Leaf; } else foreach (NodeEntry entry in node.NodeEntries) if (Overlaps(entry.MinimumBoundingBox, record.BoundingBox)) { Leaf leaf = FindLeaf(record, Cache.LookupNode(entry.Child)); if (leaf != null) return leaf; } return null; }
protected virtual void EnqueNodeEntries(KNearestNeighborQuery kNN, Node node, PriorityQueue<NodeEntry, Single> proximityQueue) { foreach (NodeEntry entry in node.NodeEntries) proximityQueue.Enqueue(entry, GetDistance(kNN.X, kNN.Y, entry.MinimumBoundingBox) * -1); }
protected override Node ChooseNode(Node node) { NodeEntry nodeEntry = new NodeEntry(node.CalculateMinimumBoundingBox(), node.Address); return ChooseNode(nodeEntry, TreeHeight - CalculateHeight(node) + 1); }
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 Single GetFutureOverlap(NodeEntry entry, NodeEntry insertionEntry, Node node) { MinimumBoundingBox overlapMinimumBoundingBox = CombineMinimumBoundingBoxes(entry.MinimumBoundingBox, insertionEntry.MinimumBoundingBox); return GetOverlap(insertionEntry, overlapMinimumBoundingBox, node); }
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 virtual Single GetMargin(Node node) { MinimumBoundingBox box = node.CalculateMinimumBoundingBox(); return (box.MaxX - box.MinX) + (box.MaxY - box.MinY); }
protected override void Insert(Node node) { Node nodeToInsertInto = ChooseNode(node); Insert(node, nodeToInsertInto); if (nodeToInsertInto.NodeEntries.Count > Constants.MAXIMUM_ENTRIES_PER_NODE) { List<Node> splitNodes = Split(nodeToInsertInto); RemoveFromParent(nodeToInsertInto); AdjustTree(splitNodes[0], splitNodes[1]); } else AdjustTree(nodeToInsertInto); }
protected virtual Single GetOverlap(NodeEntry insertionEntry, MinimumBoundingBox overlapMinimumBoundingBox, Node node) { foreach (NodeEntry nodeEntry in node.NodeEntries) if (nodeEntry != insertionEntry) overlapMinimumBoundingBox = IntersectMinimumBoundingBoxes(overlapMinimumBoundingBox, nodeEntry.MinimumBoundingBox); return (overlapMinimumBoundingBox.MaxX - overlapMinimumBoundingBox.MinX) * (overlapMinimumBoundingBox.MaxY - overlapMinimumBoundingBox.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 virtual List<Node> OverFlowTreatment(Node nodeToInsertInto, Int32 level) { if (nodeToInsertInto.Address.Equals(Root) || OverflowMarkers.Contains(level)) { return Split(nodeToInsertInto); } else { OverflowMarkers.Add(level); ReInsert(nodeToInsertInto, level); return null; } }
protected override void RemoveFromParent(Node node) { if (!node.Parent.Equals(Address.Empty)) { Node parent = Cache.LookupNode(node.Parent); NodeEntry entryToRemove = null; foreach (NodeEntry entry in parent.NodeEntries) if (entry.Child.Equals(node.Address)) entryToRemove = entry; IndexUnit indexUnit = new IndexUnit(parent.Address, node.Address, entryToRemove.MinimumBoundingBox, Operation.Delete); NodeTranslationTable.Add(indexUnit); } else Root = Address.Empty; Cache.DeletePageData(node); }
protected override List<Node> Split(Node nodeToBeSplit) { // //Determine Axis // //Sort each axis by upper and lower corners List<NodeEntry> xLowerSorted = new List<NodeEntry>(nodeToBeSplit.NodeEntries), xUpperSorted = new List<NodeEntry>(nodeToBeSplit.NodeEntries), yLowerSorted = new List<NodeEntry>(nodeToBeSplit.NodeEntries), yUpperSorted = new List<NodeEntry>(nodeToBeSplit.NodeEntries); xLowerSorted.Sort(new NodeEntryLowerAxisComparerX()); xUpperSorted.Sort(new NodeEntryUpperAxisComparerX()); yLowerSorted.Sort(new NodeEntryLowerAxisComparerY()); yUpperSorted.Sort(new NodeEntryUpperAxisComparerY()); //Generate Distributions List<Pair<Node, Node>> xLowerDistributions = new List<Pair<Node, Node>>(), xUpperDistributions = new List<Pair<Node, Node>>(), yLowerDistributions = new List<Pair<Node, Node>>(), yUpperDistributions = new List<Pair<Node, Node>>(); Dictionary<List<NodeEntry>, List<Pair<Node, Node>>> axii = new Dictionary<List<NodeEntry>, List<Pair<Node, Node>>>(); axii.Add(xLowerSorted, xLowerDistributions); axii.Add(xUpperSorted, xUpperDistributions); axii.Add(yLowerSorted, yLowerDistributions); axii.Add(yUpperSorted, yUpperDistributions); foreach (KeyValuePair<List<NodeEntry>, List<Pair<Node, Node>>> axis in axii) for (int i = 0; i < Constants.MAXIMUM_ENTRIES_PER_NODE - 2 * Constants.MINIMUM_ENTRIES_PER_NODE + 2; i++) { Node group1, group2; if (nodeToBeSplit is Leaf) { group1 = new Leaf(nodeToBeSplit.Parent); group2 = new Leaf(nodeToBeSplit.Parent); } else { group1 = new Node(nodeToBeSplit.Parent, nodeToBeSplit.ChildType); group2 = new Node(nodeToBeSplit.Parent, nodeToBeSplit.ChildType); } foreach (NodeEntry entry in axis.Key.GetRange(0, Constants.MINIMUM_ENTRIES_PER_NODE+ i)) group1.AddNodeEntry(entry); foreach (NodeEntry entry in axis.Key.GetRange(Constants.MINIMUM_ENTRIES_PER_NODE + i, axis.Key.Count - (Constants.MINIMUM_ENTRIES_PER_NODE+ i))) group2.AddNodeEntry(entry); axis.Value.Add(new Pair<Node, Node>(group1, group2)); } //Sum margins Single xLowerMarginSum = 0, xUpperMarginSum = 0, yLowerMarginSum = 0, yUpperMarginSum = 0; foreach (Pair<Node, Node> distribution in xLowerDistributions) xLowerMarginSum += GetMargin(distribution.Value1, distribution.Value2); foreach (Pair<Node, Node> distribution in xUpperDistributions) xUpperMarginSum += GetMargin(distribution.Value1, distribution.Value2); foreach (Pair<Node, Node> distribution in yLowerDistributions) yLowerMarginSum += GetMargin(distribution.Value1, distribution.Value2); foreach (Pair<Node, Node> distribution in yUpperDistributions) yUpperMarginSum += GetMargin(distribution.Value1, distribution.Value2); //Choose Axis List<Pair<Node, Node>> chosenAxis; if (xLowerMarginSum <= xUpperMarginSum && xLowerMarginSum <= yLowerMarginSum && xLowerMarginSum <= yUpperMarginSum) chosenAxis = xLowerDistributions; else if (xUpperMarginSum <= xLowerMarginSum && xUpperMarginSum <= yLowerMarginSum && xUpperMarginSum <= yUpperMarginSum) chosenAxis = xUpperDistributions; else if (yLowerMarginSum <= xUpperMarginSum && yLowerMarginSum <= xLowerMarginSum && yLowerMarginSum <= yUpperMarginSum) chosenAxis = yLowerDistributions; else chosenAxis = yUpperDistributions; // //Determine Distribution // Pair<Node, Node> chosenDistribution = chosenAxis[0]; Single minimumOverlapArea = GetOverlap(chosenDistribution.Value1, chosenDistribution.Value2); foreach (Pair<Node, Node> distribution in chosenAxis) { Single overlapArea = GetOverlap(distribution.Value1, distribution.Value2); if ((overlapArea == minimumOverlapArea && GetFutureSize(distribution.Value1.CalculateMinimumBoundingBox(), distribution.Value2.CalculateMinimumBoundingBox()) < GetFutureSize(chosenDistribution.Value1.CalculateMinimumBoundingBox(), chosenDistribution.Value2.CalculateMinimumBoundingBox()) ) || overlapArea < minimumOverlapArea) { chosenDistribution = distribution; minimumOverlapArea = overlapArea; } } // //Distribute // List<Node> newNodes = new List<Node>(); newNodes.Add(chosenDistribution.Value1); newNodes.Add(chosenDistribution.Value2); foreach (Node newNode in newNodes) { if (!(newNode is Leaf)) foreach (NodeEntry entry in newNode.NodeEntries) { Node child = Cache.LookupNode(entry.Child); child.Parent = newNode.Address; Cache.WritePageData(child); } Cache.WritePageData(newNode); } return newNodes; }
protected override List<Record> Search(KNearestNeighborQuery kNN, Node node) { return Search(kNN, node, Condense(Buffer.Buffer)); }
protected virtual void AdjustTree(Node node1, Int32 level) { AdjustTree(node1, null, level); }
protected virtual List<Record> Search(KNearestNeighborQuery kNN, Node node, List<BufferItem> changeList) { PriorityQueue<NodeEntry, Single> proximityQueue = new PriorityQueue<NodeEntry, Single>(); List<Record> results = new List<Record>(kNN.K); List<BufferItem> deletions = new List<BufferItem>(); foreach(BufferItem change in changeList) if(change.Operation == Operation.Delete) deletions.Add(change); foreach(BufferItem deletion in deletions) changeList.Remove(deletion); foreach (BufferItem insertion in changeList) proximityQueue.Enqueue(insertion.Entry, GetDistance(kNN.X, kNN.Y, insertion.Entry.MinimumBoundingBox) * -1); EnqueNodeEntries(kNN, node, proximityQueue); while (results.Count < kNN.K && proximityQueue.Count > 0) { NodeEntry closestEntry = proximityQueue.Dequeue().Value; if (closestEntry is LeafEntry) { Boolean entryDeleted = false; foreach (BufferItem deletion in deletions) if (closestEntry.Child.Equals(deletion.Entry.Child)) entryDeleted = true; if (!entryDeleted) results.Add(Cache.LookupRecord(closestEntry.Child)); } else EnqueNodeEntries(kNN, Cache.LookupNode(closestEntry.Child), proximityQueue); } while (results.Contains(null)) results.Remove(null); for(int i = 0; i < results.Count; i++) for(int j = i; j < results.Count; j++) { if (results[i].BoundingBox.MinX == results[j].BoundingBox.MinX && results[i].BoundingBox.MinY == results[j].BoundingBox.MinY && results[i].BoundingBox.MaxX == results[j].BoundingBox.MaxX && results[i].BoundingBox.MaxY == results[j].BoundingBox.MaxY) { if (results[i].RecordID.CompareTo(results[j].RecordID) > 0) { Record temp = results[i]; results[i] = results[j]; results[j] = temp; } } else break; } return results; }
protected virtual PageData LookupPageData(Address address) { PageData data; Page page = LookupPage(address); Byte type = page.Data[0], childType = page.Data[1]; if (type == (Byte)PageDataType.Node || type == (Byte)PageDataType.Leaf) if (childType == (Byte)NodeChildType.Leaf) data = new Node(address, typeof(Leaf), page.Data); else if (childType == (Byte)NodeChildType.Node) data = new Node(address, typeof(Node), page.Data); else if (childType == (Byte)NodeChildType.Record) data = new Leaf(address, page.Data); else throw new Exception("Not a node"); else if (type == (Byte)PageDataType.Record) data = new Record(address, page.Data); else if (type == (Byte)PageDataType.IndexUnitSector) data = new Sector(address, page.Data); else throw new Exception("Not valid Page Data"); CacheOverflowCheck(); return data; }
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; }