Example #1
0
        /// <summary>
        /// Creates a new updatable R-Tree instance.
        /// </summary>
        /// <param name="geoFactory">
        /// An <see cref="IGeometryFactory"/> for creating extent instances.
        /// </param>
        /// <param name="insertStrategy">
        /// Strategy used to insert new entries into the index.
        /// </param>
        /// <param name="nodeSplitStrategy">
        /// Strategy used to split nodes when they are full.
        /// </param>
        /// <param name="heuristic">
        /// Heuristics used to build the index and keep it balanced.
        /// </param>
        public DynamicRTree(
            IGeometryFactory geoFactory,
            IItemInsertStrategy <IExtents, TItem> insertStrategy,
            INodeSplitStrategy <IExtents, TItem> nodeSplitStrategy,
            DynamicRTreeBalanceHeuristic heuristic)
            : base(geoFactory)
        {
            if (insertStrategy == null)
            {
                throw new ArgumentNullException("insertStrategy");
            }

            if (nodeSplitStrategy == null)
            {
                throw new ArgumentNullException("nodeSplitStrategy");
            }

            if (heuristic == null)
            {
                throw new ArgumentNullException("heuristic");
            }

            _insertStrategy    = insertStrategy;
            _nodeSplitStrategy = nodeSplitStrategy;
            _heuristic         = heuristic;
        }
Example #2
0
        public ISpatialIndexNode <IExtents, TItem> SplitNode(
            ISpatialIndexNode <IExtents, TItem> node, IndexBalanceHeuristic heuristic)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            RTreeNode <TItem> rTreeNode = node as RTreeNode <TItem>;

            Debug.Assert(rTreeNode != null);

            DynamicRTreeBalanceHeuristic rTreeHueristic
                = heuristic as DynamicRTreeBalanceHeuristic;

            return(doSplit(rTreeNode, rTreeHueristic));
        }
        /// <summary>
        /// Creates a new SelfOptimizingDynamicSpatialIndex.
        /// </summary>
        /// <param name="geoFactory">An <see cref="IGeometryFactory"/> instance.</param>
        /// <param name="restructureStrategy">The strategy used to restructure the index.</param>
        /// <param name="restructureHeuristic">The heuristic to control when the index is restructured.</param>
        /// <param name="insertStrategy">The strategy used to insert entries into the index.</param>
        /// <param name="nodeSplitStrategy">The strategy used to split index nodes.</param>
        /// <param name="indexHeuristic">A heuristic used to balance the index for optimum efficiency.</param>
        /// <param name="idleMonitor">A monitor to determine idle conditions on the executing machine.</param>
        public SelfOptimizingDynamicSpatialIndex(IGeometryFactory geoFactory,
                                                 IIndexRestructureStrategy <IExtents, TItem> restructureStrategy,
                                                 RestructuringHuristic restructureHeuristic,
                                                 IItemInsertStrategy <IExtents, TItem> insertStrategy,
                                                 INodeSplitStrategy <IExtents, TItem> nodeSplitStrategy,
                                                 DynamicRTreeBalanceHeuristic indexHeuristic,
                                                 IdleMonitor idleMonitor)
            : base(geoFactory, insertStrategy, nodeSplitStrategy, indexHeuristic)
        {
            _periodMilliseconds = restructureHeuristic.WhenToRestructure == RestructureOpportunity.Periodic
                                                                        ? (Int32)(restructureHeuristic.Period / 1000.0)
                                                                        : -1;

            _restructureStrategy    = restructureStrategy;
            _restructuringHeuristic = restructureHeuristic;
            _idleMonitor            = idleMonitor;

            _userIdleEvent    = new AutoResetEvent(false);
            _machineIdleEvent = new AutoResetEvent(false);
            _terminateEvent   = new ManualResetEvent(false);

            if (restructureHeuristic.WhenToRestructure != RestructureOpportunity.None)
            {
                _restructureThread = new Thread(doRestructure);
                _restructureThread.Start();
            }

            RestructureOpportunity idle = RestructureOpportunity.OnMachineIdle | RestructureOpportunity.OnUserIdle;

            if (((Int32)(restructureHeuristic.WhenToRestructure & idle)) > 0)
            {
                if (_idleMonitor == null)
                {
                    throw new ArgumentNullException("idleMonitor",
                                                    "If the restructuring heuristic has a value of anything but " +
                                                    "None for WhenToRestructure, the idleMonitor cannot be null.");
                }

                _idleMonitor.UserIdle    += _idleMonitor_UserIdle;
                _idleMonitor.UserBusy    += _idleMonitor_UserBusy;
                _idleMonitor.MachineIdle += _idleMonitor_MachineIdle;
                _idleMonitor.MachineBusy += _idleMonitor_MachineBusy;
            }
        }
Example #4
0
        private RTreeNode <TItem> doSplit(RTreeNode <TItem> node, DynamicRTreeBalanceHeuristic heuristic)
        {
            Boolean isLeaf = node.IsLeaf;

            IEnumerable <IBoundable <IExtents> > boundables;
            Int32 boundablesCount;

            if (isLeaf)
            {
                boundables      = Caster.Upcast <IBoundable <IExtents>, TItem>(node.Items);
                boundablesCount = node.ItemCount;
            }
            else
            {
                boundables      = Caster.Upcast <IBoundable <IExtents>, ISpatialIndexNode <IExtents, TItem> >(node.SubNodes);
                boundablesCount = node.SubNodeCount;
            }

            List <IBoundable <IExtents> > entries = new List <IBoundable <IExtents> >(boundablesCount);

            entries.AddRange(boundables);

            IBoundable <IExtents>[] group1 = new IBoundable <IExtents> [heuristic.NodeItemMaximumCount];
            IBoundable <IExtents>[] group2 = new IBoundable <IExtents> [heuristic.NodeItemMaximumCount];

            pickSeeds(entries, group1, group2);

            Int32 group1Count = 1, group2Count = 1;

            distribute(entries, group1, group2, heuristic, ref group1Count, ref group2Count);

            if (entries.Count > 0)
            {
                if (group1Count < group2Count)
                {
                    fillShortGroup(entries, group1, ref group1Count);
                }
                else // group2Count < heuristic.NodeItemMinimumCount
                {
                    fillShortGroup(entries, group2, ref group2Count);
                }
            }

            node.Clear();

            RTreeNode <TItem> sibling = (node.Index as RTree <TItem>).CreateNode(node.Level);

            IEnumerable <IBoundable <IExtents> > g1Sized = Enumerable.Take(group1, group1Count);
            IEnumerable <IBoundable <IExtents> > g2Sized = Enumerable.Take(group2, group2Count);

            if (isLeaf)
            {
                IEnumerable <TItem> g1Cast = Caster.Downcast <TItem, IBoundable <IExtents> >(g1Sized);
                node.InsertRange(g1Cast);

                //IEnumerable<TItem> g2Cast = Caster.Downcast<TItem, IBoundable<IExtents>>(g2Sized);
                sibling.AddRange(g2Sized);
            }
            else
            {
                //IEnumerable<ISpatialIndexNode<IExtents, TItem>> g1Cast
                //    = Caster.Downcast<ISpatialIndexNode<IExtents, TItem>, IBoundable<IExtents>>(g1Sized);
                node.AddRange(g1Sized);

                //IEnumerable<ISpatialIndexNode<IExtents, TItem>> g2Cast
                //    = Caster.Downcast<ISpatialIndexNode<IExtents, TItem>, IBoundable<IExtents>>(g2Sized);
                sibling.AddRange(g2Sized);
            }

            return(sibling);
        }