Exemple #1
0
void testCactusDisk_getUniqueID_UniqueIntervals(CuTest* testCase) {
    cactusDiskTestSetup();
    stSortedSet *uniqueNames = stSortedSet_construct3(testCactusDisk_getUniqueID_UniqueP, free);
    for (int64_t i = 0; i < 10; i++) { //Gets a billion ids, checks we are good.
        int64_t intervalSize = st_randomInt(0, 100000);
        Name uniqueName = cactusDisk_getUniqueIDInterval(cactusDisk, intervalSize);
        for(int64_t j=0; j<intervalSize; j++) {
            CuAssertTrue(testCase, uniqueName > 0);
            CuAssertTrue(testCase, uniqueName < INT64_MAX);
            CuAssertTrue(testCase, uniqueName != NULL_NAME);
            char *cA = cactusMisc_nameToString(uniqueName);
            CuAssertTrue(testCase, stSortedSet_search(uniqueNames, cA) == NULL);
            CuAssertTrue(testCase, cactusMisc_stringToName(cA) == uniqueName);
            stSortedSet_insert(uniqueNames, cA);
            uniqueName++;
        }
    }
    stSortedSet_destruct(uniqueNames);
    cactusDiskTestTeardown();
}
Exemple #2
0
Name cactusDisk_addString(CactusDisk *cactusDisk, const char *string) {
    /*
     * Adds a string to the database.
     */
    if (cactusDisk->storeSequencesInAFile) {
        if (cactusDisk->sequencesWriteFileHandle == NULL) {
            //We do not allow the read file handle to be open at the same time.
            if (cactusDisk->sequencesReadFileHandle != NULL) {
                fclose(cactusDisk->sequencesReadFileHandle);
                cactusDisk->sequencesReadFileHandle = NULL;
            }
            cactusDisk->sequencesWriteFileHandle = fopen(cactusDisk->absSequencesFileName, "a");
            assert(cactusDisk->sequencesWriteFileHandle != NULL);
        }
        else {
            //The read file handle should not be open at the same time.
            assert(cactusDisk->sequencesReadFileHandle == NULL);
        }
        Name name = ftell(cactusDisk->sequencesWriteFileHandle) + 1;

        //Extra temporary cheesy code to avoid potential overflow in fprintf
        int64_t chunkSize = 1000000000; //1 gig approx chunks, to avoid a possible overflow issue with fprintf
        int64_t length = strlen(string);
        if (length > chunkSize) {
            fprintf(cactusDisk->sequencesWriteFileHandle, ">");
            for (int64_t i = 0; i < length;) {
                int64_t j = i + chunkSize <= length ? chunkSize : length - i;
                char *string2 = memcpy(st_malloc(sizeof(char) * (j + 1)), string + i, sizeof(char) * j);
                string2[j] = '\0';
                int64_t k = fprintf(cactusDisk->sequencesWriteFileHandle, "%s", string2);
                (void) k;
                assert(k == j);
                free(string2);
                i += j;
            }
        } else {
            //Replacing this line
            int64_t k = fprintf(cactusDisk->sequencesWriteFileHandle, ">%s", string);
            (void) k;
            assert(k == length + 1);
        }

#ifndef NDEBUG
        // Extra fsync may not be necessary.
        fsync(fileno(cactusDisk->sequencesWriteFileHandle));
        fclose(cactusDisk->sequencesWriteFileHandle);
        cactusDisk->sequencesWriteFileHandle = NULL;
        cactusDisk->sequencesReadFileHandle = fopen(cactusDisk->absSequencesFileName, "r");
        char *string2 = getStringFromDisk(cactusDisk->sequencesReadFileHandle, name, 0, length);
        for (int64_t i = 0; i < length; i++) {
            assert(string[i] == string2[i]);
        }
        free(string2);
#endif
        return name;
    } else {
        int64_t stringSize = strlen(string);
        int64_t intervalSize = ceil((double) stringSize / CACTUS_DISK_SEQUENCE_CHUNK_SIZE);
        Name name = cactusDisk_getUniqueIDInterval(cactusDisk, intervalSize);
        stList *insertRequests = stList_construct3(0, (void (*)(void *)) stKVDatabaseBulkRequest_destruct);
        for (int64_t i = 0; i * CACTUS_DISK_SEQUENCE_CHUNK_SIZE < stringSize; i++) {
            int64_t j =
                    (i + 1) * CACTUS_DISK_SEQUENCE_CHUNK_SIZE < stringSize ?
                            CACTUS_DISK_SEQUENCE_CHUNK_SIZE : stringSize - i * CACTUS_DISK_SEQUENCE_CHUNK_SIZE;
            char *subString = stString_getSubString(string, i * CACTUS_DISK_SEQUENCE_CHUNK_SIZE, j);
            stList_append(insertRequests, stKVDatabaseBulkRequest_constructInsertRequest(name + i, subString, j + 1));
            free(subString);
        }
        stTry
            {
                stKVDatabase_bulkSetRecords(cactusDisk->database, insertRequests);
            }
            stCatch(except)
                {
                    stThrowNewCause(except, ST_KV_DATABASE_EXCEPTION_ID,
                            "An unknown database error occurred when we tried to add a string to the cactus disk");
                }stTryEnd
        ;
        stList_destruct(insertRequests);
        return name;
    }
}