P.S. Re: corruption - Using jdbm 1.0, on WinXP. - By analyzing my console log, I see that CrashTest2 was exec'ed/killed 12,490 times before the failure occurred.
On 8/11/2010 6:00 PM, Jim Newsham wrote: > > I just came across jdbm and am considering using it (or jdbm2) for a > project. > > I see that jdbm2 was recently forked from jdbm, and is hosted > elsewhere (http://code.google.com/p/jdbm2/). However, I couldn't find > any mailing list at that location. Is this list the place for jdbm2 > questions, or did I miss something? > > On the subject of jdbm/jdbm2... I need a structured file format which > is robust (will not corrupt), and ideally just a single file (since > from the user perspective it will be an opaque configuration file that > he may want to manipulate -- i.e., backup, copy, move). I see that > jdbm can do what I need with 2 files rather than 1, which is actually > acceptable (not 100% ideal, but not too bad; on a side note, what is > the technical feasibility of stuffing the data and log into a single > file, without foregoing corruption-safety). > > I considered using jdbm2 since it's more active/recent, but when I > tried out a simple test I discovered that it creates 8 database files > immediately -- ouch, not good. So I'm giving up on jdbm2 for now. > Unless jdbm2 can be made to use just 1 or 2 files. > > Back to jdbm, I wrote a very simple corruption test, and it seemed to > run fine for a few hours but finally started throwing Errors. The > test consists of (1) a class called CrashTest2 which opens a db, > iterates all keys/values, then repeatedly puts random key/value pairs > forever (the "domain" of possible keys is limited to 10,000, so puts > will eventually overwrite); and (2) a class called Driver which starts > the db access class in another process (Runtime.exec()), waits for > some random amount of time, then kills the process -- over and over, > forever. > > Stack trace follows: > > Exception in thread "main" java.lang.Error: CRITICAL: page header > magic for block 11603 not OK 0 > at jdbm.recman.PageHeader.<init>(PageHeader.java:74) > at jdbm.recman.DataPage.<init>(DataPage.java:63) > at jdbm.recman.DataPage.getDataPageView(DataPage.java:75) > at > jdbm.recman.PhysicalRowIdManager.allocNew(PhysicalRowIdManager.java:201) > at > jdbm.recman.PhysicalRowIdManager.alloc(PhysicalRowIdManager.java:175) > at > jdbm.recman.PhysicalRowIdManager.insert(PhysicalRowIdManager.java:81) > at > jdbm.recman.BaseRecordManager.insert(BaseRecordManager.java:225) > at > jdbm.recman.CacheRecordManager.insert(CacheRecordManager.java:158) > at > jdbm.recman.CacheRecordManager.insert(CacheRecordManager.java:141) > at jdbm.htree.HTree.createInstance(HTree.java:94) > at scratch.jdbm.CrashTest2.getTree(CrashTest2.java:52) > at scratch.jdbm.CrashTest2.check(CrashTest2.java:66) > at scratch.jdbm.CrashTest2.main(CrashTest2.java:42) > > > And the code follows: > > public class CrashTest2 { > > private static final String TREE_NAME = "tree"; > > private static int commitCount; > > public static void main(String... args) throws Exception { > Runtime.getRuntime().addShutdownHook(new Thread() { > public void run() { > System.out.println(String.format("terminating after approx. %s > commits", commitCount)); > } > }); > > RecordManager recordManager = > RecordManagerFactory.createRecordManager("crashtest2"); > long startNanos = System.nanoTime(); > check(recordManager); > long endNanos = System.nanoTime(); > System.out.println(String.format("checked file in %.3fms", > (endNanos - startNanos) / 1000000.0)); > runTest(recordManager); > } > > private static HTree getTree(RecordManager recordManager, String > treeName) throws Exception { > long recordId = recordManager.getNamedObject(treeName); > if (recordId == 0) { > HTree tree = HTree.createInstance(recordManager); > recordManager.setNamedObject("htree", tree.getRecid()); > return tree; > } > else { > return HTree.load(recordManager, recordId); > } > } > > private static void check(RecordManager recordManager) throws > Exception { > // we're not really checking that everything we expect is here... > // we just traverse the entire tree to make sure everything is > readable > int keyCount = 0; > int valueCount = 0; > HTree tree = getTree(recordManager, TREE_NAME); > FastIterator iter = tree.keys(); > String key; > while ((key = (String) iter.next()) != null) { > keyCount++; > String value = (String) tree.get(key); > if (value == null) { > throw new RuntimeException("null value"); > } > } > iter = tree.keys(); > while (iter.next() != null) { > valueCount++; > } > if (keyCount != valueCount) { > throw new RuntimeException("expected the same number of keys and > values"); > } > } > > private static void runTest(RecordManager recordManager) throws > Exception { > HTree tree = getTree(recordManager, TREE_NAME); > > Random random = new Random(); > while (true) { > int key = random.nextInt(10000); > tree.put((Integer) key, (Integer) key); > recordManager.commit(); > commitCount++; > } > } > > } > > public class Driver { > > private static final Executor executor = > Executors.newCachedThreadPool(); > > public static void main(String... args) throws Exception { > String command = "java -classpath build\\classes;lib\\jdbm-1.0.jar > scratch.jdbm.CrashTest2"; > while (true) { > Process process = Runtime.getRuntime().exec(command); > drain(process.getInputStream()); > drain(process.getErrorStream()); > sleepRandomly(200L, 500L); > process.destroy(); > process.waitFor(); > } > } > > private static void drain(final InputStream in) { > executor.execute(new Runnable() { > public void run() { > int c; > try { > while ((c = in.read()) != -1) { > System.out.print((char) c); > } > } > catch(IOException ioe) { > ioe.printStackTrace(); > } > } > }); > } > > private static void sleepRandomly(long wait, long range) { > final long sleepTime = wait + (long) (Math.random() * range); > try { > Thread.sleep(sleepTime); > } > catch(InterruptedException ie) { > // do nothing > } > } > > } > > Thanks and regards, > Jim > ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ Jdbm-general mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/jdbm-general
