Question

I want to record a key-value in persistent mode but when I want to use 2 or more different stores it doesn't work.

Here's my script:

    ...
    typedef struct{
       kv_t  *kv;
       char  *name;
    } kv_data;

    int main(int argc, char *argv[])
    {
       kv_data **data = (kv_data**)get_env(argv, US_SERVER_DATA);
       if(!data[0]){
          data[0] = (kv_data*)calloc(1, sizeof(kv_data));
          if(!data[0]){
             return 500;
          }
          kv_t users;
          kv_init(&users, "users", 10, 0, 0, 0);
          data[0]->kv = &users;

          kv_item item;
          item.key = "pierre";
          item.klen = sizeof("pierre") - 1;
          item.val = "pierre@example.com";
          item.flags = 0;
          kv_add(data[0]->kv, &item);

          data[0]->name = strdup("users");
       }
    ...

This error is in line 15 with the kv_init() function.

My wish would be for example to use data[0]->kv to read and record value in "users" store and to use data[1]->kv to read and record value in other store...

Was it helpful?

Solution

I just attach a kv store that contain all the kv stores I need to the persistence pointer. G-WAN kv is fast, plus the number of records is small, it should not hurt performance.

  xbuf_t *reply = get_reply(argv);
  kv_t **kv_db = (kv_t **)get_env(argv, US_VHOST_DATA);

  if (!kv_db[0])
  {
     kv_db[0] = (kv_t*) malloc(sizeof(kv_t));

     if (!kv_db[0])
     {
        puts("Could not allocate memory for the v-host kv store");
        return 500;
     }

     kv_init(kv_db[0], "kv_db", 10, 0, 0, 0);
  }

  kv_t *blog_db = (kv_t *) kv_get(kv_db[0], "blog_db", 7);

  if (blog_db)
  {
     xbuf_cat(reply, "Blog already installed. GTFO.");
     return 200;
  }

  blog_db = (kv_t *) malloc(sizeof(kv_t));
  kv_init(blog_db, "blog_db", 0, 0, 0, 0);

  if (!blog_db)
  {
     puts("Could not allocate memory for the blog kv store");
     return 500;
  }

  _KV_ADD(kv_db[0], item, blog_db->name, blog_db, 0);

(_KV_ADD is a custom macro)

OTHER TIPS

John,

Your problem comes from the difficulty to play with pointers on pointers. We could fix this code but it will probably break later in your scripts because of its complexity.

For the long term, a simpler solution should be used to avoid bugs.

The structure attached to US_SERVER_DATA can be made simpler:

typedef struct
{
   char *name;
   kv_t *kv_1;
   kv_t *kv_2;
   void *callback;
   u32   current_time;
}

This is the way to go: allocate memory with calloc(sizeof(my_struct));, and attach this structure to your US_SERVER_DATA pointer.

Then, providing you do all this in a G-WAN handler init() call (or in the gwan/main.c maintenance script, or even in the recently added gwan/init.c script), you will have exclusive access (one single thread is doing the initialization) and you will be able to attack G-WAN KV stores (and other objects) as needed.

If, later, G-WAN servlets or handlers are modifying these structure pointers then you will have to use a lock, spinlock, etc. or atomic variables for the pointers themselves.

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top