DBLock(), DBLockGetRef(), DBDeref(), DBUnlock(), DBDirty()
To access a database item, lock it with
DBLock()
. This routine takes three arguments: the handle of the VM file, the item's group-handle, and the item's item-handle. The routine locks the item-block on the global heap and returns the address of the element. If the block is already locked (generally because another item in the item-block is locked), it increments the lock count.
In some circumstances it might be useful to know the global handle of the locked item-block and the chunk handle of the item.
For example, if you want to set up an item as a chunk array, you will need this information. For this reason, the library provides the routine
DBLockGetRef()
. This routine is just like
DBLock()
, except that it takes one additional argument: the address of a variable of type optr.
DBLockItemGetRef()
writes global and chunk handles to the optr and returns the address of the locked DB item. You can now use any of the LMem routines on the item, simply by passing the optr.
Note that the memory block attached to the item block may change each time the block is locked unless you have instructed the VM manager to preserve the handle (see the VM chapter). The chunk handle will not change, even if the file is closed and reopened, unless the chunk is resized larger. (When an item is resized larger, the DB manager may choose to move the item to a different item-block, thus changing its chunk handle.) In general, if you will need this information you should get it each time you lock the item instead of trying to preserve it from one lock to the next.
If you have an optr to a
locked
DB item, you can translate it to an address with the routine
DBDeref()
. This is useful if you have to keep one item locked while allocating or expanding another item in that group. Since the locked item might move as a result of the allocation, you can get the new address with
DBDeref()
. In general, however, you should unlock all items in a group before allocating or resizing one there. Note that
DBDeref
is simply a synonym for
LMemDeref()
; the two routines are exactly the same.
When you are done accessing an item, call
DBUnlock()
. This routine takes one argument, the address of a locked item. The routine decrements the reference count of the item's item-block. If the reference count reaches zero, the routine unlocks the block. Thus, if you lock two different items in an item block, you should unlock each item separately. As noted above, you should always unlock an item before freeing it.
If you change a DB item, you should mark the item's block as
dirty
by calling
DBDirty()
. This ensures that the changes will be copied to the disk the next time the file is saved or updated. The routine takes one argument, a pointer to an address in an item block (generally the address of an item). It will dirty the item-block containing that item. As with VM blocks, you must dirty the item
before
you unlock it, as the memory manager can discard any clean block from memory as soon as it is unlocked.