Beispiel #1
0
stList *stSet_getKeys(stSet *set) {
    stList *list = stList_construct();
    stSetIterator *iterator = stSet_getIterator(set);
    void *item;
    while ((item = stSet_getNext(iterator)) != NULL) {
        stList_append(list, item);
    }
    stSet_destructIterator(iterator);
    return list;
}
Beispiel #2
0
stSet *stSet_getUnion(stSet *set1, stSet *set2) {
    stSet_verifySetsHaveSameFunctions(set1, set2);
    stSet *set3 = stSet_construct3(stSet_getHashFunction(set1), 
                                   stSet_getEqualityFunction(set1),
                                   NULL);
    // Add everything
    stSetIterator *sit= stSet_getIterator(set1);
    void *o;
    while ((o = stSet_getNext(sit)) != NULL) {
        stSet_insert(set3, o);
    }
    stSet_destructIterator(sit);
    sit = stSet_getIterator(set2);
    while ((o = stSet_getNext(sit)) != NULL) {
        stSet_insert(set3, o);
    }
    stSet_destructIterator(sit);
    return set3;
}
Beispiel #3
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();
}
Beispiel #4
0
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;
}
Beispiel #5
0
static void test_stSet_getIntersection(CuTest* testCase) {
    testSetup();
    // Check intersection of empty sets is empty
    stSet *set2 = stSet_construct();
    stSet *set3 = stSet_construct();
    stSet *set4 = stSet_getIntersection(set2, set3);
    CuAssertTrue(testCase, stSet_size(set4) == 0);
    stSet_destruct(set2);
    stSet_destruct(set3);
    stSet_destruct(set4);
    // Check intersection of non empty set and empty set is empy
    set2 = stSet_construct();
    set3 = stSet_getIntersection(set0, set2);
    CuAssertTrue(testCase, stSet_size(set3) == 0);
    stSet_destruct(set2);
    stSet_destruct(set3);
    // Check intersection 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_getIntersection(set2, set3);
    CuAssertTrue(testCase, stSet_size(set4) == 5);
    stSetIterator *sit = stSet_getIterator(set4);
    stIntTuple *itup;
    while ((itup = stSet_getNext(sit)) != NULL) {
        CuAssertTrue(testCase, stSet_search(set2, itup) != NULL);
        CuAssertTrue(testCase, stSet_search(set3, itup) != NULL);
    }
    for (int i = 0; i < 4; ++i) {
        CuAssertTrue(testCase, stSet_search(set4, uniqs[i]) == NULL);
    }
    stSet_destructIterator(sit);
    stSet_destruct(set2);
    stSet_destruct(set3);
    stSet_destruct(set4);
    // Check we get an exception with sets with different functions.
    stTry {
        stSet_getIntersection(set0, set1);
    } stCatch(except) {
        CuAssertTrue(testCase, stExcept_getId(except) == SET_EXCEPTION_ID);
    } stTryEnd
    testTeardown();
}
void stNaiveConnectedComponentNodeIterator_destruct(stNaiveConnectedComponentNodeIterator *it) {
    stSet_destructIterator(it->it);
    free(it);
}
// 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;
}