Exemple #1
0
        /// <summary>
        /// Collects the elements in quadrant that pass the intersection test.
        /// </summary>
        /// <param name="lockedQuadrant">A quadrant on which the current thread
        /// holds a shared lock.</param>
        /// <param name="intersectionTest">An predicate P such that if a
        /// rectangle B contains a rectangle A, then P(A) implies P(B).</param>
        /// <param name="output">The output collection where to place the elements.</param>
        void CollectElementsInQuadrantThatAreInRegion(Quadrant lockedQuadrant,
                                                      Predicate <Rect> intersectionTest, ICollection <IElement> output)
        {
            Debug.Assert(lockedQuadrant.Lock.ThreadOwnsSharedLock);

            if (lockedQuadrant.IsLeaf)
            {
                foreach (var datum in lockedQuadrant.Data)
                {
                    Rect datumRect = new Rect(datum.Coordinates.Longitude, datum.Coordinates.Latitude, 0, 0);

                    if (intersectionTest(datumRect))
                    {
                        output.Add(datum);
                    }
                }

                lockedQuadrant.Lock.ExitSharedLock();
            }
            else
            {
                // Lock all children. Do this before releasing the lock
                // on the parent to prevent the parent from performing a join.
                for (int childIdx = 0; childIdx < 4; ++childIdx)
                {
                    lockedQuadrant.GetChild(childIdx).Lock.EnterSharedLock();
                }

                // Exit the lock on the parent before recursion to avoid
                // holding a shared lock on every quadrant all the way down.
                lockedQuadrant.Lock.ExitSharedLock();

                // Check each child.
                for (int childIdx = 0; childIdx < 4; ++childIdx)
                {
                    Quadrant child = lockedQuadrant.GetChild(childIdx);

                    if (intersectionTest(child.Bounds))
                    {
                        CollectElementsInQuadrantThatAreInRegion(child, intersectionTest, output);
                    }
                    else
                    {
                        child.Lock.ExitSharedLock();
                    }
                }
            }
        }
Exemple #2
0
        void SubdivideWithoutLocking(Quadrant quadrant)
        {
            if (quadrant.SubdivisionLevel >= maxSubdivisionLevel)
            {
                return;
            }

            if (quadrant.Data.Count <= maxLeafCapacity)
            {
                return;
            }

            if (!quadrant.TrySubdivide())
            {
                return;
            }

            for (int childIdx = 0; childIdx < 4; ++childIdx)
            {
                Quadrant child = quadrant.GetChild(childIdx);

                foreach (var datum in child.Data)
                {
                    elementsToNodes[datum] = child;
                }

                if (child.Data.Count > maxLeafCapacity)
                {
                    SubdivideWithoutLocking(child);
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Gets the depth of the tree rooted at this quadrant. For efficiency,
        /// this performs no locking. Because of this, the return value should be
        /// regarded as an approximation.
        /// </summary>
        int GetApproximateLargestSubdivisionLevel(Quadrant quadrant)
        {
            if (quadrant.IsLeaf)
            {
                return(0);
            }

            int maxLevel = 1;

            for (int childIdx = 0; childIdx < 4; ++childIdx)
            {
                try
                {
                    int childLevel = 1 + GetApproximateLargestSubdivisionLevel(quadrant.GetChild(childIdx));

                    if (childLevel > maxLevel)
                    {
                        maxLevel = childLevel;
                    }
                }
                catch (ApplicationException)
                {
                    // This can happen if the quadrant becomes a leaf due to
                    // a join operation (since we didn't lock it).
                    break;
                }
            }

            return(maxLevel);
        }