/* intValTree - a binary tree with integer keys and void values. This is based on the * red/black self-balancing binary tree algorithm in the rbTree module. */ #include "common.h" #include "localmem.h" #include "rbTree.h" #include "intValTree.h" int intValCmp(void *va, void *vb) /* Return -1 if a before b, 0 if a and b overlap, * and 1 if a after b. */ { struct intVal *a = va; struct intVal *b = vb; return a->key - b->key; } struct rbTree *intValTreeNew() /* Create a new, empty, tree with integer keys and void values. */ { return rbTreeNew(intValCmp); } struct intVal *intValTreeAdd(struct rbTree *tree, int key, void *val) /* Add to binary tree. Will abort if key is already in tree. */ { struct intVal *iv; lmAllocVar(tree->lm, iv); iv->key = key; iv->val = val; if (rbTreeAdd(tree, iv) != NULL) errAbort("Key %d already exists in tree", key); return iv; } struct intVal *intValTreeUpdate(struct rbTree *tree, int key, void *val) /* Add to binary tree. If key is already in tree just updates it with val. */ { struct intVal *iv = intValTreeLookup(tree, key); if (iv != NULL) iv->val = val; else iv = intValTreeAdd(tree, key, val); return iv; } struct intVal *intValTreeRemove(struct rbTree *tree, int key) /* Removes given tree from key. */ { struct intVal fullKey; fullKey.key = key; return rbTreeRemove(tree, &fullKey); } struct intVal *intValTreeLookup(struct rbTree *tree, int key) /* Returns intVal associated with given key, or NULL if none exists. */ { struct intVal fullKey; fullKey.key = key; return rbTreeFind(tree, &fullKey); } void *intValTreeFind(struct rbTree *tree, int key) /* Returns value associated with given key, or NULL if none exists. */ { struct intVal fullKey; fullKey.key = key; struct intVal *iv = rbTreeFind(tree, &fullKey); if (iv == NULL) return NULL; return iv->val; } void *intValTreeMustFind(struct rbTree *tree, int key) /* Return value associated with given key. Aborts if none exists. */ { struct intVal fullKey; fullKey.key = key; struct intVal *iv = rbTreeFind(tree, &fullKey); if (iv == NULL) errAbort("%d is not in tree", key); return iv->val; } void doAllKeys(void *item, void *context) /* Callback function for tree traversal. */ { int **pPt = context; struct intVal *iv = item; **pPt = iv->key; *pPt += 1; } int *intValTreeKeys(struct rbTree *tree) /* Returns array of keys (size is tree->n). You freeMem this when done. */ { int *results, *pt; pt = AllocArray(results, tree->n); rbTreeTraverseWithContext(tree, doAllKeys, &pt); return results; }