Local Memory: 4.3 Special LMem Uses: Name Arrays

Up: GEOS SDK TechDocs | Up | Prev: 4.2 Element Arrays

Applications can build on chunk arrays and element arrays in many ways. The chunk array library includes one example of an elaboration on these structures: the name array . The name array is a special kind of element array in which elements can be accessed by a "name" label as well as by a token. Elements in a name array are of variable size. Each element is divided into three sections: The first is the RefElementHeader ; every element in an element array must begin with one of these (and the name array is a kind of element array). The second is the data section. The data section is the same size for every element in a given name array; this size may be anything from zero bytes up to a maximum of NAME_ARRAY_MAX_DATA_SIZE (64 bytes). The data section is followed by a "name" section. This section contains a sequence of bytes of any length up to a maximum of NAME_ARRAY_MAX_NAME_SIZE (256 bytes). The name may contain nulls and need not be null terminated. You can translate a name into the element's token by calling NameArrayFind() (described below).

Note that creating elements in a name array, as in any element array, requires a search through all elements; it thus takes linear time. Furthermore, translating a name into a token also requires a linear search through the elements, and thus also takes linear time. Name arrays thus become slow if they grow too large. Accessing an element by token, however, still takes constant time.

Creating a Name Array

NameArrayCreate(), NameArrayCreateAt(), NameArrayCreateAtHandles(), NameArrayAdd(), NameArrayAddHandles(), NameArrayHeader, NameArrayAddFlags

Creating a name array is much like creating an element array. Every name array must begin with a NameArrayHeader . This structure has the following definition:

typedef struct {
	ElementArrayHeader				NAH_meta;
	word				NAH_dataSize;
} NameArrayHeader;

This structure contains one new field, namely NAH _datasize . This field specifies the size of the data area of each element; the name area is of variable size. You may examine this field at will, but you may not change it. You may set up a fixed data area between the NameArrayHeader and the elements. The usual way to do this is to define a structure whose first element is a NameArrayHeader structure.

To create a name array, call the routine NameArrayCreate() . This routine is passed three arguments:

The routine allocates a chunk in the specified heap, initializes a name array in that chunk, and returns the chunk's handle. If it fails for any reason, it returns a null chunk handle. Since the routine allocates a chunk, all pointers to the LMem heap are invalidated.

If you want to create a name array in a specific chunk, call NameArrayCreateAt() . This routine is almost the same as NameArrayCreate() . However, instead of being passed a memory handle, NameArrayCreateAt() is passed an optr to a chunk. The name array will be created in that chunk. Any data in that chunk (outside of the fixed data area) will be destroyed. Note that if the chunk is too small for the name array, NameArrayCreateAt() will resize it; thus, pointers to the LMem heap may be invalidated. There is a version of this routine which takes the chunk's global and chunk handles instead of its optr; this routine is called NameArrayCreateAtHandles() .

To create an element, call NameArrayAdd() . This routine creates an element and copies the data and name into it. The routine takes five arguments:

NameArrayAdd() allocates the element, copies in the data and name, and returns the element's token. If an element with the specified name already exists, NameArrayAdd() will not create a duplicate. Instead, if the flag NAAF_SET_DATA_ON_REPLACE was passed, NameArrayAdd() will copy the new data section into the existing element; if the flag was not passed, it will leave the existing element unchanged. In either case, it will return the existing element's token and increment its reference count. If an element is added, the name array may have to be resized; therefore, pointers into the chunk array will be invalidated. There is a version in which the name array is specified by its global and chunk handles; this version is called NameArrayAddHandles() .

Code Display 16-4 Allocating a Name Array

/* We want a fixed data space, so we define our own header structure. */
typedef	struct {
	NameArrayHeader		MNAH_meta;		/* Must begin with a NameArrayHeader!!! */
	char *		MNAH_comments[32];
} MyNameArrayHeader;
/* The data section of the name array will be this structure: */
typedef struct {
	double		MDSS_myDataFloat;
	int		MDSS_myDataInts[20];
} MyDataSectionStruct;
/* Every element in the name array will have this structure: */
typedef struct {
	RefElementHeader			MES_header;		/* For internal use */
	MyDataSectionStruct			MES_data;
	char			MES_name[]; 		/* We don't know how long this
						 * will actually be */
} MyElementStruct;
MemHandle		myLMemHeap;		/* Assume this is initialized */
ChunkHandle		myNameArray;
/* Sample call to NameArrayCreate() */
myNameArray = NameArrayCreate(myLMemHeap, sizeof(MyDataSectionStruct),
				sizeof(MyNameArrayHeader));

Accessing Elements in a Name Array

NameArrayFind(), NameArrayFindHandles(), NameArrayChangeName(), NameArrayChangeNameHandles()

Name array routines can be accessed with all the routines used for accessing element arrays. However, a few special purpose routines are also provided.

If you know the name of an element and want a copy of its data, call NameArrayFind() . This routine is passed four arguments:

NameArrayFind() will do a linear search through the elements. If it finds one with the name specified, it will return that element's token and copy the data portion into the return buffer. If there is no element with the specified name, NameArrayFind() will return the constant CA_NULL_ELEMENT. The routine NameArrayFindHandles() is identical, except that the name array is specified by its global and chunk handles.

To change an element's name, call NameArrayChangeName() . This routine is passed four arguments:

NameArrayChangeName() changes the element's name. If the new name is longer than the old, the element will have to be resized; this will invalidate pointers within that block. NameArrayChangeNameHandles() is identical, except that the name array is specified by its global and chunk handles.


Up: GEOS SDK TechDocs | Up | Prev: 4.2 Element Arrays