bool flower_deleteIfEmpty(Flower *flower) { if (flower_getEndNumber(flower) == 0 && flower_getParentGroup(flower) != NULL) { //contains nothing useful.. assert(flower_getChainNumber(flower) == 0); assert(flower_getBlockNumber(flower) == 0); while (flower_getGroupNumber(flower) > 0) { Group *group = flower_getFirstGroup(flower); if (!group_isLeaf(group)) { bool i = flower_deleteIfEmpty(group_getNestedFlower(group)); (void) i; assert(i); } } assert(flower_getGroupNumber(flower) == 0); //This needs modification so that we don't do this directly.. cactusDisk_deleteFlowerFromDisk(flower_getCactusDisk(flower), flower); Group *parentGroup = flower_getParentGroup(flower); group_destruct(parentGroup); flower_destruct(flower, 0); return 1; } return 0; }
void flower_checkNotEmpty(Flower *flower, bool recursive) { //First check the flower is not empty, unless it is the parent group. if (flower_hasParentGroup(flower)) { assert(flower_getGroupNumber(flower) > 0); assert(flower_getEndNumber(flower) > 0); assert(flower_getAttachedStubEndNumber(flower) > 0); //We must have some ends to tie us into the parent problem + flower_getBlockEndNumber(flower) > 0); } //Now Checks that each group contains at least one end and call recursive. Group *group; Flower_GroupIterator *groupIt = flower_getGroupIterator(flower); while ((group = flower_getNextGroup(groupIt)) != NULL) { assert(group_getEndNumber(group) > 0); assert(group_getAttachedStubEndNumber(group) + group_getBlockEndNumber(group) > 0); if (recursive && !group_isLeaf(group)) { flower_checkNotEmpty(group_getNestedFlower(group), 1); } } flower_destructGroupIterator(groupIt); }
void testGroup_makeNonLeaf(CuTest *testCase) { cactusGroupTestSetup(); CuAssertTrue(testCase, group_isLeaf(group2)); end_setGroup(end4, group2); group_makeNestedFlower(group2); CuAssertTrue(testCase, !group_isLeaf(group2)); Flower *nestedFlower = group_getNestedFlower(group2); CuAssertTrue(testCase, nestedFlower != NULL); CuAssertTrue(testCase, !flower_builtBlocks(flower)); CuAssertTrue(testCase, !flower_builtTrees(flower)); CuAssertTrue(testCase, !flower_builtFaces(flower)); CuAssertTrue(testCase, flower_getName(nestedFlower) == group_getName(group2)); CuAssertTrue(testCase, flower_getParentGroup(nestedFlower) == group2); CuAssertTrue(testCase, flower_getEndNumber(nestedFlower) == 1); End *nestedEnd = flower_getFirstEnd(nestedFlower); CuAssertTrue(testCase, end_getName(end4) == end_getName(nestedEnd)); CuAssertTrue(testCase, end_getGroup(nestedEnd) != NULL); CuAssertTrue(testCase, flower_getGroupNumber(nestedFlower) == 1); CuAssertTrue(testCase, flower_isTerminal(nestedFlower)); cactusGroupTestTeardown(); }
int main(int argc, char *argv[]) { st_setLogLevelFromString(argv[1]); st_logDebug("Set up logging\n"); stKVDatabaseConf *kvDatabaseConf = stKVDatabaseConf_constructFromString(argv[2]); CactusDisk *cactusDisk = cactusDisk_construct(kvDatabaseConf, 0); stKVDatabaseConf_destruct(kvDatabaseConf); st_logDebug("Set up the flower disk\n"); Name flowerName = cactusMisc_stringToName(argv[3]); Flower *flower = cactusDisk_getFlower(cactusDisk, flowerName); int64_t totalBases = flower_getTotalBaseLength(flower); int64_t totalEnds = flower_getEndNumber(flower); int64_t totalFreeEnds = flower_getFreeStubEndNumber(flower); int64_t totalAttachedEnds = flower_getAttachedStubEndNumber(flower); int64_t totalCaps = flower_getCapNumber(flower); int64_t totalBlocks = flower_getBlockNumber(flower); int64_t totalGroups = flower_getGroupNumber(flower); int64_t totalChains = flower_getChainNumber(flower); int64_t totalLinkGroups = 0; int64_t maxEndDegree = 0; int64_t maxAdjacencyLength = 0; int64_t totalEdges = 0; Flower_EndIterator *endIt = flower_getEndIterator(flower); End *end; while((end = flower_getNextEnd(endIt)) != NULL) { assert(end_getOrientation(end)); if(end_getInstanceNumber(end) > maxEndDegree) { maxEndDegree = end_getInstanceNumber(end); } stSortedSet *ends = stSortedSet_construct(); End_InstanceIterator *capIt = end_getInstanceIterator(end); Cap *cap; while((cap = end_getNext(capIt)) != NULL) { if(cap_getSequence(cap) != NULL) { Cap *adjacentCap = cap_getAdjacency(cap); assert(adjacentCap != NULL); End *adjacentEnd = end_getPositiveOrientation(cap_getEnd(adjacentCap)); stSortedSet_insert(ends, adjacentEnd); int64_t adjacencyLength = cap_getCoordinate(cap) - cap_getCoordinate(adjacentCap); if(adjacencyLength < 0) { adjacencyLength *= -1; } assert(adjacencyLength >= 1); if(adjacencyLength >= maxAdjacencyLength) { maxAdjacencyLength = adjacencyLength; } } } end_destructInstanceIterator(capIt); totalEdges += stSortedSet_size(ends); if(stSortedSet_search(ends, end) != NULL) { //This ensures we count self edges twice, so that the division works. totalEdges += 1; } stSortedSet_destruct(ends); } assert(totalEdges % 2 == 0); flower_destructEndIterator(endIt); Flower_GroupIterator *groupIt = flower_getGroupIterator(flower); Group *group; while((group = flower_getNextGroup(groupIt)) != NULL) { if(group_getLink(group) != NULL) { totalLinkGroups++; } } flower_destructGroupIterator(groupIt); printf("flower name: %" PRIi64 " total bases: %" PRIi64 " total-ends: %" PRIi64 " total-caps: %" PRIi64 " max-end-degree: %" PRIi64 " max-adjacency-length: %" PRIi64 " total-blocks: %" PRIi64 " total-groups: %" PRIi64 " total-edges: %" PRIi64 " total-free-ends: %" PRIi64 " total-attached-ends: %" PRIi64 " total-chains: %" PRIi64 " total-link groups: %" PRIi64 "\n", flower_getName(flower), totalBases, totalEnds, totalCaps, maxEndDegree, maxAdjacencyLength, totalBlocks, totalGroups, totalEdges/2, totalFreeEnds, totalAttachedEnds, totalChains, totalLinkGroups); return 0; }
bool flower_isTerminal(Flower *flower) { return flower_isLeaf(flower) && flower_getGroupNumber(flower) <= 1 && flower_getStubEndNumber(flower) == flower_getEndNumber(flower); }
void testFlower_removeIfRedundant(CuTest *testCase) { /* * Do a simple test to see if function can remove a redundant flower. */ cactusFlowerTestSetup(); endsSetup(); //First construct a redundant flower from the root. Flower *flower2 = flower_construct(cactusDisk); Group *group = group_construct(flower, flower2); end_setGroup(end, group); end_setGroup(end2, group); //Now hang another couple of flowers of that. Flower *flower3 = flower_construct(cactusDisk); group_construct(flower2, flower3); //Now hang another flower of that. Group *group3b = group_construct2(flower2); //Finally hang one more flower on the end.. Flower *flower4 = flower_construct(cactusDisk); group_construct(flower3, flower4); //Copy the ends into the flowers. end_copyConstruct(end, flower2); end_copyConstruct(end2, flower2); end_copyConstruct(end, flower3); end_setGroup(flower_getEnd(flower2, end_getName(end2)), group3b); end_copyConstruct(end, flower4); //st_uglyf("I got %" PRIi64 " %" PRIi64 " %" PRIi64 " %" PRIi64 "\n", flower_getName(flower), flower_getName(flower2), flower_getName(flower3), flower_getName(flower4)); //Write the mess to disk. cactusDisk_write(cactusDisk); //Now test the removal function (check we get a negative on this leaf). CuAssertTrue(testCase, !flower_removeIfRedundant(flower4)); //Check we can't remove the root.. CuAssertTrue(testCase, !flower_removeIfRedundant(flower)); //We will remove flower2 //Before CuAssertTrue(testCase, flower_getGroupNumber(flower) == 1); CuAssertTrue(testCase, group_getFlower(flower_getParentGroup(flower2)) == flower); CuAssertTrue(testCase, flower_removeIfRedundant(flower2)); //After, check the flower/group connections CuAssertTrue(testCase, flower_getGroupNumber(flower) == 2); CuAssertTrue(testCase, !flower_isLeaf(flower)); CuAssertTrue(testCase, group_getFlower(flower_getParentGroup(flower3)) == flower); group3b = end_getGroup(end2); CuAssertTrue(testCase, group_getFlower(group3b) == flower); CuAssertTrue(testCase, group_isLeaf(group3b)); CuAssertTrue(testCase, flower_getGroup(flower, flower_getName(flower3)) == flower_getParentGroup(flower3)); //Check the ends.. CuAssertTrue(testCase, flower_getEndNumber(flower) == 2); CuAssertTrue(testCase, flower_getEndNumber(flower3) == 1); CuAssertTrue(testCase, group_getEndNumber(group3b) == 1); CuAssertTrue(testCase, end_getGroup(end) == flower_getParentGroup(flower3)); CuAssertTrue(testCase, end_getGroup(end2) == group3b); CuAssertTrue(testCase, flower_getEnd(flower3, end_getName(end)) != NULL); //Check the child of 3 is still okay.. CuAssertTrue(testCase, group_getFlower(flower_getParentGroup(flower4)) == flower3); //Now do removal of flower3 CuAssertTrue(testCase, !flower_removeIfRedundant(flower)); CuAssertTrue(testCase, !flower_removeIfRedundant(flower4)); CuAssertTrue(testCase, flower_removeIfRedundant(flower3)); //Check groups again CuAssertTrue(testCase, flower_getGroupNumber(flower) == 2); CuAssertTrue(testCase, !flower_isLeaf(flower)); CuAssertTrue(testCase, group_getFlower(flower_getParentGroup(flower4)) == flower); CuAssertTrue(testCase, group_getFlower(group3b) == flower); CuAssertTrue(testCase, flower_getGroup(flower, flower_getName(flower4)) == flower_getParentGroup(flower4)); //Check the ends again.. CuAssertTrue(testCase, flower_getEndNumber(flower) == 2); CuAssertTrue(testCase, flower_getEndNumber(flower4) == 1); CuAssertTrue(testCase, group_getEndNumber(group3b) == 1); CuAssertTrue(testCase, end_getGroup(end) == flower_getParentGroup(flower4)); CuAssertTrue(testCase, end_getGroup(end2) == group3b); CuAssertTrue(testCase, flower_getEnd(flower4, end_getName(end)) != NULL); cactusFlowerTestTeardown(); }