internal static int TraverseForward(StorageImpl db, int pageId, int type, int height, IPersistent[] result, int pos) { Page pg = db.GetPage(pageId); int oid; try { int i, n = GetItemsCount(pg); if (--height != 0) { if (type == ClassDescriptor.tpString || type == ClassDescriptor.tpArrayOfByte) { // page of strings for (i = 0; i <= n; i++) { pos = TraverseForward(db, GetKeyStrOid(pg, i), type, height, result, pos); } } else { for (i = 0; i <= n; i++) { pos = TraverseForward(db, GetReference(pg, maxItems - i - 1), type, height, result, pos); } } } else { if (type == ClassDescriptor.tpString || type == ClassDescriptor.tpArrayOfByte) { // page of strings for (i = 0; i < n; i++) { oid = GetKeyStrOid(pg, i); result[pos++] = db.LookupObject(oid, null); } } else { // page of scalars for (i = 0; i < n; i++) { oid = GetReference(pg, maxItems - 1 - i); result[pos++] = db.LookupObject(oid, null); } } } return pos; } finally { db.pool.Unfix(pg); } }
internal static bool Find(StorageImpl db, int pageId, Key firstKey, Key lastKey, Btree tree, int height, ArrayList result) { Page pg = db.GetPage(pageId); int l = 0, n = GetItemsCount(pg), r = n; int oid; height -= 1; try { if (tree.type == ClassDescriptor.tpString) { if (firstKey != null) { while (l < r) { int i = (l + r) >> 1; if (CompareStr(firstKey, pg, i) >= firstKey.inclusion) { l = i + 1; } else { r = i; } } Assert.That(r == l); } if (lastKey != null) { if (height == 0) { while (l < n) { if (-CompareStr(lastKey, pg, l) >= lastKey.inclusion) { return false; } oid = GetKeyStrOid(pg, l); result.Add(db.LookupObject(oid, null)); l += 1; } } else { do { if (!Find(db, GetKeyStrOid(pg, l), firstKey, lastKey, tree, height, result)) { return false; } if (l == n) { return true; } } while (CompareStr(lastKey, pg, l++) >= 0); return false; } } else { if (height == 0) { while (l < n) { oid = GetKeyStrOid(pg, l); result.Add(db.LookupObject(oid, null)); l += 1; } } else { do { if (!Find(db, GetKeyStrOid(pg, l), firstKey, lastKey, tree, height, result)) { return false; } } while (++l <= n); } } } else if (tree.type == ClassDescriptor.tpArrayOfByte) { if (firstKey != null) { while (l < r) { int i = (l + r) >> 1; if (tree.CompareByteArrays(firstKey, pg, i) >= firstKey.inclusion) { l = i + 1; } else { r = i; } } Assert.That(r == l); } if (lastKey != null) { if (height == 0) { while (l < n) { if (-tree.CompareByteArrays(lastKey, pg, l) >= lastKey.inclusion) { return false; } oid = GetKeyStrOid(pg, l); result.Add(db.LookupObject(oid, null)); l += 1; } } else { do { if (!Find(db, GetKeyStrOid(pg, l), firstKey, lastKey, tree, height, result)) { return false; } if (l == n) { return true; } } while (tree.CompareByteArrays(lastKey, pg, l++) >= 0); return false; } } else { if (height == 0) { while (l < n) { oid = GetKeyStrOid(pg, l); result.Add(db.LookupObject(oid, null)); l += 1; } } else { do { if (!Find(db, GetKeyStrOid(pg, l), firstKey, lastKey, tree, height, result)) { return false; } } while (++l <= n); } } } else { if (firstKey != null) { while (l < r) { int i = (l + r) >> 1; if (Compare(firstKey, pg, i) >= firstKey.inclusion) { l = i + 1; } else { r = i; } } Assert.That(r == l); } if (lastKey != null) { if (height == 0) { while (l < n) { if (-Compare(lastKey, pg, l) >= lastKey.inclusion) { return false; } oid = GetReference(pg, maxItems - 1 - l); result.Add(db.LookupObject(oid, null)); l += 1; } return true; } else { do { if (!Find(db, GetReference(pg, maxItems - 1 - l), firstKey, lastKey, tree, height, result)) { return false; } if (l == n) { return true; } } while (Compare(lastKey, pg, l++) >= 0); return false; } } if (height == 0) { while (l < n) { oid = GetReference(pg, maxItems - 1 - l); result.Add(db.LookupObject(oid, null)); l += 1; } } else { do { if (!Find(db, GetReference(pg, maxItems - 1 - l), firstKey, lastKey, tree, height, result)) { return false; } } while (++l <= n); } } } finally { db.pool.Unfix(pg); } return true; }
internal static bool PrefixSearch(StorageImpl db, int pageId, char[] key, int height, ArrayList result) { Page pg = db.GetPage(pageId); int l = 0, n = GetItemsCount(pg), r = n; int oid; height -= 1; try { while (l < r) { int i = (l + r) >> 1; if (ComparePrefix(key, pg, i) > 0) { l = i + 1; } else { r = i; } } Assert.That(r == l); if (height == 0) { while (l < n) { if (ComparePrefix(key, pg, l) < 0) { return false; } oid = GetKeyStrOid(pg, l); result.Add(db.LookupObject(oid, null)); l += 1; } } else { do { if (!PrefixSearch(db, GetKeyStrOid(pg, l), key, height, result)) { return false; } if (l == n) { return true; } } while (ComparePrefix(key, pg, l++) >= 0); return false; } } finally { db.pool.Unfix(pg); } return true; }