Nate Eldredge wrote:
Hi all,

I am new to PalmOS programming, though not new to C/C++.  I'm trying to
debug a program written by someone else.  It has the following snippet,
which is supposed to iterate over a database and delete some of its
entries:

UInt16 record_id;

for(record_id=0;record_id<DmNumRecords(ref);record_id++) {
        rec_h = DmQueryRecord(ref, record_id);
        ...
        if(...) {
                DmRemoveRecord(ref, record_id);
        }
}

This looks highly suspicious to me.  I can't believe that the record id's
are guaranteed to be sequential.  For instance, if records were deleted,
I'd think there would be gaps in the record id's (since as far as I can
tell, deleting one record shouldn't alter the id's of the others).  In
fact, DmQueryRecord sometimes fails, as if one of the records doesn't
exist.  Is this actually the right way to iterate over a database, and if
not, what is?

Either way you look at it, I think that code has a bug.

I'm 99% sure that when you remove a record (as opposed to deleting it,
which just sets a flag to have it truly deleted at next hotsync), the
index of all the following records is reduced by one.  Someone correct
me if I'm wrong, but conceptually, I think it's valid to view a Palm
record database as basically a linked list of records, and when you
want record #42, you just start at the beginning and go to node #42,
which contains the LocalID of the record you wish to get.  (Note #1:
a LocalID is just a key that the memory manager can use to find a
chunk of memory even after the heap containing that chunk is defragged.
Note #2:  although I'm pretty sure the linked list thing is conceptually
valid, I think the actual system uses some method that has better
performance than that.)

Anyway, let's assume that you have have 10 records, numbered 0 through 9
and that you delete record #3.  Then, records 4 through 9 should become
instantly renumbered to record 3 through 8.  That is, the #4 gets moved
to #3 and so on.  If that is the case, then the above code that you
posted is not even examining the record *after* any record that is
deleted because of the "record_id++" in the third part of the for(;;) loop.
The proper logic should be something like this instead:

        for (record_id = 0; record_id < DmNumRecords (ref); )
        {
            if (need_to_delete (record_id))
            {
                DmRemoveRecord (record_id);
            }
            else
            {
                record_id++;
            }
        }

And of course, if the opposite were true (that it were possible to
have gaps in the sequence of record indices), then there would be a
bug for the reasons you described.

  - Logan

--
For information on using the PalmSource Developer Forums, or to unsubscribe, 
please see http://www.palmos.com/dev/support/forums/

Reply via email to