bool test_btree_cursor(int testn) { bool result = false, bsuccess = false, asuccess = false; int n; const uint16_t order = 5; // small, so we get lots of tree changes time_t start; int32_t rec, before, after; char * filename = "relative.itz"; itzam_btree btree; itzam_state state; if (testn < 0) testn = 50; // create an empty database file state = itzam_btree_create(&btree, filename, order, sizeof(int32_t), itzam_comparator_int32, error_handler); if (state != ITZAM_OKAY) { printf("uable to create index file\n"); return false; } // fill the btree with a known sequence int32_t largest = -1; int32_t x = -1; for (int n = 0; n < testn; ++n) { x += random_int32(3) + 1; largest = x; state = itzam_btree_insert(&btree, &x); if (state != ITZAM_OKAY) { printf("could not add %d to index file\n",n); return false; } } itzam_btree_analyze(&btree, stdout); itzam_btree_dump_btree(&btree); itzam_btree_cursor cursor; // forward tests printf("\nforward tests\n"); for (int target = 0; target < largest + 1; ++ target) { printf ("t = %3d: ", target); itzam_btree_cursor_create_at(&cursor, &btree, &target, false); do { // get the key pointed to by the cursor state = itzam_btree_cursor_read(&cursor,(void *)&rec); if (state == ITZAM_OKAY) { printf("%d, ",rec); fflush(stdout); } else not_okay(state); } while (itzam_btree_cursor_next(&cursor)); printf("\b\b\n"); itzam_btree_cursor_free(&cursor); } // backward tests printf("\nbackward tests\n"); for (int target = 0; target < largest + 1; ++target) { printf ("t = %3d: ", target); itzam_btree_cursor_create_at(&cursor, &btree, &target, false); do { // get the key pointed to by the cursor state = itzam_btree_cursor_read(&cursor,(void *)&rec); if (state == ITZAM_OKAY) { printf("%d, ",rec); fflush(stdout); } else not_okay(state); } while (itzam_btree_cursor_prev(&cursor)); printf("\b\b\n"); itzam_btree_cursor_free(&cursor); } // done return true; }
bool test_btree_insert() { itzam_btree btree; itzam_state state; record rec; int n; char * filename = "insert.itz"; itzam_int test_size = 10000000; int order = 25; time_t start = time(NULL); memset(&rec.m_data,0,REC_SIZE * sizeof(uint32_t)); rec.m_key = 0; // banner for this test printf("\nItzam/C B-Tree Test\nStraight Insertion Performance\n"); printf("Please wait while I insert %d records of %d bytes...\n", (int)test_size, (int)(REC_SIZE * sizeof(uint32_t))); state = itzam_btree_create(&btree, filename, order, sizeof(record), compare_recs, error_handler); if (state != ITZAM_OKAY) { not_okay(state); return false; } for (n = 1; n <= test_size; ++ n) { rec.m_key = n; rec.m_data[0] = n; rec.m_data[REC_SIZE - 1] = n; state = itzam_btree_insert(&btree,(const void *)&rec); if (state != ITZAM_OKAY) { not_okay(state); return false; } } time_t elapsed = time(NULL) - start; printf(" database count: %d\n", (int)btree.m_header->m_count); printf(" database ticker: %d\n", (int)btree.m_header->m_ticker); printf(" total run time: %d seconds\n", (int)elapsed); printf("insertions per second: %f\n", ((double)test_size / (double)elapsed)); // verify database after benchmark itzam_btree_cursor cursor; state = itzam_btree_cursor_create(&cursor, &btree); if (state == ITZAM_OKAY) { do { // get the key pointed to by the cursor state = itzam_btree_cursor_read(&cursor,(void *)&rec); if (state == ITZAM_OKAY) { if ((rec.m_key != rec.m_data[0]) || (rec.m_key != rec.m_data[REC_SIZE - 1])) { printf("ERROR: record retrieved for %u does not match %u or %u\n",rec.m_key,rec.m_data[0],rec.m_data[REC_SIZE - 1]); break; } } else not_okay(state); } while (itzam_btree_cursor_next(&cursor)); state = itzam_btree_cursor_free(&cursor); if (state != ITZAM_OKAY) return false; } state = itzam_btree_close(&btree); if (state != ITZAM_OKAY) { not_okay(state); return false; } return true; }
itzam_bool test_btree_overwrite() { itzam_datafile datafile; itzam_state state; char * record; char * filename = "overwrite.itz"; int n, i; itzam_ref w[TEST_SIZE]; // banner for this test printf("\nOverwrite Testing for Itzam/C B-tree indexes\n"); state = itzam_datafile_create(&datafile, filename); if (state != ITZAM_OKAY) { not_okay(state); return itzam_false; } itzam_datafile_set_error_handler(&datafile, error_handler); // fill datafile for (n = 0; n < TEST_SIZE; ++n) { record = (char *)malloc(REC_SIZE + 1); for (i = 0; i < REC_SIZE; ++i) record[i] = 'A' + n; record[REC_SIZE] = 0; w[n] = itzam_datafile_write(&datafile, record, REC_SIZE + 1, ITZAM_NULL_REF); free(record); } // display what's in the DB printf("\nInitial DB contents:\n"); itzam_int len; for (n = 0; n < TEST_SIZE; ++n) { itzam_datafile_seek(&datafile, w[n]); itzam_datafile_read_alloc(&datafile, (void **)&record, &len); printf(" %s @ %d\n", record, (int)w[n]); } // modify a few records what's in the DB char * change = "---"; itzam_datafile_overwrite(&datafile, (void *)change, 3, w[2], 4); itzam_datafile_overwrite(&datafile, (void *)change, 3, w[3], 0); itzam_datafile_overwrite(&datafile, (void *)change, 3, w[5], REC_SIZE - strlen(change)); // modify a few records what's in the DB state = itzam_datafile_overwrite(&datafile, (void *)change, 3, w[4], 9); if (state != ITZAM_OVERWRITE_TOO_LONG) { printf("Error: Overwrite beyond end of record should have failed.\n"); return itzam_false; } // modify a few records what's in the DB change = "****"; itzam_datafile_transaction_start(&datafile); itzam_datafile_overwrite(&datafile, (void *)change, 3, w[8], 5); itzam_datafile_overwrite(&datafile, (void *)change, 3, w[9], 0); itzam_datafile_transaction_rollback(&datafile); // display what's in the DB printf("\nAfter overwrites, DB contents:\n"); for (n = 0; n < TEST_SIZE; ++n) { itzam_datafile_seek(&datafile, w[n]); itzam_datafile_read_alloc(&datafile, (void **)&record, &len); printf(" %s @ %d\n", record, (int)w[n]); } printf("\nShould look like:\n"); printf(" AAAAAAAAAA @ 24\n"); printf(" BBBBBBBBBB @ 51\n"); printf(" CCCC---CCC @ 78\n"); printf(" ---DDDDDDD @ 105\n"); printf(" EEEEEEEEEE @ 132\n"); printf(" FFFFFFF--- @ 159\n"); printf(" GGGGGGGGGG @ 186\n"); printf(" HHHHHHHHHH @ 213\n"); printf(" IIIIIIIIII @ 240\n"); printf(" JJJJJJJJJJ @ 267\n\n"); // close state = itzam_datafile_close(&datafile); if (state != ITZAM_OKAY) { not_okay(state); return itzam_false; } return itzam_true; }