mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 14:54:20 +01:00
remove app_private; merge in dup pma;
git-svn-id: file:///svn/tokudb@567 c7de825b-a66e-492c-adef-691d508d4ae1
This commit is contained in:
parent
0e463512cb
commit
1620ec5815
8 changed files with 273 additions and 352 deletions
|
@ -57,6 +57,13 @@ struct brtnode {
|
|||
} u;
|
||||
};
|
||||
|
||||
enum {
|
||||
BRT_PIVOT_PRESENT_L = 1,
|
||||
BRT_PIVOT_PRESENT_R = 2,
|
||||
BRT_PIVOT_TRUNC = 4,
|
||||
BRT_PIVOT_FRONT_COMPRESS = 8,
|
||||
};
|
||||
|
||||
struct brt_header {
|
||||
int dirty;
|
||||
unsigned int nodesize;
|
||||
|
@ -106,10 +113,6 @@ void brtnode_free (BRTNODE *node);
|
|||
|
||||
//int write_brt_header (int fd, struct brt_header *header);
|
||||
|
||||
static inline void brtnode_set_dirty(BRTNODE node) {
|
||||
node->dirty = 1;
|
||||
}
|
||||
|
||||
#if 1
|
||||
#define DEADBEEF ((void*)0xDEADBEEF)
|
||||
#else
|
||||
|
|
|
@ -693,26 +693,14 @@ void test_cursor_next (void) {
|
|||
|
||||
}
|
||||
|
||||
static int nonce;
|
||||
DB nonce_db;
|
||||
|
||||
DBT *fill_b(DBT *x, unsigned char *key, unsigned int keylen) {
|
||||
fill_dbt(x, key, keylen);
|
||||
#if USE_DBT_APP_PRIVATE
|
||||
x->app_private = &nonce;
|
||||
#endif
|
||||
return x;
|
||||
}
|
||||
|
||||
int wrong_compare_fun(DB *db, const DBT *a, const DBT *b) {
|
||||
unsigned int i;
|
||||
unsigned char *ad=a->data;
|
||||
unsigned char *bd=b->data;
|
||||
unsigned int siz=a->size;
|
||||
assert(a->size==b->size);
|
||||
#if USE_DBT_APP_PRIVATE
|
||||
assert(a->app_private == &nonce); // a must have the nonce in it, but I don't care if b does.
|
||||
#endif
|
||||
assert(db==&nonce_db); // make sure the db was passed down correctly
|
||||
for (i=0; i<siz; i++) {
|
||||
if (ad[siz-1-i]<bd[siz-1-i]) return -1;
|
||||
|
@ -738,8 +726,8 @@ static void test_wrongendian_compare (int wrong_p, unsigned int N) {
|
|||
char a[4]={0,1,0,0};
|
||||
char b[4]={1,0,0,0};
|
||||
DBT at, bt;
|
||||
assert(wrong_compare_fun(&nonce_db, fill_dbt_ap(&at, a, 4, &nonce), fill_dbt(&bt, b, 4))>0);
|
||||
assert(wrong_compare_fun(&nonce_db, fill_dbt_ap(&at, b, 4, &nonce), fill_dbt(&bt, a, 4))<0);
|
||||
assert(wrong_compare_fun(&nonce_db, fill_dbt(&at, a, 4), fill_dbt(&bt, b, 4))>0);
|
||||
assert(wrong_compare_fun(&nonce_db, fill_dbt(&at, b, 4), fill_dbt(&bt, a, 4))<0);
|
||||
}
|
||||
|
||||
r = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0);
|
||||
|
@ -753,7 +741,7 @@ static void test_wrongendian_compare (int wrong_p, unsigned int N) {
|
|||
b[2] = a[1] = (i>>8)&255;
|
||||
b[1] = a[2] = (i>>16)&255;
|
||||
b[0] = a[3] = (i>>24)&255;
|
||||
fill_b(&kbt, a, sizeof(a));
|
||||
fill_dbt(&kbt, a, sizeof(a));
|
||||
fill_dbt(&vbt, b, sizeof(b));
|
||||
printf("%s:%d insert: %02x%02x%02x%02x -> %02x%02x%02x%02x\n", __FILE__, __LINE__,
|
||||
((char*)kbt.data)[0], ((char*)kbt.data)[1], ((char*)kbt.data)[2], ((char*)kbt.data)[3],
|
||||
|
@ -788,7 +776,7 @@ static void test_wrongendian_compare (int wrong_p, unsigned int N) {
|
|||
b[2] = a[1] = (i>>8)&255;
|
||||
b[1] = a[2] = (i>>16)&255;
|
||||
b[0] = a[3] = (i>>24)&255;
|
||||
fill_b(&kbt, a, sizeof(a));
|
||||
fill_dbt(&kbt, a, sizeof(a));
|
||||
fill_dbt(&vbt, b, sizeof(b));
|
||||
if (0) printf("%s:%d insert: %02x%02x%02x%02x -> %02x%02x%02x%02x\n", __FILE__, __LINE__,
|
||||
((unsigned char*)kbt.data)[0], ((unsigned char*)kbt.data)[1], ((unsigned char*)kbt.data)[2], ((unsigned char*)kbt.data)[3],
|
||||
|
@ -827,28 +815,11 @@ static void test_wrongendian_compare (int wrong_p, unsigned int N) {
|
|||
|
||||
int test_cursor_debug = 0;
|
||||
|
||||
DB *test_db = 0;
|
||||
void *test_app_private = 0;
|
||||
|
||||
void set_test_db_app(DB *db, void *app_private) {
|
||||
test_db = db;
|
||||
test_app_private = app_private;
|
||||
}
|
||||
|
||||
void clear_test_db() {
|
||||
test_db = null_db;
|
||||
test_app_private = 0;
|
||||
}
|
||||
|
||||
int test_brt_cursor_keycompare(DB *db, const DBT *a, const DBT *b) {
|
||||
assert(db == test_db);
|
||||
#if USE_DBT_APP_PRIVATE
|
||||
assert(a->app_private == test_app_private);
|
||||
#endif
|
||||
int test_brt_cursor_keycompare(DB *db __attribute__((unused)), const DBT *a, const DBT *b) {
|
||||
return keycompare(a->data, a->size, b->data, b->size);
|
||||
}
|
||||
|
||||
void assert_cursor_notfound(BRT brt, int position, DB *db, void *app_private) {
|
||||
void assert_cursor_notfound(BRT brt, int position, DB *db) {
|
||||
BRT_CURSOR cursor;
|
||||
int r;
|
||||
DBT kbt, vbt;
|
||||
|
@ -856,7 +827,7 @@ void assert_cursor_notfound(BRT brt, int position, DB *db, void *app_private) {
|
|||
r = brt_cursor(brt, &cursor);
|
||||
assert(r==0);
|
||||
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC; dbt_set_app_private(&kbt, app_private);
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC;
|
||||
init_dbt(&vbt); vbt.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursor, &kbt, &vbt, position, db, null_txn);
|
||||
assert(r == DB_NOTFOUND);
|
||||
|
@ -865,7 +836,7 @@ void assert_cursor_notfound(BRT brt, int position, DB *db, void *app_private) {
|
|||
assert(r==0);
|
||||
}
|
||||
|
||||
void assert_cursor_value(BRT brt, int position, long long value, DB *db, void *app_private) {
|
||||
void assert_cursor_value(BRT brt, int position, long long value, DB *db) {
|
||||
BRT_CURSOR cursor;
|
||||
int r;
|
||||
DBT kbt, vbt;
|
||||
|
@ -875,7 +846,7 @@ void assert_cursor_value(BRT brt, int position, long long value, DB *db, void *a
|
|||
assert(r==0);
|
||||
|
||||
if (test_cursor_debug) printf("key: ");
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC; dbt_set_app_private(&kbt, app_private);
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC;
|
||||
init_dbt(&vbt); vbt.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursor, &kbt, &vbt, position, db, null_txn);
|
||||
assert(r == 0);
|
||||
|
@ -891,7 +862,7 @@ void assert_cursor_value(BRT brt, int position, long long value, DB *db, void *a
|
|||
assert(r==0);
|
||||
}
|
||||
|
||||
void assert_cursor_first_last(BRT brt, long long firstv, long long lastv, DB *db, void *app_private) {
|
||||
void assert_cursor_first_last(BRT brt, long long firstv, long long lastv, DB *db) {
|
||||
BRT_CURSOR cursor;
|
||||
int r;
|
||||
DBT kbt, vbt;
|
||||
|
@ -901,7 +872,7 @@ void assert_cursor_first_last(BRT brt, long long firstv, long long lastv, DB *db
|
|||
assert(r==0);
|
||||
|
||||
if (test_cursor_debug) printf("first key: ");
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC; dbt_set_app_private(&kbt, app_private);
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC;
|
||||
init_dbt(&vbt); vbt.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursor, &kbt, &vbt, DB_FIRST, db, null_txn);
|
||||
assert(r == 0);
|
||||
|
@ -914,7 +885,7 @@ void assert_cursor_first_last(BRT brt, long long firstv, long long lastv, DB *db
|
|||
if (test_cursor_debug) printf("\n");
|
||||
|
||||
if (test_cursor_debug) printf("last key:");
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC; dbt_set_app_private(&kbt, app_private);
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC;
|
||||
init_dbt(&vbt); vbt.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursor, &kbt, &vbt, DB_LAST, db, null_txn);
|
||||
assert(r == 0);
|
||||
|
@ -936,11 +907,9 @@ void test_brt_cursor_first(int n, DB *db) {
|
|||
BRT brt;
|
||||
int r;
|
||||
int i;
|
||||
int my_app_private;
|
||||
|
||||
printf("test_brt_cursor_first:%d %p\n", n, db);
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
r = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
|
@ -955,7 +924,7 @@ void test_brt_cursor_first(int n, DB *db) {
|
|||
DBT kbt, vbt;
|
||||
|
||||
snprintf(key, sizeof key, "%4.4d", i);
|
||||
fill_dbt_ap(&kbt, key, strlen(key)+1, &my_app_private);
|
||||
fill_dbt(&kbt, key, strlen(key)+1);
|
||||
v = i;
|
||||
fill_dbt(&vbt, &v, sizeof v);
|
||||
r = brt_insert(brt, &kbt, &vbt, db, 0);
|
||||
|
@ -963,17 +932,15 @@ void test_brt_cursor_first(int n, DB *db) {
|
|||
}
|
||||
|
||||
if (n == 0)
|
||||
assert_cursor_notfound(brt, DB_FIRST, db, &my_app_private);
|
||||
assert_cursor_notfound(brt, DB_FIRST, db);
|
||||
else
|
||||
assert_cursor_value(brt, DB_FIRST, 0, db, &my_app_private);
|
||||
assert_cursor_value(brt, DB_FIRST, 0, db);
|
||||
|
||||
r = close_brt(brt);
|
||||
assert(r==0);
|
||||
|
||||
r = cachetable_close(&ct);
|
||||
assert(r==0);
|
||||
|
||||
clear_test_db();
|
||||
}
|
||||
|
||||
void test_brt_cursor_last(int n, DB *db) {
|
||||
|
@ -982,11 +949,9 @@ void test_brt_cursor_last(int n, DB *db) {
|
|||
BRT brt;
|
||||
int r;
|
||||
int i;
|
||||
int my_app_private;
|
||||
|
||||
printf("test_brt_cursor_last:%d %p\n", n, db);
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
r = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
|
@ -1001,7 +966,7 @@ void test_brt_cursor_last(int n, DB *db) {
|
|||
DBT kbt, vbt;
|
||||
|
||||
snprintf(key, sizeof key, "%4.4d", i);
|
||||
fill_dbt_ap(&kbt, key, strlen(key)+1, &my_app_private);
|
||||
fill_dbt(&kbt, key, strlen(key)+1);
|
||||
v = i;
|
||||
fill_dbt(&vbt, &v, sizeof v);
|
||||
r = brt_insert(brt, &kbt, &vbt, db, 0);
|
||||
|
@ -1009,17 +974,15 @@ void test_brt_cursor_last(int n, DB *db) {
|
|||
}
|
||||
|
||||
if (n == 0)
|
||||
assert_cursor_notfound(brt, DB_LAST, db, &my_app_private);
|
||||
assert_cursor_notfound(brt, DB_LAST, db);
|
||||
else
|
||||
assert_cursor_value(brt, DB_LAST, n-1, db, &my_app_private);
|
||||
assert_cursor_value(brt, DB_LAST, n-1, db);
|
||||
|
||||
r = close_brt(brt);
|
||||
assert(r==0);
|
||||
|
||||
r = cachetable_close(&ct);
|
||||
assert(r==0);
|
||||
|
||||
clear_test_db();
|
||||
}
|
||||
|
||||
void test_brt_cursor_first_last(int n, DB *db) {
|
||||
|
@ -1028,11 +991,9 @@ void test_brt_cursor_first_last(int n, DB *db) {
|
|||
BRT brt;
|
||||
int r;
|
||||
int i;
|
||||
int my_app_private;
|
||||
|
||||
printf("test_brt_cursor_first_last:%d %p\n", n, db);
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
r = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
|
@ -1047,18 +1008,19 @@ void test_brt_cursor_first_last(int n, DB *db) {
|
|||
DBT kbt, vbt;
|
||||
|
||||
snprintf(key, sizeof key, "%4.4d", i);
|
||||
fill_dbt_ap(&kbt, key, strlen(key)+1, &my_app_private);
|
||||
fill_dbt(&kbt, key, strlen(key)+1);
|
||||
v = i;
|
||||
fill_dbt(&vbt, &v, sizeof v);
|
||||
|
||||
r = brt_insert(brt, &kbt, &vbt, db, 0);
|
||||
assert(r==0);
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
assert_cursor_notfound(brt, DB_FIRST, db, &my_app_private);
|
||||
assert_cursor_notfound(brt, DB_LAST, db, &my_app_private);
|
||||
assert_cursor_notfound(brt, DB_FIRST, db);
|
||||
assert_cursor_notfound(brt, DB_LAST, db);
|
||||
} else
|
||||
assert_cursor_first_last(brt, 0, n-1, db, &my_app_private);
|
||||
assert_cursor_first_last(brt, 0, n-1, db);
|
||||
|
||||
r = close_brt(brt);
|
||||
assert(r==0);
|
||||
|
@ -1075,11 +1037,9 @@ void test_brt_cursor_rfirst(int n, DB *db) {
|
|||
BRT brt;
|
||||
int r;
|
||||
int i;
|
||||
int my_app_private;
|
||||
|
||||
printf("test_brt_cursor_rfirst:%d %p\n", n, db);
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
r = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
|
@ -1093,8 +1053,9 @@ void test_brt_cursor_rfirst(int n, DB *db) {
|
|||
char key[8]; long long v;
|
||||
DBT kbt, vbt;
|
||||
|
||||
|
||||
snprintf(key, sizeof key, "%4.4d", i);
|
||||
fill_dbt_ap(&kbt, key, strlen(key)+1, &my_app_private);
|
||||
fill_dbt(&kbt, key, strlen(key)+1);
|
||||
v = i;
|
||||
fill_dbt(&vbt, &v, sizeof v);
|
||||
r = brt_insert(brt, &kbt, &vbt, db, 0);
|
||||
|
@ -1102,20 +1063,18 @@ void test_brt_cursor_rfirst(int n, DB *db) {
|
|||
}
|
||||
|
||||
if (n == 0)
|
||||
assert_cursor_notfound(brt, DB_FIRST, db, &my_app_private);
|
||||
assert_cursor_notfound(brt, DB_FIRST, db);
|
||||
else
|
||||
assert_cursor_value(brt, DB_FIRST, 0, db, &my_app_private);
|
||||
assert_cursor_value(brt, DB_FIRST, 0, db);
|
||||
|
||||
r = close_brt(brt);
|
||||
assert(r==0);
|
||||
|
||||
r = cachetable_close(&ct);
|
||||
assert(r==0);
|
||||
|
||||
clear_test_db();
|
||||
}
|
||||
|
||||
void assert_cursor_walk(BRT brt, int n, DB *db, void *app_private) {
|
||||
void assert_cursor_walk(BRT brt, int n, DB *db) {
|
||||
BRT_CURSOR cursor;
|
||||
int i;
|
||||
int r;
|
||||
|
@ -1128,7 +1087,7 @@ void assert_cursor_walk(BRT brt, int n, DB *db, void *app_private) {
|
|||
DBT kbt, vbt;
|
||||
long long v;
|
||||
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC; dbt_set_app_private(&kbt, app_private);
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC;
|
||||
init_dbt(&vbt); vbt.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursor, &kbt, &vbt, DB_NEXT, db, null_txn);
|
||||
if (r != 0)
|
||||
|
@ -1153,11 +1112,9 @@ void test_brt_cursor_walk(int n, DB *db) {
|
|||
BRT brt;
|
||||
int r;
|
||||
int i;
|
||||
int my_app_private;
|
||||
|
||||
printf("test_brt_cursor_walk:%d %p\n", n, db);
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
r = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
|
@ -1172,7 +1129,7 @@ void test_brt_cursor_walk(int n, DB *db) {
|
|||
DBT kbt, vbt;
|
||||
|
||||
snprintf(key, sizeof key, "%4.4d", i);
|
||||
fill_dbt_ap(&kbt, key, strlen(key)+1, &my_app_private);
|
||||
fill_dbt(&kbt, key, strlen(key)+1);
|
||||
v = i;
|
||||
fill_dbt(&vbt, &v, sizeof v);
|
||||
r = brt_insert(brt, &kbt, &vbt, db, 0);
|
||||
|
@ -1180,7 +1137,7 @@ void test_brt_cursor_walk(int n, DB *db) {
|
|||
}
|
||||
|
||||
/* walk the tree */
|
||||
assert_cursor_walk(brt, n, db, &my_app_private);
|
||||
assert_cursor_walk(brt, n, db);
|
||||
|
||||
r = close_brt(brt);
|
||||
assert(r==0);
|
||||
|
@ -1188,10 +1145,9 @@ void test_brt_cursor_walk(int n, DB *db) {
|
|||
r = cachetable_close(&ct);
|
||||
assert(r==0);
|
||||
|
||||
clear_test_db();
|
||||
}
|
||||
|
||||
void assert_cursor_rwalk(BRT brt, int n, DB *db, void *app_private) {
|
||||
void assert_cursor_rwalk(BRT brt, int n, DB *db) {
|
||||
BRT_CURSOR cursor;
|
||||
int i;
|
||||
int r;
|
||||
|
@ -1204,7 +1160,7 @@ void assert_cursor_rwalk(BRT brt, int n, DB *db, void *app_private) {
|
|||
DBT kbt, vbt;
|
||||
long long v;
|
||||
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC; dbt_set_app_private(&kbt, app_private);
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC;
|
||||
init_dbt(&vbt); vbt.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursor, &kbt, &vbt, DB_PREV, db, null_txn);
|
||||
if (r != 0)
|
||||
|
@ -1229,11 +1185,9 @@ void test_brt_cursor_rwalk(int n, DB *db) {
|
|||
BRT brt;
|
||||
int r;
|
||||
int i;
|
||||
int my_app_private;
|
||||
|
||||
printf("test_brt_cursor_rwalk:%d %p\n", n, db);
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
r = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
|
@ -1248,7 +1202,7 @@ void test_brt_cursor_rwalk(int n, DB *db) {
|
|||
DBT kbt, vbt;
|
||||
|
||||
k = htonl(i);
|
||||
fill_dbt_ap(&kbt, &k, sizeof k, &my_app_private);
|
||||
fill_dbt(&kbt, &k, sizeof k);
|
||||
v = i;
|
||||
fill_dbt(&vbt, &v, sizeof v);
|
||||
r = brt_insert(brt, &kbt, &vbt, db, 0);
|
||||
|
@ -1256,7 +1210,7 @@ void test_brt_cursor_rwalk(int n, DB *db) {
|
|||
}
|
||||
|
||||
/* walk the tree */
|
||||
assert_cursor_rwalk(brt, n, db, &my_app_private);
|
||||
assert_cursor_rwalk(brt, n, db);
|
||||
|
||||
r = close_brt(brt);
|
||||
assert(r==0);
|
||||
|
@ -1264,10 +1218,9 @@ void test_brt_cursor_rwalk(int n, DB *db) {
|
|||
r = cachetable_close(&ct);
|
||||
assert(r==0);
|
||||
|
||||
clear_test_db();
|
||||
}
|
||||
|
||||
void assert_cursor_walk_inorder(BRT brt, int n, DB *db, void *app_private) {
|
||||
void assert_cursor_walk_inorder(BRT brt, int n, DB *db) {
|
||||
BRT_CURSOR cursor;
|
||||
int i;
|
||||
int r;
|
||||
|
@ -1282,7 +1235,7 @@ void assert_cursor_walk_inorder(BRT brt, int n, DB *db, void *app_private) {
|
|||
DBT kbt, vbt;
|
||||
long long v;
|
||||
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC; dbt_set_app_private(&kbt, app_private);
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC;
|
||||
init_dbt(&vbt); vbt.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursor, &kbt, &vbt, DB_NEXT, db, null_txn);
|
||||
if (r != 0)
|
||||
|
@ -1311,11 +1264,9 @@ void test_brt_cursor_rand(int n, DB *db) {
|
|||
BRT brt;
|
||||
int r;
|
||||
int i;
|
||||
int my_app_private;
|
||||
|
||||
printf("test_brt_cursor_rand:%d %p\n", n, db);
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
r = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
|
@ -1332,7 +1283,7 @@ void test_brt_cursor_rand(int n, DB *db) {
|
|||
for (;;) {
|
||||
v = ((long long) random() << 32) + random();
|
||||
snprintf(key, sizeof key, "%lld", v);
|
||||
fill_dbt_ap(&kbt, key, strlen(key)+1, &my_app_private);
|
||||
fill_dbt(&kbt, key, strlen(key)+1);
|
||||
v = i;
|
||||
fill_dbt(&vbt, &v, sizeof v);
|
||||
r = brt_lookup(brt, &kbt, &vbt, db);
|
||||
|
@ -1347,7 +1298,7 @@ void test_brt_cursor_rand(int n, DB *db) {
|
|||
}
|
||||
|
||||
/* walk the tree */
|
||||
assert_cursor_walk_inorder(brt, n, db, &my_app_private);
|
||||
assert_cursor_walk_inorder(brt, n, db);
|
||||
|
||||
r = close_brt(brt);
|
||||
assert(r==0);
|
||||
|
@ -1355,7 +1306,6 @@ void test_brt_cursor_rand(int n, DB *db) {
|
|||
r = cachetable_close(&ct);
|
||||
assert(r==0);
|
||||
|
||||
clear_test_db();
|
||||
}
|
||||
|
||||
void test_brt_cursor_split(int n, DB *db) {
|
||||
|
@ -1367,11 +1317,9 @@ void test_brt_cursor_split(int n, DB *db) {
|
|||
int keyseqnum;
|
||||
int i;
|
||||
DBT kbt, vbt;
|
||||
int my_app_private;
|
||||
|
||||
printf("test_brt_cursor_split:%d %p\n", n, db);
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
r = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
|
@ -1385,7 +1333,7 @@ void test_brt_cursor_split(int n, DB *db) {
|
|||
char key[8]; long long v;
|
||||
|
||||
snprintf(key, sizeof key, "%4.4d", keyseqnum);
|
||||
fill_dbt_ap(&kbt, key, strlen(key)+1, &my_app_private);
|
||||
fill_dbt(&kbt, key, strlen(key)+1);
|
||||
v = keyseqnum;
|
||||
fill_dbt(&vbt, &v, sizeof v);
|
||||
r = brt_insert(brt, &kbt, &vbt, db, 0);
|
||||
|
@ -1397,7 +1345,7 @@ void test_brt_cursor_split(int n, DB *db) {
|
|||
|
||||
if (test_cursor_debug) printf("key: ");
|
||||
for (i=0; i<n/2; i++) {
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC; dbt_set_app_private(&kbt, &my_app_private);
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC;
|
||||
init_dbt(&vbt); vbt.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursor, &kbt, &vbt, DB_NEXT, db, null_txn);
|
||||
assert(r==0);
|
||||
|
@ -1411,7 +1359,7 @@ void test_brt_cursor_split(int n, DB *db) {
|
|||
char key[8]; long long v;
|
||||
|
||||
snprintf(key, sizeof key, "%4.4d", keyseqnum);
|
||||
fill_dbt_ap(&kbt, key, strlen(key)+1, &my_app_private);
|
||||
fill_dbt(&kbt, key, strlen(key)+1);
|
||||
v = keyseqnum;
|
||||
fill_dbt(&vbt, &v, sizeof v);
|
||||
r = brt_insert(brt, &kbt, &vbt, db, 0);
|
||||
|
@ -1420,7 +1368,7 @@ void test_brt_cursor_split(int n, DB *db) {
|
|||
|
||||
if (test_cursor_debug) printf("key: ");
|
||||
for (;;) {
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC; dbt_set_app_private(&kbt, &my_app_private);
|
||||
init_dbt(&kbt); kbt.flags = DB_DBT_MALLOC;
|
||||
init_dbt(&vbt); vbt.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursor, &kbt, &vbt, DB_NEXT, db, null_txn);
|
||||
if (r != 0)
|
||||
|
@ -1439,8 +1387,6 @@ void test_brt_cursor_split(int n, DB *db) {
|
|||
|
||||
r = cachetable_close(&ct);
|
||||
assert(r==0);
|
||||
|
||||
clear_test_db();
|
||||
}
|
||||
|
||||
void test_multiple_brt_cursors(int n, DB *db) {
|
||||
|
@ -1451,9 +1397,7 @@ void test_multiple_brt_cursors(int n, DB *db) {
|
|||
CACHETABLE ct;
|
||||
BRT brt;
|
||||
BRT_CURSOR cursors[n];
|
||||
int my_app_private;
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
r = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
|
@ -1478,8 +1422,6 @@ void test_multiple_brt_cursors(int n, DB *db) {
|
|||
|
||||
r = cachetable_close(&ct);
|
||||
assert(r==0);
|
||||
|
||||
clear_test_db();
|
||||
}
|
||||
|
||||
static int log16(int n) {
|
||||
|
@ -1502,9 +1444,7 @@ void test_multiple_brt_cursor_walk(int n, DB *db) {
|
|||
const int cursor_gap = 1000;
|
||||
const int ncursors = n/cursor_gap;
|
||||
BRT_CURSOR cursors[ncursors];
|
||||
int my_app_private;
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
int nodesize = 1<<12;
|
||||
|
@ -1531,7 +1471,7 @@ void test_multiple_brt_cursor_walk(int n, DB *db) {
|
|||
for (i=0; i<n; i++) {
|
||||
k = htonl(i);
|
||||
v = i;
|
||||
fill_dbt_ap(&key, &k, sizeof k, &my_app_private);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
fill_dbt(&val, &v, sizeof v);
|
||||
r = brt_insert(brt, &key, &val, db, 0);
|
||||
assert(r == 0);
|
||||
|
@ -1539,7 +1479,7 @@ void test_multiple_brt_cursor_walk(int n, DB *db) {
|
|||
/* point cursor i / cursor_gap to the current last key i */
|
||||
if ((i % cursor_gap) == 0) {
|
||||
c = i / cursor_gap;
|
||||
init_dbt(&key); key.flags = DB_DBT_MALLOC; dbt_set_app_private(&key, &my_app_private);
|
||||
init_dbt(&key); key.flags = DB_DBT_MALLOC;
|
||||
init_dbt(&val); val.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursors[c], &key, &val, DB_LAST, db, null_txn);
|
||||
assert(r == 0);
|
||||
|
@ -1551,7 +1491,7 @@ void test_multiple_brt_cursor_walk(int n, DB *db) {
|
|||
/* walk the cursors by cursor_gap */
|
||||
for (i=0; i<cursor_gap; i++) {
|
||||
for (c=0; c<ncursors; c++) {
|
||||
init_dbt(&key); key.flags = DB_DBT_MALLOC; dbt_set_app_private(&key, &my_app_private);
|
||||
init_dbt(&key); key.flags = DB_DBT_MALLOC;
|
||||
init_dbt(&val); val.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursors[c], &key, &val, DB_NEXT, db, null_txn);
|
||||
if (r == DB_NOTFOUND) {
|
||||
|
@ -1579,8 +1519,6 @@ void test_multiple_brt_cursor_walk(int n, DB *db) {
|
|||
|
||||
r = cachetable_close(&ct);
|
||||
assert(r==0);
|
||||
|
||||
clear_test_db();
|
||||
}
|
||||
|
||||
void test_brt_cursor_set(int n, int cursor_op, DB *db) {
|
||||
|
@ -1591,9 +1529,7 @@ void test_brt_cursor_set(int n, int cursor_op, DB *db) {
|
|||
CACHETABLE ct;
|
||||
BRT brt;
|
||||
BRT_CURSOR cursor;
|
||||
int my_app_private;
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
r = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
|
@ -1610,8 +1546,8 @@ void test_brt_cursor_set(int n, int cursor_op, DB *db) {
|
|||
for (i=0; i<n; i++) {
|
||||
k = htonl(10*i);
|
||||
v = 10*i;
|
||||
fill_dbt_ap(&key, &k, sizeof k, &my_app_private);
|
||||
fill_dbt_ap(&val, &v, sizeof v, &my_app_private);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
fill_dbt(&val, &v, sizeof v);
|
||||
r = brt_insert(brt, &key, &val, db, 0);
|
||||
assert(r == 0);
|
||||
}
|
||||
|
@ -1625,7 +1561,7 @@ void test_brt_cursor_set(int n, int cursor_op, DB *db) {
|
|||
|
||||
v = 10*(random() % n);
|
||||
k = htonl(v);
|
||||
fill_dbt_ap(&key, &k, sizeof k, &my_app_private);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
init_dbt(&val); val.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursor, &key, &val, cursor_op, db, null_txn);
|
||||
assert(r == 0);
|
||||
|
@ -1640,7 +1576,7 @@ void test_brt_cursor_set(int n, int cursor_op, DB *db) {
|
|||
if (i % 10 == 0)
|
||||
continue;
|
||||
k = htonl(i);
|
||||
fill_dbt_ap(&key, &k, sizeof k, &my_app_private);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
init_dbt(&val); val.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursor, &key, &val, DB_SET, db, null_txn);
|
||||
assert(r == DB_NOTFOUND);
|
||||
|
@ -1654,8 +1590,6 @@ void test_brt_cursor_set(int n, int cursor_op, DB *db) {
|
|||
|
||||
r = cachetable_close(&ct);
|
||||
assert(r==0);
|
||||
|
||||
clear_test_db();
|
||||
}
|
||||
|
||||
void test_brt_cursor_set_range(int n, DB *db) {
|
||||
|
@ -1666,9 +1600,7 @@ void test_brt_cursor_set_range(int n, DB *db) {
|
|||
CACHETABLE ct;
|
||||
BRT brt;
|
||||
BRT_CURSOR cursor;
|
||||
int my_app_private;
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
r = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
|
@ -1686,8 +1618,8 @@ void test_brt_cursor_set_range(int n, DB *db) {
|
|||
for (i=0; i<n; i++) {
|
||||
k = htonl(10*i);
|
||||
v = 10*i;
|
||||
fill_dbt_ap(&key, &k, sizeof k, &my_app_private);
|
||||
fill_dbt_ap(&val, &v, sizeof v, &my_app_private);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
fill_dbt(&val, &v, sizeof v);
|
||||
r = brt_insert(brt, &key, &val, db, 0);
|
||||
assert(r == 0);
|
||||
}
|
||||
|
@ -1702,7 +1634,7 @@ void test_brt_cursor_set_range(int n, DB *db) {
|
|||
|
||||
v = random() % (10*n);
|
||||
k = htonl(v);
|
||||
fill_dbt_ap(&key, &k, sizeof k, &my_app_private);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
init_dbt(&val); val.flags = DB_DBT_MALLOC;
|
||||
r = brt_cursor_get(cursor, &key, &val, DB_SET_RANGE, db, null_txn);
|
||||
if (v > max_key)
|
||||
|
@ -1725,8 +1657,6 @@ void test_brt_cursor_set_range(int n, DB *db) {
|
|||
|
||||
r = cachetable_close(&ct);
|
||||
assert(r==0);
|
||||
|
||||
clear_test_db();
|
||||
}
|
||||
|
||||
void test_brt_cursor_delete(int n, DB *db) {
|
||||
|
@ -1737,9 +1667,7 @@ void test_brt_cursor_delete(int n, DB *db) {
|
|||
CACHETABLE ct;
|
||||
BRT brt;
|
||||
BRT_CURSOR cursor;
|
||||
int my_app_private;
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
error = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
|
@ -1759,7 +1687,7 @@ void test_brt_cursor_delete(int n, DB *db) {
|
|||
for (i=0; i<n; i++) {
|
||||
k = htonl(i);
|
||||
v = i;
|
||||
fill_dbt_ap(&key, &k, sizeof k, &my_app_private);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
fill_dbt(&val, &v, sizeof v);
|
||||
error = brt_insert(brt, &key, &val, db, 0);
|
||||
assert(error == 0);
|
||||
|
@ -1767,7 +1695,7 @@ void test_brt_cursor_delete(int n, DB *db) {
|
|||
|
||||
/* walk the tree and delete under the cursor */
|
||||
for (;;) {
|
||||
init_dbt(&key); key.flags = DB_DBT_MALLOC; dbt_set_app_private(&key, &my_app_private);
|
||||
init_dbt(&key); key.flags = DB_DBT_MALLOC;
|
||||
init_dbt(&val); val.flags = DB_DBT_MALLOC;
|
||||
error = brt_cursor_get(cursor, &key, &val, DB_NEXT, db, null_txn);
|
||||
if (error == DB_NOTFOUND)
|
||||
|
@ -1791,8 +1719,6 @@ void test_brt_cursor_delete(int n, DB *db) {
|
|||
|
||||
error = cachetable_close(&ct);
|
||||
assert(error == 0);
|
||||
|
||||
clear_test_db();
|
||||
}
|
||||
|
||||
void test_brt_cursor_get_both(int n, DB *db) {
|
||||
|
@ -1803,9 +1729,7 @@ void test_brt_cursor_get_both(int n, DB *db) {
|
|||
CACHETABLE ct;
|
||||
BRT brt;
|
||||
BRT_CURSOR cursor;
|
||||
int my_app_private;
|
||||
|
||||
set_test_db_app(db, &my_app_private);
|
||||
unlink(fname);
|
||||
|
||||
error = brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
|
||||
|
@ -1823,7 +1747,7 @@ void test_brt_cursor_get_both(int n, DB *db) {
|
|||
/* verify get_both on an empty tree fails */
|
||||
k = htonl(n+1);
|
||||
v = n+1;
|
||||
fill_dbt_ap(&key, &k, sizeof k, &my_app_private);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
fill_dbt(&val, &v, sizeof v);
|
||||
error = brt_cursor_get(cursor, &key, &val, DB_GET_BOTH, db, null_txn);
|
||||
assert(error == DB_NOTFOUND);
|
||||
|
@ -1833,7 +1757,7 @@ void test_brt_cursor_get_both(int n, DB *db) {
|
|||
for (i=0; i<n; i++) {
|
||||
k = htonl(i);
|
||||
v = i;
|
||||
fill_dbt_ap(&key, &k, sizeof k, &my_app_private);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
fill_dbt(&val, &v, sizeof v);
|
||||
error = brt_insert(brt, &key, &val, db, 0);
|
||||
assert(error == 0);
|
||||
|
@ -1842,7 +1766,7 @@ void test_brt_cursor_get_both(int n, DB *db) {
|
|||
/* verify that keys not in the tree fail */
|
||||
k = htonl(n+1);
|
||||
v = n-1;
|
||||
fill_dbt_ap(&key, &k, sizeof k, &my_app_private);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
fill_dbt(&val, &v, sizeof v);
|
||||
error = brt_cursor_get(cursor, &key, &val, DB_GET_BOTH, db, null_txn);
|
||||
assert(error == DB_NOTFOUND);
|
||||
|
@ -1851,8 +1775,8 @@ void test_brt_cursor_get_both(int n, DB *db) {
|
|||
for (i=0; i<n; i++) {
|
||||
k = htonl(i);
|
||||
v = i+1;
|
||||
fill_dbt_ap(&key, &k, sizeof k, &my_app_private);
|
||||
fill_dbt_ap(&val, &v, sizeof v, &my_app_private);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
fill_dbt(&val, &v, sizeof v);
|
||||
error = brt_cursor_get(cursor, &key, &val, DB_GET_BOTH, db, null_txn);
|
||||
assert(error == DB_NOTFOUND);
|
||||
}
|
||||
|
@ -1861,8 +1785,8 @@ void test_brt_cursor_get_both(int n, DB *db) {
|
|||
for (i=0; i<n; i++) {
|
||||
k = htonl(i);
|
||||
v = i;
|
||||
fill_dbt_ap(&key, &k, sizeof k, &my_app_private);
|
||||
fill_dbt_ap(&val, &v, sizeof v, &my_app_private);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
fill_dbt(&val, &v, sizeof v);
|
||||
error = brt_cursor_get(cursor, &key, &val, DB_GET_BOTH, db, null_txn);
|
||||
assert(error == 0);
|
||||
#ifdef DB_CURRENT
|
||||
|
@ -1882,8 +1806,8 @@ void test_brt_cursor_get_both(int n, DB *db) {
|
|||
|
||||
k = htonl(i);
|
||||
v = i;
|
||||
fill_dbt_ap(&key, &k, sizeof k, &my_app_private);
|
||||
fill_dbt_ap(&val, &v, sizeof v, &my_app_private);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
fill_dbt(&val, &v, sizeof v);
|
||||
error = brt_cursor_get(cursor, &key, &val, DB_GET_BOTH, db, null_txn);
|
||||
assert(error == DB_NOTFOUND);
|
||||
}
|
||||
|
@ -1899,8 +1823,6 @@ void test_brt_cursor_get_both(int n, DB *db) {
|
|||
|
||||
error = cachetable_close(&ct);
|
||||
assert(error == 0);
|
||||
|
||||
clear_test_db();
|
||||
}
|
||||
|
||||
|
||||
|
|
137
newbrt/brt.c
137
newbrt/brt.c
|
@ -277,7 +277,7 @@ static void initialize_brtnode (BRT t, BRTNODE n, DISKOFF nodename, int height)
|
|||
n->height = height;
|
||||
n->rand4fingerprint = random();
|
||||
n->local_fingerprint = 0;
|
||||
brtnode_set_dirty(n);
|
||||
n->dirty = 1;
|
||||
assert(height>=0);
|
||||
if (height>0) {
|
||||
n->u.n.n_children = 0;
|
||||
|
@ -347,16 +347,6 @@ void delete_node (BRT t, BRTNODE node) {
|
|||
cachetable_remove(t->cf, node->thisnodename, 0); /* Don't write it back to disk. */
|
||||
}
|
||||
|
||||
#define USE_PMA_SPLIT 1
|
||||
#if ! USE_PMA_SPLIT
|
||||
static void insert_to_buffer_in_leaf (BRTNODE node, DBT *k, DBT *v, DB *db) {
|
||||
unsigned int n_bytes_added = KEY_VALUE_OVERHEAD + k->size + v->size;
|
||||
int r = pma_insert(node->u.l.buffer, k, v, db);
|
||||
assert(r==0);
|
||||
node->u.l.n_bytes_in_buffer += n_bytes_added;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int insert_to_hash_in_nonleaf (BRTNODE node, int childnum, DBT *k, DBT *v, int type) {
|
||||
unsigned int n_bytes_added = BRT_CMD_OVERHEAD + KEY_VALUE_OVERHEAD + k->size + v->size;
|
||||
int r = toku_hash_insert(node->u.n.htables[childnum], k->data, k->size, v->data, v->size, type);
|
||||
|
@ -364,12 +354,12 @@ static int insert_to_hash_in_nonleaf (BRTNODE node, int childnum, DBT *k, DBT *v
|
|||
node->local_fingerprint += node->rand4fingerprint*toku_calccrc32_cmd(type, k->data, k->size, v->data, v->size);
|
||||
node->u.n.n_bytes_in_hashtable[childnum] += n_bytes_added;
|
||||
node->u.n.n_bytes_in_hashtables += n_bytes_added;
|
||||
brtnode_set_dirty(node);
|
||||
node->dirty = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int brtleaf_split (BRT t, BRTNODE node, BRTNODE *nodea, BRTNODE *nodeb, DBT *splitk, void *app_private, DB *db) {
|
||||
int brtleaf_split (BRT t, BRTNODE node, BRTNODE *nodea, BRTNODE *nodeb, DBT *splitk, DB *db) {
|
||||
BRTNODE A,B;
|
||||
assert(node->height==0);
|
||||
assert(t->h->nodesize>=node->nodesize); /* otherwise we might be in trouble because the nodesize shrank. */
|
||||
|
@ -383,41 +373,11 @@ int brtleaf_split (BRT t, BRTNODE node, BRTNODE *nodea, BRTNODE *nodeb, DBT *spl
|
|||
//printf("%s:%d A is at %lld\n", __FILE__, __LINE__, A->thisnodename);
|
||||
//printf("%s:%d B is at %lld nodesize=%d\n", __FILE__, __LINE__, B->thisnodename, B->nodesize);
|
||||
assert(node->height>0 || node->u.l.buffer!=0);
|
||||
#if USE_PMA_SPLIT
|
||||
{
|
||||
int r;
|
||||
|
||||
r = pma_split(node->u.l.buffer, &node->u.l.n_bytes_in_buffer,
|
||||
r = pma_split(node->u.l.buffer, &node->u.l.n_bytes_in_buffer, splitk, db,
|
||||
A->u.l.buffer, &A->u.l.n_bytes_in_buffer, A->rand4fingerprint, &A->local_fingerprint,
|
||||
B->u.l.buffer, &B->u.l.n_bytes_in_buffer, B->rand4fingerprint, &B->local_fingerprint);
|
||||
assert(r == 0);
|
||||
|
||||
r = pma_get_last(A->u.l.buffer, splitk, 0);
|
||||
assert(r == 0);
|
||||
|
||||
/* unused */
|
||||
app_private = app_private;
|
||||
db = db;
|
||||
}
|
||||
#else
|
||||
{
|
||||
int did_split = 0;
|
||||
PMA_ITERATE(node->u.l.buffer, key, keylen, val, vallen,
|
||||
({
|
||||
DBT k,v;
|
||||
if (!did_split) {
|
||||
insert_to_buffer_in_leaf(A, fill_dbt_ap(&k, key, keylen, app_private), fill_dbt(&v, val, vallen), db);
|
||||
if (A->u.l.n_bytes_in_buffer *2 >= node->u.l.n_bytes_in_buffer) {
|
||||
fill_dbt(splitk, memdup(key, keylen), keylen);
|
||||
did_split=1;
|
||||
}
|
||||
} else {
|
||||
insert_to_buffer_in_leaf(B, fill_dbt_ap(&k, key, keylen, app_private), fill_dbt(&v, val, vallen), db);
|
||||
}
|
||||
}));
|
||||
assert(did_split==1);
|
||||
}
|
||||
#endif
|
||||
assert(node->height>0 || node->u.l.buffer!=0);
|
||||
/* Remove it from the cache table, and free its storage. */
|
||||
//printf("%s:%d old pma = %p\n", __FILE__, __LINE__, node->u.l.buffer);
|
||||
|
@ -627,7 +587,7 @@ static int push_a_brt_cmd_down (BRT t, BRTNODE node, BRTNODE child, int childnum
|
|||
int n_bytes_removed = (k->size + v->size + KEY_VALUE_OVERHEAD + BRT_CMD_OVERHEAD);
|
||||
node->u.n.n_bytes_in_hashtables -= n_bytes_removed;
|
||||
node->u.n.n_bytes_in_hashtable[childnum] -= n_bytes_removed;
|
||||
brtnode_set_dirty(node);
|
||||
node->dirty = 1;
|
||||
}
|
||||
if (*child_did_split) {
|
||||
fixup_child_fingerprint(node, childnum, *childa);
|
||||
|
@ -652,7 +612,6 @@ static int handle_split_of_child (BRT t, BRTNODE node, int childnum,
|
|||
DBT *childsplitk, /* the data in the childsplitk is alloc'd and is consumed by this call. */
|
||||
int *did_split, BRTNODE *nodea, BRTNODE *nodeb,
|
||||
DBT *splitk,
|
||||
void *app_private,
|
||||
DB *db,
|
||||
TOKUTXN txn) {
|
||||
assert(node->height>0);
|
||||
|
@ -671,7 +630,7 @@ static int handle_split_of_child (BRT t, BRTNODE node, int childnum,
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
brtnode_set_dirty(node);
|
||||
node->dirty = 1;
|
||||
|
||||
//verify_local_fingerprint_nonleaf(node);
|
||||
|
||||
|
@ -719,7 +678,7 @@ static int handle_split_of_child (BRT t, BRTNODE node, int childnum,
|
|||
/* Keep pushing to the children, but not if the children would require a pushdown */
|
||||
HASHTABLE_ITERATE(old_h, skey, skeylen, sval, svallen, type, ({
|
||||
DBT skd, svd;
|
||||
fill_dbt_ap(&skd, skey, skeylen, app_private);
|
||||
fill_dbt(&skd, skey, skeylen);
|
||||
fill_dbt(&svd, sval, svallen);
|
||||
BRT_CMD brtcmd;
|
||||
brtcmd.type = type; brtcmd.u.id.key = &skd; brtcmd.u.id.val = &svd; brtcmd.u.id.db = db;
|
||||
|
@ -775,7 +734,6 @@ static int push_some_brt_cmds_down (BRT t, BRTNODE node, int childnum,
|
|||
int *did_split, BRTNODE *nodea, BRTNODE *nodeb,
|
||||
DBT *splitk,
|
||||
int debug,
|
||||
void *app_private,
|
||||
DB *db,
|
||||
TOKUTXN txn) {
|
||||
void *childnode_v;
|
||||
|
@ -817,7 +775,7 @@ static int push_some_brt_cmds_down (BRT t, BRTNODE node, int childnum,
|
|||
DBT childsplitk;
|
||||
BRT_CMD brtcmd;
|
||||
|
||||
fill_dbt_ap(&hk, key, keylen, app_private);
|
||||
fill_dbt(&hk, key, keylen);
|
||||
fill_dbt(&hv, val, vallen);
|
||||
brtcmd.type = type;
|
||||
brtcmd.u.id.key = &hk;
|
||||
|
@ -826,7 +784,6 @@ static int push_some_brt_cmds_down (BRT t, BRTNODE node, int childnum,
|
|||
|
||||
//printf("%s:%d random_picked\n", __FILE__, __LINE__);
|
||||
init_dbt(&childsplitk);
|
||||
dbt_set_app_private(&childsplitk, dbt_get_app_private(splitk));
|
||||
if (debug) printf("%s:%d %*spush down %s\n", __FILE__, __LINE__, debug, "", (char*)key);
|
||||
r = push_a_brt_cmd_down (t, node, child, childnum,
|
||||
&brtcmd,
|
||||
|
@ -850,7 +807,7 @@ static int push_some_brt_cmds_down (BRT t, BRTNODE node, int childnum,
|
|||
r=handle_split_of_child (t, node, childnum,
|
||||
childa, childb, &childsplitk,
|
||||
did_split, nodea, nodeb, splitk,
|
||||
app_private, db, txn);
|
||||
db, txn);
|
||||
//if (*did_split) {
|
||||
// verify_local_fingerprint_nonleaf(*nodea);
|
||||
// verify_local_fingerprint_nonleaf(*nodeb);
|
||||
|
@ -873,7 +830,7 @@ int debugp1 (int debug) {
|
|||
return debug ? debug+1 : 0;
|
||||
}
|
||||
|
||||
static int brtnode_maybe_push_down(BRT t, BRTNODE node, int *did_split, BRTNODE *nodea, BRTNODE *nodeb, DBT *splitk, int debug, void *app_private, DB *db, TOKUTXN txn)
|
||||
static int brtnode_maybe_push_down(BRT t, BRTNODE node, int *did_split, BRTNODE *nodea, BRTNODE *nodeb, DBT *splitk, int debug, DB *db, TOKUTXN txn)
|
||||
/* If the buffer is too full, then push down. Possibly the child will split. That may make us split. */
|
||||
{
|
||||
assert(node->height>0);
|
||||
|
@ -889,7 +846,7 @@ static int brtnode_maybe_push_down(BRT t, BRTNODE node, int *did_split, BRTNODE
|
|||
find_heaviest_child(node, &childnum);
|
||||
if (0) printf("%s:%d %*spush some down from %lld into %lld (child %d)\n", __FILE__, __LINE__, debug, "", node->thisnodename, node->u.n.children[childnum], childnum);
|
||||
assert(node->u.n.children[childnum]!=0);
|
||||
int r = push_some_brt_cmds_down(t, node, childnum, did_split, nodea, nodeb, splitk, debugp1(debug), app_private, db, txn);
|
||||
int r = push_some_brt_cmds_down(t, node, childnum, did_split, nodea, nodeb, splitk, debugp1(debug), db, txn);
|
||||
if (r!=0) return r;
|
||||
assert(*did_split==0 || *did_split==1);
|
||||
if (debug) printf("%s:%d %*sdid push_some_brt_cmds_down did_split=%d\n", __FILE__, __LINE__, debug, "", *did_split);
|
||||
|
@ -919,8 +876,6 @@ static int brtnode_maybe_push_down(BRT t, BRTNODE node, int *did_split, BRTNODE
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define INSERT_ALL_AT_ONCE
|
||||
|
||||
static int brt_leaf_put_cmd (BRT t, BRTNODE node, BRT_CMD *cmd,
|
||||
int *did_split, BRTNODE *nodea, BRTNODE *nodeb, DBT *splitk,
|
||||
int debug,
|
||||
|
@ -930,7 +885,6 @@ static int brt_leaf_put_cmd (BRT t, BRTNODE node, BRT_CMD *cmd,
|
|||
DBT *k = cmd->u.id.key;
|
||||
DBT *v = cmd->u.id.val;
|
||||
DB *db = cmd->u.id.db;
|
||||
#ifdef INSERT_ALL_AT_ONCE
|
||||
int replaced_v_size;
|
||||
enum pma_errors pma_status = pma_insert_or_replace(node->u.l.buffer, k, v, &replaced_v_size, db, txn, node->thisnodename, node->rand4fingerprint, &node->local_fingerprint);
|
||||
assert(pma_status==BRT_OK);
|
||||
|
@ -940,24 +894,13 @@ static int brt_leaf_put_cmd (BRT t, BRTNODE node, BRT_CMD *cmd,
|
|||
} else {
|
||||
node->u.l.n_bytes_in_buffer += k->size + v->size + KEY_VALUE_OVERHEAD;
|
||||
}
|
||||
#else
|
||||
DBT v2;
|
||||
enum pma_errors pma_status = pma_lookup(node->u.l.buffer, k, init_dbt(&v2), db);
|
||||
if (pma_status==BRT_OK) {
|
||||
pma_status = pma_delete(node->u.l.buffer, k, db);
|
||||
assert(pma_status==BRT_OK);
|
||||
node->u.l.n_bytes_in_buffer -= k->size + v2.size + KEY_VALUE_OVERHEAD;
|
||||
}
|
||||
pma_status = pma_insert(node->u.l.buffer, k, v, db);
|
||||
node->u.l.n_bytes_in_buffer += k->size + v->size + KEY_VALUE_OVERHEAD;
|
||||
#endif
|
||||
brtnode_set_dirty(node);
|
||||
node->dirty = 1;
|
||||
|
||||
// pma_verify_fingerprint(node->u.l.buffer, node->rand4fingerprint, node->subtree_fingerprint);
|
||||
|
||||
// If it doesn't fit, then split the leaf.
|
||||
if (serialize_brtnode_size(node) > node->nodesize) {
|
||||
int r = brtleaf_split (t, node, nodea, nodeb, splitk, dbt_get_app_private(k), db);
|
||||
int r = brtleaf_split (t, node, nodea, nodeb, splitk, db);
|
||||
if (r!=0) return r;
|
||||
//printf("%s:%d splitkey=%s\n", __FILE__, __LINE__, (char*)*splitkey);
|
||||
split_count++;
|
||||
|
@ -972,28 +915,19 @@ static int brt_leaf_put_cmd (BRT t, BRTNODE node, BRT_CMD *cmd,
|
|||
*did_split = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cmd->type == BRT_DELETE) {
|
||||
int r;
|
||||
DBT val;
|
||||
|
||||
/* TODO combine lookup and delete */
|
||||
init_dbt(&val);
|
||||
r = pma_lookup(node->u.l.buffer, cmd->u.id.key, &val, cmd->u.id.db);
|
||||
if (r == 0) {
|
||||
r = pma_delete(node->u.l.buffer, cmd->u.id.key, cmd->u.id.db, node->rand4fingerprint, &node->local_fingerprint);
|
||||
assert(r == BRT_OK);
|
||||
node->u.l.n_bytes_in_buffer -= cmd->u.id.key->size + val.size + KEY_VALUE_OVERHEAD;
|
||||
brtnode_set_dirty(node);
|
||||
} else if (cmd->type == BRT_DELETE) {
|
||||
u_int32_t delta;
|
||||
int r = pma_delete(node->u.l.buffer, cmd->u.id.key, cmd->u.id.db, node->rand4fingerprint, &node->local_fingerprint, &delta);
|
||||
if (r == BRT_OK) {
|
||||
node->u.l.n_bytes_in_buffer -= delta;
|
||||
node->dirty = 1;
|
||||
}
|
||||
*did_split = 0;
|
||||
return BRT_OK;
|
||||
}
|
||||
|
||||
/* unknown message */
|
||||
assert(0);
|
||||
return 0;
|
||||
} else
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
static unsigned int brtnode_which_child (BRTNODE node , DBT *k, BRT t, DB *db) {
|
||||
|
@ -1043,12 +977,11 @@ static int brt_nonleaf_put_cmd_child (BRT t, BRTNODE node, BRT_CMD *cmd,
|
|||
if (child_did_split) {
|
||||
if (0) printf("brt_nonleaf_insert child_split %p\n", child);
|
||||
assert(cmd->type == BRT_INSERT || cmd->type == BRT_DELETE);
|
||||
DBT *k = cmd->u.id.key;
|
||||
DB *db = cmd->u.id.db;
|
||||
r = handle_split_of_child(t, node, childnum,
|
||||
childa, childb, &childsplitk,
|
||||
did_split, nodea, nodeb, splitk,
|
||||
dbt_get_app_private(k), db, txn);
|
||||
db, txn);
|
||||
assert(r == 0);
|
||||
} else {
|
||||
//verify_local_fingerprint_nonleaf(child);
|
||||
|
@ -1109,7 +1042,7 @@ static int brt_nonleaf_put_cmd (BRT t, BRTNODE node, BRT_CMD *cmd,
|
|||
assert(r==0);
|
||||
node->u.n.n_bytes_in_hashtables -= diff;
|
||||
node->u.n.n_bytes_in_hashtable[childnum] -= diff;
|
||||
brtnode_set_dirty(node);
|
||||
node->dirty = 1;
|
||||
//printf("%s:%d deleted %d bytes\n", __FILE__, __LINE__, diff);
|
||||
}
|
||||
}
|
||||
|
@ -1131,11 +1064,11 @@ static int brt_nonleaf_put_cmd (BRT t, BRTNODE node, BRT_CMD *cmd,
|
|||
node->local_fingerprint += node->rand4fingerprint * toku_calccrc32_cmd(type, k->data, k->size, v->data, v->size);
|
||||
node->u.n.n_bytes_in_hashtables += diff;
|
||||
node->u.n.n_bytes_in_hashtable[childnum] += diff;
|
||||
brtnode_set_dirty(node);
|
||||
node->dirty = 1;
|
||||
}
|
||||
if (debug) printf("%s:%d %*sDoing maybe_push_down\n", __FILE__, __LINE__, debug, "");
|
||||
//verify_local_fingerprint_nonleaf(node);
|
||||
int r = brtnode_maybe_push_down(t, node, did_split, nodea, nodeb, splitk, debugp1(debug), dbt_get_app_private(k), db, txn);
|
||||
int r = brtnode_maybe_push_down(t, node, did_split, nodea, nodeb, splitk, debugp1(debug), db, txn);
|
||||
if (r!=0) return r;
|
||||
if (debug) printf("%s:%d %*sDid maybe_push_down\n", __FILE__, __LINE__, debug, "");
|
||||
if (*did_split) {
|
||||
|
@ -1771,7 +1704,7 @@ int brt_flush_debug = 0;
|
|||
* then reflect the node split up the cursor path towards the tree root.
|
||||
* If the root is reached then create a new root
|
||||
*/
|
||||
void brt_flush_child(BRT t, BRTNODE node, int childnum, BRT_CURSOR cursor, void *app_private, DB *db, TOKUTXN txn) {
|
||||
void brt_flush_child(BRT t, BRTNODE node, int childnum, BRT_CURSOR cursor, DB *db, TOKUTXN txn) {
|
||||
int r;
|
||||
int child_did_split;
|
||||
BRTNODE childa, childb;
|
||||
|
@ -1784,7 +1717,7 @@ void brt_flush_child(BRT t, BRTNODE node, int childnum, BRT_CURSOR cursor, void
|
|||
|
||||
init_dbt(&child_splitk);
|
||||
r = push_some_brt_cmds_down(t, node, childnum,
|
||||
&child_did_split, &childa, &childb, &child_splitk, brt_flush_debug, app_private, db, txn);
|
||||
&child_did_split, &childa, &childb, &child_splitk, brt_flush_debug, db, txn);
|
||||
assert(r == 0);
|
||||
if (brt_flush_debug) {
|
||||
printf("brt_flush_child done %lld %d\n", node->thisnodename, childnum);
|
||||
|
@ -1818,7 +1751,7 @@ void brt_flush_child(BRT t, BRTNODE node, int childnum, BRT_CURSOR cursor, void
|
|||
r = handle_split_of_child(t, upnode, childnum,
|
||||
childa, childb, &child_splitk,
|
||||
&child_did_split, &childa, &childb, &child_splitk,
|
||||
app_private, db, txn);
|
||||
db, txn);
|
||||
assert(r == 0);
|
||||
}
|
||||
}
|
||||
|
@ -2120,7 +2053,7 @@ int brtcurs_set_position_last (BRT_CURSOR cursor, DISKOFF off, DBT *key, DB *db,
|
|||
cursor->pathcnum[cursor->path_len-1] = childnum;
|
||||
brt_node_add_cursor(node, childnum, cursor);
|
||||
if (node->u.n.n_bytes_in_hashtable[childnum] > 0) {
|
||||
brt_flush_child(cursor->brt, node, childnum, cursor, dbt_get_app_private(key), db, txn);
|
||||
brt_flush_child(cursor->brt, node, childnum, cursor, db, txn);
|
||||
/*
|
||||
* the flush may have been partially successfull. it may have also
|
||||
* changed the tree such that the current node have expanded or been
|
||||
|
@ -2182,7 +2115,7 @@ int brtcurs_set_position_first (BRT_CURSOR cursor, DISKOFF off, DBT *key, DB *db
|
|||
cursor->pathcnum[cursor->path_len-1] = childnum;
|
||||
brt_node_add_cursor(node, childnum, cursor);
|
||||
if (node->u.n.n_bytes_in_hashtable[childnum] > 0) {
|
||||
brt_flush_child(cursor->brt, node, childnum, cursor, dbt_get_app_private(key), db, txn);
|
||||
brt_flush_child(cursor->brt, node, childnum, cursor, db, txn);
|
||||
/*
|
||||
* the flush may have been partially successfull. it may have also
|
||||
* changed the tree such that the current node have expanded or been
|
||||
|
@ -2253,7 +2186,7 @@ int brtcurs_set_position_next2(BRT_CURSOR cursor, DBT *key, DB *db, TOKUTXN txn)
|
|||
more = node->u.n.n_bytes_in_hashtable[childnum];
|
||||
if (more == 0)
|
||||
break;
|
||||
brt_flush_child(cursor->brt, node, childnum, cursor, dbt_get_app_private(key), db, txn);
|
||||
brt_flush_child(cursor->brt, node, childnum, cursor, db, txn);
|
||||
node = cursor->path[cursor->path_len-1];
|
||||
childnum = cursor->pathcnum[cursor->path_len-1];
|
||||
}
|
||||
|
@ -2314,7 +2247,7 @@ int brtcurs_set_position_prev2(BRT_CURSOR cursor, DBT *key, DB *db, TOKUTXN txn)
|
|||
more = node->u.n.n_bytes_in_hashtable[childnum];
|
||||
if (more == 0)
|
||||
break;
|
||||
brt_flush_child(cursor->brt, node, childnum, cursor, dbt_get_app_private(key), db, txn);
|
||||
brt_flush_child(cursor->brt, node, childnum, cursor, db, txn);
|
||||
node = cursor->path[cursor->path_len-1];
|
||||
childnum = cursor->pathcnum[cursor->path_len-1];
|
||||
}
|
||||
|
@ -2363,7 +2296,7 @@ int brtcurs_set_key(BRT_CURSOR cursor, DISKOFF off, DBT *key, DBT *val, int flag
|
|||
brt_node_add_cursor(node, childnum, cursor);
|
||||
int more = node->u.n.n_bytes_in_hashtable[childnum];
|
||||
if (more > 0) {
|
||||
brt_flush_child(cursor->brt, node, childnum, cursor, dbt_get_app_private(key), db, txn);
|
||||
brt_flush_child(cursor->brt, node, childnum, cursor, db, txn);
|
||||
node = cursor->path[cursor->path_len-1];
|
||||
childnum = cursor->pathcnum[cursor->path_len-1];
|
||||
brt_node_remove_cursor(node, childnum, cursor);
|
||||
|
@ -2427,7 +2360,7 @@ int brtcurs_set_range(BRT_CURSOR cursor, DISKOFF off, DBT *key, DB *db, TOKUTXN
|
|||
brt_node_add_cursor(node, childnum, cursor);
|
||||
int more = node->u.n.n_bytes_in_hashtable[childnum];
|
||||
if (more > 0) {
|
||||
brt_flush_child(cursor->brt, node, childnum, cursor, dbt_get_app_private(key), db, txn);
|
||||
brt_flush_child(cursor->brt, node, childnum, cursor, db, txn);
|
||||
node = cursor->path[cursor->path_len-1];
|
||||
childnum = cursor->pathcnum[cursor->path_len-1];
|
||||
brt_node_remove_cursor(node, childnum, cursor);
|
||||
|
@ -2594,7 +2527,7 @@ int brt_cursor_delete(BRT_CURSOR cursor, int flags __attribute__((__unused__)))
|
|||
r = pma_cursor_delete_under(cursor->pmacurs, &kvsize);
|
||||
if (r == 0) {
|
||||
node->u.l.n_bytes_in_buffer -= KEY_VALUE_OVERHEAD + kvsize;
|
||||
brtnode_set_dirty(node);
|
||||
node->dirty = 1;
|
||||
}
|
||||
} else
|
||||
r = DB_NOTFOUND;
|
||||
|
|
|
@ -270,7 +270,7 @@ static void do_insert (PMA pma, const void *key, int keylen, const void *data, i
|
|||
static void do_delete (PMA pma, const void *key, int keylen, const void *data, int datalen, u_int32_t rand4fingerprint, u_int32_t *sum, u_int32_t *expect_fingerprint) {
|
||||
DBT k;
|
||||
assert(*sum==*expect_fingerprint);
|
||||
int r = pma_delete(pma, fill_dbt(&k, key, keylen), 0, rand4fingerprint, sum);
|
||||
int r = pma_delete(pma, fill_dbt(&k, key, keylen), 0, rand4fingerprint, sum, 0);
|
||||
assert(r==BRT_OK);
|
||||
add_fingerprint_and_check(-rand4fingerprint, *sum, expect_fingerprint, key, keylen, data, datalen); // negative rand4 means subtract.
|
||||
pma_verify_fingerprint(pma, rand4fingerprint, *sum);
|
||||
|
@ -297,7 +297,7 @@ static void test_pma_random_pick (void) {
|
|||
assert(keylen==6); assert(vallen==6);
|
||||
assert(strcmp(key,"hello")==0);
|
||||
assert(strcmp(val,"there")==0);
|
||||
r = pma_delete(pma, fill_dbt(&k, "nothello", 9), 0, rand4fingerprint, &sum);
|
||||
r = pma_delete(pma, fill_dbt(&k, "nothello", 9), 0, rand4fingerprint, &sum, 0);
|
||||
assert(r==DB_NOTFOUND);
|
||||
assert(sum==expect_fingerprint); // didn't change because nothing was deleted.
|
||||
|
||||
|
@ -844,7 +844,7 @@ void test_pma_split_n(int n) {
|
|||
|
||||
printf("a:"); print_pma(pmaa);
|
||||
|
||||
error = pma_split(pmaa, 0, pmab, 0, brand, &bsum, pmac, 0, crand, &csum);
|
||||
error = pma_split(pmaa, 0, 0, null_db, pmab, 0, brand, &bsum, pmac, 0, crand, &csum);
|
||||
assert(error == 0);
|
||||
pma_verify(pmaa, null_db);
|
||||
pma_verify(pmab, null_db);
|
||||
|
@ -870,6 +870,83 @@ void test_pma_split_n(int n) {
|
|||
assert(error == 0);
|
||||
}
|
||||
|
||||
void test_pma_dup_split_n(int n, int dup_mode) {
|
||||
PMA pmaa, pmab, pmac;
|
||||
int error;
|
||||
int i;
|
||||
int na, nb, nc;
|
||||
|
||||
u_int32_t rand4sum = random();
|
||||
u_int32_t sum = 0;
|
||||
u_int32_t expect_sum = 0;
|
||||
|
||||
u_int32_t brand = random();
|
||||
u_int32_t bsum = 0;
|
||||
u_int32_t crand = random();
|
||||
u_int32_t csum = 0;
|
||||
|
||||
printf("test_pma_dup_split_n:%d %d\n", n, dup_mode);
|
||||
|
||||
error = pma_create(&pmaa, default_compare_fun, 0);
|
||||
assert(error == 0);
|
||||
pma_set_dup_mode(pmaa, dup_mode);
|
||||
error = pma_create(&pmab, default_compare_fun, 0);
|
||||
assert(error == 0);
|
||||
pma_set_dup_mode(pmab, dup_mode);
|
||||
error = pma_create(&pmac, default_compare_fun, 0);
|
||||
assert(error == 0);
|
||||
pma_set_dup_mode(pmac, dup_mode);
|
||||
|
||||
/* insert some kv pairs */
|
||||
int dupkey = random();
|
||||
for (i=0; i<n; i++) {
|
||||
int v = i;
|
||||
do_insert(pmaa, &dupkey, sizeof dupkey, &v, sizeof v, rand4sum, &sum, &expect_sum);
|
||||
|
||||
pma_verify(pmaa, null_db);
|
||||
}
|
||||
|
||||
printf("a:"); print_pma(pmaa);
|
||||
|
||||
DBT splitk;
|
||||
|
||||
error = pma_split(pmaa, 0, &splitk, null_db, pmab, 0, brand, &bsum, pmac, 0, crand, &csum);
|
||||
assert(error == 0);
|
||||
pma_verify(pmaa, null_db);
|
||||
pma_verify(pmab, null_db);
|
||||
pma_verify(pmac, null_db);
|
||||
pma_verify_fingerprint(pmab, brand, bsum);
|
||||
pma_verify_fingerprint(pmac, crand, csum);
|
||||
|
||||
if (0) { printf("a:"); print_pma(pmaa); }
|
||||
na = pma_n_entries(pmaa);
|
||||
if (0) { printf("b:"); print_pma(pmab); }
|
||||
nb = pma_n_entries(pmab);
|
||||
if (0) { printf("c:"); print_pma(pmac); }
|
||||
nc = pma_n_entries(pmac);
|
||||
|
||||
if (na > 0) {
|
||||
int kk;
|
||||
assert(splitk.size == sizeof kk);
|
||||
memcpy(&kk, splitk.data, splitk.size);
|
||||
assert(kk == dupkey);
|
||||
if (nb > 0) assert(splitk.flags & BRT_PIVOT_PRESENT_L);
|
||||
if (nc > 0) assert(splitk.flags & BRT_PIVOT_PRESENT_R);
|
||||
}
|
||||
|
||||
if (splitk.data) toku_free(splitk.data);
|
||||
|
||||
assert(na == 0);
|
||||
assert(nb + nc == n);
|
||||
|
||||
error = pma_free(&pmaa);
|
||||
assert(error == 0);
|
||||
error = pma_free(&pmab);
|
||||
assert(error == 0);
|
||||
error = pma_free(&pmac);
|
||||
assert(error == 0);
|
||||
}
|
||||
|
||||
void test_pma_split_varkey(void) {
|
||||
char *keys[] = {
|
||||
"this", "is", "a", "key", "this is a really really big key", "zz", 0 };
|
||||
|
@ -905,7 +982,7 @@ void test_pma_split_varkey(void) {
|
|||
|
||||
printf("a:"); print_pma(pmaa);
|
||||
|
||||
error = pma_split(pmaa, 0, pmab, 0, brand, &bsum, pmac, 0, crand, &csum);
|
||||
error = pma_split(pmaa, 0, 0, null_db, pmab, 0, brand, &bsum, pmac, 0, crand, &csum);
|
||||
assert(error == 0);
|
||||
pma_verify(pmaa, null_db);
|
||||
pma_verify(pmab, null_db);
|
||||
|
@ -1049,7 +1126,7 @@ void test_pma_split_cursor(void) {
|
|||
// print_cursor("cursorc", cursorc);
|
||||
assert_cursor_val(cursorc, 16);
|
||||
|
||||
error = pma_split(pmaa, 0, pmab, 0, brand, &bsum, pmac, 0, crand, &csum);
|
||||
error = pma_split(pmaa, 0, 0, null_db, pmab, 0, brand, &bsum, pmac, 0, crand, &csum);
|
||||
assert(error == 0);
|
||||
|
||||
pma_verify_fingerprint(pmab, brand, bsum);
|
||||
|
@ -1103,6 +1180,9 @@ void test_pma_split(void) {
|
|||
test_pma_split_n(4); memory_check_all_free();
|
||||
test_pma_split_n(8); memory_check_all_free();
|
||||
test_pma_split_n(9); memory_check_all_free();
|
||||
test_pma_dup_split_n(0, DB_DUP); memory_check_all_free();
|
||||
test_pma_dup_split_n(1, DB_DUP); memory_check_all_free();
|
||||
test_pma_dup_split_n(9, DB_DUP); memory_check_all_free();
|
||||
test_pma_split_varkey(); memory_check_all_free();
|
||||
test_pma_split_cursor(); memory_check_all_free();
|
||||
}
|
||||
|
@ -1510,7 +1590,7 @@ void test_pma_double_delete() {
|
|||
|
||||
k = 1;
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
error = pma_delete(pma, &key, 0, rand4fingerprint, &sum);
|
||||
error = pma_delete(pma, &key, 0, rand4fingerprint, &sum, 0);
|
||||
assert(error == DB_NOTFOUND);
|
||||
assert(sum == expect_fingerprint);
|
||||
|
||||
|
@ -2085,7 +2165,7 @@ void test_dup_key_delete(int n, int mode) {
|
|||
}
|
||||
|
||||
k = htonl(2);
|
||||
r = pma_delete(pma, fill_dbt(&key, &k, sizeof k), null_db, rand4fingerprint, &sum);
|
||||
r = pma_delete(pma, fill_dbt(&key, &k, sizeof k), null_db, rand4fingerprint, &sum, 0);
|
||||
if (r != 0) assert(n == 0);
|
||||
expect_fingerprint = sum_before_all_the_duplicates;
|
||||
assert(sum == expect_fingerprint);
|
||||
|
@ -2140,9 +2220,10 @@ void test_dup_key_delete(int n, int mode) {
|
|||
assert(r == 0);
|
||||
}
|
||||
|
||||
/* insert n duplicate keys */
|
||||
void test_dupsort_key_insert(int n) {
|
||||
printf("test_dup_key_insert:%d\n", n);
|
||||
/* insert n duplicate keys with random data
|
||||
verify that the data is sorted */
|
||||
void test_dupsort_key_insert(int n, int dup_data) {
|
||||
printf("test_dupsort_key_insert:%d %d\n", n, dup_data);
|
||||
|
||||
PMA pma;
|
||||
int r;
|
||||
|
@ -2172,13 +2253,14 @@ void test_dupsort_key_insert(int n) {
|
|||
do_insert(pma, &k, sizeof k, &v, sizeof v, rand4fingerprint, &sum, &expect_fingerprint);
|
||||
pma_verify(pma, null_db);
|
||||
|
||||
k = htonl(2);
|
||||
int values[n];
|
||||
|
||||
int i;
|
||||
for (i=0; i<n; i++)
|
||||
values[i] = (i==0 || dup_data) ? (int) htonl(random()) : values[i-1];
|
||||
|
||||
/* insert 2->n-i */
|
||||
for (i=0; i<n; i++) {
|
||||
k = htonl(2);
|
||||
values[i] = htonl(random());
|
||||
do_insert(pma, &k, sizeof k, &values[i], sizeof values[i], rand4fingerprint, &sum, &expect_fingerprint);
|
||||
pma_verify(pma, null_db);
|
||||
}
|
||||
|
@ -2188,7 +2270,6 @@ void test_dupsort_key_insert(int n) {
|
|||
r = pma_cursor(pma, &cursor);
|
||||
assert(r == 0);
|
||||
|
||||
k = htonl(2);
|
||||
fill_dbt(&key, &k, sizeof k);
|
||||
r = pma_cursor_set_key(cursor, &key, 0);
|
||||
if (r != 0) {
|
||||
|
@ -2301,8 +2382,10 @@ void test_dup() {
|
|||
test_dup_key_insert(1000); memory_check_all_free();
|
||||
test_dup_key_delete(0, DB_DUP); memory_check_all_free();
|
||||
test_dup_key_delete(1000, DB_DUP); memory_check_all_free();
|
||||
test_dupsort_key_insert(2); memory_check_all_free();
|
||||
test_dupsort_key_insert(1000); memory_check_all_free();
|
||||
test_dupsort_key_insert(2, 0); memory_check_all_free();
|
||||
test_dupsort_key_insert(1000, 0); memory_check_all_free();
|
||||
test_dupsort_key_insert(2, 1); memory_check_all_free();
|
||||
test_dupsort_key_insert(1000, 1); memory_check_all_free();
|
||||
test_dup_key_delete(0, DB_DUP+DB_DUPSORT); memory_check_all_free();
|
||||
test_dup_key_delete(1000, DB_DUP+DB_DUPSORT); memory_check_all_free();
|
||||
test_dup_key_lookup(32, DB_DUP); memory_check_all_free();
|
||||
|
|
123
newbrt/pma.c
123
newbrt/pma.c
|
@ -984,7 +984,7 @@ static int pma_next_key(PMA pma, DBT *k, DB *db, int here, int n, int *found) {
|
|||
return here;
|
||||
}
|
||||
|
||||
static int pma_delete_dup (PMA pma, DBT *k, DB *db, u_int32_t rand4sem, u_int32_t *fingerprint) {
|
||||
static int pma_delete_dup (PMA pma, DBT *k, DB *db, u_int32_t rand4sem, u_int32_t *fingerprint, u_int32_t *deleted_size) {
|
||||
/* find the left most matching key in the pma */
|
||||
int found, lefthere;
|
||||
lefthere = __pma_left_search(pma, k, db, 0, pma->N, &found);
|
||||
|
@ -993,6 +993,7 @@ static int pma_delete_dup (PMA pma, DBT *k, DB *db, u_int32_t rand4sem, u_int32_
|
|||
struct kv_pair *kv = pma->pairs[righthere];
|
||||
if (kv_pair_valid(kv)) {
|
||||
/* mark the pair as deleted */
|
||||
*deleted_size += KEY_VALUE_OVERHEAD + kv_pair_keylen(kv) + kv_pair_vallen(kv);
|
||||
*fingerprint -= rand4sem*toku_calccrc32_kvpair (kv_pair_key_const(kv), kv_pair_keylen(kv), kv_pair_val_const(kv), kv_pair_vallen(kv));
|
||||
pma->pairs[righthere] = kv_pair_set_deleted(kv);
|
||||
if (__pma_count_cursor_refs(pma, righthere) == 0) {
|
||||
|
@ -1011,13 +1012,14 @@ static int pma_delete_dup (PMA pma, DBT *k, DB *db, u_int32_t rand4sem, u_int32_
|
|||
return found ? BRT_OK : DB_NOTFOUND;
|
||||
}
|
||||
|
||||
static int pma_delete_nodup (PMA pma, DBT *k, DB *db, u_int32_t rand4sem, u_int32_t *fingerprint) {
|
||||
static int pma_delete_nodup (PMA pma, DBT *k, DB *db, u_int32_t rand4sem, u_int32_t *fingerprint, u_int32_t *deleted_size) {
|
||||
int idx = pmainternal_find(pma, k, db);
|
||||
struct kv_pair *kv = pma->pairs[idx];
|
||||
if (!kv_pair_valid(kv)) {
|
||||
if (0) printf("%s:%d l=%d r=%d\n", __FILE__, __LINE__, idx, DB_NOTFOUND);
|
||||
return DB_NOTFOUND;
|
||||
}
|
||||
*deleted_size = KEY_VALUE_OVERHEAD + kv_pair_keylen(kv) + kv_pair_vallen(kv);
|
||||
*fingerprint -= rand4sem*toku_calccrc32_kvpair (kv_pair_key_const(kv), kv_pair_keylen(kv), kv_pair_val_const(kv), kv_pair_vallen(kv));
|
||||
pma->pairs[idx] = kv_pair_set_deleted(kv);
|
||||
if (__pma_count_cursor_refs(pma, idx) == 0)
|
||||
|
@ -1025,11 +1027,15 @@ static int pma_delete_nodup (PMA pma, DBT *k, DB *db, u_int32_t rand4sem, u_int3
|
|||
return BRT_OK;
|
||||
}
|
||||
|
||||
int pma_delete (PMA pma, DBT *k, DB *db, u_int32_t rand4sem, u_int32_t *fingerprint) {
|
||||
int pma_delete (PMA pma, DBT *k, DB *db, u_int32_t rand4sem, u_int32_t *fingerprint, u_int32_t *deleted_size) {
|
||||
u_int32_t my_deleted_size;
|
||||
if (!deleted_size)
|
||||
deleted_size = &my_deleted_size;
|
||||
*deleted_size = 0;
|
||||
if (pma->dup_mode & DB_DUP)
|
||||
return pma_delete_dup(pma, k, db, rand4sem, fingerprint);
|
||||
return pma_delete_dup(pma, k, db, rand4sem, fingerprint, deleted_size);
|
||||
else
|
||||
return pma_delete_nodup(pma, k, db, rand4sem, fingerprint);
|
||||
return pma_delete_nodup(pma, k, db, rand4sem, fingerprint, deleted_size);
|
||||
}
|
||||
|
||||
void __pma_delete_resume(PMA pma, int here) {
|
||||
|
@ -1121,30 +1127,41 @@ int pma_insert_or_replace (PMA pma, DBT *k, DBT *v,
|
|||
DB *db, TOKUTXN txn, DISKOFF diskoff,
|
||||
u_int32_t rand4fingerprint, u_int32_t *fingerprint) {
|
||||
//printf("%s:%d v->size=%d\n", __FILE__, __LINE__, v->size);
|
||||
int idx = pmainternal_find(pma, k, db);
|
||||
struct kv_pair *kv;
|
||||
int r;
|
||||
if (idx < pma_index_limit(pma) && (kv = pma->pairs[idx])) {
|
||||
DBT k2;
|
||||
// printf("%s:%d\n", __FILE__, __LINE__);
|
||||
kv = kv_pair_ptr(kv);
|
||||
if (0==pma->compare_fun(db, k, fill_dbt(&k2, kv->key, kv->keylen))) {
|
||||
if (!kv_pair_deleted(pma->pairs[idx])) {
|
||||
*replaced_v_size = kv->vallen;
|
||||
*fingerprint -= rand4fingerprint*toku_calccrc32_kvpair(kv_pair_key_const(kv), kv_pair_keylen(kv), kv_pair_val_const(kv), kv_pair_vallen(kv));
|
||||
r=tokulogger_log_phys_add_or_delete_in_leaf(db, txn, diskoff, 0, kv);
|
||||
if (r!=0) return r;
|
||||
}
|
||||
if (v->size == (unsigned int) kv_pair_vallen(kv)) {
|
||||
memcpy(kv_pair_val(kv), v->data, v->size);
|
||||
} else {
|
||||
pma_mfree_kv_pair(pma, kv);
|
||||
pma->pairs[idx] = pma_malloc_kv_pair(pma, k->data, k->size, v->data, v->size);
|
||||
assert(pma->pairs[idx]);
|
||||
int idx, found;
|
||||
if (pma->dup_mode & DB_DUPSORT) {
|
||||
idx = __pma_dup_search(pma, k, v, db, 0, pma->N, &found);
|
||||
if (found)
|
||||
idx += 1;
|
||||
} else if (pma->dup_mode & DB_DUP) {
|
||||
idx = __pma_right_search(pma, k, db, 0, pma->N, &found);
|
||||
if (found)
|
||||
idx += 1;
|
||||
} else {
|
||||
idx = pmainternal_find(pma, k, db);
|
||||
struct kv_pair *kv;
|
||||
if (idx < pma_index_limit(pma) && (kv = pma->pairs[idx])) {
|
||||
DBT k2;
|
||||
// printf("%s:%d\n", __FILE__, __LINE__);
|
||||
kv = kv_pair_ptr(kv);
|
||||
if (0==pma->compare_fun(db, k, fill_dbt(&k2, kv->key, kv->keylen))) {
|
||||
if (!kv_pair_deleted(pma->pairs[idx])) {
|
||||
*replaced_v_size = kv->vallen;
|
||||
*fingerprint -= rand4fingerprint*toku_calccrc32_kvpair(kv_pair_key_const(kv), kv_pair_keylen(kv), kv_pair_val_const(kv), kv_pair_vallen(kv));
|
||||
r=tokulogger_log_phys_add_or_delete_in_leaf(db, txn, diskoff, 0, kv);
|
||||
if (r!=0) return r;
|
||||
}
|
||||
if (v->size == (unsigned int) kv_pair_vallen(kv)) {
|
||||
memcpy(kv_pair_val(kv), v->data, v->size);
|
||||
} else {
|
||||
pma_mfree_kv_pair(pma, kv);
|
||||
pma->pairs[idx] = pma_malloc_kv_pair(pma, k->data, k->size, v->data, v->size);
|
||||
assert(pma->pairs[idx]);
|
||||
}
|
||||
r = tokulogger_log_phys_add_or_delete_in_leaf(db, txn, diskoff, 0, pma->pairs[idx]);
|
||||
*fingerprint += rand4fingerprint*toku_calccrc32_kvpair(k->data, k->size, v->data, v->size);
|
||||
return r;
|
||||
}
|
||||
r = tokulogger_log_phys_add_or_delete_in_leaf(db, txn, diskoff, 0, pma->pairs[idx]);
|
||||
*fingerprint += rand4fingerprint*toku_calccrc32_kvpair(k->data, k->size, v->data, v->size);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
if (kv_pair_inuse(pma->pairs[idx])) {
|
||||
|
@ -1274,7 +1291,7 @@ static void __pma_relocate_kvpairs(PMA pma) {
|
|||
|
||||
#endif
|
||||
|
||||
int pma_split(PMA origpma, unsigned int *origpma_size,
|
||||
int pma_split(PMA origpma, unsigned int *origpma_size, DBT *splitk, DB *db,
|
||||
PMA leftpma, unsigned int *leftpma_size, u_int32_t leftrand4fp, u_int32_t *leftfingerprint,
|
||||
PMA rightpma, unsigned int *rightpma_size, u_int32_t rightrand4fp, u_int32_t *rightfingerprint) {
|
||||
int error;
|
||||
|
@ -1289,8 +1306,11 @@ int pma_split(PMA origpma, unsigned int *origpma_size,
|
|||
|
||||
/* extract the pairs */
|
||||
npairs = pma_n_entries(origpma);
|
||||
if (npairs == 0)
|
||||
if (npairs == 0) {
|
||||
if (splitk)
|
||||
memset(splitk, 0, sizeof *splitk);
|
||||
return 0;
|
||||
}
|
||||
assert(pma_n_entries(leftpma) == 0);
|
||||
assert(pma_n_entries(rightpma) == 0);
|
||||
|
||||
|
@ -1342,6 +1362,22 @@ int pma_split(PMA origpma, unsigned int *origpma_size,
|
|||
*rightfingerprint += rightrand4fp * sum;
|
||||
}
|
||||
|
||||
if (splitk) {
|
||||
struct kv_pair *kv = pairs[spliti-1].pair;
|
||||
assert(kv_pair_valid(kv));
|
||||
splitk->size = kv_pair_keylen(kv);
|
||||
splitk->data = memdup(kv_pair_key(kv), splitk->size);
|
||||
splitk->flags = BRT_PIVOT_PRESENT_L;
|
||||
if (spliti < npairs) {
|
||||
kv = pairs[spliti].pair;
|
||||
DBT k2;
|
||||
int cmp = origpma->compare_fun(db, splitk, fill_dbt(&k2, kv_pair_key(kv), kv_pair_keylen(kv)));
|
||||
if (cmp == 0) {
|
||||
splitk->flags += BRT_PIVOT_PRESENT_R;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* put the first half of pairs into the left pma */
|
||||
n = spliti;
|
||||
error = __pma_resize_array(leftpma, n + n/4, 0);
|
||||
|
@ -1376,34 +1412,6 @@ int pma_split(PMA origpma, unsigned int *origpma_size,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pma_get_last(PMA pma, DBT *key, DBT *val) {
|
||||
int position;
|
||||
struct kv_pair *pair;
|
||||
void *v; int vlen;
|
||||
|
||||
position = pma->N - 1;
|
||||
while ((pair = pma->pairs[position]) == 0) {
|
||||
if (position > 0)
|
||||
position--;
|
||||
else
|
||||
return DB_NOTFOUND;
|
||||
}
|
||||
|
||||
if (key) {
|
||||
v = kv_pair_key(pair);
|
||||
vlen = kv_pair_keylen(pair);
|
||||
fill_dbt(key, memdup(v, vlen), vlen);
|
||||
}
|
||||
|
||||
if (val) {
|
||||
v = kv_pair_val(pair);
|
||||
vlen = kv_pair_vallen(pair);
|
||||
fill_dbt(val, memdup(v, vlen), vlen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __pma_bulk_cleanup(struct pma *pma, struct kv_pair_tag *pairs, int n) {
|
||||
int i;
|
||||
|
||||
|
@ -1514,6 +1522,7 @@ void pma_verify(PMA pma, DB *db) {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void pma_verify_fingerprint (PMA pma, u_int32_t rand4fingerprint, u_int32_t fingerprint) {
|
||||
u_int32_t actual_fingerprint=0;
|
||||
PMA_ITERATE(pma, kv, kl, dv, dl,
|
||||
|
|
|
@ -47,7 +47,7 @@ enum pma_errors pma_insert (PMA, DBT*, DBT*, DB*, TOKUTXN txn, DISKOFF, u_int32_
|
|||
/* This returns an error if the key is NOT present. */
|
||||
int pma_replace (PMA, bytevec key, ITEMLEN keylen, bytevec data, ITEMLEN datalen);
|
||||
/* This returns an error if the key is NOT present. */
|
||||
int pma_delete (PMA, DBT *, DB*, u_int32_t /*random for fingerprint*/, u_int32_t */*fingerprint*/);
|
||||
int pma_delete (PMA, DBT *, DB*, u_int32_t /*random for fingerprint*/, u_int32_t */*fingerprint*/, u_int32_t *deleted_size);
|
||||
|
||||
int pma_insert_or_replace (PMA pma, DBT *k, DBT *v,
|
||||
int *replaced_v_size, /* If it is a replacement, set to the size of the old value, otherwise set to -1. */
|
||||
|
@ -69,7 +69,7 @@ enum pma_errors pma_lookup (PMA, DBT*, DBT*, DB*);
|
|||
* leftpma - the pma assigned keys <= pivot key
|
||||
* rightpma - the pma assigned keys > pivot key
|
||||
*/
|
||||
int pma_split(PMA origpma, unsigned int *origpma_size,
|
||||
int pma_split(PMA origpma, unsigned int *origpma_size, DBT *splitk, DB *db,
|
||||
PMA leftpma, unsigned int *leftpma_size, u_int32_t leftrand4sum, u_int32_t *leftfingerprint,
|
||||
PMA rightpma, unsigned int *rightpma_size, u_int32_t rightrand4sum, u_int32_t *rightfingerprint);
|
||||
|
||||
|
@ -112,9 +112,6 @@ int pma_cursor_set_range(PMA_CURSOR c, DBT *key, DB *db);
|
|||
/* delete the key value pair under the cursor, return the size of the pair */
|
||||
int pma_cursor_delete_under(PMA_CURSOR c, int *kvsize);
|
||||
|
||||
/* get the last key and value in the pma */
|
||||
int pma_get_last(PMA pma, DBT *key, DBT *val);
|
||||
|
||||
int pma_random_pick(PMA, bytevec *key, ITEMLEN *keylen, bytevec *data, ITEMLEN *datalen);
|
||||
|
||||
int pma_index_limit(PMA);
|
||||
|
|
|
@ -16,15 +16,6 @@ DBT *fill_dbt(DBT *dbt, bytevec k, ITEMLEN len) {
|
|||
return dbt;
|
||||
}
|
||||
|
||||
DBT *fill_dbt_ap(DBT *dbt, bytevec k, ITEMLEN len, void *app_private __attribute__((unused))) {
|
||||
fill_dbt(dbt, k, len);
|
||||
#if USE_DBT_APP_PRIVATE
|
||||
dbt->app_private=app_private;
|
||||
#endif
|
||||
return dbt;
|
||||
}
|
||||
|
||||
|
||||
int ybt_set_value (DBT *ybt, bytevec val, ITEMLEN vallen, void **staticptrp) {
|
||||
if (ybt->flags==DB_DBT_MALLOC) {
|
||||
domalloc:
|
||||
|
|
17
newbrt/ybt.h
17
newbrt/ybt.h
|
@ -8,25 +8,8 @@
|
|||
|
||||
DBT* init_dbt (DBT *);
|
||||
DBT *fill_dbt(DBT *dbt, bytevec k, ITEMLEN len);
|
||||
DBT *fill_dbt_ap(DBT *dbt, bytevec k, ITEMLEN len, void *app_private);
|
||||
int ybt_set_value (DBT *, bytevec val, ITEMLEN vallen, void **staticptrp);
|
||||
|
||||
#ifndef USE_DBT_APP_PRIVATE
|
||||
#define USE_DBT_APP_PRIVATE 0
|
||||
#endif
|
||||
|
||||
static inline void *dbt_get_app_private(DBT *dbt __attribute__((unused))) {
|
||||
#if USE_DBT_APP_PRIVATE
|
||||
return dbt->app_private;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void dbt_set_app_private(DBT *dbt __attribute__((unused)), void *ap __attribute__((unused))) {
|
||||
#if USE_DBT_APP_PRIVATE
|
||||
dbt->app_private = ap;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue