d762c6dd610c1983daf0e73f3696960f286cdaf9 braney Sat May 6 11:30:17 2017 -0700 make rangeTree functions thread safe. diff --git src/lib/rangeTree.c src/lib/rangeTree.c index 7e8b708..b71cb7e 100644 --- src/lib/rangeTree.c +++ src/lib/rangeTree.c @@ -202,75 +202,74 @@ } } } boolean rangeTreeOverlaps(struct rbTree *tree, int start, int end) /* Return TRUE if start-end overlaps anything in tree */ { struct range tempR; tempR.start = start; tempR.end = end; tempR.val = NULL; return rbTreeFind(tree, &tempR) != NULL; } -static struct range *rangeList; - -static void rangeListAdd(void *v) +static void rangeListAdd(void *v, void *context) /* Callback to add item to range list. */ { struct range *r = v; -slAddHead(&rangeList, r); +struct range **list = (struct range **)context; +slAddHead(list, r); } struct range *rangeTreeList(struct rbTree *tree) /* Return list of all ranges in tree in order. Not thread safe. * No need to free this when done, memory is local to tree. */ { -rangeList = NULL; -rbTreeTraverse(tree, rangeListAdd); +struct range *rangeList = NULL; +rbTreeTraverseWithContext(tree, rangeListAdd, &rangeList); slReverse(&rangeList); return rangeList; } struct range *rangeTreeFindEnclosing(struct rbTree *tree, int start, int end) /* Find item in range tree that encloses range between start and end * if there is any such item. */ { struct range tempR, *r; tempR.start = start; tempR.end = end; r = rbTreeFind(tree, &tempR); if (r != NULL && r->start <= start && r->end >= end) { r->next = NULL; /* this can be set by previous calls to the List functions */ return r; } return NULL; } struct range *rangeTreeAllOverlapping(struct rbTree *tree, int start, int end) /* Return list of all items in range tree that overlap interval start-end. * Do not free this list, it is owned by tree. However it is only good until * next call to rangeTreeFindInRange or rangeTreeList. Not thread safe. */ { struct range tempR; tempR.start = start; tempR.end = end; -rangeList = NULL; -rbTreeTraverseRange(tree, &tempR, &tempR, rangeListAdd); +struct range *rangeList = NULL; +rbTreeTraverseRangeWithContext(tree, &tempR, &tempR, rangeListAdd, &rangeList); slReverse(&rangeList); return rangeList; } struct range *rangeTreeMaxOverlapping(struct rbTree *tree, int start, int end) /* Return item that overlaps most with start-end. Not thread safe. Trashes list used * by rangeTreeAllOverlapping. */ { struct range *range, *best = NULL; int bestOverlap = 0; for (range = rangeTreeAllOverlapping(tree, start, end); range != NULL; range = range->next) { int overlap = rangeIntersection(range->start, range->end, start, end); if (overlap > bestOverlap)