Commit 39f01834 authored by Rusty Russell's avatar Rusty Russell

tdb2: initial commit (doesn't work, still writing tests)

parent ce58fbd1
#include <string.h>
#include <stdio.h>
/**
* tdb2 - [[WORK IN PROGRESS!]] The trivial (64bit transactional) database
*
* The tdb2 module provides an efficient keyword data mapping (usually
* within a file). It supports transactions, so the contents of the
* database is reliable even across crashes.
*
* Example:
* #include <ccan/tdb2/tdb2.h>
* #include <ccan/str/str.h>
* #include <err.h>
* #include <stdio.h>
*
* static void usage(void)
* {
* errx(1, "Usage: %s fetch <dbfile> <key>\n"
* "OR %s store <dbfile> <key> <data>");
* }
*
* int main(int argc, char *argv[])
* {
* struct tdb_context *tdb;
* TDB_DATA key, value;
*
* if (argc < 4)
* usage();
*
* tdb = tdb_open(argv[2], 1024, TDB_DEFAULT, O_CREAT|O_RDWR,
* 0600);
* if (!tdb)
* err(1, "Opening %s", argv[2]);
*
* key.dptr = (void *)argv[3];
* key.dsize = strlen(argv[3]);
*
* if (streq(argv[1], "fetch")) {
* if (argc != 4)
* usage();
* value = tdb_fetch(tdb, key);
* if (!value.dptr)
* errx(1, "fetch %s: %s",
* argv[3], tdb_errorstr(tdb));
* printf("%.*s\n", value.dsize, (char *)value.dptr);
* free(value.dptr);
* } else if (streq(argv[1], "store")) {
* if (argc != 5)
* usage();
* value.dptr = (void *)argv[4];
* value.dsize = strlen(argv[4]);
* if (tdb_store(tdb, key, value, 0) != 0)
* errx(1, "store %s: %s",
* argv[3], tdb_errorstr(tdb));
* } else
* usage();
*
* return 0;
* }
*
* Maintainer: Rusty Russell <rusty@rustcorp.com.au>
*
* Author: Rusty Russell
*
* Licence: LGPLv3 (or later)
*/
int main(int argc, char *argv[])
{
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0) {
printf("ccan/hash\n");
printf("ccan/likely\n");
printf("ccan/asearch\n");
return 0;
}
return 1;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#include <ccan/tdb2/tdb.c>
#include <ccan/tdb2/free.c>
#include <ccan/tdb2/lock.c>
#include <ccan/tdb2/io.c>
#include <ccan/tap/tap.h>
int main(int argc, char *argv[])
{
unsigned int i;
struct tdb_used_record rec;
struct tdb_context tdb = { .log = null_log_fn, .log_priv = NULL };
plan_tests(64 + 32 + 48*6);
/* We should be able to encode any data value. */
for (i = 0; i < 64; i++)
ok1(set_header(&tdb, &rec, 0, 1ULL << i, 1ULL << i, 0) == 0);
/* And any key and data with < 64 bits between them. */
for (i = 0; i < 32; i++) {
tdb_len_t dlen = 1ULL >> (63 - i), klen = 1ULL << i;
ok1(set_header(&tdb, &rec, klen, dlen, klen + dlen, 0) == 0);
}
/* We should neatly encode all values. */
for (i = 0; i < 48; i++) {
uint64_t h = 1ULL << (i < 11 ? 63 - i : 63 - 10);
uint64_t klen = 1ULL << (i < 16 ? i : 15);
uint64_t dlen = 1ULL << i;
uint64_t xlen = 1ULL << (i < 32 ? i : 31);
ok1(set_header(&tdb, &rec, klen, dlen, klen + dlen + xlen, h)
== 0);
ok1(rec_key_length(&rec) == klen);
ok1(rec_data_length(&rec) == dlen);
ok1(rec_extra_padding(&rec) == xlen);
ok1(rec_hash(&rec) == h);
ok1(rec_magic(&rec) == TDB_MAGIC);
}
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/tap/tap.h>
static unsigned int dumb_fls(uint64_t num)
{
int i;
for (i = 63; i >= 0; i--) {
if (num & (1ULL << i))
break;
}
return i + 1;
}
int main(int argc, char *argv[])
{
unsigned int i, j;
plan_tests(64 * 64 + 2);
ok1(fls64(0) == 0);
ok1(dumb_fls(0) == 0);
for (i = 0; i < 64; i++) {
for (j = 0; j < 64; j++) {
uint64_t val = (1ULL << i) | (1ULL << j);
ok(fls64(val) == dumb_fls(val),
"%llu -> %u should be %u", (long long)val,
fls64(val), dumb_fls(val));
}
}
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