예제 #1
0
        private void insertToLeaf(RTreeNode newNode)
        {
            if (Root == null)
            {
                Root = new RTreeNode(maxKeysPerNode, null);
                Root.AddChild(newNode);
                return;
            }

            var leafToInsert = findInsertionLeaf(Root, newNode);

            insertAndSplit(leafToInsert, newNode);
        }
예제 #2
0
        /// <summary>
        ///     Insert and split recursively up until no split is required
        /// </summary>
        /// <param name="node"></param>
        /// <param name="newValue"></param>
        private void insertAndSplit(RTreeNode node, RTreeNode newValue)
        {
            //newValue have room to fit in this node
            if (node.KeyCount < maxKeysPerNode)
            {
                node.AddChild(newValue);
                expandAncestorMBRs(node);
                return;
            }

            var e = new List <RTreeNode>(new RTreeNode[] { newValue });

            e.AddRange(node.Children);

            var distantPairs = getDistantPairs(e);

            //Let E be the set consisting of all current entries and new entry.
            //Select as seeds two entries e1, e2 ∈ E, where the distance between
            //left and right is the maximum among all other pairs of entries from E
            var e1 = new RTreeNode(maxKeysPerNode, null);
            var e2 = new RTreeNode(maxKeysPerNode, null);

            e1.AddChild(distantPairs.Item1);
            e2.AddChild(distantPairs.Item2);

            e = e.Where(x => x != distantPairs.Item1 && x != distantPairs.Item2)
                .ToList();

            /*Examine the remaining members of E one by one and assign them
             * to e1 or e2, depending on which of the MBRs of these nodes
             * will require the minimum area enlargement so as to cover this entry.
             * If a tie occurs, assign the entry to the node whose MBR has the smaller area.
             * If a tie occurs again, assign the entry to the node that contains the smaller number of entries*/
            while (e.Count > 0)
            {
                var current = e[e.Count - 1];

                var leftEnlargementArea  = e1.MBRectangle.GetEnlargementArea(current.MBRectangle);
                var rightEnlargementArea = e2.MBRectangle.GetEnlargementArea(current.MBRectangle);

                if (leftEnlargementArea == rightEnlargementArea)
                {
                    var leftArea  = e1.MBRectangle.Area();
                    var rightArea = e2.MBRectangle.Area();

                    if (leftArea == rightArea)
                    {
                        if (e1.KeyCount < e2.KeyCount)
                        {
                            e1.AddChild(current);
                        }
                        else
                        {
                            e2.AddChild(current);
                        }
                    }
                    else if (leftArea < rightArea)
                    {
                        e1.AddChild(current);
                    }
                    else
                    {
                        e2.AddChild(current);
                    }
                }
                else if (leftEnlargementArea < rightEnlargementArea)
                {
                    e1.AddChild(current);
                }
                else
                {
                    e2.AddChild(current);
                }

                e.RemoveAt(e.Count - 1);

                var remaining = e.Count;

                /*if during the assignment of entries, there remain λ entries to be assigned
                 * and the one node contains minKeysPerNode − λ entries then
                 * assign all the remaining entries to this node without considering
                 * the aforementioned criteria
                 * so that the node will contain at least minKeysPerNode entries */
                if (e1.KeyCount == minKeysPerNode - remaining)
                {
                    foreach (var entry in e)
                    {
                        e1.AddChild(entry);
                    }
                    e.Clear();
                }
                else if (e2.KeyCount == minKeysPerNode - remaining)
                {
                    foreach (var entry in e)
                    {
                        e2.AddChild(entry);
                    }
                    e.Clear();
                }
            }

            var parent = node.Parent;

            if (parent != null)
            {
                //replace current node with e1
                parent.SetChild(node.Index, e1);
                //insert overflow element to parent
                insertAndSplit(parent, e2);
            }
            else
            {
                //node is the root.
                //increase the height of RTree by one by adding a new root.
                Root = new RTreeNode(maxKeysPerNode, null);
                Root.AddChild(e1);
                Root.AddChild(e2);
            }
        }