/*
* tree.h
*
* data type providing a map from a key to a value, where the value is
* an arbitrary area of storage.
*
* The current implementation of this is a binary search tree with no
* balancing, so it will be inefficient if the data is presented in
* strict ascending or descending order.
*
* all memory is allocated from a gmem_* heap that is passed on
* creation of the tree.
*
* include gutils.h before this.
*/
/* handle for a tree */
typedef struct tree FAR * TREE;
/* keys in these trees are DWORDs */
typedef DWORD TREEKEY;
/* some sort of place-holder understood only by tree_search and
* tree_addafter
*/
typedef struct treeitem FAR * TREEITEM;
/* pointer to one of these place holders */
typedef TREEITEM FAR * PTREEITEM;
/*
* create an empty tree and return a handle to it. Pass the heap to
* be used for all memory allocations.
*/
TREE APIENTRY tree_create(HANDLE hHeap);
/* delete a tree and discard any associated memory. The tree need not be
* empty. This will discard the elements of the tree; but if these
* contained pointers to further data blocks, these will not be discarded-
* you must free these before deleting the tree.
*/
void APIENTRY tree_delete(TREE tree);
/* add new element to the tree, mapping the key given to the value
*
* a block of data of length bytes will be inserted in the tree, mapped
* to this key, a pointer to this block will be returned. if the
* value pointer is non-null, the block value[0..length-1] will be copied
* to the new block.
*
* if the key already exists, the value block will be replaced with the
* new size and (if value is non-null) contents.
*/
LPVOID APIENTRY tree_update(TREE tree, TREEKEY key, LPVOID value, UINT length);
/* return a pointer to the value associated with a given key in this tree.
* returns NULL if the key is not found.
*/
LPVOID APIENTRY tree_find(TREE tree, TREEKEY key);
/*
* a common tree operation is to insert a new element into the
* tree only if that key is not found, and otherwise to update in some
* way the existing value. Using the standard functions above, that
* would require one lookup for the tree_find, and then a second lookup
* to insert the new element.
*
* the two functions below provide an optimisation over this. tree_search
* will return the value if found; if not, it will return NULL, and set
* pitem to a pointer to a place holder in the tree where the item
* should be inserted. tree_addafter takes this placeholder as
* an argument, and will insert the key/value in the tree at that point.
*
* as for tree_update, the value pointer can be NULL - in this case
* the block is allocated on the tree, but not initialised.
*
* the return value from tree_addafter is a pointer to the value block in
* the tree
*/
LPVOID APIENTRY tree_search(TREE tree, TREEKEY key, PTREEITEM place);
LPVOID APIENTRY tree_addafter(TREE tree, PTREEITEM place, TREEKEY key, LPVOID value,
UINT length);
/* -- ctree ---------------
*
* this is a type of tree based on the tree_ data type above, that implements
* counting for insertions of identical keys.
*
* ctree_update, if the key is unique, will insert the object and set the count
* to 1. if the key is not unique, it will just increment the reference count.
*
* ctree_getcount returns the reference count for a tree.
* ctree_find returns the first value inserted for that key, if any
*/
/*
* create an empty counting-tree and return handle. pass in the gmem_init()
* heap to be used for all memory allocations.
*/
TREE APIENTRY ctree_create(HANDLE hHeap);
/*
* delete a tree and all memory associated directly with it.
*/
void APIENTRY ctree_delete(TREE tree);
/*
* if the KEY is unique within the tree, insert the value and
* set the count for that key to 1. If the key is not unique, add one to
* the reference count for that key but leave the value untouched.
*/
LPVOID APIENTRY ctree_update(TREE tree, TREEKEY key, LPVOID value, UINT length);
/*
* find the reference count for the given key
*/
long APIENTRY ctree_getcount(TREE tree, TREEKEY key);
/*
* return the value for the given key (note this will be the value for
* the first insertion of this key
*/
LPVOID APIENTRY ctree_find(TREE tree, TREEKEY key);