static void test_stSet_getUnion(CuTest* testCase) { testSetup(); // Check union of empty sets is empty stSet *set2 = stSet_construct(); stSet *set3 = stSet_construct(); stSet *set4 = stSet_getUnion(set2, set3); CuAssertTrue(testCase, stSet_size(set4) == 0); stSet_destruct(set2); stSet_destruct(set3); stSet_destruct(set4); // Check union of non empty set and empty set is non-empty set2 = stSet_construct(); set3 = stSet_getUnion(set0, set2); CuAssertTrue(testCase, stSet_size(set3) == 6); stSet_destruct(set2); stSet_destruct(set3); // Check union of two non-empty overlapping sets is correct set2 = stSet_construct(); set3 = stSet_construct(); stIntTuple **uniqs = (stIntTuple **) st_malloc(sizeof(*uniqs) * 4); uniqs[0] = stIntTuple_construct2(9, 0); uniqs[1] = stIntTuple_construct2(9, 1); uniqs[2] = stIntTuple_construct2(9, 2); uniqs[3] = stIntTuple_construct2(9, 3); stIntTuple **common = (stIntTuple **) st_malloc(sizeof(*uniqs) * 5); common[0] = stIntTuple_construct2(5, 0); common[1] = stIntTuple_construct2(5, 1); common[2] = stIntTuple_construct2(5, 2); common[3] = stIntTuple_construct2(5, 3); common[4] = stIntTuple_construct2(5, 4); for (int i = 0; i < 5; ++i) { stSet_insert(set2, common[i]); stSet_insert(set3, common[i]); } stSet_insert(set2, uniqs[0]); stSet_insert(set2, uniqs[1]); stSet_insert(set3, uniqs[2]); stSet_insert(set3, uniqs[3]); set4 = stSet_getUnion(set2, set3); CuAssertTrue(testCase, stSet_size(set4) == 9); for (int i = 0; i < 4; ++i) { CuAssertTrue(testCase, stSet_search(set4, uniqs[i]) != NULL); } for (int i = 0; i < 5; ++i) { CuAssertTrue(testCase, stSet_search(set4, common[i]) != NULL); } stSet_destruct(set2); stSet_destruct(set3); stSet_destruct(set4); // Check we get an exception with sets with different functions. stTry { stSet_getUnion(set0, set1); } stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == SET_EXCEPTION_ID); } stTryEnd testTeardown(); }
static void test_stSet_remove(CuTest* testCase) { testSetup(); CuAssertTrue(testCase, stSet_remove(set0, one) == one); CuAssertTrue(testCase, stSet_search(set0, one) == NULL); CuAssertTrue(testCase, stSet_remove(set1, one) == one); CuAssertTrue(testCase, stSet_search(set1, one) == NULL); stSet_insert(set1, one); CuAssertTrue(testCase, stSet_search(set1, one) == one); testTeardown(); }
static void test_stSet_insert(CuTest* testCase) { /* * Tests inserting already present keys. */ testSetup(); CuAssertTrue(testCase, stSet_search(set0, one) == one); stSet_insert(set0, one); CuAssertTrue(testCase, stSet_search(set0, one) == one); stSet_insert(set0, three); CuAssertTrue(testCase, stSet_search(set0, three) == three); stIntTuple *seven = stIntTuple_construct2(7, 7); CuAssertTrue(testCase, stSet_search(set0, seven) == NULL); stSet_insert(set0, seven); CuAssertTrue(testCase, stSet_search(set0, seven) == seven); stIntTuple_destruct(seven); testTeardown(); }
static void assignEventsAndSequences(Event *parentEvent, stTree *tree, stSet *outgroupNameSet, char *argv[], int64_t *j) { Event *myEvent = NULL; // To distinguish from the global "event" variable. assert(tree != NULL); totalEventNumber++; if (stTree_getChildNumber(tree) > 0) { myEvent = event_construct3(stTree_getLabel(tree), stTree_getBranchLength(tree), parentEvent, eventTree); for (int64_t i = 0; i < stTree_getChildNumber(tree); i++) { assignEventsAndSequences(myEvent, stTree_getChild(tree, i), outgroupNameSet, argv, j); } } if (stTree_getChildNumber(tree) == 0 || (stTree_getLabel(tree) != NULL && (stSet_search(outgroupNameSet, (char *)stTree_getLabel(tree)) != NULL))) { // This event is a leaf and/or an outgroup, so it has // associated sequence. assert(stTree_getLabel(tree) != NULL); assert(stTree_getBranchLength(tree) != INFINITY); if (stTree_getChildNumber(tree) == 0) { // Construct the leaf event myEvent = event_construct3(stTree_getLabel(tree), stTree_getBranchLength(tree), parentEvent, eventTree); } char *fileName = argv[*j]; if (!stFile_exists(fileName)) { st_errAbort("File does not exist: %s\n", fileName); } // Set the global "event" variable, which is needed for the // function provided to fastaReadToFunction. event = myEvent; if (stFile_isDir(fileName)) { st_logInfo("Processing directory: %s\n", fileName); stList *filesInDir = stFile_getFileNamesInDirectory(fileName); for (int64_t i = 0; i < stList_length(filesInDir); i++) { char *absChildFileName = stFile_pathJoin(fileName, stList_get(filesInDir, i)); assert(stFile_exists(absChildFileName)); setCompleteStatus(absChildFileName); //decide if the sequences in the file should be free or attached. FILE *fileHandle = fopen(absChildFileName, "r"); fastaReadToFunction(fileHandle, processSequence); fclose(fileHandle); free(absChildFileName); } stList_destruct(filesInDir); } else { st_logInfo("Processing file: %s\n", fileName); setCompleteStatus(fileName); //decide if the sequences in the file should be free or attached. FILE *fileHandle = fopen(fileName, "r"); fastaReadToFunction(fileHandle, processSequence); fclose(fileHandle); } (*j)++; } }
static void test_stSet_testIterator(CuTest *testCase) { testSetup(); stSetIterator *iterator = stSet_getIterator(set0); stSetIterator *iteratorCopy = stSet_copyIterator(iterator); int64_t i = 0; stSet *seen = stSet_construct(); for (i = 0; i < 6; i++) { void *o = stSet_getNext(iterator); CuAssertTrue(testCase, o != NULL); CuAssertTrue(testCase, stSet_search(set0, o) != NULL); CuAssertTrue(testCase, stSet_search(seen, o) == NULL); CuAssertTrue(testCase, stSet_getNext(iteratorCopy) == o); stSet_insert(seen, o); } CuAssertTrue(testCase, stSet_getNext(iterator) == NULL); CuAssertTrue(testCase, stSet_getNext(iterator) == NULL); CuAssertTrue(testCase, stSet_getNext(iteratorCopy) == NULL); stSet_destruct(seen); stSet_destructIterator(iterator); stSet_destructIterator(iteratorCopy); testTeardown(); }
stNaiveConnectedComponent *stNaiveConnectivity_getConnectedComponent(stNaiveConnectivity *connectivity, void *node) { computeConnectedComponents(connectivity); stNaiveConnectedComponent *curComponent = connectivity->connectedComponentCache; while (curComponent != NULL) { if (stSet_search(curComponent->nodes, node)) { break; } curComponent = curComponent->next; } assert(curComponent != NULL); return curComponent; }
stSet *stSet_getDifference(stSet *set1, stSet *set2) { stSet_verifySetsHaveSameFunctions(set1, set2); stSet *set3 = stSet_construct3(stSet_getHashFunction(set1), stSet_getEqualityFunction(set1), NULL); // Add those from set1 only if they are not in set2 stSetIterator *sit= stSet_getIterator(set1); void *o; while ((o = stSet_getNext(sit)) != NULL) { if (stSet_search(set2, o) == NULL) { stSet_insert(set3, o); } } stSet_destructIterator(sit); return set3; }
stTree *stTree_getMRCA(stTree *node1, stTree *node2) { // Find all of node 1's parents (inclusive of node 1) stSet *parents = stSet_construct(); stTree *curNode = node1; do { stSet_insert(parents, curNode); } while ((curNode = stTree_getParent(curNode)) != NULL); // Find the first parent of node 2 that is a parent of node 1 stTree *ret = NULL; curNode = node2; do { if (stSet_search(parents, curNode) != NULL) { ret = curNode; break; } } while ((curNode = stTree_getParent(curNode)) != NULL); stSet_destruct(parents); return ret; }
static void test_stSet_search(CuTest* testCase) { testSetup(); stIntTuple *i = stIntTuple_construct1( 0); stIntTuple *j = stIntTuple_construct2(10, 0); stIntTuple *k = stIntTuple_construct1( 5); //Check search by memory address CuAssertTrue(testCase, stSet_search(set0, one) == one); CuAssertTrue(testCase, stSet_search(set0, two) == two); CuAssertTrue(testCase, stSet_search(set0, three) == three); CuAssertTrue(testCase, stSet_search(set0, four) == four); CuAssertTrue(testCase, stSet_search(set0, five) == five); CuAssertTrue(testCase, stSet_search(set0, six) == six); //Check not present CuAssertTrue(testCase, stSet_search(set0, i) == NULL); CuAssertTrue(testCase, stSet_search(set0, j) == NULL); CuAssertTrue(testCase, stSet_search(set0, k) == NULL); //Check search by memory address CuAssertTrue(testCase, stSet_search(set1, one) == one); CuAssertTrue(testCase, stSet_search(set1, two) == two); CuAssertTrue(testCase, stSet_search(set1, three) == three); CuAssertTrue(testCase, stSet_search(set1, four) == four); CuAssertTrue(testCase, stSet_search(set1, five) == five); CuAssertTrue(testCase, stSet_search(set1, six) == six); //Check not present CuAssertTrue(testCase, stSet_search(set1, j) == NULL); //Check is searching by memory CuAssertTrue(testCase, stSet_search(set1, i) == one); CuAssertTrue(testCase, stSet_search(set1, k) == six); stIntTuple_destruct(i); stIntTuple_destruct(j); stIntTuple_destruct(k); testTeardown(); }
// Compute the connected components, if they haven't been computed // already since the last modification. static void computeConnectedComponents(stNaiveConnectivity *connectivity) { if (connectivity->connectedComponentCache != NULL) { // Already computed the connected components. return; } stHashIterator *nodeIt = stHash_getIterator(connectivity->nodesToAdjList); void *node; stNaiveConnectedComponent *componentsHead = NULL; while ((node = stHash_getNext(nodeIt)) != NULL) { stSet *myNodeSet = stSet_construct(); stSet_insert(myNodeSet, node); struct adjacency *adjList = stHash_search(connectivity->nodesToAdjList, node); if (adjList != NULL) { while (adjList != NULL) { stSet_insert(myNodeSet, adjList->toNode); adjList = adjList->next; } } // Now go through the existing connected components and see if // this overlaps any of them. If it's not a full overlap, then // this set becomes the union, and we continue looking for // additional overlaps, then this becomes a new connected // component. If we find that this is a subset of an existing // component, we can quit early, since we can't possibly add // to it or any others. stNaiveConnectedComponent *curComponent = componentsHead; while (curComponent != NULL) { stNaiveConnectedComponent *next = curComponent->next; // Find out whether our node set is a subset of this // connected component, or if it shares any overlap. bool isSubset = true; bool overlap = false; stSetIterator *myNodeIt = stSet_getIterator(myNodeSet); void *node; while ((node = stSet_getNext(myNodeIt)) != NULL) { if (stSet_search(curComponent->nodes, node)) { overlap = true; } else { isSubset = false; } } stSet_destructIterator(myNodeIt); if (isSubset) { assert(overlap == true); // Quit early. stSet_destruct(myNodeSet); myNodeSet = NULL; break; } else if (overlap) { stSet *newNodeSet = stSet_getUnion(myNodeSet, curComponent->nodes); stSet_destruct(myNodeSet); removeComponent(&componentsHead, curComponent); myNodeSet = newNodeSet; } curComponent = next; } if (myNodeSet != NULL) { // We have a new (or possibly merged) connected component to // add to the list. stNaiveConnectedComponent *newComponent = malloc(sizeof(stNaiveConnectedComponent)); newComponent->nodes = myNodeSet; newComponent->next = componentsHead; componentsHead = newComponent; } } stHash_destructIterator(nodeIt); connectivity->connectedComponentCache = componentsHead; }
void stSet_insert(stSet *set, void *key) { if (stSet_search(set, key) != NULL) { // This will ensure we don't end up with duplicate keys.. stSet_remove(set, key); } stHash_insert(set->hash, key, key); }