我使用的是db4o 8.0。db4odatabase文件大小为21MB。数据库中有以下对象。
User : There is 1 user in db.
PostedMessage : There are 10000 postedMessages in db.我删除了所有10000个PostedMessages。然后,我尝试对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个User对象。但是,在运行上述代码之后,db4odatabase变得完全为空。为什么会发生这样的事情?
如何避免丢失未删除的其他对象(在本例中为1个用户对象)?对db4o数据库进行碎片整理的正确方法是什么?
发布于 2012-09-11 03:02:51
如果它因为找不到这个类而不接受它,那么您可以尝试编写一个只接受所有StoredClass对象的StoredClassFilter。
public class AcceptAllClassFilter implements StoredClassFilter {
@Override
public boolean accept(StoredClass storedClass) {
return true;
}
}然后:
config.storedClassFilter(new AcceptAllClassFilter());除非碎片整理过程自动删除没有StoredClass的所有内容,否则这将起作用。如果是这种情况,我们可能需要弄清楚为什么User类没有对应的容器StoredClass实例。
发布于 2012-09-11 03:59:57
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-11 04:06:46
最后,在Brian的AcceptAllFilter类的帮助下,我可以成功地对db4oDatabase文件进行碎片整理。大小从21MB减少到12MB。工作方法如下所示。
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。
但是,正如他们所说,有总比没有好。有了这样的成功,我将继续寻找更好的碎片整理。如果我碰巧得到了更好的结果,我会把它们贴在这里。
https://stackoverflow.com/questions/12355384
复制相似问题