Commit dbf1ac48 authored by Rusty Russell's avatar Rusty Russell

tdb2: delete and fetch now work.

parent 29d640f6
...@@ -842,23 +842,24 @@ delete: ...@@ -842,23 +842,24 @@ delete:
goto unlock_err; goto unlock_err;
/* Rehash anything following. */ /* Rehash anything following. */
for (i = old_bucket+1; i < h + num_locks; i++) { for (i = hash_off(tdb, old_bucket+1);
i != hash_off(tdb, h + num_locks);
i += sizeof(tdb_off_t)) {
tdb_off_t off2; tdb_off_t off2;
uint64_t h2; uint64_t h2;
off2 = tdb_read_off(tdb, hash_off(tdb, i)); off2 = tdb_read_off(tdb, i);
if (unlikely(off2 == TDB_OFF_ERR)) if (unlikely(off2 == TDB_OFF_ERR))
goto unlock_err; goto unlock_err;
/* Maybe use a bit to indicate it is in ideal place? */ /* Maybe use a bit to indicate it is in ideal place? */
h2 = hash_record(tdb, off2); h2 = hash_record(tdb, off2);
/* Is it happy where it is? */ /* Is it happy where it is? */
if ((h2 & ((1ULL << tdb->header.v.hash_bits)-1)) if (hash_off(tdb, h2) == i)
== (i & ((1ULL << tdb->header.v.hash_bits)-1)))
continue; continue;
/* Remove it. */ /* Remove it. */
if (tdb_write_off(tdb, hash_off(tdb, i), 0) == -1) if (tdb_write_off(tdb, i, 0) == -1)
goto unlock_err; goto unlock_err;
/* Rehash it. */ /* Rehash it. */
......
#ifndef TDB2_TEST_LOGGING_H #ifndef TDB2_TEST_LOGGING_H
#define TDB2_TEST_LOGGING_H #define TDB2_TEST_LOGGING_H
#include <ccan/tdb2/tdb2.h> #include <ccan/tdb2/tdb2.h>
#include <stdbool.h>
#include <string.h>
unsigned tap_log_messages; unsigned tap_log_messages;
void tap_log_fn(struct tdb_context *tdb, void tap_log_fn(struct tdb_context *tdb,
enum tdb_debug_level level, void *priv, enum tdb_debug_level level, void *priv,
const char *fmt, ...); const char *fmt, ...);
static inline bool data_equal(struct tdb_data a, struct tdb_data b)
{
if (a.dsize != b.dsize)
return false;
return memcmp(a.dptr, b.dptr, a.dsize) == 0;
}
#endif /* TDB2_TEST_LOGGING_H */ #endif /* TDB2_TEST_LOGGING_H */
#include <ccan/tdb2/tdb.c>
#include <ccan/tdb2/free.c>
#include <ccan/tdb2/lock.c>
#include <ccan/tdb2/io.c>
#include <ccan/tdb2/check.c>
#include <ccan/tap/tap.h>
#include "logging.h"
int main(int argc, char *argv[])
{
unsigned int i;
struct tdb_context *tdb;
int flags[] = { TDB_INTERNAL, TDB_DEFAULT,
TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT };
struct tdb_data key = { (unsigned char *)"key", 3 };
struct tdb_data data = { (unsigned char *)"data", 4 };
plan_tests(sizeof(flags) / sizeof(flags[0]) * 8 + 1);
for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
tdb = tdb_open("/tmp/run-new_database.tdb", flags[i],
O_RDWR|O_CREAT|O_TRUNC, 0600, NULL);
tdb->log = tap_log_fn;
ok1(tdb);
if (tdb) {
/* Delete should fail. */
ok1(tdb_delete(tdb, key) == -1);
ok1(tdb_error(tdb) == TDB_ERR_NOEXIST);
ok1(tdb_check(tdb, NULL, NULL) == 0);
/* Insert should succeed. */
ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
ok1(tdb_check(tdb, NULL, NULL) == 0);
/* Delete should now work. */
ok1(tdb_delete(tdb, key) == 0);
ok1(tdb_check(tdb, NULL, NULL) == 0);
tdb_close(tdb);
}
}
ok1(tap_log_messages == 0);
return exit_status();
}
#include <ccan/tdb2/tdb.c>
#include <ccan/tdb2/free.c>
#include <ccan/tdb2/lock.c>
#include <ccan/tdb2/io.c>
#include <ccan/tdb2/check.c>
#include <ccan/tap/tap.h>
#include "logging.h"
int main(int argc, char *argv[])
{
unsigned int i;
struct tdb_context *tdb;
int flags[] = { TDB_INTERNAL, TDB_DEFAULT,
TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT };
struct tdb_data key = { (unsigned char *)"key", 3 };
struct tdb_data data = { (unsigned char *)"data", 4 };
plan_tests(sizeof(flags) / sizeof(flags[0]) * 8 + 1);
for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
tdb = tdb_open("/tmp/run-new_database.tdb", flags[i],
O_RDWR|O_CREAT|O_TRUNC, 0600, NULL);
tdb->log = tap_log_fn;
ok1(tdb);
if (tdb) {
struct tdb_data d;
/* fetch should fail. */
d = tdb_fetch(tdb, key);
ok1(d.dptr == NULL);
ok1(tdb_error(tdb) == TDB_ERR_NOEXIST);
ok1(tdb_check(tdb, NULL, NULL) == 0);
/* Insert should succeed. */
ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
ok1(tdb_check(tdb, NULL, NULL) == 0);
/* Fetch should now work. */
d = tdb_fetch(tdb, key);
ok1(data_equal(d, data));
ok1(tdb_check(tdb, NULL, NULL) == 0);
tdb_close(tdb);
}
}
ok1(tap_log_messages == 0);
return exit_status();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment