void testFlower_isLeaf(CuTest *testCase) { cactusFlowerTestSetup(); CuAssertTrue(testCase, flower_isLeaf(flower)); Group *group = group_construct2(flower); CuAssertTrue(testCase, flower_isLeaf(flower)); group_makeNestedFlower(group); CuAssertTrue(testCase, !flower_isLeaf(flower)); cactusFlowerTestTeardown(); }
void flower_check(Flower *flower) { eventTree_check(flower_getEventTree(flower)); Flower_GroupIterator *groupIterator = flower_getGroupIterator(flower); Group *group; while ((group = flower_getNextGroup(groupIterator)) != NULL) { group_check(group); } flower_destructGroupIterator(groupIterator); Flower_ChainIterator *chainIterator = flower_getChainIterator(flower); Chain *chain; while ((chain = flower_getNextChain(chainIterator)) != NULL) { chain_check(chain); } flower_destructCapIterator(chainIterator); //We check built trees in here. Flower_EndIterator *endIterator = flower_getEndIterator(flower); End *end; while ((end = flower_getNextEnd(endIterator)) != NULL) { end_check(end); end_check(end_getReverse(end)); //We will test everything backwards also. } flower_destructEndIterator(endIterator); if (flower_builtFaces(flower)) { Flower_FaceIterator *faceIterator = flower_getFaceIterator(flower); Face *face; while ((face = flower_getNextFace(faceIterator)) != NULL) { face_check(face); } flower_destructFaceIterator(faceIterator); face_checkFaces(flower); } else { cactusCheck(flower_getFaceNumber(flower) == 0); } if (flower_builtBlocks(flower)) { //Note that a flower for which the blocks are not yet built must be a leaf. Flower_BlockIterator *blockIterator = flower_getBlockIterator(flower); Block *block; while ((block = flower_getNextBlock(blockIterator)) != NULL) { block_check(block); block_check(block_getReverse(block)); //We will test everything backwards also. } flower_destructBlockIterator(blockIterator); } else { cactusCheck(flower_isLeaf(flower)); //Defensive cactusCheck(flower_isTerminal(flower)); //Checks that a flower without built blocks is a leaf and does not //contain any blocks. } Flower_SequenceIterator *sequenceIterator = flower_getSequenceIterator(flower); Sequence *sequence; while ((sequence = flower_getNextSequence(sequenceIterator)) != NULL) { sequence_check(sequence); } flower_destructSequenceIterator(sequenceIterator); }
bool flower_removeIfRedundant(Flower *flower) { if (!flower_isLeaf(flower) && flower_getParentGroup(flower) != NULL && flower_getBlockNumber(flower) == 0) { //We will remove this flower.. Group *parentGroup = flower_getParentGroup(flower); //This group will be destructed //Deal with any parent chain.. if (group_isLink(parentGroup)) { link_split(group_getLink(parentGroup)); } Flower *parentFlower = group_getFlower(parentGroup); //We will add the groups in the flower to the parent /* * For each group in the flower we take its nested flower and attach it to the parent. */ Group *group; Flower_GroupIterator *groupIt = flower_getGroupIterator(flower); while ((group = flower_getNextGroup(groupIt)) != NULL) { if (!group_isLeaf(group)) { //Copy the group into the parent.. Flower *nestedFlower = group_getNestedFlower(group); assert(nestedFlower != NULL); Group *newParentGroup = group_construct(parentFlower, nestedFlower); flower_setParentGroup(nestedFlower, newParentGroup); group_constructChainForLink(newParentGroup); } else { Group *newParentGroup = group_construct2(parentFlower); End *end; Group_EndIterator *endIt = group_getEndIterator(group); while ((end = group_getNextEnd(endIt)) != NULL) { End *parentEnd = flower_getEnd(parentFlower, end_getName(end)); assert(parentEnd != NULL); end_setGroup(parentEnd, newParentGroup); } group_destructEndIterator(endIt); group_constructChainForLink(newParentGroup); } } flower_destructGroupIterator(groupIt); //The group attached to the flower should now be empty assert(group_getEndNumber(parentGroup) == 0); group_destruct(parentGroup); //Now wipe the flower out.. cactusDisk_deleteFlowerFromDisk(flower_getCactusDisk(flower), flower); flower_destruct(flower, 0); return 1; } 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(); }