0

I am using Tokyo Cabinet for creating persistent storage database.

I am using void *tcbdbget(TCBDB *bdb, const void *kbuf, int ksiz, int *sp); It gives segfault in tcbdb.h file on *sp = rec->vsiz;.

Is there a bug in Tokyo Cabinet or am I missing something?

Because inserting the record works fine that means all the void pointers are perfectly getting inserted, just lookup has problem. The insert function is this bool tcbdbput(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);.

deltheil
  • 15,496
  • 2
  • 44
  • 64
dev0z
  • 2,275
  • 1
  • 15
  • 16

1 Answers1

0

It gives segfault in tcbdb.h file on *sp = rec->vsiz;

Tokyo Cabinet (a.k.a TC) expects you pass a valid, non NULL pointer to store the size of the value when you call tcbdbget, e.g:

int size;
char *buf = tcbdbget(bdb, kbuf, ksiz, &size);

Passing a NULL pointer could explain the segfault at this precise code section. Please find below a sample code that you can build with BUG = 1 to generate a segfault - with BUG = 0 everything works like a charm :)

#include <stdio.h>
#include <string.h>
#include <tcbdb.h>

#define BUG 0

int
main(void)
{
  TCBDB *bdb = tcbdbnew();

  if (!tcbdbopen(bdb, "store.db", BDBOWRITER | BDBOCREAT)) {
    fprintf(stderr, "error: %s\n", tcbdberrmsg(tcbdbecode(bdb)));
  }

  char *key = "foo";
  char *val = "bar";

  if (!tcbdbput(bdb, key, strlen(key), val, strlen(val))) {
    fprintf(stderr, "error: %s\n", tcbdberrmsg(tcbdbecode(bdb)));
  }

  int size;
#if BUG
  char *buf = tcbdbget(bdb, key, strlen(key), NULL);
#else
  char *buf = tcbdbget(bdb, key, strlen(key), &size);
#endif

  if (!buf && tcbdbecode(bdb) != TCENOREC) {
    fprintf(stderr, "error: %s\n", tcbdberrmsg(tcbdbecode(bdb)));
  }

  if (buf)
    printf("%s -> %s\n", key, buf);

  free(buf);
  tcbdbdel(bdb);
  return 0;
}

Note: since TC always append a trailing terminator \0, and since I know I've stored a character string I can safely printf buf with %s.

deltheil
  • 15,496
  • 2
  • 44
  • 64
  • Works like a charm :) thanks a lot... I am going to use this to create a lookup of access of media files from lighttpd server. I hope I have made a right choice.... – dev0z Oct 31 '13 at 16:42
  • Would need to know more about your use case to say if it is a good choice or not :) That being said Tokyo Cabinet is a powerful and rock-solid piece of software (and very pleasant to work with!). – deltheil Oct 31 '13 at 17:59
  • So I am using TC for creating a lookup of all media files on my server. Name as key and their duration as value. Streaming is done by HLS protocol. Files will be served from lighttpd. I have written a plugin for lightty which will send filename to a daemon which will look into TC for duration and accumulate duration. This application basically calculates how many time a particular media was watched by user. My use case is 500 users streaming together. About a million records and 5 hits to TC per second for lookup. – dev0z Oct 31 '13 at 18:53
  • I would say it makes sense. Keep in mind you may have to tune TC (there are many params, including bucket number and internal nodes/leaves caching, that are important). Question: why don't you use [Tokyo Tyrant](http://fallabs.com/tokyotyrant/) - the TC network interface, with a custom [Lua extension](http://fallabs.com/tokyotyrant/spex.html#luaext) to implement your custom logic instead of your daemon? – deltheil Nov 01 '13 at 08:24
  • Yes, I have tuned TC according to my use case. Also compressed the .tcb file as the space is limited. In my use case only one process will access the DB. Also there should be no communication over TCP/IP as I dont want any network overhead. This is a standalone system. This module is just one part of a larger system. I am using UNIX domain socket for communication between processes. – dev0z Nov 01 '13 at 17:46