示例#1
0
        public void Run(TestConfig config)
        {
            int count = config.Count;
            var res   = new TestIndexResult();

            config.Result = res;
            IDatabase db = config.GetDatabase();

            if (config.Serializable)
            {
                db.BeginThreadTransaction(TransactionMode.Serializable);
            }

            Root root = (Root)db.Root;

            Tests.Assert(null == root);
            root           = new Root();
            root.strIndex  = db.CreateIndex <string, RecordFull>(IndexType.Unique);
            root.longIndex = db.CreateIndex <long, RecordFull>(IndexType.Unique);
            db.Root        = root;
            var strIndex = root.strIndex;

            Tests.Assert(typeof(string) == strIndex.KeyType);
            var longIndex = root.longIndex;

            Tests.Assert(typeof(long) == longIndex.KeyType);
            DateTime start         = DateTime.Now;
            int      startWithOne  = 0;
            int      startWithFive = 0;
            string   strFirst      = "z";
            string   strLast       = "0";

            int n = 0;

            foreach (var key in Tests.KeySeq(count))
            {
                RecordFull rec = new RecordFull(key);
                if (rec.StrVal[0] == '1')
                {
                    startWithOne += 1;
                }
                else if (rec.StrVal[0] == '5')
                {
                    startWithFive += 1;
                }
                if (rec.StrVal.CompareTo(strFirst) < 0)
                {
                    strFirst = rec.StrVal;
                }
                else if (rec.StrVal.CompareTo(strLast) > 0)
                {
                    strLast = rec.StrVal;
                }
                longIndex[rec.Int32Val] = rec;
                strIndex[rec.StrVal]    = rec;
                n++;
                if (n % 100 == 0)
                {
                    MyCommit(db, config.Serializable);
                }
            }
            MyCommit(db, config.Serializable);

            Tests.Assert(longIndex.Count == count);
            Tests.Assert(strIndex.Count == count);

            res.InsertTime = DateTime.Now - start;
            start          = System.DateTime.Now;

            foreach (var key in Tests.KeySeq(count))
            {
                RecordFull rec1 = longIndex[key];
                RecordFull rec2 = strIndex[Convert.ToString(key)];
                Tests.Assert(rec1 != null && rec2 != null);
                Tests.Assert(rec1 == rec2);
            }
            res.IndexSearchTime = DateTime.Now - start;
            start = System.DateTime.Now;

            var k = Int64.MinValue;

            n = 0;
            foreach (RecordFull rec in longIndex)
            {
                Tests.Assert(rec.Int32Val >= k);
                k  = rec.Int32Val;
                n += 1;
            }
            Tests.Assert(n == count);

            String strKey = "";

            n = 0;
            foreach (RecordFull rec in strIndex)
            {
                Tests.Assert(rec.StrVal.CompareTo(strKey) >= 0);
                strKey = rec.StrVal;
                n     += 1;
            }
            Tests.Assert(n == count);
            res.IterationTime = DateTime.Now - start;
            start             = System.DateTime.Now;

            IDictionaryEnumerator de = longIndex.GetDictionaryEnumerator();

            n = VerifyDictionaryEnumerator(de, IterationOrder.AscentOrder);
            Tests.Assert(n == count);

            long mid = 0;
            long max = long.MaxValue;

            de = longIndex.GetDictionaryEnumerator(new Key(mid), new Key(max), IterationOrder.DescentOrder);
            VerifyDictionaryEnumerator(de, IterationOrder.DescentOrder);

            Tests.AssertDatabaseException(() => longIndex.PrefixSearch("1"),
                                          DatabaseException.ErrorCode.INCOMPATIBLE_KEY_TYPE);
            RecordFull[] recs = strIndex.PrefixSearch("1");
            Tests.Assert(startWithOne == recs.Length);
            foreach (var r in recs)
            {
                Tests.Assert(r.StrVal.StartsWith("1"));
            }
            recs = strIndex.PrefixSearch("5");
            Tests.Assert(startWithFive == recs.Length);
            foreach (var r in recs)
            {
                Tests.Assert(r.StrVal.StartsWith("5"));
            }
            recs = strIndex.PrefixSearch("0");
            Tests.Assert(0 == recs.Length);

            recs = strIndex.PrefixSearch("a");
            Tests.Assert(0 == recs.Length);

            recs = strIndex.PrefixSearch(strFirst);
            Tests.Assert(recs.Length >= 1);
            Tests.Assert(recs[0].StrVal == strFirst);
            foreach (var r in recs)
            {
                Tests.Assert(r.StrVal.StartsWith(strFirst));
            }

            recs = strIndex.PrefixSearch(strLast);
            Tests.Assert(recs.Length == 1);
            Tests.Assert(recs[0].StrVal == strLast);

            n = 0;
            RecordFull oneRemoved = null;

            foreach (var key in Tests.KeySeq(count))
            {
                n++;
                if (n % 3 == 0)
                {
                    continue;
                }
                RecordFull rec     = longIndex.Get(key);
                RecordFull removed = longIndex.RemoveKey(key);
                Tests.Assert(removed == rec);
                strIndex.Remove(new Key(System.Convert.ToString(key)), rec);
                Tests.Assert(!strIndex.Contains(removed));
                if (null == oneRemoved)
                {
                    oneRemoved = removed;
                }
            }
            db.Rollback();
            //TODO: shouldn't this be true?
            //Tests.Assert(strIndex.Contains(oneRemoved));

            res.RemoveTime = DateTime.Now - start;
            db.Close();
            if (config.IsTransient)
            {
                return;
            }

            db        = config.GetDatabase(false);
            root      = (Root)db.Root;
            longIndex = root.longIndex;
            strIndex  = root.strIndex;
            k         = Int64.MinValue;
            n         = 0;
            RecordFull firstRec   = null;
            RecordFull removedRec = null;

            foreach (RecordFull rec in longIndex)
            {
                Tests.Assert(rec.Int32Val >= k);
                k = rec.Int32Val;
                if (null == firstRec)
                {
                    firstRec = rec;
                }
                else if (null == removedRec)
                {
                    removedRec = rec;
                    strIndex.Remove(removedRec.StrVal, removedRec);
                }
                n++;
            }
            Tests.Assert(longIndex.Count == n);
            Tests.Assert(strIndex.Count == n - 1);
            Tests.Assert(longIndex.Contains(firstRec));
            Tests.Assert(strIndex.Contains(firstRec));
            Tests.Assert(!strIndex.Contains(removedRec));
            RecordFull notPresent = new RecordFull();

            Tests.Assert(!strIndex.Contains(notPresent));
            Tests.Assert(!longIndex.Contains(notPresent));
            longIndex.Clear();
            Tests.Assert(!longIndex.Contains(firstRec));
            db.Close();
        }
示例#2
0
文件: TestIndex.cs 项目: kjk/volante
        public void Run(TestConfig config)
        {
            int count = config.Count;
            var res = new TestIndexResult();
            config.Result = res;
            IDatabase db = config.GetDatabase();
            if (config.Serializable)
                db.BeginThreadTransaction(TransactionMode.Serializable);

            Root root = (Root)db.Root;
            Tests.Assert(null == root);
            root = new Root();
            root.strIndex = db.CreateIndex<string, RecordFull>(IndexType.Unique);
            root.longIndex = db.CreateIndex<long, RecordFull>(IndexType.Unique);
            db.Root = root;
            var strIndex = root.strIndex;
            Tests.Assert(typeof(string) == strIndex.KeyType);
            var longIndex = root.longIndex;
            Tests.Assert(typeof(long) == longIndex.KeyType);
            DateTime start = DateTime.Now;
            int startWithOne = 0;
            int startWithFive = 0;
            string strFirst = "z";
            string strLast  = "0";

            int n = 0;
            foreach (var key in Tests.KeySeq(count))
            {
                RecordFull rec = new RecordFull(key);
                if (rec.StrVal[0] == '1')
                    startWithOne += 1;
                else if (rec.StrVal[0] == '5')
                    startWithFive += 1;
                if (rec.StrVal.CompareTo(strFirst) < 0)
                    strFirst = rec.StrVal;
                else if (rec.StrVal.CompareTo(strLast) > 0)
                    strLast = rec.StrVal;
                longIndex[rec.Int32Val] = rec;
                strIndex[rec.StrVal] = rec;
                n++;
                if (n % 100 == 0)
                    MyCommit(db, config.Serializable);
            }
            MyCommit(db, config.Serializable);

            Tests.Assert(longIndex.Count == count);
            Tests.Assert(strIndex.Count == count);

            res.InsertTime = DateTime.Now - start;
            start = System.DateTime.Now;

            foreach (var key in Tests.KeySeq(count))
            {
                RecordFull rec1 = longIndex[key];
                RecordFull rec2 = strIndex[Convert.ToString(key)];
                Tests.Assert(rec1 != null && rec2 != null);
                Tests.Assert(rec1 == rec2);
            }
            res.IndexSearchTime = DateTime.Now - start;
            start = System.DateTime.Now;

            var k = Int64.MinValue;
            n = 0;
            foreach (RecordFull rec in longIndex)
            {
                Tests.Assert(rec.Int32Val >= k);
                k = rec.Int32Val;
                n += 1;
            }
            Tests.Assert(n == count);

            String strKey = "";
            n = 0;
            foreach (RecordFull rec in strIndex)
            {
                Tests.Assert(rec.StrVal.CompareTo(strKey) >= 0);
                strKey = rec.StrVal;
                n += 1;
            }
            Tests.Assert(n == count);
            res.IterationTime = DateTime.Now - start;
            start = System.DateTime.Now;

            IDictionaryEnumerator de = longIndex.GetDictionaryEnumerator();
            n = VerifyDictionaryEnumerator(de, IterationOrder.AscentOrder);
            Tests.Assert(n == count);

            long mid = 0;
            long max = long.MaxValue;
            de = longIndex.GetDictionaryEnumerator(new Key(mid), new Key(max), IterationOrder.DescentOrder);
            VerifyDictionaryEnumerator(de, IterationOrder.DescentOrder);

            Tests.AssertDatabaseException(() => longIndex.PrefixSearch("1"),
                DatabaseException.ErrorCode.INCOMPATIBLE_KEY_TYPE);
            RecordFull[] recs = strIndex.PrefixSearch("1");
            Tests.Assert(startWithOne == recs.Length);
            foreach (var r in recs)
            {
                Tests.Assert(r.StrVal.StartsWith("1"));
            }
            recs = strIndex.PrefixSearch("5");
            Tests.Assert(startWithFive == recs.Length);
            foreach (var r in recs)
            {
                Tests.Assert(r.StrVal.StartsWith("5"));
            }
            recs = strIndex.PrefixSearch("0");
            Tests.Assert(0 == recs.Length);

            recs = strIndex.PrefixSearch("a");
            Tests.Assert(0 == recs.Length);

            recs = strIndex.PrefixSearch(strFirst);
            Tests.Assert(recs.Length >= 1);
            Tests.Assert(recs[0].StrVal == strFirst);
            foreach (var r in recs)
            {
                Tests.Assert(r.StrVal.StartsWith(strFirst));
            }

            recs = strIndex.PrefixSearch(strLast);
            Tests.Assert(recs.Length == 1);
            Tests.Assert(recs[0].StrVal == strLast);

            n = 0;
            RecordFull oneRemoved = null;
            foreach (var key in Tests.KeySeq(count))
            {
                n++;
                if (n % 3 == 0)
                    continue;
                RecordFull rec = longIndex.Get(key);
                RecordFull removed = longIndex.RemoveKey(key);
                Tests.Assert(removed == rec);
                strIndex.Remove(new Key(System.Convert.ToString(key)), rec);
                Tests.Assert(!strIndex.Contains(removed));
                if (null == oneRemoved)
                    oneRemoved = removed;
            }
            db.Rollback();
            //TODO: shouldn't this be true?
            //Tests.Assert(strIndex.Contains(oneRemoved));

            res.RemoveTime = DateTime.Now - start;
            db.Close();
            if (config.IsTransient)
                return;

            db = config.GetDatabase(false);
            root = (Root)db.Root;
            longIndex = root.longIndex;
            strIndex = root.strIndex;
            k = Int64.MinValue;
            n = 0;
            RecordFull firstRec = null;
            RecordFull removedRec = null;
            foreach (RecordFull rec in longIndex)
            {
                Tests.Assert(rec.Int32Val >= k);
                k = rec.Int32Val;
                if (null == firstRec)
                    firstRec = rec;
                else if (null == removedRec)
                {
                    removedRec = rec;
                    strIndex.Remove(removedRec.StrVal, removedRec);
                }
                n++;
            }
            Tests.Assert(longIndex.Count == n);
            Tests.Assert(strIndex.Count == n-1);
            Tests.Assert(longIndex.Contains(firstRec));
            Tests.Assert(strIndex.Contains(firstRec));
            Tests.Assert(!strIndex.Contains(removedRec));
            RecordFull notPresent = new RecordFull();
            Tests.Assert(!strIndex.Contains(notPresent));
            Tests.Assert(!longIndex.Contains(notPresent));
            longIndex.Clear();
            Tests.Assert(!longIndex.Contains(firstRec));
            db.Close();
        }
示例#3
0
        public void Run(TestConfig config)
        {
            int count = config.Count;
            var res   = new TestIndexResult();

            config.Result = res;
            IDatabase db = config.GetDatabase();

            Root root = (Root)db.Root;

            Tests.Assert(null == root);
            root         = new Root();
            root.strIdx  = db.CreateThickIndex <string, RecordFull>();
            root.byteIdx = db.CreateThickIndex <byte, RecordFull>();
            db.Root      = root;
            Tests.Assert(typeof(string) == root.strIdx.KeyType);
            Tests.Assert(typeof(byte) == root.byteIdx.KeyType);

            int    startWithOne  = 0;
            int    startWithFive = 0;
            string strFirst      = "z";
            string strLast       = "0";

            int n            = 0;
            var inThickIndex = new Dictionary <byte, List <RecordFull> >();

            foreach (var key in Tests.KeySeq(count))
            {
                RecordFull rec = new RecordFull(key);
                if (rec.StrVal[0] == '1')
                {
                    startWithOne += 1;
                }
                else if (rec.StrVal[0] == '5')
                {
                    startWithFive += 1;
                }
                if (rec.StrVal.CompareTo(strFirst) < 0)
                {
                    strFirst = rec.StrVal;
                }
                else if (rec.StrVal.CompareTo(strLast) > 0)
                {
                    strLast = rec.StrVal;
                }
                root.strIdx.Put(rec.StrVal, rec);
                root.byteIdx.Put(rec.ByteVal, rec);
                n++;
                if (n % 100 == 0)
                {
                    db.Commit();
                }
                ;
            }
            db.Commit();

            Tests.Assert(root.strIdx.Count == count);
            Tests.Assert(root.byteIdx.Count <= count);

            Tests.AssertDatabaseException(() =>
                                          { root.strIdx.RemoveKey(""); },
                                          DatabaseException.ErrorCode.KEY_NOT_UNIQUE);

            Tests.AssertDatabaseException(() =>
                                          { root.strIdx.Remove(new Key("")); },
                                          DatabaseException.ErrorCode.KEY_NOT_UNIQUE);

            foreach (var mk in inThickIndex.Keys)
            {
                var list = inThickIndex[mk];
                while (list.Count > 1)
                {
                    var el = list[0];
                    list.Remove(el);
                    root.byteIdx.Remove(el.ByteVal, el);
                }
            }

            RecordFull[] recs;
            foreach (var key in Tests.KeySeq(count))
            {
                RecordFull rec1 = root.strIdx[Convert.ToString(key)];
                recs = root.byteIdx[rec1.ByteVal, rec1.ByteVal];
                Tests.Assert(rec1 != null && recs.Length >= 1);
                Tests.Assert(rec1.ByteVal == recs[0].ByteVal);
            }

            // test for non-existent key
            Tests.Assert(null == root.strIdx.Get("-122"));

            recs = root.byteIdx.ToArray();
            Tests.Assert(recs.Length == root.byteIdx.Count);

            var prevByte = byte.MinValue;

            n = 0;
            foreach (RecordFull rec in root.byteIdx)
            {
                Tests.Assert(rec.ByteVal >= prevByte);
                prevByte = rec.ByteVal;
                n       += 1;
            }
            Tests.Assert(n == count);

            String prevStrKey = "";

            n = 0;
            foreach (RecordFull rec in  root.strIdx)
            {
                Tests.Assert(rec.StrVal.CompareTo(prevStrKey) >= 0);
                prevStrKey = rec.StrVal;
                n         += 1;
            }
            IDictionaryEnumerator de = root.strIdx.GetDictionaryEnumerator();

            n = VerifyDictionaryEnumerator(de, IterationOrder.AscentOrder);
            Tests.Assert(n == count);

            string mid = "0";
            string max = long.MaxValue.ToString();;

            de = root.strIdx.GetDictionaryEnumerator(new Key(mid), new Key(max), IterationOrder.DescentOrder);
            VerifyDictionaryEnumerator(de, IterationOrder.DescentOrder);

            Tests.AssertDatabaseException(
                () => root.byteIdx.PrefixSearch("1"),
                DatabaseException.ErrorCode.INCOMPATIBLE_KEY_TYPE);
            // TODO: FAILED_TEST broken for altbtree, returns no results
            if (!config.AltBtree)
            {
                recs = root.strIdx.GetPrefix("1");
                Tests.Assert(recs.Length > 0);
                foreach (var r in recs)
                {
                    Tests.Assert(r.StrVal.StartsWith("1"));
                }
            }
            recs = root.strIdx.PrefixSearch("1");
            Tests.Assert(startWithOne == recs.Length);
            foreach (var r in recs)
            {
                Tests.Assert(r.StrVal.StartsWith("1"));
            }
            recs = root.strIdx.PrefixSearch("5");
            Tests.Assert(startWithFive == recs.Length);
            foreach (var r in recs)
            {
                Tests.Assert(r.StrVal.StartsWith("5"));
            }
            recs = root.strIdx.PrefixSearch("0");
            Tests.Assert(0 == recs.Length);

            recs = root.strIdx.PrefixSearch("a");
            Tests.Assert(0 == recs.Length);

            recs = root.strIdx.PrefixSearch(strFirst);
            Tests.Assert(recs.Length >= 1);
            Tests.Assert(recs[0].StrVal == strFirst);
            foreach (var r in recs)
            {
                Tests.Assert(r.StrVal.StartsWith(strFirst));
            }

            recs = root.strIdx.PrefixSearch(strLast);
            Tests.Assert(recs.Length == 1);
            Tests.Assert(recs[0].StrVal == strLast);

            n = 0;
            foreach (var key in Tests.KeySeq(count))
            {
                n++;
                if (n % 3 == 0)
                {
                    continue;
                }
                string     strKey = key.ToString();
                RecordFull rec    = root.strIdx.Get(strKey);
                root.strIdx.Remove(strKey, rec);
            }
            root.byteIdx.Clear();

            int  BTREE_THRESHOLD = 128;
            byte bKey            = 1;

            for (int i = 0; i < BTREE_THRESHOLD + 10; i++)
            {
                RecordFull r = new RecordFull(0);
                if (i == 0)
                {
                    root.byteIdx[bKey] = r;
                    continue;
                }
                if (i == 1)
                {
                    root.byteIdx.Set(bKey, r);
                    continue;
                }
                root.byteIdx.Put(bKey, r);
            }

            Tests.AssertDatabaseException(
                () => root.byteIdx.Set(bKey, new RecordFull(1)),
                DatabaseException.ErrorCode.KEY_NOT_UNIQUE);
            Tests.AssertDatabaseException(
                () => root.byteIdx.Get(bKey),
                DatabaseException.ErrorCode.KEY_NOT_UNIQUE);
            recs = root.byteIdx.ToArray();
            foreach (var r in recs)
            {
                root.byteIdx.Remove(bKey, r);
            }
            Tests.AssertDatabaseException(
                () => root.byteIdx.Remove(bKey, new RecordFull(0)),
                DatabaseException.ErrorCode.KEY_NOT_FOUND);
            IEnumerator <RecordFull> e = root.byteIdx.GetEnumerator();

            while (e.MoveNext())
            {
            }
            Tests.Assert(!e.MoveNext());
            db.Close();
        }
示例#4
0
        public void Run(TestConfig config)
        {
            int count = config.Count;
            var res = new TestIndexResult();
            config.Result = res;
            IDatabase db = config.GetDatabase();

            Root root = (Root)db.Root;
            Tests.Assert(null == root);
            root = new Root();
            root.strIdx = db.CreateThickIndex<string, RecordFull>();
            root.byteIdx = db.CreateThickIndex<byte, RecordFull>();
            db.Root = root;
            Tests.Assert(typeof(string) == root.strIdx.KeyType);
            Tests.Assert(typeof(byte) == root.byteIdx.KeyType);

            int startWithOne = 0;
            int startWithFive = 0;
            string strFirst = "z";
            string strLast = "0";

            int n = 0;
            var inThickIndex = new Dictionary<byte, List<RecordFull>>();
            foreach (var key in Tests.KeySeq(count))
            {
                RecordFull rec = new RecordFull(key);
                if (rec.StrVal[0] == '1')
                    startWithOne += 1;
                else if (rec.StrVal[0] == '5')
                    startWithFive += 1;
                if (rec.StrVal.CompareTo(strFirst) < 0)
                    strFirst = rec.StrVal;
                else if (rec.StrVal.CompareTo(strLast) > 0)
                    strLast = rec.StrVal;
                root.strIdx.Put(rec.StrVal, rec);
                root.byteIdx.Put(rec.ByteVal, rec);
                n++;
                if (n % 100 == 0)
                    db.Commit(); ;
            }
            db.Commit();

            Tests.Assert(root.strIdx.Count == count);
            Tests.Assert(root.byteIdx.Count <= count);

            Tests.AssertDatabaseException(() =>
                { root.strIdx.RemoveKey(""); },
                DatabaseException.ErrorCode.KEY_NOT_UNIQUE);

            Tests.AssertDatabaseException(() =>
                { root.strIdx.Remove(new Key("")); },
                DatabaseException.ErrorCode.KEY_NOT_UNIQUE);

            foreach (var mk in inThickIndex.Keys)
            {
                var list = inThickIndex[mk];
                while (list.Count > 1)
                {
                    var el = list[0];
                    list.Remove(el);
                    root.byteIdx.Remove(el.ByteVal, el);
                }
            }

            RecordFull[] recs;
            foreach (var key in Tests.KeySeq(count))
            {
                RecordFull rec1 = root.strIdx[Convert.ToString(key)];
                recs = root.byteIdx[rec1.ByteVal, rec1.ByteVal];
                Tests.Assert(rec1 != null && recs.Length >= 1);
                Tests.Assert(rec1.ByteVal == recs[0].ByteVal);
            }

            // test for non-existent key
            Tests.Assert(null == root.strIdx.Get("-122"));

            recs = root.byteIdx.ToArray();
            Tests.Assert(recs.Length == root.byteIdx.Count);

            var prevByte = byte.MinValue;
            n = 0;
            foreach (RecordFull rec in root.byteIdx)
            {
                Tests.Assert(rec.ByteVal >= prevByte);
                prevByte = rec.ByteVal;
                n += 1;
            }
            Tests.Assert(n == count);

            String prevStrKey = "";
            n = 0;
            foreach (RecordFull rec in  root.strIdx)
            {
                Tests.Assert(rec.StrVal.CompareTo(prevStrKey) >= 0);
                prevStrKey = rec.StrVal;
                n += 1;
            }
            IDictionaryEnumerator de = root.strIdx.GetDictionaryEnumerator();
            n = VerifyDictionaryEnumerator(de, IterationOrder.AscentOrder);
            Tests.Assert(n == count);

            string mid = "0";
            string max = long.MaxValue.ToString(); ;
            de = root.strIdx.GetDictionaryEnumerator(new Key(mid), new Key(max), IterationOrder.DescentOrder);
            VerifyDictionaryEnumerator(de, IterationOrder.DescentOrder);

            Tests.AssertDatabaseException(
                () => root.byteIdx.PrefixSearch("1"),
                DatabaseException.ErrorCode.INCOMPATIBLE_KEY_TYPE);
            // TODO: FAILED_TEST broken for altbtree, returns no results
            if (!config.AltBtree)
            {
                recs = root.strIdx.GetPrefix("1");
                Tests.Assert(recs.Length > 0);
                foreach (var r in recs)
                {
                    Tests.Assert(r.StrVal.StartsWith("1"));
                }
            }
            recs = root.strIdx.PrefixSearch("1");
            Tests.Assert(startWithOne == recs.Length);
            foreach (var r in recs)
            {
                Tests.Assert(r.StrVal.StartsWith("1"));
            }
            recs = root.strIdx.PrefixSearch("5");
            Tests.Assert(startWithFive == recs.Length);
            foreach (var r in recs)
            {
                Tests.Assert(r.StrVal.StartsWith("5"));
            }
            recs = root.strIdx.PrefixSearch("0");
            Tests.Assert(0 == recs.Length);

            recs = root.strIdx.PrefixSearch("a");
            Tests.Assert(0 == recs.Length);

            recs = root.strIdx.PrefixSearch(strFirst);
            Tests.Assert(recs.Length >= 1);
            Tests.Assert(recs[0].StrVal == strFirst);
            foreach (var r in recs)
            {
                Tests.Assert(r.StrVal.StartsWith(strFirst));
            }

            recs = root.strIdx.PrefixSearch(strLast);
            Tests.Assert(recs.Length == 1);
            Tests.Assert(recs[0].StrVal == strLast);

            n = 0;
            foreach (var key in Tests.KeySeq(count))
            {
                n++;
                if (n % 3 == 0)
                    continue;
                string strKey = key.ToString();
                RecordFull rec = root.strIdx.Get(strKey);
                root.strIdx.Remove(strKey, rec);
            }
            root.byteIdx.Clear();

            int BTREE_THRESHOLD = 128;
            byte bKey = 1;
            for (int i = 0; i < BTREE_THRESHOLD + 10; i++)
            {
                RecordFull r = new RecordFull(0);
                if (i == 0)
                {
                    root.byteIdx[bKey] = r;
                    continue;
                }
                if (i == 1)
                {
                    root.byteIdx.Set(bKey, r);
                    continue;
                }
                root.byteIdx.Put(bKey, r);
            }

            Tests.AssertDatabaseException(
                () => root.byteIdx.Set(bKey, new RecordFull(1)),
                DatabaseException.ErrorCode.KEY_NOT_UNIQUE);
            Tests.AssertDatabaseException(
                () => root.byteIdx.Get(bKey),
                DatabaseException.ErrorCode.KEY_NOT_UNIQUE);
            recs = root.byteIdx.ToArray();
            foreach (var r in recs)
            {
                root.byteIdx.Remove(bKey, r);
            }
            Tests.AssertDatabaseException(
                () => root.byteIdx.Remove(bKey, new RecordFull(0)),
                DatabaseException.ErrorCode.KEY_NOT_FOUND);
            IEnumerator<RecordFull> e = root.byteIdx.GetEnumerator();
            while (e.MoveNext()) { }
            Tests.Assert(!e.MoveNext());
            db.Close();
        }