Class for specifying key value (neededd to access object by key usig index)
Пример #1
0
 internal OldBtreeKey(Key key, int oid)
 {
     this.key = key;
     this.oid = oid;
 }
Пример #2
0
        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;

            }
        }
Пример #3
0
 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);
 }
Пример #4
0
 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);
 }
Пример #5
0
        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;
        }
Пример #6
0
 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;
 }
Пример #7
0
        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;
        }
Пример #8
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();
        }
Пример #9
0
        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();
        }