public virtual void Clear() { if (root != null) { root.Purge(height); root = null; } height = 0; n = 0; Modify(); }
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(); } }
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; }
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; }
internal RtreeEntry(RtreePage pg, int pos) { this.pg = pg; this.pos = pos; }
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(); }
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(); }