Larry Johnson wrote:
[Doug, I had no idea! You're response is excellent. Thanks!]
I had no idea there is so much overhead. But I guess with dirty bits
and privacy flags and who knows what, it all adds up. And since my
application is read-only, this overhead is a waste.
So if I'm going to combine my records as you suggest, would it be best
to continue to use PDBs, or should I use PRCs?
What advantage would a PRC afford you? It has the same per-record overhead.
The only real difference is that it has a different scheme for naming
the records. PDBs use contiguous indices, and PRCs use types (which
are really 32-bit integers) and indices (16-bit integers).
I also considered FeatureMemory. I know this doesn't survive soft-boot,
but for my application this is not a major problem. I understand Feature
Memory may be quite fast. The application is read-only. So if I could
allocate 7 megs contiguous of Feature memory, I could have a real fast
and compact solution. What do you think?
Feature memory is fast, but it's not any faster than the memory in
a PDB. Feature memory is nothing other than a way to get a handle
to memory from the same pool that PDB and PRC records are stored in.
The major difference is that the memory you get is not bound to any
kind of database and is reclaimed on soft reset. Well, that and
IIRC it has been said that OS 6 (Cobalt) will not provide backward
compatibility with feature memory.
Aside from the possible compatibility problems in the future, you
are highly unlikely to get 7 MB of contiguous memory of any kind on
a Palm device, feature memory or otherwise.
Personally, if I were you, I would simply take advantage of your
fixed record size and pack several of your records into a single
PDB record. If records in one database are 22 bytes, then since
a PDB record can be 65000 bytes (or more, but the efficiency gains
from pushing the limits are tiny), you can fit over 2900 of your
22-byte records into a single PDB record. For the sake of
simplicity, let's assume you put 2048 of them into each PDB record.
Thus if you'd like to access your record number 6789, you'd simply
look at PDB record number 6789 / 2048 == 3 and make sure to start
looking at byte number (6789 % 2048) * 22 == 14190 of the PDB.
(By which I mean you'd look at bytes 14190 through 14211.)
If you go with this scheme, there is one bit of extra complication:
you have to put a layer around the PDB records to take care of
complications like what to do with DmGetRecord() and MemHandleLock().
IIRC, MemHandleLock() has a very low maximum lock count, possibly 15,
and if you are packing thousands of your records into a single
PDB record, you could easily imagine exceeding the PDB record's
maximum lock count. Plus, it's hard to be sure exactly when to
release the record if it is being shared.
The easiest way to do this is, for each PDB record you access, keep
track of the pointer to that record, and keep your own lock count.
You need only call DmGetRecord() and MemHandleLock() when the lock
count changes from 0 to 1 and MemHandleUnlock() and DmReleaseRecord()
when the lock count changes from 1 to 0. If you have only 7 MB of
data, you could easily enough just create an array with a MemHandle
and a lock count for each record in it. That's only 64 bits per
record of dynamic heap, and if you put 2048 * 22 bytes == 45056 bytes
in one PDB record, you'd only need about 162 PDB records for 7 MB's
worth of 22-byte records, which means you'd use only 1296 bytes for
your array of MemHandles and lock counts. (You could also store a
MemPtr in the array, but it isn't strictly necessary, since if you've
*already* got the handle locked, the pointer won't change until the
last lock is released, so you can obtain the same pointer by doing
a MemHandleLock() immediately followed by a MemHandleUnlock(). Or
just store the MemPtr if you wish -- it makes the array a bit bigger
but does eliminate two system calls.)
- Logan
--
For information on using the PalmSource Developer Forums, or to unsubscribe,
please see http://www.palmos.com/dev/support/forums/