GEOS SDK TechDocs
|
|
5.2 Basic Huge Array Routines
HugeArrayNext(), HugeArrayPrev(), HugeArrayExpand(), HugeArrayContract(), HugeArrayEnum(), HugeArrayCompressBlocks(), ECCheckHugeArray()
The routines in the other section may be all you will need for using Huge Arrays. However, you can improve access time by taking advantage of the structure of a Huge Array. As noted above, you can use any of the VM Chain routines on a Huge Array, as long as none of the blocks are locked.
If you have been accessing an element in a Huge Array and you want to move
on to the next one, you can call the routine HugeArrayNext().
The routine takes a pointer to a pointer to the element. It changes that
pointer to point to the next element in the array, which may be in a
different block. If the routine changes blocks, it will unlock the old block
and lock the next one. It returns the number of consecutive elements starting
with the element we just advanced to. If we were at the last element in the
Huge Array, it returns zero and the pointer will point to the last element.
If you want to move to the previous element instead of the next one, call
HugeArrayPrev(). It also takes a pointer to a pointer to an
element. It changes that pointer to a pointer to the previous element; if
this means switching blocks, it unlocks the current block and locks the
previous one. It returns the number of elements which come before the
newly-locked one in its block, counting the newly-locked element. If the
pointer was pointing to the first element in the Huge Array, it returns
zero and the pointer will point to the first element.
If you have a block of the Huge Array locked and you want to insert an element or elements at an address in that block, call the routine
HugeArrayExpand()
. It takes three arguments:
The routine inserts the elements, dirtying any appropriate blocks. It writes a pointer to the first new element into the pointer passed. Since the data block may be resized or divided to accommodate the request, this address may be different from the one you pass. The routine returns the number of consecutive elements beginning with the one whose address was written. If the new element is in a different block from the address passed, the old block will be unlocked, and the new one will be locked.
If you have a block of a Huge Array locked and you want to delete one or more elements starting with one within the block, you can call
HugeArrayContract()
. This routine takes two arguments:
The routine deletes the elements, dirtying any appropriate blocks. It then changes the pointer to point to the first element after the deleted ones. If this element is in a different block, it will unlock the old block and lock the new one. It returns the number of consecutive elements following the one whose address was written.
You may wish to perform the same operation on a number of consecutive elements of a Huge Array.
HugeArrayEnum()
is a routine which lets you do this efficiently.
HugeArrayEnum()
takes six arguments:
HugeArrayEnum()
. The callback routine can abort the enumeration by returning
true
(
i.e.
, non-zero).
HugeArrayEnum()
calls the callback routine for every element, in order, from the first element. It passes the callback a pointer to the element and the pointer passed to
HugeArrayEnum()
. The callback routine may not do anything which would invalidate any pointers to the Huge Array; for example, it may not allocate, delete, or resize any of the elements. The callback routine should restrict itself to examining elements and altering them (
without
resizing them). The callback routine can abort the enumeration by returning
true
(
i.e.
, non-zero); if it does so,
HugeArrayEnum()
will return
true
. If
HugeArrayEnum()
finishes the enumeration without aborting, it returns
false
(
i.e.
, zero).
If the count is large enough to take
HugeArrayEnum()
past the end of the array,
HugeArrayEnum()
will simply enumerate up to the last element, then stop. For example, if you pass a start index of 9,000 and a count of 2,000, but the Huge Array has only 10,000 elements,
HugeArrayEnum()
will enumerate up through the last element (with index 9,999) then stop. However, the starting index
must
be the index of an element in the Huge Array. You can also pass a count of -1, indicatingg that
HugeArrayEnum()
should enumerate through the last element of the array. Therefore, to enumerate the entire array, pass a starting element of zero and a count of -1.
As noted above, most Huge Arrays contain a fair amount of unused space. This makes it much faster to add and remove elements, since blocks don't need to be resized very often. However, if you have a Huge Array that is not frequently changed, this is an inefficient use of space. You can free this space by calling
HugeArrayCompressBlocks()
. This routine is passed two arguments: the handle of the VM file, and the
VMBlockHandle
of the Huge Array. The routine does not change any element in the Huge Array; it simply resizes the directory and data blocks to be no larger than necessary to hold their elements. The routine does not return anything.
If you want to verify (in error-checking code) that a given VM block is the directory block of a Huge Array, you can call
ECCheckHugeArray()
. This routine is passed the VM file and block handles of the block in question. If the block is the directory block of a Huge Array, the routine returns normally; otherwise it causes a fatal error. The routine should not, therefore, be used in non-EC code.
GEOS SDK TechDocs
|
|
5.2 Basic Huge Array Routines