/// <summary> /// Creates parent nodes, grandparent nodes, and so forth up to the root /// node, for the data that has been inserted into the tree. Can only be /// called once, and thus can be called only after all of the data has been /// inserted into the tree. /// </summary> public void Build() { Assert.IsTrue(!built); root = (itemBoundables.Count == 0) ? CreateNode(0) : CreateHigherLevels(itemBoundables, -1); built = true; }
private bool Remove(object searchBounds, AbstractNode node, object item) { // first try removing item from this node var found = RemoveItem(node, item); if (found) return true; AbstractNode childToPrune = null; // next try removing item from lower nodes for (var i = node.ChildBoundables.GetEnumerator(); i.MoveNext(); ) { var childBoundable = (IBoundable)i.Current; if (!IntersectsOp.Intersects(childBoundable.Bounds, searchBounds)) continue; if (!(childBoundable is AbstractNode)) continue; found = Remove(searchBounds, (AbstractNode)childBoundable, item); // if found, record child for pruning and exit if (!found) continue; childToPrune = (AbstractNode)childBoundable; break; } // prune child if possible if (childToPrune != null) if (childToPrune.ChildBoundables.Count == 0) node.ChildBoundables.Remove(childToPrune); return found; }
private void BoundablesAtLevel(int level, AbstractNode top, ref IList boundables) { Assert.IsTrue(level > -2); if (top.Level == level) { boundables.Add(top); return; } for (var i = top.ChildBoundables.GetEnumerator(); i.MoveNext(); ) { var boundable = (IBoundable)i.Current; if (boundable is AbstractNode) BoundablesAtLevel(level, (AbstractNode)boundable, ref boundables); else { Assert.IsTrue(boundable is ItemBoundable); if (level == -1) boundables.Add(boundable); } } }
private IList ItemsTree(AbstractNode node) { var valuesTreeForNode = new ArrayList(); foreach (IBoundable childBoundable in node.ChildBoundables) { if (childBoundable is AbstractNode) { var valuesTreeForChild = ItemsTree((AbstractNode)childBoundable); // only add if not null (which indicates an item somewhere in this tree if (valuesTreeForChild != null) valuesTreeForNode.Add(valuesTreeForChild); } else if (childBoundable is ItemBoundable) valuesTreeForNode.Add(((ItemBoundable) childBoundable).Item); else Assert.ShouldNeverReachHere(); } return valuesTreeForNode.Count <= 0 ? null : valuesTreeForNode; }
private bool RemoveItem(AbstractNode node, object item) { IBoundable childToRemove = null; for (var i = node.ChildBoundables.GetEnumerator(); i.MoveNext(); ) { var childBoundable = (IBoundable)i.Current; if (childBoundable is ItemBoundable) if (((ItemBoundable)childBoundable).Item == item) childToRemove = childBoundable; } if (childToRemove != null) { node.ChildBoundables.Remove(childToRemove); return true; } return false; }
private void Query(object searchBounds, AbstractNode node, IItemVisitor visitor) { foreach (var obj in node.ChildBoundables) { var childBoundable = (IBoundable)obj; if (!IntersectsOp.Intersects(childBoundable.Bounds, searchBounds)) continue; if (childBoundable is AbstractNode) Query(searchBounds, (AbstractNode)childBoundable, visitor); else if (childBoundable is ItemBoundable) visitor.VisitItem(((ItemBoundable)childBoundable).Item); else Assert.ShouldNeverReachHere(); } }
protected int GetDepth(AbstractNode node) { var maxChildDepth = 0; for (var i = node.ChildBoundables.GetEnumerator(); i.MoveNext(); ) { var childBoundable = (IBoundable)i.Current; if (!(childBoundable is AbstractNode)) continue; var childDepth = GetDepth((AbstractNode)childBoundable); if (childDepth > maxChildDepth) maxChildDepth = childDepth; } return maxChildDepth + 1; }
protected int GetSize(AbstractNode node) { var size = 0; for (var i = node.ChildBoundables.GetEnumerator(); i.MoveNext(); ) { var childBoundable = (IBoundable)i.Current; if (childBoundable is AbstractNode) size += GetSize((AbstractNode)childBoundable); else if (childBoundable is ItemBoundable) size += 1; } return size; }
/// <summary> /// /// </summary> /// <param name="searchBounds"></param> /// <param name="node"></param> /// <param name="matches"></param> private void Query(object searchBounds, AbstractNode node, IList matches) { foreach(object obj in node.ChildBoundables) { IBoundable childBoundable = (IBoundable) obj; if (!IntersectsOp.Intersects(childBoundable.Bounds, searchBounds)) continue; if(childBoundable is AbstractNode) Query(searchBounds, (AbstractNode) childBoundable, matches); else if(childBoundable is ItemBoundable) matches.Add(((ItemBoundable) childBoundable).Item); else Assert.ShouldNeverReachHere(); } }
/// <summary> /// /// </summary> /// <param name="node"></param> /// <returns></returns> protected int GetDepth(AbstractNode node) { int maxChildDepth = 0; for (IEnumerator i = node.ChildBoundables.GetEnumerator(); i.MoveNext(); ) { IBoundable childBoundable = (IBoundable) i.Current; if (childBoundable is AbstractNode) { int childDepth = GetDepth((AbstractNode) childBoundable); if (childDepth > maxChildDepth) maxChildDepth = childDepth; } } return maxChildDepth + 1; }