2

C# で Berkeley DB を使用して探索する小さなプログラムを作成しました。

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

using BerkeleyDB;

namespace bdbtest {

    class Program {

        const string dbfile = @"c:\tmp\test.db";
        const int nIndexes = 5, nRecords = 500;

        static SecondaryKeyGenDelegate MakeKeyGen(int idx) {
            return (k, v) => new DatabaseEntry(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(v.Data) + string.Format("_{0}", idx)));
        }

        static void Main(string[] args) {

            File.Delete(dbfile);

            var environment = DatabaseEnvironment.Open(null,
                new DatabaseEnvironmentConfig() {
                    Create = true,
                    Private = true,
                    UseMPool = true,
                    ErrorPrefix = "Env: ",
                    ErrorFeedback = (pfx, msg) => Console.WriteLine(pfx + msg),
                });

            var table = RecnoDatabase.Open(dbfile, "table",
                new RecnoDatabaseConfig() {
                    Env = environment,
                    Creation = CreatePolicy.IF_NEEDED,
                    ErrorPrefix = "Table: ",
                    ErrorFeedback = (pfx, msg) => Console.WriteLine(pfx + msg),
                });

            var indexes = new List<SecondaryBTreeDatabase>();
            for (int idx = 0; idx < nIndexes; ++idx)
                indexes.Add(SecondaryBTreeDatabase.Open(dbfile, string.Format("index_{0}", idx),
                    new SecondaryBTreeDatabaseConfig(table, MakeKeyGen(idx)) {
                        Env = environment,
                        Creation = CreatePolicy.IF_NEEDED,
                        Compare = (k1, k2) => string.Compare(Encoding.UTF8.GetString(k1.Data), Encoding.UTF8.GetString(k2.Data)),
                        ErrorPrefix = "Index: ",
                        ErrorFeedback = (pfx, msg) => Console.WriteLine(pfx + msg),
                    }));

            for (int rn = 0; rn < nRecords; ++rn) {
                string s = string.Format("rec{0}", rn);
                table.Append(new DatabaseEntry(Encoding.UTF8.GetBytes(s)));
                Console.WriteLine(s);
            }

            foreach (var index in indexes)
                index.Close();
            indexes.Clear();
            table.Close();
            environment.Close();
        }
    }
}

テーブルとして使用するデータベースと、そのテーブルのインデックスとして多数のセカンダリ データベースを作成します。問題は、次のエラーでクラッシュすることです。

未処理の例外: System.AccessViolationException: 保護されたメモリの読み取りまたは書き込みを試みました。これは多くの場合、他のメモリが破損していることを示しています。
   BerkeleyDB.Internal.libdb_csharpPINVOKE.DB_put (HandleRef jarg1、HandleRef jarg2、HandleRef jarg3、HandleRef jarg4、UInt32 jarg5) で
   BerkeleyDB.Internal.DB.put (DB_TXN txn、DatabaseEntry キー、DatabaseEntry データ、UInt32 フラグ) で
   BerkeleyDB.Database.Put (DatabaseEntry キー、DatabaseEntry データ、トランザクション txn、UInt32 フラグ) で
   BerkeleyDB.RecnoDatabase.Append (DatabaseEntry データ、トランザクション txn) で
   BerkeleyDB.RecnoDatabase.Append(DatabaseEntry データ) で
   C:\Users\fgb\Documents\Visual Studio 2008\Projects\bdbtest\bdbtest\Program.cs:line 53 の bdbtest.Program.Main(String[] args)

特定の数のレコードがテーブルに書き込まれると、常にクラッシュします。さらに、nIndexes の値を増やすと、クラッシュする前に書き込まれるレコードの数が減少します。値が十分に小さい場合 (nIndexes = 5、nRecords = 50 など)、プログラムは問題なく完了します。これは、有限のリソースを使い果たしていると思いますが、どこに問題があるのか​​ わかりません。

4

0 に答える 0