internal int balanceRightBranch(ref TtreePage pgRef) { if (balance > 0) { balance = 0; return(UNDERFLOW); } else if (balance == 0) { balance = -1; return(OK); } else { TtreePage lp = this.left; lp.Load(); lp.Modify(); if (lp.balance <= 0) { // single LL turn this.left = lp.right; lp.right = this; if (lp.balance == 0) { balance = -1; lp.balance = 1; pgRef = lp; return(OK); } else { balance = 0; lp.balance = 0; pgRef = lp; return(UNDERFLOW); } } else { // double LR turn TtreePage rp = lp.right; rp.Load(); rp.Modify(); lp.right = rp.left; rp.left = lp; this.left = rp.right; rp.right = this; balance = rp.balance < 0 ? 1 : 0; lp.balance = rp.balance > 0 ? -1 : 0; rp.balance = 0; pgRef = rp; return(UNDERFLOW); } } }
internal int insert(PersistentComparator comparator, IPersistent mbr, bool unique, ref TtreePage pgRef) { Load(); int n = nItems; TtreePage pg; int diff = comparator.CompareMembers(mbr, loadItem(0)); if (diff <= 0) { if (unique && diff == 0) { return(NOT_UNIQUE); } if ((left == null || diff == 0) && n != maxItems) { Modify(); //for (int i = n; i > 0; i--) item[i] = item[i-1]; Array.Copy(item, 0, item, 1, n); item[0] = mbr; nItems += 1; return(OK); } if (left == null) { Modify(); left = new TtreePage(mbr); } else { pg = pgRef; pgRef = left; int result = left.insert(comparator, mbr, unique, ref pgRef); if (result == NOT_UNIQUE) { return(NOT_UNIQUE); } Modify(); left = pgRef; pgRef = pg; if (result == OK) { return(OK); } } if (balance > 0) { balance = 0; return(OK); } else if (balance == 0) { balance = -1; return(OVERFLOW); } else { TtreePage lp = this.left; lp.Load(); lp.Modify(); if (lp.balance < 0) { // single LL turn this.left = lp.right; lp.right = this; balance = 0; lp.balance = 0; pgRef = lp; } else { // double LR turn TtreePage rp = lp.right; rp.Load(); rp.Modify(); lp.right = rp.left; rp.left = lp; this.left = rp.right; rp.right = this; balance = (rp.balance < 0) ? 1 : 0; lp.balance = (rp.balance > 0) ? -1 : 0; rp.balance = 0; pgRef = rp; } return(OK); } } diff = comparator.CompareMembers(mbr, loadItem(n - 1)); if (diff >= 0) { if (unique && diff == 0) { return(NOT_UNIQUE); } if ((right == null || diff == 0) && n != maxItems) { Modify(); item[n] = mbr; nItems += 1; return(OK); } if (right == null) { Modify(); right = new TtreePage(mbr); } else { pg = pgRef; pgRef = right; int result = right.insert(comparator, mbr, unique, ref pgRef); if (result == NOT_UNIQUE) { return(NOT_UNIQUE); } Modify(); right = pgRef; pgRef = pg; if (result == OK) { return(OK); } } if (balance < 0) { balance = 0; return(OK); } else if (balance == 0) { balance = 1; return(OVERFLOW); } else { TtreePage rp = this.right; rp.Load(); rp.Modify(); if (rp.balance > 0) { // single RR turn this.right = rp.left; rp.left = this; balance = 0; rp.balance = 0; pgRef = rp; } else { // double RL turn TtreePage lp = rp.left; lp.Load(); lp.Modify(); rp.left = lp.right; lp.right = rp; this.right = lp.left; lp.left = this; balance = (lp.balance > 0) ? -1 : 0; rp.balance = (lp.balance < 0) ? 1 : 0; lp.balance = 0; pgRef = lp; } return(OK); } } int l = 1, r = n - 1; while (l < r) { int i = (l + r) >> 1; diff = comparator.CompareMembers(mbr, loadItem(i)); if (diff > 0) { l = i + 1; } else { r = i; if (diff == 0) { if (unique) { return(NOT_UNIQUE); } break; } } } // Insert before item[r] Modify(); if (n != maxItems) { Array.Copy(item, r, item, r + 1, n - r); //for (int i = n; i > r; i--) item[i] = item[i-1]; item[r] = mbr; nItems += 1; return(OK); } else { IPersistent reinsertItem; if (balance >= 0) { reinsertItem = loadItem(0); Array.Copy(item, 1, item, 0, r - 1); //for (int i = 1; i < r; i++) item[i-1] = item[i]; item[r - 1] = mbr; } else { reinsertItem = loadItem(n - 1); Array.Copy(item, r, item, r + 1, n - r - 1); //for (int i = n-1; i > r; i--) item[i] = item[i-1]; item[r] = mbr; } return(insert(comparator, reinsertItem, unique, ref pgRef)); } }