public void Put(T obj, int mask) { DatabaseImpl db = (DatabaseImpl)Database; if (db == null) { throw new DatabaseException(DatabaseException.ErrorCode.DELETED_OBJECT); } if (!obj.IsPersistent()) { db.MakePersistent(obj); } Key ins = new Key(mask, obj.Oid); if (root == 0) { root = BitIndexPage.allocate(db, 0, ins); height = 1; } else { OldBtreeResult result = BitIndexPage.insert(db, root, ins, height); if (result == OldBtreeResult.Overflow) { root = BitIndexPage.allocate(db, root, ins); height += 1; } } updateCounter += 1; nElems += 1; Modify(); }
public override bool Remove(T obj) { DatabaseImpl db = (DatabaseImpl)Database; if (db == null) { throw new DatabaseException(DatabaseException.ErrorCode.DELETED_OBJECT); } if (root == 0) { return(false); } OldBtreeResult result = BitIndexPage.remove(db, root, obj.Oid, height); if (result == OldBtreeResult.NotFound) { return(false); } nElems -= 1; if (result == OldBtreeResult.Underflow) { Page pg = db.getPage(root); if (BitIndexPage.getnItems(pg) == 0) { int newRoot = 0; if (height != 1) { newRoot = BitIndexPage.getItem(pg, BitIndexPage.maxItems - 1); } db.freePage(root); root = newRoot; height -= 1; } db.pool.unfix(pg); } updateCounter += 1; Modify(); return(true); }
internal static OldBtreeResult remove(DatabaseImpl db, int pageId, int oid, int height) { Page pg = db.getPage(pageId); try { int i, n = getnItems(pg), l = 0, r = n; if (--height == 0) { while (l < r) { i = (l + r) >> 1; if (oid > getItem(pg, maxItems - 1 - i)) { l = i + 1; } else { r = i; } } if (r < n && getItem(pg, maxItems - r - 1) == oid) { db.pool.unfix(pg); pg = null; pg = db.putPage(pageId); memcpy(pg, r, pg, r + 1, n - r - 1); memcpy(pg, maxItems - n + 1, pg, maxItems - n, n - r - 1); setnItems(pg, --n); return(n < max / 2 ? OldBtreeResult.Underflow : OldBtreeResult.Done); } return(OldBtreeResult.NotFound); } else { while (l < r) { i = (l + r) >> 1; if (oid > getItem(pg, i)) { l = i + 1; } else { r = i; } } OldBtreeResult result = remove(db, getItem(pg, maxItems - r - 1), oid, height); if (result == OldBtreeResult.Underflow) { db.pool.unfix(pg); pg = null; pg = db.putPage(pageId); return(handlePageUnderflow(db, pg, r, height)); } return(result); } } finally { if (pg != null) { db.pool.unfix(pg); } } }
internal static OldBtreeResult insert(DatabaseImpl db, int pageId, Key ins, int height) { Page pg = db.getPage(pageId); int l = 0, n = getnItems(pg), r = n; int oid = ins.oid; try { if (--height != 0) { while (l < r) { int i = (l + r) >> 1; if (oid > getItem(pg, i)) { l = i + 1; } else { r = i; } } Debug.Assert(l == r); /* insert before e[r] */ OldBtreeResult result = insert(db, getItem(pg, maxItems - r - 1), ins, height); Debug.Assert(result != OldBtreeResult.NotFound); if (result != OldBtreeResult.Overflow) { return(result); } n += 1; } else { while (l < r) { int i = (l + r) >> 1; if (oid > getItem(pg, maxItems - 1 - i)) { l = i + 1; } else { r = i; } } if (r < n && oid == getItem(pg, maxItems - 1 - r)) { db.pool.unfix(pg); pg = null; pg = db.putPage(pageId); setItem(pg, r, ins.key); return(OldBtreeResult.Overwrite); } } db.pool.unfix(pg); pg = null; pg = db.putPage(pageId); if (n < max) { memcpy(pg, r + 1, pg, r, n - r); memcpy(pg, maxItems - n - 1, pg, maxItems - n, n - r); setItem(pg, r, ins.key); setItem(pg, maxItems - 1 - r, ins.oid); setnItems(pg, getnItems(pg) + 1); return(OldBtreeResult.Done); } else { /* page is full then divide page */ pageId = db.allocatePage(); Page b = db.putPage(pageId); Debug.Assert(n == max); int m = max / 2; if (r < m) { memcpy(b, 0, pg, 0, r); memcpy(b, r + 1, pg, r, m - r - 1); memcpy(pg, 0, pg, m - 1, max - m + 1); memcpy(b, maxItems - r, pg, maxItems - r, r); setItem(b, r, ins.key); setItem(b, maxItems - 1 - r, ins.oid); memcpy(b, maxItems - m, pg, maxItems - m + 1, m - r - 1); memcpy(pg, maxItems - max + m - 1, pg, maxItems - max, max - m + 1); } else { memcpy(b, 0, pg, 0, m); memcpy(pg, 0, pg, m, r - m); memcpy(pg, r - m + 1, pg, r, max - r); memcpy(b, maxItems - m, pg, maxItems - m, m); memcpy(pg, maxItems - r + m, pg, maxItems - r, r - m); setItem(pg, r - m, ins.key); setItem(pg, maxItems - 1 - r + m, ins.oid); memcpy(pg, maxItems - max + m - 1, pg, maxItems - max, max - r); } ins.oid = pageId; if (height == 0) { ins.key = getItem(b, maxItems - m); setnItems(pg, max - m + 1); setnItems(b, m); } else { ins.key = getItem(b, m - 1); setnItems(pg, max - m); setnItems(b, m - 1); } db.pool.unfix(b); return(OldBtreeResult.Overflow); } } finally { if (pg != null) { db.pool.unfix(pg); } } }