Error adding an entry to B-tree.

Help
2003-09-17
2003-09-17
  • I am getting the following error when I try to add an entry to the B-tree.
    java.lang.Error: Offset too large for record header (3845:8493)
            at jdbm.recman.RecordHeader.<init>(RecordHeader.java:75)
            at jdbm.recman.PhysicalRowIdManager.allocNew(PhysicalRowIdManager.java:210)
            at jdbm.recman.PhysicalRowIdManager.alloc(PhysicalRowIdManager.java:164)
            at jdbm.recman.PhysicalRowIdManager.update(PhysicalRowIdManager.java:95)
            at jdbm.recman.RecordManager.update(RecordManager.java:190)
            at jdbm.recman.RecordManager.update(RecordManager.java:206)
            at jdbm.helper.ObjectCache.flushAll(ObjectCache.java:190)
            at jdbm.recman.RecordManager.commit(RecordManager.java:272)

     
    • Alex Boisvert
      Alex Boisvert
      2003-09-17

      Can you provide a little more context about what you are doing when the error happens?

      alex

       
      • I am using B+tree to store the indices of the byte arrays that are stored in the flat file. The flat file consists of byte arrays and the B+Tree stores the offsets of those byte arrays. The kay is an object that consists of String (byte array) and int (version number). The value corresponding to the key is an object that consists of String (file name), long(offset) and int (size of the byte array).

        This is the code that I use to obtain the B+Tree

        RecordManager m_indexRecordManager = new RecordManager(m_repositoryfile);
        ObjectCache cache = new ObjectCache(m_indexRecordManager, new MRU(100));
        BTree m_indexTree = null;

        // Try to reload an existing B+Tree.
        long recid = m_indexRecordManager.getNamedObject(BTREE_NAME);
        if ( recid != 0 ) {
        m_indexTree = BTree.load(m_indexRecordManager, cache, recid);
        }
        else {
        // Create a new B+Tree data structure and use a
        // EntryKeyComparator to order the records based on their keys.
        m_indexTree = new BTree(m_indexRecordManager, cache, new EntryKeyComparator());
        m_indexRecordManager.setNamedObject(BTREE_NAME, m_indexTree.getRecid() );
        }

        I use
        m_indexTree.insert(key, entryLocator, true);
        m_indexRecordManager.commit();

        to add the key and a value to the B+Tree.

        I use
        (EntryLocator)m_indexTree.find(key)

        to return the location of the byte array in the flat file.

        And I use the following code to remove entry from the B+Tree

        EntryLocator locator = (EntryLocator)m_indexTree.remove(key);
        if (locator != null) {
        m_indexRecordManager.commit();
        }
        return locator;

        I have another B+Tree in this application that has its own file but is used in the similar manner.

        This is a multithreaded application where multiple threads concurrently modify the B+Tree. I have implemented
        a ReadWrite lock so multiple users may read from the B+Tree and only a single user can modify the B+Tree.

        I have been using this application for the last 6 month and never had an issue. I saw this problem today when I was trying to insert an entry into the B+Tree. Somehow the B+Tree got into this state that I cannot add an entry to it. I constantly get the java.lang.Error: Offset too large for record header (3845:8493) exception.
        Another important fact is that the ****.db file is 31,514,624 bytes.

         
        • Alex Boisvert
          Alex Boisvert
          2003-09-17

          It seems like a genuine corruption problem but it's difficult to say if it's due to software or hardware.

          I would willingly accept that it's a bug in JDBM but before I do so, I would like to take a look at your database file if it's possible for you.  Can you zip it and place it on a server somewhere?  (Send me a private email)

          thanks,
          alex

           
    • I am using B+tree to store the indices of the byte arrays that are stored in the flat file. The flat file consists of byte arrays and the B+Tree stores the offsets of those byte arrays. The kay is an object that consists of String (byte array) and int (version number). The value corresponding to the key is an object that consists of String (file name), long(offset) and int (size of the byte array).

      This is the code that I use to obtain the B+Tree

              RecordManager m_indexRecordManager = new RecordManager(m_repositoryfile);
              ObjectCache cache = new ObjectCache(m_indexRecordManager, new MRU(100));
              BTree m_indexTree = null;

              // Try to reload an existing B+Tree.
              long recid = m_indexRecordManager.getNamedObject(BTREE_NAME);
              if ( recid != 0 ) {
                  m_indexTree = BTree.load(m_indexRecordManager, cache, recid);
              }
              else {
                  // Create a new B+Tree data structure and use a
                  // EntryKeyComparator to order the records based on their keys.
                  m_indexTree = new BTree(m_indexRecordManager, cache, new EntryKeyComparator());
                  m_indexRecordManager.setNamedObject(BTREE_NAME, m_indexTree.getRecid() );
              }

            I use       
              m_indexTree.insert(key, entryLocator, true);
              m_indexRecordManager.commit();

           to add the key and a value to the B+Tree.

           I use
           (EntryLocator)m_indexTree.find(key)

           to return the location of the byte array in the flat file.

          And I use the following code to remove entry from the B+Tree

              EntryLocator locator = (EntryLocator)m_indexTree.remove(key);
              if (locator != null) {
                  m_indexRecordManager.commit();
              }
              return locator;

      I have another B+Tree in this application that has its own file but is used in the similar manner.

      This is a multithreaded application where multiple threads concurrently modify the B+Tree. I have implemented
      a ReadWrite lock so multiple users may read from the B+Tree and only a single user can modify the B+Tree.

      I have been using this application for the last 6 month and never had an issue. I saw this problem today when I was trying to insert an entry into the B+Tree. Somehow the B+Tree got into this state that I cannot add an entry to it. I constantly get the java.lang.Error: Offset too large for record header (3845:8493) exception.
      Another important fact is that the ****.db file is 31,514,624 bytes.