private void InitializeIfNecessary(TItem item)
        {
            if (Root != null)
            {
                return;
            }

            Root = new GenericPartitionTreeSection <TBoundary, TItem>(GetSectionBoundary(GetItemPoint(item), InitialPartitionSize));
        }
        protected void RedistributeItemsWithinSubsections(GenericPartitionTreeSection <TBoundary, TItem> section)
        {
            foreach (var item in section.Items)
            {
                FindPointSubsection(section, item)?.AddItem(item);
            }

            section.RemoveItems();
        }
        private void RemoveAllItems(GenericPartitionTreeSection <TBoundary, TItem> root)
        {
            root.RemoveItems();

            foreach (var subsection in root.Subsections)
            {
                RemoveAllItems(subsection);
            }
        }
        private bool HasItem(TItem item, GenericPartitionTreeSection <TBoundary, TItem> root)
        {
            if (root == null)
            {
                return(false);
            }

            return(root.Items.Contains(item) || root.Subsections.Any(subsection => HasItem(item, subsection)));
        }
        protected void AddSubsection(GenericPartitionTreeSection <TBoundary, TItem> root, GenericPartitionTreeSection <TBoundary, TItem> section)
        {
            if (root.SubsectionCount >= SubsectionsPerSection)
            {
                throw new IndexOutOfRangeException();
            }

            section.Parent = root;
            root.AddSubsection(section);
        }
        private IEnumerable <TItem> GetItemsWithinBoundary(TBoundary boundary, GenericPartitionTreeSection <TBoundary, TItem> section)
        {
            var list = new List <TItem>();

            if (!BoundaryContains(section.Boundary, boundary) && !BoundaryIntersects(section.Boundary, boundary))
            {
                return(list);
            }

            if (section.SubsectionCount == 0)
            {
                return(section.Items);
            }

            foreach (var subsection in section.Subsections)
            {
                list.AddRange(GetItemsWithinBoundary(boundary, subsection));
            }

            return(list);
        }
        private GenericPartitionTreeSection <TBoundary, TItem> FindPointSubsection(GenericPartitionTreeSection <TBoundary, TItem> root, TItem item)
        {
            if (!SectionContains(root, item))
            {
                return(null);
            }

            if (root.SubsectionCount == 0)
            {
                return(root);
            }

            foreach (var subsection in root.Subsections)
            {
                var sec = FindPointSubsection(subsection, item);
                if (sec != null)
                {
                    return(sec);
                }
            }

            return(null);
        }
 protected abstract void Subdivide(GenericPartitionTreeSection <TBoundary, TItem> section);
 protected abstract bool SectionContains(GenericPartitionTreeSection <TBoundary, TItem> section, TItem item);
 internal void AddSubsection(GenericPartitionTreeSection <TBoundary, TItem> section)
 {
     _subsections.Add(section);
 }
 private GenericPartitionTreeSection <TBoundary, TItem> GetItemSection(TItem item, GenericPartitionTreeSection <TBoundary, TItem> root)
 {
     return(root.Items.Contains(item) ? root : root.Subsections.Select(subsection => GetItemSection(item, subsection)).FirstOrDefault());
 }
 private bool SectionNeedsSubdividing(GenericPartitionTreeSection <TBoundary, TItem> section)
 {
     return(section.ItemCount >= SectionItemMaxCount);
 }