Пример #1
0
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();
}
Пример #2
0
static void testSetup() {
    // compare by value of memory address
    set0 = stSet_construct();
    // compare by value of ints.
    set1 = stSet_construct3((uint64_t(*)(const void *)) stIntTuple_hashKey, 
                            (int(*)(const void *, const void *)) stIntTuple_equalsFn,
                            (void(*)(void *)) stIntTuple_destruct);
    one = stIntTuple_construct1( 0);
    two = stIntTuple_construct1( 1);
    three = stIntTuple_construct1( 2);
    four = stIntTuple_construct1( 3);
    five = stIntTuple_construct1( 4);
    six = stIntTuple_construct1( 5);
    stSet_insert(set0, one);
    stSet_insert(set0, two);
    stSet_insert(set0, three);
    stSet_insert(set0, four);
    stSet_insert(set0, five);
    stSet_insert(set0, six);
    stSet_insert(set1, one);
    stSet_insert(set1, two);
    stSet_insert(set1, three);
    stSet_insert(set1, four);
    stSet_insert(set1, five);
    stSet_insert(set1, six);
}
Пример #3
0
static void test_stSet_size(CuTest *testCase) {
    /*
     * Tests the size function of the hash.
     */
    testSetup();
    CuAssertTrue(testCase, stSet_size(set0) == 6);
    CuAssertTrue(testCase, stSet_size(set1) == 6);
    stSet *set2 = stSet_construct();
    CuAssertTrue(testCase, stSet_size(set2) == 0);
    stSet_destruct(set2);
    testTeardown();
}
Пример #4
0
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;
}
Пример #5
0
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();
}
// 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;
}