Ejemplo n.º 1
0
 public virtual void Clear()
 {
     if (root != null)
     {
         root.Purge(height);
         root = null;
     }
     height = 0;
     n = 0;
     Modify();
 }
Ejemplo n.º 2
0
 internal RtreePage(Storage storage, RtreePage root, RtreePage p)
 {
     branch = storage.CreateLink(card);
     branch.Size = card;
     b = new Rectangle[card];
     n = 2;
     SetBranch(0, root.Cover(), root);
     SetBranch(1, p.Cover(), p);
     for (int i = 2; i < card; i++)
     {
         b[i] = new Rectangle();
     }
 }
Ejemplo n.º 3
0
        internal RtreePage SplitPage(Storage storage, Rectangle r, IPersistent obj)
        {
            int i, j, seed0 = 0, seed1 = 0;
            long[] rectArea = new long[card + 1];
            long waste;
            long worstWaste = Int64.MinValue;
            //
            // As the seeds for the two groups, find two rectangles which waste
            // the most area if covered by a single rectangle.
            //
            rectArea[0] = r.Area();
            for (i = 0; i < card; i++)
            {
                rectArea[i + 1] = b[i].Area();
            }
            Rectangle bp = r;
            for (i = 0; i < card; i++)
            {
                for (j = i + 1; j <= card; j++)
                {
                    waste = Rectangle.JoinArea(bp, b[j - 1]) - rectArea[i] - rectArea[j];
                    if (waste > worstWaste)
                    {
                        worstWaste = waste;
                        seed0 = i;
                        seed1 = j;
                    }
                }
                bp = b[i];
            }
            byte[] taken = new byte[card];
            Rectangle group0, group1;
            long groupArea0, groupArea1;
            int groupCard0, groupCard1;
            RtreePage pg;

            taken[seed1 - 1] = 2;
            group1 = new Rectangle(b[seed1 - 1]);

            if (seed0 == 0)
            {
                group0 = new Rectangle(r);
                pg = new RtreePage(storage, obj, r);
            }
            else
            {
                group0 = new Rectangle(b[seed0 - 1]);
                pg = new RtreePage(storage, branch.GetRaw(seed0 - 1), group0);
                SetBranch(seed0 - 1, r, obj);
            }
            groupCard0 = groupCard1 = 1;
            groupArea0 = rectArea[seed0];
            groupArea1 = rectArea[seed1];
            //
            // Split remaining rectangles between two groups.
            // The one chosen is the one with the greatest difference in area
            // expansion depending on which group - the rect most strongly
            // attracted to one group and repelled from the other.
            //
            while (groupCard0 + groupCard1 < card + 1 && groupCard0 < card + 1 - minFill && groupCard1 < card + 1 - minFill)
            {
                int betterGroup = -1, chosen = -1;
                long biggestDiff = -1;
                for (i = 0; i < card; i++)
                {
                    if (taken[i] == 0)
                    {
                        long diff = (Rectangle.JoinArea(group0, b[i]) - groupArea0) - (Rectangle.JoinArea(group1, b[i]) - groupArea1);
                        if (diff > biggestDiff || -diff > biggestDiff)
                        {
                            chosen = i;
                            if (diff < 0)
                            {
                                betterGroup = 0;
                                biggestDiff = -diff;
                            }
                            else
                            {
                                betterGroup = 1;
                                biggestDiff = diff;
                            }
                        }
                    }
                }
                Assert.That(chosen >= 0);
                if (betterGroup == 0)
                {
                    group0.Join(b[chosen]);
                    groupArea0 = group0.Area();
                    taken[chosen] = 1;
                    pg.SetBranch(groupCard0++, b[chosen], branch.GetRaw(chosen));
                }
                else
                {
                    groupCard1 += 1;
                    group1.Join(b[chosen]);
                    groupArea1 = group1.Area();
                    taken[chosen] = 2;
                }
            }

            // If one group gets too full, then remaining rectangle are
            // split between two groups in such way to balance cards of two groups.
            if (groupCard0 + groupCard1 < card + 1)
            {
                for (i = 0; i < card; i++)
                {
                    if (taken[i] == 0)
                    {
                        if (groupCard0 >= groupCard1)
                        {
                            taken[i] = 2;
                            groupCard1 += 1;
                        }
                        else
                        {
                            taken[i] = 1;
                            pg.SetBranch(groupCard0++, b[i], branch.GetRaw(i));
                        }
                    }
                }
            }
            pg.n = groupCard0;
            n = groupCard1;
            for (i = 0, j = 0; i < groupCard1; j++)
            {
                if (taken[j] == 2)
                {
                    SetBranch(i++, b[j], branch.GetRaw(j));
                }
            }
            return pg;
        }
Ejemplo n.º 4
0
 private bool GotoFirstItem(int sp, RtreePage pg)
 {
     for (int i = 0, n = pg.n; i < n; i++)
     {
         if (r.Intersects(pg.b[i]))
         {
             if (sp + 1 == Enclosing_Instance.height || GotoFirstItem(sp + 1, (RtreePage) pg.branch.Get(i)))
             {
                 pageStack[sp] = pg;
                 posStack[sp] = i;
                 return true;
             }
         }
     }
     return false;
 }
Ejemplo n.º 5
0
 internal RtreeEntry(RtreePage pg, int pos)
 {
     this.pg = pg;
     this.pos = pos;
 }
Ejemplo n.º 6
0
        public virtual void Remove(Rectangle r, IPersistent obj)
        {
            if (root == null)
            {
                throw new StorageError(StorageError.KEY_NOT_FOUND);
            }
            ArrayList reinsertList = new ArrayList();
            int reinsertLevel = root.Remove(r, obj, height, reinsertList);
            if (reinsertLevel < 0)
            {
                throw new StorageError(StorageError.KEY_NOT_FOUND);
            }

            for (int i = reinsertList.Count; --i >= 0; )
            {
                RtreePage p = (RtreePage) reinsertList[i];
                for (int j = 0, n2 = p.n; j < n2; j++)
                {
                    RtreePage q = root.Insert(Storage, p.b[j], p.branch.Get(j), height - reinsertLevel);
                    if (q != null)
                    {
                        // root split
                        root = new RtreePage(Storage, root, q);
                        height += 1;
                    }
                }
                reinsertLevel -= 1;
                p.Deallocate();
            }

            if (root.n == 1 && height > 1)
            {
                RtreePage newRoot = (RtreePage) root.branch.Get(0);
                root.Deallocate();
                root = newRoot;
                height -= 1;
            }
            n -= 1;
            updateCounter += 1;
            Modify();
        }
Ejemplo n.º 7
0
 public virtual void Put(Rectangle r, IPersistent obj)
 {
     if (root == null)
     {
         root = new RtreePage(Storage, obj, r);
         height = 1;
     }
     else
     {
         RtreePage p = root.Insert(Storage, r, obj, height);
         if (p != null)
         {
             root = new RtreePage(Storage, root, p);
             height += 1;
         }
     }
     updateCounter += 1;
     n += 1;
     Modify();
 }