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

Reply via email to