// Black box tester, uses only the public interfaces. #include "gpma.h" #include "memory.h" #include "toku_assert.h" #include "../include/db.h" #include #include int verbose; static int count_frees=0; static void free_callback (u_int32_t len __attribute__((__unused__)), void*freeme, void *extra) { assert(extra==(void*)&verbose); toku_free(freeme); count_frees++; } static void test_create_and_free (void) { int r; GPMA pma; r = toku_gpma_create(&pma, 0); assert(r==0); count_frees=0; toku_gpma_free(&pma, free_callback, &verbose); assert(count_frees==0); } static int compare_strings(u_int32_t alen, void *aval, u_int32_t blen, void *bval, void *extra __attribute__((__unused__))) { assert(alen==strlen(aval)+1); assert(blen==strlen(bval)+1); return strcmp(aval, bval); } static int rcall_never (u_int32_t nitems __attribute__((__unused__)), u_int32_t *froms __attribute__((__unused__)), u_int32_t *tos __attribute__((__unused__)), struct gitem *items __attribute__((__unused__)), u_int32_t old_N __attribute__((__unused__)), u_int32_t new_N __attribute__((__unused__)), void *extra __attribute__((__unused__))) { assert(0); return 0; } static int rcall_ok (u_int32_t nitems __attribute__((__unused__)), u_int32_t *froms __attribute__((__unused__)), u_int32_t *tos __attribute__((__unused__)), struct gitem *items __attribute__((__unused__)), u_int32_t old_N __attribute__((__unused__)), u_int32_t new_N __attribute__((__unused__)), void *extra __attribute__((__unused__))) { return 0; } static void test_insert_A (void) { int r; GPMA pma; r = toku_gpma_create(&pma, 0); assert(r==0); char *k1,*k2,*k3; r = toku_gpma_insert(pma, 6, k1=strdup("hello"), compare_strings, 0, rcall_never, "hello", 0); assert(r==0); assert(toku_gpma_n_entries(pma)==1); r = toku_gpma_insert(pma, 6, k2=strdup("gello"), compare_strings, 0, rcall_ok, "gello", 0); assert(r==0); r = toku_gpma_insert(pma, 6, k3=strdup("fello"), compare_strings, 0, rcall_ok, "fello", 0); assert(r==0); void *k; r = toku_gpma_insert(pma, 6, k=strdup("fello"), compare_strings, 0, rcall_ok, "fello", 0); assert(r==DB_KEYEXIST); toku_free(k); //printf("size=%d\n", toku_gpma_index_limit(pma)); u_int32_t resultlen; void *resultdata; r = toku_gpma_lookup_item(pma, 6, "hello", compare_strings, 0, &resultlen, &resultdata, 0); assert(r==0); assert(strcmp(resultdata, "hello")==0); assert(resultdata==k1); r = toku_gpma_lookup_item(pma, 6, "gello", compare_strings, 0, &resultlen, &resultdata, 0); assert(r==0); assert(strcmp(resultdata, "gello")==0); assert(resultdata==k2); u_int32_t idx=999; r = toku_gpma_lookup_item(pma, 6, "fello", compare_strings, 0, &resultlen, &resultdata, &idx); assert(r==0); assert(strcmp(resultdata, "fello")==0); assert(resultdata==k3); assert(idx!=999); r = toku_gpma_lookup_item(pma, 6, "aello", compare_strings, 0, &resultlen, &resultdata, 0); assert(r==DB_NOTFOUND); r = toku_gpma_lookup_item(pma, 6, "fillo", compare_strings, 0, &resultlen, &resultdata, 0); assert(r==DB_NOTFOUND); r = toku_gpma_lookup_item(pma, 6, "gillo", compare_strings, 0, &resultlen, &resultdata, 0); assert(r==DB_NOTFOUND); r = toku_gpma_lookup_item(pma, 6, "hillo", compare_strings, 0, &resultlen, &resultdata, 0); assert(r==DB_NOTFOUND); r = toku_gpma_lookup_item(pma, 6, "zello", compare_strings, 0, &resultlen, &resultdata, 0); assert(r==DB_NOTFOUND); { int bes (u_int32_t dlen __attribute__((__unused__)), void *dval, void *extra __attribute__((__unused__))) { return strcmp(dval, "a"); // This will return 1 for everything. For dir<=0 we'll have DB_NOTFOUND, for dir>0 we'll have "fello" } r = toku_gpma_lookup_bessel(pma, bes, -1, 0, &resultlen, &resultdata, 0); assert(r==DB_NOTFOUND); r = toku_gpma_lookup_bessel(pma, bes, 0, 0, &resultlen, &resultdata, 0); assert(r==DB_NOTFOUND); r = toku_gpma_lookup_bessel(pma, bes, +1, 0, &resultlen, &resultdata, 0); assert(r==0); assert(strcmp(resultdata, "fello")==0); } { int bes (u_int32_t dlen __attribute__((__unused__)), void *dval, void *extra __attribute__((__unused__))) { return strcmp(dval, "z"); // This will return -1 for everything. For dir>=0 we'll have DB_NOTFOUND, for dir<0 we'll have "hello" } r = toku_gpma_lookup_bessel(pma, bes, -1, 0, &resultlen, &resultdata, 0); // find the rightmost thing assert(r==0); assert(strcmp(resultdata, "hello")==0); r = toku_gpma_lookup_bessel(pma, bes, 0, 0, &resultlen, &resultdata, 0); assert(r==DB_NOTFOUND); r = toku_gpma_lookup_bessel(pma, bes, +1, 0, &resultlen, &resultdata, 0); assert(r==DB_NOTFOUND); } count_frees=0; toku_gpma_free(&pma, free_callback, &verbose); assert(count_frees==3); } void test_split_internal (const char *strings[], int expect_n_left, u_int32_t *expect_froms_left, u_int32_t *expect_tos_left, int expect_n_right, u_int32_t *expect_froms_right, u_int32_t *expect_tos_right) { GPMA pma1, pma2; int r; r = toku_gpma_create(&pma1, 0); assert(r==0); r = toku_gpma_create(&pma2, 0); assert(r==0); assert(0==toku_gpma_valididx(pma1, toku_gpma_index_limit(pma1))); // because it's off the end of the array assert(0==toku_gpma_valididx(pma1, 0)); // because nothing is there assert(0!=toku_gpma_get_from_index(pma1, toku_gpma_index_limit(pma1), 0, 0)); u_int32_t i; u_int32_t current_estimate_of_N = toku_gpma_index_limit(pma1); //printf("%s:%d N=%d\n", __FILE__, __LINE__, current_estimate_of_N); for (i=0; strings[i]; i++) { int rcall_a (u_int32_t nitems __attribute__((__unused__)), u_int32_t *froms __attribute__((__unused__)), u_int32_t *tos __attribute__((__unused__)), struct gitem *items __attribute__((__unused__)), u_int32_t old_N, u_int32_t new_N, void *extra __attribute__((__unused__))) { //printf("%s:%d old_N=%d new_N=%d est=%d\n", __FILE__, __LINE__, old_N, new_N, current_estimate_of_N); assert(old_N==current_estimate_of_N); current_estimate_of_N = new_N; //printf("est=%d\n", current_estimate_of_N); return 0; } u_int32_t idx, len; void *data; r = toku_gpma_insert(pma1, 1+strlen(strings[i]), (char*)strings[i], compare_strings, 0, rcall_a, (char*)strings[i], &idx); //printf("est=%d\n", current_estimate_of_N); assert(r==0); r = toku_gpma_get_from_index(pma1, idx, &len, &data); assert(r==0); assert(len==1+strlen(strings[i])); assert(data==strings[i]); } u_int32_t n_strings = i; { int do_realloc (u_int32_t len, void *data, void**ndata, void *extra) { assert(extra==0); assert(len=1+strlen(data)); *ndata = data; // Don't have to do anything return 0; } int did_n_left=-1, did_n_right=-1; int rcall0 (u_int32_t nitems, u_int32_t *froms, u_int32_t *tos, struct gitem *items, u_int32_t old_N, u_int32_t new_N, void *extra) { //printf("%s:%d old_N=%d new_N=%d\n", __FILE__, __LINE__, old_N, new_N); assert(old_N==current_estimate_of_N); current_estimate_of_N = new_N; assert(extra==0); u_int32_t j; if (expect_n_left>=0) assert(nitems==(u_int32_t)expect_n_left); did_n_left=nitems; //printf("did_n_left=%d nitems=%d n_strings=%d\n", did_n_left, nitems, n_strings); assert(did_n_left+nitems==n_strings); //printf("inner moved:"); for (j=0; j%d", froms[j], tos[j]); printf("\n"); for (j=0; j0) { assert(froms[j-1]=0) assert(nitems==(u_int32_t)expect_n_right); //printf("outer moved:"); for (j=0; j%d", froms[j], tos[j]); printf("\n"); for (j=0; j0) { assert(froms[j-1]=0 || foundem_right[j]>=0); } } toku_gpma_free(&pma1, 0, 0); toku_gpma_free(&pma2, 0, 0); } void test_split (void) { { const char *strings[]={"the", "quick", "brown", "fox", 0}; u_int32_t expect_froms_l[]={1,3}; u_int32_t expect_tos_l []={0,2}; u_int32_t expect_froms_r[]={5,7}; u_int32_t expect_tos_r []={0,2}; test_split_internal(strings, 2, expect_froms_l, expect_tos_l, 2, expect_froms_r, expect_tos_r); } } int delete_free_callback (u_int32_t slotnum __attribute__((__unused__)), u_int32_t deletelen, void *deletedata, void *extra) { assert(deletelen==6); assert(extra==deletedata); //printf("Freeing %s\n", (char*)deletedata); toku_free(deletedata); return 0; } void test_delete_n (int N) { GPMA pma; int r = toku_gpma_create(&pma, 0); assert(r==0); int i; char *strings[N]; for (i=0; i