×

Discussion Board

Results 1 to 8 of 8
  1. #1
    Registered User
    Join Date
    Jul 2007
    Location
    Paris, France
    Posts
    41

    RecordComparator.compare gets called with null

    Hi

    I use RecordComparator to access my records in order.

    I noticed that sometimes the compare callback gets called by the system with null as one of the records.
    I mean that when the system calls

    Code:
    public int compare( byte[] b1, byte[] b2 )
    b1 or b2 is null.

    There's nothing unusual about my record store, I have about 500 records, they are about 100 bytes average each.

    What could be causing this ?

    Also, I now check for null in my compare function, to prevent the app from crashing.
    And now, when i do
    Code:
    while( en.hasNextElement )
    {
      id = en.nextRecordId();
    }
    I get a InvalidRecordIdException !

    Could my record store have become corrupted somehow?
    How can I guard against this ?

  2. #2
    Registered User
    Join Date
    Jul 2007
    Location
    Paris, France
    Posts
    41

    Re: RecordComparator.compare gets called with null

    More info :

    First, I was mistaken; nextRecordId doesn't throw InvalidRecordIdException, it just returns 0 for the
    record id. InvalidRecordIdException was thrown later by me trying to use this record id.

    Here is some code that I wrote to test this:

    Code:
    RecordStore rs = null;
    RecordEnumeration en = null;
    		
    int nNulls = 0;
    			
    rs = RecordStore.openRecordStore( recStoreName, false );
    int nRecs = rs.getNumRecords(); 
    
    int nRecsEnumerated = 0;
    en = rs.enumerateRecords( null, null, false );
    int nRecsEnum = en.numRecords();
    while( en.hasNextElement() )
    {
    	int ri = en.nextRecordId();
    	if( ri == 0 )
    	{
    		nNulls++;
    	}
    	nRecsEnumerated++;
    }
    In the above,
    rs.getNumRecords returns 500 (number of records in the record store)
    en.numRecords returns 500 (number of records in the enumeration)

    At the end of the loop, nRecsEnumerated is 500.
    This means that hasNextElement sees 500 records.

    However, at the end of the loop nNulls is 475, meaning that nextRecordId is unable
    to retrieve all the records that the record store claims to have.

    Can't see what I did wrong; is there some major corruption going on here or what ?

    My app is deployed on about 200 phones and so far I have seen only 2 with these symptoms.
    My app is multithreaded, but I understand that the RecordStore API is thread safe.

    Any thoughts ?

  3. #3
    Super Contributor
    Join Date
    Jun 2003
    Location
    Cheshire, UK
    Posts
    7,395

    Re: RecordComparator.compare gets called with null

    RMS, generally, behaves surprisingly badly.

    My recommendations are:

    * Don't use RecordComparator or RecordEnumation

    * Don't use deleteRecord()

    * Don't use setRecord(), unless you have only one record

    * Keep the record store open for the shortest possible time - close it as soon as you can

    * Don't access the same record store from two threads at the same time

    * Always, always, always, close the record store


    Make sure you use finally{} to close the record store for you.

    Code:
    RecordStore rs = RecordStore.openRecordStore(RECORD_STORE_NAME, true);
    try {
        // do some record store work here
    } finally {
        rs.closeRecordStore()
    }
    Bad things happen if you don't close record stores properly (loss of updates, or corruption of the rms files).

    Graham.

  4. #4
    Registered User
    Join Date
    Jul 2007
    Location
    Paris, France
    Posts
    41

    Re: RecordComparator.compare gets called with null

    Quote Originally Posted by grahamhughes View Post
    RMS, generally, behaves surprisingly badly.
    My recommendations are:
    * Don't use RecordComparator or RecordEnumation
    All right but (sorry to sound a bit naive here) how do you sort records then ?

    Quote Originally Posted by grahamhughes View Post
    * Don't use deleteRecord()
    All right but how do you delete records then ?

    Quote Originally Posted by grahamhughes View Post
    * Don't use setRecord(), unless you have only one record
    setRecord only works on one record anyway (or are you saying that there should
    be at most one record in a store??)


    Quote Originally Posted by grahamhughes View Post
    * Keep the record store open for the shortest possible time - close it as soon as you can
    * Don't access the same record store from two threads at the same time
    * Always, always, always, close the record store
    Make sure you use finally{} to close the record store for you.
    Bad things happen if you don't close record stores properly (loss of updates, or corruption of the rms files).
    Yes, I always close in finally .

    Your recommendations seem a bit extreme. Basically you're saying, don't use the RMS.
    How do you store your data then ?

  5. #5
    Super Contributor
    Join Date
    Jun 2003
    Location
    Cheshire, UK
    Posts
    7,395

    Re: RecordComparator.compare gets called with null

    At most one record in the store, yes.

    There are two techniques that seem to work reliably.

    1: Delete and Re-create

    • Load all the records into a Vector, and edit them there (add, delete, update, whatever)
    • Delete the old data with deleteRecordStore()
    • Create a new record store (same name) and store all the data to it


    2: One Big Record

    • Use DataOutputStream and ByteArrayOutputStream to pack all the data into one large byte array
    • First time you save this, use addRecord(data, 0, data.length)
    • Subsequently, use setRecord(1, data, 0, data.length)
    • Again, all the processing is in memory


    Or you can use both at the same time, to be doubly safe.

    How much data do you have?

    Graham.

  6. #6
    Registered User
    Join Date
    Jul 2007
    Location
    Paris, France
    Posts
    41

    Re: RecordComparator.compare gets called with null

    Quote Originally Posted by grahamhughes View Post
    At most one record in the store, yes.
    There are two techniques that seem to work reliably.
    1: Delete and Re-create
    2: One Big Record
    Hmmm. Gotta rewrite all my data layer.

    Quote Originally Posted by grahamhughes View Post
    How much data do you have?
    Well my typical store has under 100 recs, each record is 300 bytes at the most.

    I also have pictures; typically 4 or 5 pics at a given time, depending on the resolution each
    record might be about 50 or 60 kilobytes. They get sent to a server and deleted (with deleteRecord )

    The record store which I have problems with is different, I use it to log stuff, and
    it can get pretty big sometimes. One record equals one line; I limit it to 500 records; when that
    limit is reached, I delete a number of older records to make room for new ones. The limit is usually
    not reached because the data is sent to a server and deleted.

    In this case, I suppose a connection was unavailable and the log kept growing, reached the 500 limit, and
    from then on, it was delete a chunk or records, add more records, delete a chunk again, etc.

    After a while, due to the exceptions I described, the store could not be sent at all
    and just sat there.

    Your recommendations could work for my application data but for logging, I would have
    to load one huge record in memory everytime I want to add a line, not sure about this...

    Gotta think this one over.

  7. #7
    Super Contributor
    Join Date
    Jun 2003
    Location
    Cheshire, UK
    Posts
    7,395

    Re: RecordComparator.compare gets called with null

    Well, you can make some variations on those two schemes.

    Adding to end of a record store is not usually a problem. Problems seem to arise if you delete records, or if you change the contents of a record with data of a different length to the original. (Though, take a look at this thread.)

    On Nokias, don't worry about using more record stores, with one record each if you need. Mutliple records are fine if you don't need to update them (just delete the whole record store when you're finished with it).

    Perhaps, store your log in five record stores of 100 records each ("log1".."log5"). When "log5" is full, delete and re-create "log1", for example.

    Hope that helps.

    Graham.

  8. #8
    Registered User
    Join Date
    Jul 2007
    Location
    Paris, France
    Posts
    41

    Re: RecordComparator.compare gets called with null

    Well then it looks like I've got my work cut out.
    Thanks for your advice.

Similar Threads

  1. How to use ChoiceGroup in J2ME
    By ngs_t in forum Mobile Java General
    Replies: 17
    Last Post: 2010-06-27, 16:51
  2. io error occured
    By vdx in forum Mobile Java General
    Replies: 8
    Last Post: 2009-06-01, 19:18
  3. problem with bluetooth and n70
    By kikoy87 in forum Mobile Java Games
    Replies: 3
    Last Post: 2008-03-24, 15:09
  4. Video playback with sound but nothing on Screen
    By abdullah829 in forum Mobile Java Media (Graphics & Sounds)
    Replies: 5
    Last Post: 2007-11-30, 14:04
  5. Problem with HTTP POST
    By thathoo in forum Mobile Java General
    Replies: 2
    Last Post: 2006-12-18, 18:23

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×