3

我正在使用 db4o 8.0。db4o 数据库文件大小为 21MB。数据库中有以下对象。

User : There is 1 user in db.
PostedMessage : There are 10000 postedMessages in db.

我删除了所有 10000 条 PostedMessage。然后我尝试对 db4o 数据库进行碎片整理。以下代码用于碎片整理。

private void processDefrag() {
    try {
        String dbpath = "D:\\db4oDatabase";

        IdMapping mapping = new InMemoryIdMapping();
        //new DatabaseIdMapping(dbpath); //use this if heap overflows

        DefragmentConfig config = new DefragmentConfig(dbpath, dbpath+".bak", mapping);
        config.storedClassFilter(new AvailableClassFilter());
        config.forceBackupDelete(false);
        config.objectCommitFrequency(1000);
        Defragment.defrag(config);
        System.out.println("Defrag completed");

    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

我的期望是 db4oDatabase 文件大小将回到 21 Kb。并且 db4oDatabase 仍将包含 1 个用户对象。然而,运行上述代码后,db4odatabase 完全为空。为什么会这样?

如何避免丢失未删除的其他对象(在本例中为 1 个用户对象)?在 db4o 数据库上进行碎片整理的正确方法是什么?

4

3 回答 3

2

如果它因为找不到该类而不接受该类,则可以尝试编写StoredClassFilter自己的只接受所有StoredClass对象的类。

public class AcceptAllClassFilter implements StoredClassFilter {

    @Override
    public boolean accept(StoredClass storedClass) {
        return true;
    }
}

然后:

config.storedClassFilter(new AcceptAllClassFilter());

这将起作用,除非碎片整理过程只是StoredClass自动删除所有内容。如果是这种情况,我们可能需要弄清楚为什么User该类没有StoredClass容器的相应实例。

于 2012-09-10T19:02:50.837 回答
0
public static void printStoredClasses(ObjectContainer db) {
    StoredClass[] storedClasses = db.ext().storedClasses();
    for (StoredClass sc : storedClasses) {
        try {        
            Class<?> c = Class.forName(sc.getName());
            DebugMessagePrinter.print(c.getName());
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
    }
}

我使用上述方法打印存储的类。正如 Brian 猜测的那样,出于某种原因,它没有打印 User 和 PostedMessage 类名。这意味着它无法在 db4o 数据库文件中看到这些类。

于 2012-09-10T19:59:57.020 回答
0

最后,在 Brian 的 AcceptAllFilter 类的帮助下,我可以成功地对 db4oDatabase 文件进行碎片整理。大小从 21 MB 减少到 12 MB。工作方法如下图所示。

private void process() {
    try {
        String dbpath = "D:\\db4oDatabase";
        printStoredClassNames(dbpath);

        IdMapping mapping = new InMemoryIdMapping();
        //new DatabaseIdMapping(dbpath); //use this if heap overflows

        DefragmentConfig config = new DefragmentConfig(dbpath, dbpath+".bak2", mapping);
        config.storedClassFilter(new AcceptAllClassFilter());
        config.forceBackupDelete(false);
        config.objectCommitFrequency(1000);
        config.db4oConfig().add(new UuidSupport());
        Defragment.defrag(config);
        System.out.println("Defrag completed" + t.s());

    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

顺便说一句,碎片整理似乎并没有尽其所能。删除 10000 个 PostedMessage 对象后,数据库只包含 1 个用户对象。我希望数据库文件大小以 KB 为单位。

但是,正如他们所说,有总比没有好。有了这一些成功,我将继续寻找更好的碎片整理。如果我碰巧得到更好的结果,我会在这里发布。

于 2012-09-10T20:06:45.943 回答