static void teardown() { if (database != NULL) { stKVDatabase_deleteFromDisk(database); stKVDatabase_destruct(database); database = NULL; } }
void cactusDisk_destruct(CactusDisk *cactusDisk) { Flower *flower; MetaSequence *metaSequence; while ((flower = stSortedSet_getFirst(cactusDisk->flowers)) != NULL) { flower_destruct(flower, FALSE); } stSortedSet_destruct(cactusDisk->flowers); stSortedSet_destruct(cactusDisk->flowerNamesMarkedForDeletion); while ((metaSequence = stSortedSet_getFirst(cactusDisk->metaSequences)) != NULL) { metaSequence_destruct(metaSequence); } stSortedSet_destruct(cactusDisk->metaSequences); //close DB stKVDatabase_destruct(cactusDisk->database); //Close the sequences files. if (cactusDisk->storeSequencesInAFile) { free(cactusDisk->sequencesFileName); free(cactusDisk->absSequencesFileName); if (cactusDisk->sequencesReadFileHandle != NULL) { fclose(cactusDisk->sequencesReadFileHandle); } if (cactusDisk->sequencesWriteFileHandle != NULL) { fsync(fileno(cactusDisk->sequencesWriteFileHandle)); fclose(cactusDisk->sequencesWriteFileHandle); } } else { assert(cactusDisk->sequencesFileName == NULL); assert(cactusDisk->sequencesReadFileHandle == NULL); assert(cactusDisk->absSequencesFileName == NULL); } stCache_destruct(cactusDisk->cache); //Get rid of the cache stCache_destruct(cactusDisk->stringCache); stList_destruct(cactusDisk->updateRequests); free(cactusDisk); }
static void readWriteAndRemoveRecordsLotsIteration(CuTest *testCase, int numRecords, bool reopenDatabase) { //Make a big old list of records.. stSortedSet *set = stSortedSet_construct3((int(*)(const void *, const void *)) stIntTuple_cmpFn, (void(*)(void *)) stIntTuple_destruct); while (stSortedSet_size(set) < numRecords) { int32_t key = st_randomInt(0, 100 * numRecords); stIntTuple *tuple = stIntTuple_construct(1, key); if (stSortedSet_search(set, tuple) == NULL) { CuAssertTrue(testCase, !stKVDatabase_containsRecord(database, key)); stSortedSet_insert(set, tuple); stKVDatabase_insertRecord(database, key, &key, sizeof(int32_t)); CuAssertTrue(testCase, stKVDatabase_containsRecord(database, key)); } else { CuAssertTrue(testCase, stKVDatabase_containsRecord(database, key)); stIntTuple_destruct(tuple); // already in db } } readWriteAndRemoveRecordsLotsCheck(testCase, set, 1); //Update all records to negate values stSortedSetIterator *it = stSortedSet_getIterator(set); stIntTuple *tuple; while ((tuple = stSortedSet_getNext(it)) != NULL) { int32_t *value = (int32_t *) stKVDatabase_getRecord(database, stIntTuple_getPosition(tuple, 0)); *value *= -1; stKVDatabase_updateRecord(database, stIntTuple_getPosition(tuple, 0), value, sizeof(int32_t)); CuAssertTrue(testCase, stKVDatabase_containsRecord(database, stIntTuple_getPosition(tuple, 0))); free(value); } stSortedSet_destructIterator(it); readWriteAndRemoveRecordsLotsCheck(testCase, set, -1); //Try optionally committing the transaction and reloading the database.. if (reopenDatabase) { //stKVDatabase_commitTransaction(database); stKVDatabase_destruct(database); database = stKVDatabase_construct(conf, false); //stKVDatabase_startTransaction(database); } //Now remove each one.. it = stSortedSet_getIterator(set); while ((tuple = stSortedSet_getNext(it)) != NULL) { CuAssertTrue(testCase, stKVDatabase_containsRecord(database, stIntTuple_getPosition(tuple, 0))); stKVDatabase_removeRecord(database, stIntTuple_getPosition(tuple, 0)); CuAssertTrue(testCase, !stKVDatabase_containsRecord(database, stIntTuple_getPosition(tuple, 0))); //Test we get exception if we remove twice. stTry { stKVDatabase_removeRecord(database, stIntTuple_getPosition(tuple, 0)); CuAssertTrue(testCase, 0); } stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == ST_KV_DATABASE_EXCEPTION_ID); }stTryEnd; } stSortedSet_destructIterator(it); CuAssertIntEquals(testCase, 0, stKVDatabase_getNumberOfRecords(database)); stSortedSet_destruct(set); }
int main(int argc, char *argv[]) { /* * Script for adding a reference genome to a flower. */ /* * Arguments/options */ char * logLevelString = NULL; char * cactusDiskDatabaseString = NULL; char * secondaryDatabaseString = NULL; char *referenceEventString = (char *) cactusMisc_getDefaultReferenceEventHeader(); bool bottomUpPhase = 0; /////////////////////////////////////////////////////////////////////////// // (0) Parse the inputs handed by genomeCactus.py / setup stuff. /////////////////////////////////////////////////////////////////////////// while (1) { static struct option long_options[] = { { "logLevel", required_argument, 0, 'a' }, { "cactusDisk", required_argument, 0, 'b' }, { "secondaryDisk", required_argument, 0, 'd' }, { "referenceEventString", required_argument, 0, 'g' }, { "help", no_argument, 0, 'h' }, { "bottomUpPhase", no_argument, 0, 'j' }, { 0, 0, 0, 0 } }; int option_index = 0; int key = getopt_long(argc, argv, "a:b:c:d:e:g:hi:j", long_options, &option_index); if (key == -1) { break; } switch (key) { case 'a': logLevelString = stString_copy(optarg); break; case 'b': cactusDiskDatabaseString = stString_copy(optarg); break; case 'd': secondaryDatabaseString = stString_copy(optarg); break; case 'g': referenceEventString = stString_copy(optarg); break; case 'h': usage(); return 0; case 'j': bottomUpPhase = 1; break; default: usage(); return 1; } } /////////////////////////////////////////////////////////////////////////// // (0) Check the inputs. /////////////////////////////////////////////////////////////////////////// assert(cactusDiskDatabaseString != NULL); ////////////////////////////////////////////// //Set up logging ////////////////////////////////////////////// st_setLogLevelFromString(logLevelString); ////////////////////////////////////////////// //Load the database ////////////////////////////////////////////// st_logInfo("referenceEventString = %s\n", referenceEventString); st_logInfo("bottomUpPhase = %i\n", bottomUpPhase); stKVDatabaseConf *kvDatabaseConf = stKVDatabaseConf_constructFromString(cactusDiskDatabaseString); CactusDisk *cactusDisk = cactusDisk_construct(kvDatabaseConf, false, true); stKVDatabaseConf_destruct(kvDatabaseConf); st_logInfo("Set up the flower disk\n"); stKVDatabase *sequenceDatabase = NULL; if (secondaryDatabaseString != NULL) { kvDatabaseConf = stKVDatabaseConf_constructFromString(secondaryDatabaseString); sequenceDatabase = stKVDatabase_construct(kvDatabaseConf, 0); stKVDatabaseConf_destruct(kvDatabaseConf); } FlowerStream *flowerStream = flowerWriter_getFlowerStream(cactusDisk, stdin); Flower *flower; while ((flower = flowerStream_getNext(flowerStream)) != NULL) { st_logDebug("Processing flower %" PRIi64 "\n", flower_getName(flower)); /////////////////////////////////////////////////////////////////////////// // Get the appropriate event names /////////////////////////////////////////////////////////////////////////// st_logInfo("%s\n", eventTree_makeNewickString(flower_getEventTree(flower))); Event *referenceEvent = eventTree_getEventByHeader(flower_getEventTree(flower), referenceEventString); if (referenceEvent == NULL) { st_errAbort("Reference event %s not found in tree. Check your " "--referenceEventString option", referenceEventString); } Name referenceEventName = event_getName(referenceEvent); /////////////////////////////////////////////////////////////////////////// // Now do bottom up or top down, depending /////////////////////////////////////////////////////////////////////////// stList *flowers = stList_construct(); stList_append(flowers, flower); preCacheNestedFlowers(cactusDisk, flowers); if (bottomUpPhase) { assert(sequenceDatabase != NULL); cactusDisk_preCacheSegmentStrings(cactusDisk, flowers); bottomUp(flowers, sequenceDatabase, referenceEventName, !flower_hasParentGroup(flower), generateJukesCantorMatrix); // Unload the nested flowers to save memory. They haven't // been changed, so we don't write them to the cactus // disk. Flower_GroupIterator *groupIt = flower_getGroupIterator(flower); Group *group; while ((group = flower_getNextGroup(groupIt)) != NULL) { if (!group_isLeaf(group)) { flower_unload(group_getNestedFlower(group)); } } flower_destructGroupIterator(groupIt); assert(!flower_isParentLoaded(flower)); // Write this flower to disk. cactusDisk_addUpdateRequest(cactusDisk, flower); } else { topDown(flower, referenceEventName); // We've changed the nested flowers, but not this // flower. We write the nested flowers to disk, then // unload them to save memory. This flower will be // unloaded by the flower-stream code. Flower_GroupIterator *groupIt = flower_getGroupIterator(flower); Group *group; while ((group = flower_getNextGroup(groupIt)) != NULL) { if (!group_isLeaf(group)) { cactusDisk_addUpdateRequest(cactusDisk, group_getNestedFlower(group)); flower_unload(group_getNestedFlower(group)); } } flower_destructGroupIterator(groupIt); } stList_destruct(flowers); } /////////////////////////////////////////////////////////////////////////// // Write the flower(s) back to disk. /////////////////////////////////////////////////////////////////////////// cactusDisk_write(cactusDisk); st_logInfo("Updated the flower on disk\n"); /////////////////////////////////////////////////////////////////////////// //Clean up. /////////////////////////////////////////////////////////////////////////// if (sequenceDatabase != NULL) { stKVDatabase_destruct(sequenceDatabase); } cactusDisk_destruct(cactusDisk); return 0; //Exit without clean up is quicker, enable cleanup when doing memory leak detection. free(cactusDiskDatabaseString); free(referenceEventString); free(logLevelString); st_logInfo("Cleaned stuff up and am finished\n"); return 0; }