private void Split(INode nodeAfterEntryAdded) { INode newN1, newN2; if (nodeAfterEntryAdded is NonLeafNode) { var result = SplitEntries(nodeAfterEntryAdded); NonLeafNode n1 = new NonLeafNode(NonLeafNodeIDGenerater()); n1.Level = nodeAfterEntryAdded.Level; n1.AddEntries(result.Item1); NonLeafNode n2 = new NonLeafNode(NonLeafNodeIDGenerater()); n2.AddEntries(result.Item2); n2.Level = nodeAfterEntryAdded.Level; newN1 = n1; newN2 = n2; } else { var result = SplitEntries(nodeAfterEntryAdded); Leaf n1 = new Leaf(NonLeafNodeIDGenerater()); n1.Level = nodeAfterEntryAdded.Level; n1.AddEntries(result.Item1); Leaf n2 = new Leaf(NonLeafNodeIDGenerater()); n2.Level = nodeAfterEntryAdded.Level; n2.AddEntries(result.Item2); newN1 = n1; newN2 = n2; } _nodesMap.AddOrUpdate(newN1.ID, newN1, (i, n) => { return(newN1); }); _nodesMap.AddOrUpdate(newN2.ID, newN2, (i, n) => { return(newN2); }); NonLeafNode parentNode; if (!nodeAfterEntryAdded.IsRoot) { parentNode = nodeAfterEntryAdded.ParentNode as NonLeafNode; parentNode.RemoveEntry(nodeAfterEntryAdded.ID); _nodesMap.TryRemove(nodeAfterEntryAdded.ID, out nodeAfterEntryAdded); } else { parentNode = new NonLeafNode(NonLeafNodeIDGenerater()); parentNode.Level = 1; _root = parentNode; _nodesMap.AddOrUpdate(_root.ID, _root, (i, n) => { return(_root); }); _nodesMap.TryRemove(nodeAfterEntryAdded.ID, out nodeAfterEntryAdded); } parentNode.AddEntry(newN1); parentNode.AddEntry(newN2); parentNode.UpdateSubTreeLevel(parentNode.Level); if (parentNode.Entries.Count() > DEFAULT_MAX_NODE_ENTRIES) { OverflowTreatment(parentNode); } }
/// <summary> /// /// </summary> /// <param name="entryToAdd"></param> /// <param name="nodeAddTo"></param> /// <returns></returns> private INode ChooseSubTree(IEntry entryToAdd, INode nodeAddTo, int entryLevel = -1) { if (entryToAdd is NonLeafNode && nodeAddTo is NonLeafNode && (nodeAddTo as NonLeafNode).Entries.First() is Leaf) { return(nodeAddTo); } if (entryToAdd is DataEntry && nodeAddTo is Leaf) { return(nodeAddTo); } if (entryLevel == nodeAddTo.Level + 1) { if (entryToAdd is Leaf && nodeAddTo is NonLeafNode && !((nodeAddTo as NonLeafNode).Entries.First() is Leaf)) { return(ChooseSubTree(entryToAdd, nodeAddTo, ++entryLevel)); } else { return(nodeAddTo); } } NonLeafNode nlf = nodeAddTo as NonLeafNode; if (nlf.Entries.First() is Leaf) { var chosenEntryID = nlf.Entries//.AsParallel() .OrderBy(e => e.MBR.Area) .OrderBy(e => e.MBR.EnlargementSize(entryToAdd.MBR)) .OrderBy(e => { return((e as Leaf).Entries .Sum(e2 => e2.MBR.OverlapSize(entryToAdd.MBR))); }) .Take(2) .First().ID; return(ChooseSubTree(entryToAdd, _nodesMap[chosenEntryID], entryLevel)); } else { var chosenEntryID = nlf.Entries//.AsParallel() .OrderBy(e => e.MBR.Area) .OrderBy(e => e.MBR.EnlargementSize(entryToAdd.MBR)) .First().ID; return(ChooseSubTree(entryToAdd, _nodesMap[chosenEntryID], entryLevel)); } }