Beispiel #1
0
        private void QueryRange(IntervalTreeNode intervalTreeNode, Int64 start, Int64 end, List <T> results)
        {
            for (int i = intervalTreeNode.first; i <= intervalTreeNode.last; i++)
            {
                var entry = m_Entries[i];
                if (end >= entry.intervalStart && start < entry.intervalEnd)
                {
                    results.Add(entry.item);
                }
            }

            if (intervalTreeNode.center == kCenterUnknown)
            {
                return;
            }
            if (intervalTreeNode.left != kInvalidNode && start < intervalTreeNode.center)
            {
                QueryRange(m_Nodes[intervalTreeNode.left], start, end, results);
            }
            if (intervalTreeNode.right != kInvalidNode && end > intervalTreeNode.center)
            {
                QueryRange(m_Nodes[intervalTreeNode.right], start, end, results);
            }
        }
Beispiel #2
0
        private void Query(IntervalTreeNode intervalTreeNode, Int64 value, List <T> results)
        {
            for (int i = intervalTreeNode.first; i <= intervalTreeNode.last; i++)
            {
                var entry = m_Entries[i];
                if (value >= entry.intervalStart && value < entry.intervalEnd)
                {
                    results.Add(entry.item);
                }
            }

            if (intervalTreeNode.center == kCenterUnknown)
            {
                return;
            }
            if (intervalTreeNode.left != kInvalidNode && value < intervalTreeNode.center)
            {
                Query(m_Nodes[intervalTreeNode.left], value, results);
            }
            if (intervalTreeNode.right != kInvalidNode && value > intervalTreeNode.center)
            {
                Query(m_Nodes[intervalTreeNode.right], value, results);
            }
        }
Beispiel #3
0
        private int Rebuild(int start, int end)
        {
            IntervalTreeNode intervalTreeNode = new IntervalTreeNode();

            // minimum size, don't subdivide
            int count = end - start + 1;

            if (count < kMinNodeSize)
            {
                intervalTreeNode = new IntervalTreeNode()
                {
                    center = kCenterUnknown, first = start, last = end, left = kInvalidNode, right = kInvalidNode
                };
                m_Nodes.Add(intervalTreeNode);
                return(m_Nodes.Count - 1);
            }

            var min = Int64.MaxValue;
            var max = Int64.MinValue;

            for (int i = start; i <= end; i++)
            {
                var o = m_Entries[i];
                min = Math.Min(min, o.intervalStart);
                max = Math.Max(max, o.intervalEnd);
            }

            var center = (max + min) / 2;

            intervalTreeNode.center = center;

            // first pass, put every thing left of center, left
            int x = start;
            int y = end;

            while (true)
            {
                while (x <= end && m_Entries[x].intervalEnd < center)
                {
                    x++;
                }

                while (y >= start && m_Entries[y].intervalEnd >= center)
                {
                    y--;
                }

                if (x > y)
                {
                    break;
                }

                var nodeX = m_Entries[x];
                var nodeY = m_Entries[y];

                m_Entries[y] = nodeX;
                m_Entries[x] = nodeY;
            }

            intervalTreeNode.first = x;

            // second pass, put every start passed the center right
            y = end;
            while (true)
            {
                while (x <= end && m_Entries[x].intervalStart <= center)
                {
                    x++;
                }

                while (y >= start && m_Entries[y].intervalStart > center)
                {
                    y--;
                }

                if (x > y)
                {
                    break;
                }

                var nodeX = m_Entries[x];
                var nodeY = m_Entries[y];

                m_Entries[y] = nodeX;
                m_Entries[x] = nodeY;
            }

            intervalTreeNode.last = y;

            // reserve a place
            m_Nodes.Add(new IntervalTreeNode());
            int index = m_Nodes.Count - 1;

            intervalTreeNode.left  = kInvalidNode;
            intervalTreeNode.right = kInvalidNode;

            if (start < intervalTreeNode.first)
            {
                intervalTreeNode.left = Rebuild(start, intervalTreeNode.first - 1);
            }

            if (end > intervalTreeNode.last)
            {
                intervalTreeNode.right = Rebuild(intervalTreeNode.last + 1, end);
            }

            m_Nodes[index] = intervalTreeNode;
            return(index);
        }