diff --git a/newbrt/cachetable.c b/newbrt/cachetable.c index 48f51756d3d..b03a4818c48 100644 --- a/newbrt/cachetable.c +++ b/newbrt/cachetable.c @@ -119,13 +119,11 @@ static FILENUM next_filenum_to_use={0}; static void cachefile_init_filenum(CACHEFILE newcf, int fd, const char *fname, struct fileid fileid) \ { - newcf->filenum.fileid = next_filenum_to_use.fileid++; newcf->fd = fd; newcf->fileid = fileid; newcf->fname = fname ? toku_strdup(fname) : 0; } - // If something goes wrong, close the fd. After this, the caller shouldn't close the fd, but instead should close the cachefile. int toku_cachetable_openfd (CACHEFILE *cf, CACHETABLE t, int fd, const char *fname) { int r; @@ -156,6 +154,7 @@ int toku_cachetable_openfd (CACHEFILE *cf, CACHETABLE t, int fd, const char *fna { CACHEFILE MALLOC(newcf); newcf->cachetable = t; + newcf->filenum.fileid = next_filenum_to_use.fileid++; cachefile_init_filenum(newcf, fd, fname, fileid); newcf->refcount = 1; newcf->header_fullhash = toku_cachetable_hash(newcf, 0); diff --git a/src/tests/test_truncate_txn_commit2.c b/src/tests/test_truncate_txn_commit2.c new file mode 100644 index 00000000000..8683890490a --- /dev/null +++ b/src/tests/test_truncate_txn_commit2.c @@ -0,0 +1,125 @@ +// truncate a database within a transaction +// begin txn; insert (n,n); truncate; commit +// verify that the database is empty + +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +int test_truncate_txn_commit2(int n) { + int r; + + DB_ENV *env; + DB *db; + DBC *cursor; + + r = db_env_create(&env, 0); assert(r == 0); + r = env->open(env, ENVDIR, DB_INIT_MPOOL + DB_INIT_LOCK + DB_INIT_TXN + DB_PRIVATE + DB_CREATE, 0777); assert(r == 0); + + int i; + + // populate the tree + r = db_create(&db, env, 0); assert(r == 0); + r = db->open(db, 0, "test.db", 0, DB_BTREE, DB_CREATE, 0777); assert(r == 0); + + for (i=0; iput(db, 0, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); assert(r == 0); + } + + r = db->close(db, 0); assert(r == 0); + + r = db_create(&db, env, 0); assert(r == 0); + r = db->open(db, 0, "test.db", 0, DB_UNKNOWN, DB_AUTO_COMMIT, 0777); assert(r == 0); + + DB_TXN *txn; + + // walk - expect n rows + r = env->txn_begin(env, NULL, &txn, 0); assert(r == 0); + i = 0; + r = db->cursor(db, txn, &cursor, 0); assert(r == 0); + while (1) { + DBT key, val; + r = cursor->c_get(cursor, dbt_init(&key, 0, 0), dbt_init(&val, 0, 0), DB_NEXT); + if (r == DB_NOTFOUND) break; + i++; + } + r = cursor->c_close(cursor); assert(r == 0); + assert(i == n); + + r = txn->commit(txn, 0); assert(r == 0); + + // truncate the db + r = env->txn_begin(env, NULL, &txn, 0); assert(r == 0); + + // insert key n val n + { + int k = htonl(n); int v = n; + DBT key, val; + r = db->put(db, txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); assert(r == 0); + } + + u_int32_t row_count = 0; + r = db->truncate(db, txn, &row_count, 0); assert(r == 0); + + r = txn->commit(txn, 0); assert(r == 0); + + // walk - expect 0 rows + r = env->txn_begin(env, 0, &txn, 0); assert(r == 0); + + i = 0; + r = db->cursor(db, txn, &cursor, 0); assert(r == 0); + while (1) { + DBT key, val; + r = cursor->c_get(cursor, dbt_init(&key, 0, 0), dbt_init(&val, 0, 0), DB_NEXT); + if (r == DB_NOTFOUND) break; + i++; + } + r = cursor->c_close(cursor); assert(r == 0); + assert(i == 0); + + r = txn->commit(txn, 0); assert(r == 0); + + r = db->close(db, 0); assert(r == 0); + + // walk the tree - expect 0 rows + r = db_create(&db, env, 0); assert(r == 0); + r = db->open(db, 0, "test.db", 0, DB_UNKNOWN, DB_AUTO_COMMIT, 0777); assert(r == 0); + + r = env->txn_begin(env, 0, &txn, 0); assert(r == 0); + + i = 0; + r = db->cursor(db, txn, &cursor, 0); assert(r == 0); + while (1) { + DBT key, val; + r = cursor->c_get(cursor, dbt_init(&key, 0, 0), dbt_init(&val, 0, 0), DB_NEXT); + if (r == DB_NOTFOUND) break; + i++; + } + r = cursor->c_close(cursor); assert(r == 0); + assert(i == 0); + + r = txn->commit(txn, 0); assert(r == 0); + + r = db->close(db, 0); assert(r == 0); + + r = env->close(env, 0); assert(r == 0); + return 0; +} + +int main(int argc, const char *argv[]) { + parse_args(argc, argv); + int nodesize = 1024*1024; + int leafentry = 25; + int n = (nodesize/leafentry) * 2; + system("rm -rf " ENVDIR); + mkdir(ENVDIR, 0777); + int r = test_truncate_txn_commit2(n); + return r; +} diff --git a/src/tests/test_truncate_txn_commit3.c b/src/tests/test_truncate_txn_commit3.c new file mode 100644 index 00000000000..abd2ad34aad --- /dev/null +++ b/src/tests/test_truncate_txn_commit3.c @@ -0,0 +1,125 @@ +// truncate a database within a transaction +// begin txn; delete 0; truncate; commit +// verify that the database is empty + +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +int test_truncate_txn_commit2(int n) { + int r; + + DB_ENV *env; + DB *db; + DBC *cursor; + + r = db_env_create(&env, 0); assert(r == 0); + r = env->open(env, ENVDIR, DB_INIT_MPOOL + DB_INIT_LOCK + DB_INIT_TXN + DB_PRIVATE + DB_CREATE, 0777); assert(r == 0); + + int i; + + // populate the tree + r = db_create(&db, env, 0); assert(r == 0); + r = db->open(db, 0, "test.db", 0, DB_BTREE, DB_CREATE, 0777); assert(r == 0); + + for (i=0; iput(db, 0, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); assert(r == 0); + } + + r = db->close(db, 0); assert(r == 0); + + r = db_create(&db, env, 0); assert(r == 0); + r = db->open(db, 0, "test.db", 0, DB_UNKNOWN, DB_AUTO_COMMIT, 0777); assert(r == 0); + + DB_TXN *txn; + + // walk - expect n rows + r = env->txn_begin(env, NULL, &txn, 0); assert(r == 0); + i = 0; + r = db->cursor(db, txn, &cursor, 0); assert(r == 0); + while (1) { + DBT key, val; + r = cursor->c_get(cursor, dbt_init(&key, 0, 0), dbt_init(&val, 0, 0), DB_NEXT); + if (r == DB_NOTFOUND) break; + i++; + } + r = cursor->c_close(cursor); assert(r == 0); + assert(i == n); + + r = txn->commit(txn, 0); assert(r == 0); + + // truncate the db + r = env->txn_begin(env, NULL, &txn, 0); assert(r == 0); + + // delete 0 + { + int k = htonl(0); + DBT key; + r = db->del(db, txn, dbt_init(&key, &k, sizeof k), 0); assert(r == 0); + } + + u_int32_t row_count = 0; + r = db->truncate(db, txn, &row_count, 0); assert(r == 0); + + r = txn->commit(txn, 0); assert(r == 0); + + // walk - expect 0 rows + r = env->txn_begin(env, 0, &txn, 0); assert(r == 0); + + i = 0; + r = db->cursor(db, txn, &cursor, 0); assert(r == 0); + while (1) { + DBT key, val; + r = cursor->c_get(cursor, dbt_init(&key, 0, 0), dbt_init(&val, 0, 0), DB_NEXT); + if (r == DB_NOTFOUND) break; + i++; + } + r = cursor->c_close(cursor); assert(r == 0); + assert(i == 0); + + r = txn->commit(txn, 0); assert(r == 0); + + r = db->close(db, 0); assert(r == 0); + + // walk the tree - expect 0 rows + r = db_create(&db, env, 0); assert(r == 0); + r = db->open(db, 0, "test.db", 0, DB_UNKNOWN, DB_AUTO_COMMIT, 0777); assert(r == 0); + + r = env->txn_begin(env, 0, &txn, 0); assert(r == 0); + + i = 0; + r = db->cursor(db, txn, &cursor, 0); assert(r == 0); + while (1) { + DBT key, val; + r = cursor->c_get(cursor, dbt_init(&key, 0, 0), dbt_init(&val, 0, 0), DB_NEXT); + if (r == DB_NOTFOUND) break; + i++; + } + r = cursor->c_close(cursor); assert(r == 0); + assert(i == 0); + + r = txn->commit(txn, 0); assert(r == 0); + + r = db->close(db, 0); assert(r == 0); + + r = env->close(env, 0); assert(r == 0); + return 0; +} + +int main(int argc, const char *argv[]) { + parse_args(argc, argv); + int nodesize = 1024*1024; + int leafentry = 25; + int n = (nodesize/leafentry) * 2; + system("rm -rf " ENVDIR); + mkdir(ENVDIR, 0777); + int r = test_truncate_txn_commit2(n); + return r; +}