I store LinkedList values with String keys and sadly, more or less by accident, I recognized that jdbm/mapdb loses a single entry from a LinkedList that I stored. I tried to reproduce this in a small snippet which was not so easy, because most of the times everything worked well - but now I have a stable setting (see below). The snippet runs on a linux 64 bit jdk 1.7.0_09-b05. I started with the jdbm3-alpha4, tried 5, 3-SNAPSHOT, and now I use the MapDB-0.9-SNAPSHOT maven snapshot. No difference, beside some new Exception with MapDB, also look to the snippet for this.
I guess it could be something with the serialization, because the behaviour is only seen after writing a certain amount of entries. Here is the according snippet:
// without appendOnlyEnable()
DB jdbmDB = DBMaker.newTempFileDB().asyncWriteDisable().closeOnJvmShutdown().deleteFilesAfterClose().journalDisable().make();
// with appendOnlyEnable()
// DB jdbmDB = DBMaker.newTempFileDB().asyncWriteDisable().closeOnJvmShutdown().deleteFilesAfterClose().journalDisable().appendOnlyEnable().make();
// with TreeMap, the second list value is lost
Map<String, LinkedList<String>> map = jdbmDB.getTreeMap("testMap");
// with HashMap, all List values are lost
// Map<String, LinkedList<String>> map = jdbmDB.getHashMap("testMap");
// with asyncWrite - ConcurrentModificationException at SerializerBase.serializeCollection(SerializerBase.java:498)
// Map<String, LinkedList<String>> map =DBMaker.newTempTreeMap();
int iLoops = 2000000;
for (int i = 0; i < iLoops; i++)
{
String strRandomKey = String.valueOf(Math.random());
LinkedList<String> llVals4RandomKey = map.get(strRandomKey);
if(llVals4RandomKey == null)
{
llVals4RandomKey = new LinkedList<String>();
map.put(strRandomKey, llVals4RandomKey);
}
llVals4RandomKey.add(UUID.randomUUID().toString());
if(i == (int) (iLoops * 0.9))
{
System.out.println("insert first");
LinkedList<String> llFirstValue = new LinkedList<String>();
map.put("ourKey", llFirstValue);
llFirstValue.add("firstValue");
}
if(i == (int) (iLoops * 0.97))
{
System.out.println("insert second");
LinkedList<String> llValues = map.get("ourKey");
llValues.add("secondValue");
}
if(i % 100000 == 0) System.out.println(i);
}
System.out.println(map.get("ourKey"));
if(map.get("ourKey").size() < 2)
System.err.println("some value is lost :(");
else
System.out.println("everything seems to be fine...");
jdbmDB.close();