3

I am using BerkerlyDB with c# on windows. I have a HashDatabase routine which adds 1 byte key and 1 byte data pairs using db.Put. The problem is when i use cursor.movenext() they dont come out in ascending order.

                env = OpenEnv();
                db = OpenDB(env, dBName);
                byte[] rec1 = new byte[1];
                rec1[0] = (byte)'D';
                byte[] data = new byte[1] { 0 };
                BDB.DatabaseEntry dbek1 = new BDB.DatabaseEntry(rec1);
                db.Put(dbek1, new BDB.DatabaseEntry(data));
                byte[] rec2 = new byte[1];
                rec2[0] = (byte)'C';
                BDB.DatabaseEntry dbek2 = new BDB.DatabaseEntry(rec2);
                db.Put(dbek2, new BDB.DatabaseEntry(data));
                cursor = db.Cursor();
                while (cursor.MoveNext())
                {
                    sb.Clear();
                    byte[] key = cursor.Current.Key.Data;
                    byte[] d = cursor.Current.Value.Data;
                    foreach (char c in key)
                        sb.Append(c);
                    sb.Append(' ');
                    foreach (int c in d)
                        sb.Append(c.ToString() + " ");
                    Console.WriteLine(sb.ToString());
                } 

        private static BDB.HashDatabase OpenDB(BDB.DatabaseEnvironment env, string dbFileName)
        {
            BDB.HashDatabaseConfig hashConfig = new BDB.HashDatabaseConfig();
            hashConfig.Env = env;
            hashConfig.Duplicates = BDB.DuplicatesPolicy.SORTED;
            hashConfig.Creation = BDB.CreatePolicy.IF_NEEDED;
            hashConfig.PageSize = 4 * 4096;
            hashConfig.FillFactor = (hashConfig.PageSize - 26) / (1 + 1 + 6);
            //            hashConfig.TableSize = 2000000;
            return BDB.HashDatabase.Open(dbFileName, hashConfig);
        }
        private static BDB.DatabaseEnvironment OpenEnv()
        {
            BDB.MPoolConfig mpoolConfig = new BDB.MPoolConfig();
            uint cacheSize = 2;
            mpoolConfig.MaxCacheSize = new BDB.CacheInfo(cacheSize, 8192 * 4096, 1);
            mpoolConfig.CacheSize = new BDB.CacheInfo(cacheSize, 4096 * 4096, 1);
            BDB.MutexConfig mutexConfig = new BDB.MutexConfig();
            mutexConfig.InitMutexes = 0;
            mutexConfig.MaxMutexes = 0;
            mutexConfig.Increment = 0;
            BDB.DatabaseEnvironmentConfig envConfig = new BDB.DatabaseEnvironmentConfig();
            envConfig.MPoolSystemCfg = mpoolConfig;
//            envConfig.NoMMap = true;
            envConfig.Private = true;
            envConfig.Create = true;
            envConfig.UseMPool = true;
            envConfig.ForceFlush = true;
            envConfig.MutexSystemCfg = mutexConfig;
            return BDB.DatabaseEnvironment.Open(".", envConfig);
        }

Any ideas would be appreciated.

  • 2
    Most likely the cursor retrieves records or keys in the order they are stored in a underlying hashtable (judging by the name). There is no guarantee that the keys will be retrieved in any specific order. You could almost say that the guarantee you have is that you will *not* return them in a specific order. This is the nature of hashtables. I don't have any experience with BerkeleyDB though so I cannot say if this holds true for that, but judging by the name, and your observation, I would say it does. – Lasse V. Karlsen Nov 06 '14 at 12:28

1 Answers1

1

Yes records will be returned as found through a cursor using DB_HASH.

If you wish sorted order through cursors, the simplest fix is to switch from DB_HASH to DB_BTREE, where leaves are always sorted. (But note that if you are using integer keys, you should use network/bigendian order for keys).

Otherwise, sort after retrieval from hash isn't impossibly hard.

Jeff Johnson
  • 2,310
  • 13
  • 23