xchange v0.9
Structured data exchange for C/C++
Loading...
Searching...
No Matches
xlookup.c File Reference

Macros

#define __XCHANGE_INTERNAL_API__
 Use internal definitions.
 

Functions

XLookupTablexAllocLookup (unsigned int size)
 
XLookupTablexCreateLookup (const XStructure *s, boolean recursive)
 
void xDestroyLookup (XLookupTable *tab)
 
long xLookupCount (const XLookupTable *tab)
 
XFieldxLookupField (const XLookupTable *tab, const char *id)
 
int xLookupPut (XLookupTable *tab, const char *prefix, const XField *field, XField **oldValue)
 
int xLookupPutAll (XLookupTable *tab, const char *prefix, const XStructure *s, boolean recursive)
 
XFieldxLookupRemove (XLookupTable *tab, const char *id)
 
int xLookupRemoveAll (XLookupTable *tab, const char *prefix, const XStructure *s, boolean recursive)
 

Detailed Description

Date
Created on Aug 30, 2024
Author
Attila Kovacs

Lookup table for faster field access in large fixed-layout structures.

Function Documentation

◆ xAllocLookup()

XLookupTable * xAllocLookup ( unsigned int  size)

Allocates a new lookup with the specified hash size. The hash size should correspond to the number of elements stored in the lookup. If it's larger or roughtly equal to the number of elements to be stored, then the lookup time will stay approximately constant with the number of elements. If the size is much smaller than the number of elements N stored, then the lookup time will scale as O(N/size) typically.

Parameters
sizeThe number of hash bins to allocate
Returns
The new lookup table, or else NULL if there was an error.
See also
xCreateLookup()
xDestroyLookup()

References FALSE, XLookupTable::priv, and x_error().

◆ xCreateLookup()

XLookupTable * xCreateLookup ( const XStructure s,
boolean  recursive 
)

Creates a fast name lookup table for the fields of structure, with or without including fields of embedded substructures also. For structures with a large number of fields, such a lookup can significantly improve access times for retrieving specific fields from a structure. However, the lookup will not track fields added or removed after its creation, and so it is suited for accessing structures with a fixed layout only.

Since the lookup table contains references to the structure, you should not destroy the structure as long as the lookup table is used.

Once the lookup table is no longer used, the caller should explicitly destroy it with xDestroyLookup()

Parameters
sPointer to a structure, for which to create a field lookup.
recursiveWhether to include fields from substructures recursively in the lookup.
Returns
The lookup table, or NULL if there was an error (errno will inform about the type of error).
See also
xLookupField()
xDestroyLookup()

References x_error(), x_trace_null(), xAllocLookup(), xCountFields(), and xDeepCountFields().

◆ xDestroyLookup()

void xDestroyLookup ( XLookupTable tab)

Destroys a lookup table, freeing up it's in-memory resources.

Parameters
tabPointer to the lookup table to destroy.
See also
xCreateLookup()

References XLookupTable::priv.

◆ xLookupCount()

long xLookupCount ( const XLookupTable tab)

Returns the number of fields in the lookup table.

Parameters
tabPointer to the lookup table
Returns
the number of fields stored.

References XLookupTable::priv.

◆ xLookupField()

XField * xLookupField ( const XLookupTable tab,
const char *  id 
)

Returns a named field from a lookup table. When retriving a large number (hundreds or more) fields by name from very large structures, this methods of locating the relevant data can be significantly faster than the xGetField() / xGetSubstruct() approach.

Note however, that preparing the lookup table has significant O(N) computational cost also, whereas retrieving M fields with xGetField() / xGetSubstruct() have costs that scale O(N×M). Therefore, a lookup table is practical only if you are going to use it repeatedly, many times over. As a rule of thumb, lookups may have the advantage if accessing fields in a structure by name hundreds of times, or more.

Parameters
tabPointer to the lookup table
idThe aggregate ID of the field to find.
Returns
The corresponding field or NULL if no such field exists or tab was NULL.
See also
xCreateLookup()
xGetField()

References XLookupTable::priv, and x_error().

◆ xLookupPut()

int xLookupPut ( XLookupTable tab,
const char *  prefix,
const XField field,
XField **  oldValue 
)

Puts a field into the lookup table with the specified aggregate ID prefix. For example, if the prefix is "system:subsystem", and the field's name is "property", then the field will be available as "system:subsystem:property" in the lookup.

Parameters
tabPointer to a lookup table
prefixThe aggregate ID prefix before the field's name, not including a separator
fieldThe field
oldValue(optional) pointer to a buffer in which to return the old field value (if any) stored under the same name. It may be NULL if not needed.
Returns
0 if successfully added a new field, 1 if updated an existing fields, or else X_NULL if either of the arguments were NULL, or X_FAILURE if some other error.
See also
xLookupPutAll()
xLookupRemove()

References XLookupTable::priv, x_error(), X_FAILURE, and X_NULL.

◆ xLookupPutAll()

int xLookupPutAll ( XLookupTable tab,
const char *  prefix,
const XStructure s,
boolean  recursive 
)

Puts all fields from a structure into the lookup table with the specified aggregate ID prefix, with or without including embedded substructures. For example, if the prefix is "system:subsystem", and a field's name is "property", then that field will be available as "system:subsystem:property" in the lookup.

Parameters
tabPointer to a lookup table
prefixThe aggregate ID prefix before the field's name, not including a separator
sThe structure
recursiveWhether to include fields in all substructures recursively also.
Returns
the number of fields added (<=0), or else X_NULL if either of the arguments were NULL, or X_FAILURE if some other error.
See also
xLookupRemoveAll()

References XLookupTable::priv, x_error(), X_FAILURE, and X_NULL.

◆ xLookupRemove()

XField * xLookupRemove ( XLookupTable tab,
const char *  id 
)

Removes a field from a lookup table.

Parameters
tabPointer to the lookup table
idThe aggregate ID of the field as stored in the lookup
Returns
The field that was removed, or else NULL if not found.
See also
xLookupRemoveAll()
xLookupPut()

References XLookupTable::priv, x_error(), and X_NULL.

◆ xLookupRemoveAll()

int xLookupRemoveAll ( XLookupTable tab,
const char *  prefix,
const XStructure s,
boolean  recursive 
)

Removes all fields of a structure from the lookup table with the specified aggregate ID prefix, with or without including embedded substructures. For example, if the prefix is "system:subsystem", and a field's name is "property", then the field referred to as "system:subsystem:property" in the lookup is affected.

Parameters
tabPointer to a lookup table
prefixThe aggregate ID prefix before the field's name, not including a separator
sThe structure
recursiveWhether to include fields in all substructures recursively also.
Returns
the number of fields removed (<=0), or else X_NULL if either of the arguments were NULL, or X_FAILURE if some other error.
See also
xLookupRemoveAll()

References XLookupTable::priv, x_error(), X_FAILURE, and X_NULL.