internal OldBtreeKey(Key key, int oid) { this.key = key; this.oid = oid; }
internal void extract(Page pg, int offs, ClassDescriptor.FieldType type) { byte[] data = pg.data; switch (type) { case ClassDescriptor.FieldType.tpBoolean: key = new Key(data[offs] != 0); break; case ClassDescriptor.FieldType.tpSByte: key = new Key((sbyte)data[offs]); break; case ClassDescriptor.FieldType.tpByte: key = new Key(data[offs]); break; case ClassDescriptor.FieldType.tpShort: key = new Key(Bytes.unpack2(data, offs)); break; case ClassDescriptor.FieldType.tpUShort: key = new Key((ushort)Bytes.unpack2(data, offs)); break; case ClassDescriptor.FieldType.tpChar: key = new Key((char)Bytes.unpack2(data, offs)); break; case ClassDescriptor.FieldType.tpInt: key = new Key(Bytes.unpack4(data, offs)); break; case ClassDescriptor.FieldType.tpEnum: case ClassDescriptor.FieldType.tpUInt: case ClassDescriptor.FieldType.tpObject: case ClassDescriptor.FieldType.tpOid: key = new Key((uint)Bytes.unpack4(data, offs)); break; case ClassDescriptor.FieldType.tpLong: key = new Key(Bytes.unpack8(data, offs)); break; case ClassDescriptor.FieldType.tpDate: case ClassDescriptor.FieldType.tpULong: key = new Key((ulong)Bytes.unpack8(data, offs)); break; case ClassDescriptor.FieldType.tpFloat: key = new Key(Bytes.unpackF4(data, offs)); break; case ClassDescriptor.FieldType.tpDouble: key = new Key(Bytes.unpackF8(data, offs)); break; case ClassDescriptor.FieldType.tpGuid: key = new Key(Bytes.unpackGuid(data, offs)); break; case ClassDescriptor.FieldType.tpDecimal: key = new Key(Bytes.unpackDecimal(data, offs)); break; default: Debug.Assert(false, "Invalid type"); break; } }
internal void getByteArray(Page pg, int i) { int len = OldBtreePage.getKeyStrSize(pg, i); int offs = OldBtreePage.firstKeyOffs + OldBtreePage.getKeyStrOffs(pg, i); byte[] bval = new byte[len]; Array.Copy(pg.data, offs, bval, 0, len); key = new Key(bval); }
internal void getStr(Page pg, int i) { int len = OldBtreePage.getKeyStrSize(pg, i); int offs = OldBtreePage.firstKeyOffs + OldBtreePage.getKeyStrOffs(pg, i); char[] sval = new char[len]; for (int j = 0; j < len; j++) { sval[j] = (char)Bytes.unpack2(pg.data, offs); offs += 2; } key = new Key(sval); }
internal static bool find(DatabaseImpl db, int pageId, Key firstKey, Key lastKey, OldBtree tree, int height, ArrayList result) { Page pg = db.getPage(pageId); int l = 0, n = getnItems(pg), r = n; int oid; height -= 1; try { if (tree.FieldType == ClassDescriptor.FieldType.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; } Debug.Assert(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.FieldType == ClassDescriptor.FieldType.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; } Debug.Assert(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; } Debug.Assert(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 int compareStr(Key key, Page pg, int i) { char[] chars = null; string s = key.oval as string; if (s != null) chars = s.ToCharArray(); else chars = (char[])key.oval; int alen = chars.Length; int blen = OldBtreePage.getKeyStrSize(pg, i); int minlen = alen < blen ? alen : blen; int offs = OldBtreePage.getKeyStrOffs(pg, i) + OldBtreePage.firstKeyOffs; byte[] b = pg.data; for (int j = 0; j < minlen; j++) { int diff = chars[j] - (char)Bytes.unpack2(b, offs); if (diff != 0) return diff; offs += 2; } return alen - blen; }
internal static int compare(Key key, Page pg, int i) { long i8; ulong u8; int i4; uint u4; float r4; double r8; switch (key.type) { case ClassDescriptor.FieldType.tpSByte: return (sbyte)key.ival - (sbyte)pg.data[OldBtreePage.firstKeyOffs + i]; case ClassDescriptor.FieldType.tpBoolean: case ClassDescriptor.FieldType.tpByte: return (byte)key.ival - pg.data[OldBtreePage.firstKeyOffs + i]; case ClassDescriptor.FieldType.tpShort: return (short)key.ival - Bytes.unpack2(pg.data, OldBtreePage.firstKeyOffs + i * 2); case ClassDescriptor.FieldType.tpUShort: return (ushort)key.ival - (ushort)Bytes.unpack2(pg.data, OldBtreePage.firstKeyOffs + i * 2); case ClassDescriptor.FieldType.tpChar: return (char)key.ival - (char)Bytes.unpack2(pg.data, OldBtreePage.firstKeyOffs + i * 2); case ClassDescriptor.FieldType.tpObject: case ClassDescriptor.FieldType.tpUInt: case ClassDescriptor.FieldType.tpOid: case ClassDescriptor.FieldType.tpEnum: u4 = (uint)Bytes.unpack4(pg.data, OldBtreePage.firstKeyOffs + i * 4); return (uint)key.ival < u4 ? -1 : (uint)key.ival == u4 ? 0 : 1; case ClassDescriptor.FieldType.tpInt: i4 = Bytes.unpack4(pg.data, OldBtreePage.firstKeyOffs + i * 4); return key.ival < i4 ? -1 : key.ival == i4 ? 0 : 1; case ClassDescriptor.FieldType.tpLong: i8 = Bytes.unpack8(pg.data, OldBtreePage.firstKeyOffs + i * 8); return key.lval < i8 ? -1 : key.lval == i8 ? 0 : 1; case ClassDescriptor.FieldType.tpDate: case ClassDescriptor.FieldType.tpULong: u8 = (ulong)Bytes.unpack8(pg.data, OldBtreePage.firstKeyOffs + i * 8); return (ulong)key.lval < u8 ? -1 : (ulong)key.lval == u8 ? 0 : 1; case ClassDescriptor.FieldType.tpFloat: r4 = Bytes.unpackF4(pg.data, OldBtreePage.firstKeyOffs + i * 4); return key.dval < r4 ? -1 : key.dval == r4 ? 0 : 1; case ClassDescriptor.FieldType.tpDouble: r8 = Bytes.unpackF8(pg.data, OldBtreePage.firstKeyOffs + i * 8); return key.dval < r8 ? -1 : key.dval == r8 ? 0 : 1; case ClassDescriptor.FieldType.tpDecimal: return key.dec.CompareTo(Bytes.unpackDecimal(pg.data, OldBtreePage.firstKeyOffs + i * 16)); case ClassDescriptor.FieldType.tpGuid: return key.guid.CompareTo(Bytes.unpackGuid(pg.data, OldBtreePage.firstKeyOffs + i * 16)); } Debug.Assert(false, "Invalid type"); return 0; }
public void Run(TestConfig config) { int count = config.Count; var res = new TestEnumeratorResult(); config.Result = res; var start = DateTime.Now; IDatabase db = config.GetDatabase(); Indices root = (Indices)db.Root; Tests.Assert(root == null); root = new Indices(); root.strIndex = db.CreateIndex<string, Record>(IndexType.NonUnique); root.intIndex = db.CreateIndex<long, Record>(IndexType.NonUnique); db.Root = root; IIndex<long, Record> intIndex = root.intIndex; IIndex<string, Record> strIndex = root.strIndex; Record[] records; long key = 1999; int i, j; for (i = 0; i < count; i++) { key = (3141592621L * key + 2718281829L) % 1000000007L; Record rec = new Record(); rec.intKey = key; rec.strKey = Convert.ToString(key); for (j = (int)(key % 10); --j >= 0; ) { intIndex[rec.intKey] = rec; strIndex[rec.strKey] = rec; } } db.Commit(); res.InsertTime = DateTime.Now - start; start = DateTime.Now; key = 1999; for (i = 0; i < count; i++) { key = (3141592621L * key + 2718281829L) % 1000000007L; Key fromInclusive = new Key(key); Key fromInclusiveStr = new Key(Convert.ToString(key)); Key fromExclusive = new Key(key, false); Key fromExclusiveStr = new Key(Convert.ToString(key), false); key = (3141592621L * key + 2718281829L) % 1000000007L; Key tillInclusive = new Key(key); Key tillInclusiveStr = new Key(Convert.ToString(key)); Key tillExclusive = new Key(key, false); Key tillExclusiveStr = new Key(Convert.ToString(key), false); // int key ascent order records = intIndex.Get(fromInclusive, tillInclusive); j = 0; foreach (Record rec in intIndex.Range(fromInclusive, tillInclusive, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = intIndex.Get(fromInclusive, tillExclusive); j = 0; foreach (Record rec in intIndex.Range(fromInclusive, tillExclusive, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = intIndex.Get(fromExclusive, tillInclusive); j = 0; foreach (Record rec in intIndex.Range(fromExclusive, tillInclusive, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = intIndex.Get(fromExclusive, tillExclusive); j = 0; foreach (Record rec in intIndex.Range(fromExclusive, tillExclusive, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = intIndex.Get(fromInclusive, null); j = 0; foreach (Record rec in intIndex.Range(fromInclusive, null, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = intIndex.Get(fromExclusive, null); j = 0; foreach (Record rec in intIndex.Range(fromExclusive, null, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = intIndex.Get(null, tillInclusive); j = 0; foreach (Record rec in intIndex.Range(null, tillInclusive, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = intIndex.Get(null, tillExclusive); j = 0; foreach (Record rec in intIndex.Range(null, tillExclusive, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = intIndex.ToArray(); j = 0; foreach (Record rec in intIndex) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); // int key descent order records = intIndex.Get(fromInclusive, tillInclusive); j = records.Length; foreach (Record rec in intIndex.Range(fromInclusive, tillInclusive, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = intIndex.Get(fromInclusive, tillExclusive); j = records.Length; foreach (Record rec in intIndex.Range(fromInclusive, tillExclusive, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = intIndex.Get(fromExclusive, tillInclusive); j = records.Length; foreach (Record rec in intIndex.Range(fromExclusive, tillInclusive, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = intIndex.Get(fromExclusive, tillExclusive); j = records.Length; foreach (Record rec in intIndex.Range(fromExclusive, tillExclusive, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = intIndex.Get(fromInclusive, null); j = records.Length; foreach (Record rec in intIndex.Range(fromInclusive, null, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = intIndex.Get(fromExclusive, null); j = records.Length; foreach (Record rec in intIndex.Range(fromExclusive, null, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = intIndex.Get(null, tillInclusive); j = records.Length; foreach (Record rec in intIndex.Range(null, tillInclusive, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = intIndex.Get(null, tillExclusive); j = records.Length; foreach (Record rec in intIndex.Range(null, tillExclusive, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = intIndex.ToArray(); j = records.Length; foreach (Record rec in intIndex.Reverse()) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); // str key ascent order records = strIndex.Get(fromInclusiveStr, tillInclusiveStr); j = 0; foreach (Record rec in strIndex.Range(fromInclusiveStr, tillInclusiveStr, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = strIndex.Get(fromInclusiveStr, tillExclusiveStr); j = 0; foreach (Record rec in strIndex.Range(fromInclusiveStr, tillExclusiveStr, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = strIndex.Get(fromExclusiveStr, tillInclusiveStr); j = 0; foreach (Record rec in strIndex.Range(fromExclusiveStr, tillInclusiveStr, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = strIndex.Get(fromExclusiveStr, tillExclusiveStr); j = 0; foreach (Record rec in strIndex.Range(fromExclusiveStr, tillExclusiveStr, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = strIndex.Get(fromInclusiveStr, null); j = 0; foreach (Record rec in strIndex.Range(fromInclusiveStr, null, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = strIndex.Get(fromExclusiveStr, null); j = 0; foreach (Record rec in strIndex.Range(fromExclusiveStr, null, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = strIndex.Get(null, tillInclusiveStr); j = 0; foreach (Record rec in strIndex.Range(null, tillInclusiveStr, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = strIndex.Get(null, tillExclusiveStr); j = 0; foreach (Record rec in strIndex.Range(null, tillExclusiveStr, IterationOrder.AscentOrder)) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); records = strIndex.ToArray(); j = 0; foreach (Record rec in strIndex) { Tests.Assert(rec == records[j++]); } Tests.Assert(j == records.Length); // str key descent order records = strIndex.Get(fromInclusiveStr, tillInclusiveStr); j = records.Length; foreach (Record rec in strIndex.Range(fromInclusiveStr, tillInclusiveStr, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = strIndex.Get(fromInclusiveStr, tillExclusiveStr); j = records.Length; foreach (Record rec in strIndex.Range(fromInclusiveStr, tillExclusiveStr, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = strIndex.Get(fromExclusiveStr, tillInclusiveStr); j = records.Length; foreach (Record rec in strIndex.Range(fromExclusiveStr, tillInclusiveStr, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = strIndex.Get(fromExclusiveStr, tillExclusiveStr); j = records.Length; foreach (Record rec in strIndex.Range(fromExclusiveStr, tillExclusiveStr, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = strIndex.Get(fromInclusiveStr, null); j = records.Length; foreach (Record rec in strIndex.Range(fromInclusiveStr, null, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = strIndex.Get(fromExclusiveStr, null); j = records.Length; foreach (Record rec in strIndex.Range(fromExclusiveStr, null, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = strIndex.Get(null, tillInclusiveStr); j = records.Length; foreach (Record rec in strIndex.Range(null, tillInclusiveStr, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = strIndex.Get(null, tillExclusiveStr); j = records.Length; foreach (Record rec in strIndex.Range(null, tillExclusiveStr, IterationOrder.DescentOrder)) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); records = strIndex.ToArray(); j = records.Length; foreach (Record rec in strIndex.Reverse()) { Tests.Assert(rec == records[--j]); } Tests.Assert(j == 0); } res.IterationTime = DateTime.Now - start; strIndex.Clear(); intIndex.Clear(); Tests.Assert(!strIndex.GetEnumerator().MoveNext()); Tests.Assert(!intIndex.GetEnumerator().MoveNext()); Tests.Assert(!strIndex.Reverse().GetEnumerator().MoveNext()); Tests.Assert(!intIndex.Reverse().GetEnumerator().MoveNext()); db.Commit(); db.Gc(); db.Close(); }
public void Run(TestConfig config) { int count = config.Count; var res = new TestResult(); config.Result = res; IDatabase db = config.GetDatabase(); Root root = (Root)db.Root; Tests.Assert(null == root); root = new Root(); root.strIndex = db.CreateIndex<string, Record>(IndexType.Unique); db.Root = root; string[] strs = new string[] { "one", "two", "three", "four" }; int no = 0; for (var i = 0; i < count; i++) { foreach (string s in strs) { var s2 = String.Format("{0}-{1}", s, i); Record o = new Record(); o.strKey = s2; o.intKey = no++; root.strIndex[s2] = o; } } db.Commit(); // Test that modyfing an index while traversing it throws an exception // Tests Btree.BtreeEnumerator long n = -1; Tests.AssertException<InvalidOperationException>( () => { foreach (Record r in root.strIndex) { n = r.intKey; var i = n % strs.Length; var j = n / strs.Length; var sBase = strs[i]; var expectedStr = String.Format("{0}-{1}", sBase, j); string s = r.strKey; Tests.Assert(s == expectedStr); if (n == 0) { Record o = new Record(); o.strKey = "five"; o.intKey = 5; root.strIndex[o.strKey] = o; } } }); Tests.Assert(n == 0); // Test that modyfing an index while traversing it throws an exception // Tests Btree.BtreeSelectionIterator Key keyStart = new Key("four", true); Key keyEnd = new Key("three", true); Tests.AssertException<InvalidOperationException>(() => { foreach (Record r in root.strIndex.Range(keyStart, keyEnd, IterationOrder.AscentOrder)) { n = r.intKey; var i = n % strs.Length; var j = n / strs.Length; var sBase = strs[i]; var expectedStr = String.Format("{0}-{1}", sBase, j); string s = r.strKey; Tests.Assert(s == expectedStr); Record o = new Record(); o.strKey = "six"; o.intKey = 6; root.strIndex[o.strKey] = o; } }); db.Close(); }