diff options
Diffstat (limited to 'src/third_party/wiredtiger/test/format/bdb.c')
-rw-r--r-- | src/third_party/wiredtiger/test/format/bdb.c | 92 |
1 files changed, 84 insertions, 8 deletions
diff --git a/src/third_party/wiredtiger/test/format/bdb.c b/src/third_party/wiredtiger/test/format/bdb.c index adf32713cd2..c5d11dcefc7 100644 --- a/src/third_party/wiredtiger/test/format/bdb.c +++ b/src/third_party/wiredtiger/test/format/bdb.c @@ -32,6 +32,10 @@ static DBT key, value; static WT_ITEM keyitem; +#define bdb_die(ret, fmt, ...) \ + testutil_die(0, "%s/%d: %s: " fmt, \ + __func__, __LINE__, db_strerror(ret), __VA_ARGS__); + static int bdb_compare_reverse(DB *dbp, const DBT *k1, const DBT *k2 #if DB_VERSION_MAJOR >= 6 @@ -69,7 +73,7 @@ bdb_open(void) DB_CREATE | DB_INIT_LOCK | DB_INIT_MPOOL | DB_PRIVATE, 0) == 0); assert(db_create(&db, dbenv, 0) == 0); - if (g.type == ROW && g.c_reverse) + if (g.c_reverse) assert(db->set_bt_compare(db, bdb_compare_reverse) == 0); assert(db->open( @@ -127,7 +131,7 @@ bdb_np(bool next, if ((ret = dbc->get(dbc, &key, &value, next ? DB_NEXT : DB_PREV)) != 0) { if (ret != DB_NOTFOUND) - testutil_die(ret, "dbc.get: %s: {%.*s}", + bdb_die(ret, "dbc.get: %s: {%.*s}", next ? "DB_NEXT" : "DB_PREV", (int)key.size, (char *)key.data); *notfoundp = 1; @@ -152,7 +156,7 @@ bdb_read(uint64_t keyno, void *valuep, size_t *valuesizep, int *notfoundp) *notfoundp = 0; if ((ret = dbc->get(dbc, &key, &value, DB_SET)) != 0) { if (ret != DB_NOTFOUND) - testutil_die(ret, "dbc.get: DB_SET: {%.*s}", + bdb_die(ret, "dbc.get: DB_SET: {%.*s}", (int)key.size, (char *)key.data); *notfoundp = 1; } else { @@ -174,7 +178,7 @@ bdb_update(const void *arg_key, size_t arg_key_size, value.size = (u_int32_t)arg_value_size; if ((ret = dbc->put(dbc, &key, &value, DB_KEYFIRST)) != 0) - testutil_die(ret, "dbc.put: DB_KEYFIRST: {%.*s}{%.*s}", + bdb_die(ret, "dbc.put: DB_KEYFIRST: {%.*s}{%.*s}", (int)key.size, (char *)key.data, (int)value.size, (char *)value.data); } @@ -196,10 +200,82 @@ bdb_remove(uint64_t keyno, int *notfoundp) if (*notfoundp) return; - if ((ret = dbc->del(dbc, 0)) != 0) { - if (ret != DB_NOTFOUND) - testutil_die(ret, "dbc.del: {%.*s}", + /* Deleting a fixed-length item is the same as setting the bits to 0. */ + if (g.type == FIX) + bdb_update(key.data, key.size, "", 1); + else + if ((ret = dbc->del(dbc, 0)) != 0) { + if (ret != DB_NOTFOUND) + bdb_die(ret, "dbc.del: {%.*s}", + (int)key.size, (char *)key.data); + *notfoundp = 1; + } +} + +void +bdb_truncate(uint64_t start, uint64_t stop) +{ + DBC *dbc = g.dbc; + size_t len; + int cmp, ret, notfound; + + /* Deleting a fixed-length item is the same as setting the bits to 0. */ + if (g.type == FIX) { + /* + * If we're deleting from/to the start/end of the database, + * correct for the number of records we have. + */ + if (start == 0) + start = 1; + if (stop == 0) + stop = g.rows; + for (; start <= stop; ++start) + bdb_remove(start, ¬found); + return; + } + + if (start == 0) { + ret = dbc->get(dbc, &key, &value, DB_FIRST); + if (ret != 0 && ret != DB_NOTFOUND) + bdb_die(ret, "%s", "dbc.get: DB_FIRST"); + } else { + key_gen(&keyitem, start); + key.data = (void *)keyitem.data; + key.size = (u_int32_t)keyitem.size; + ret = dbc->get(dbc, &key, &value, DB_SET_RANGE); + if (ret != 0 && ret != DB_NOTFOUND) + bdb_die(ret, "dbc.get: DB_SET: {%.*s}", (int)key.size, (char *)key.data); - *notfoundp = 1; } + if (ret == DB_NOTFOUND) + return; + + if (stop == 0) { + do { + ret = dbc->del(dbc, 0); + if (ret != 0 && ret != DB_NOTFOUND) + bdb_die(ret, "dbc.del: {%.*s}", + (int)key.size, (char *)key.data); + } while ((ret = dbc->get(dbc, &key, &value, DB_NEXT)) == 0); + } else { + key_gen(&keyitem, stop); + do { + len = WT_MIN(key.size, keyitem.size); + cmp = memcmp(key.data, keyitem.data, len); + if (g.c_reverse) { + if (cmp < 0 || + (cmp == 0 && key.size < keyitem.size)) + break; + } else + if (cmp > 0 || + (cmp == 0 && key.size > keyitem.size)) + break; + ret = dbc->del(dbc, 0); + if (ret != 0 && ret != DB_NOTFOUND) + bdb_die(ret, "dbc.del: {%.*s}", + (int)key.size, (char *)key.data); + } while ((ret = dbc->get(dbc, &key, &value, DB_NEXT)) == 0); + } + if (ret != 0 && ret != DB_NOTFOUND) + bdb_die(ret, "%s", "dbc.get: DB_NEXT"); } |