d762c6dd610c1983daf0e73f3696960f286cdaf9 braney Sat May 6 11:30:17 2017 -0700 make rangeTree functions thread safe. diff --git src/lib/rbTree.c src/lib/rbTree.c index 42952f8..7dff20d 100644 --- src/lib/rbTree.c +++ src/lib/rbTree.c @@ -603,57 +603,93 @@ { dumpFile = f; dumpLevel = 0; dumpIt = dumpItem; fprintf(f, "rbTreeDump\n"); rTreeDump(tree->root); } /* Variables to help recursively traverse tree. */ static void (*doIt)(void *item); static void *minIt, *maxIt; static int (*compareIt)(void *, void *); +/* Structure to pass down to make thread safe versions of range functions */ +struct rangeParams +{ +void (*doIt)(void *item, void *context); +void *minIt, *maxIt; +int (*compareIt)(void *, void *); +}; + +static void rTreeTraverseRangeWithContext(struct rbTreeNode *n, struct rangeParams *rp, void *context) +/* Recursively traverse tree in range applying doIt with context. */ +{ +if (n != NULL) + { + int minCmp = rp->compareIt(n->item, rp->minIt); + int maxCmp = rp->compareIt(n->item, rp->maxIt); + if (minCmp >= 0) + rTreeTraverseRangeWithContext(n->left, rp, context); + if (minCmp >= 0 && maxCmp <= 0) + rp->doIt(n->item, context); + if (maxCmp <= 0) + rTreeTraverseRangeWithContext(n->right, rp, context); + } +} + static void rTreeTraverseRange(struct rbTreeNode *n) /* Recursively traverse tree in range applying doIt. */ { if (n != NULL) { int minCmp = compareIt(n->item, minIt); int maxCmp = compareIt(n->item, maxIt); if (minCmp >= 0) rTreeTraverseRange(n->left); if (minCmp >= 0 && maxCmp <= 0) doIt(n->item); if (maxCmp <= 0) rTreeTraverseRange(n->right); } } static void rTreeTraverse(struct rbTreeNode *n) /* Recursively traverse full tree applying doIt. */ { if (n != NULL) { rTreeTraverse(n->left); doIt(n->item); rTreeTraverse(n->right); } } +void rbTreeTraverseRangeWithContext(struct rbTree *tree, void *minItem, void *maxItem, + void (*doItem)(void *item, void *context), void *context) +/* Apply doItem function to all items in tree such that + * minItem <= item <= maxItem. THREAD SAFE */ +{ +struct rangeParams ourParams; +ourParams.doIt = doItem; +ourParams.minIt = minItem; +ourParams.maxIt = maxItem; +ourParams.compareIt = tree->compare; +rTreeTraverseRangeWithContext(tree->root, &ourParams, context); +} void rbTreeTraverseRange(struct rbTree *tree, void *minItem, void *maxItem, void (*doItem)(void *item)) /* Apply doItem function to all items in tree such that * minItem <= item <= maxItem */ { doIt = doItem; minIt = minItem; maxIt = maxItem; compareIt = tree->compare; rTreeTraverseRange(tree->root); } void rbTreeTraverse(struct rbTree *tree, void (*doItem)(void *item)) /* Apply doItem function to all items in tree */