GWAN键值持久化多存储

3

我想以持久化模式记录键值,但当我想要使用两个或更多不同的存储时,它无法正常工作。

这是我的脚本:

    ...
    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");
       }
    ...

这个错误在kv_init()函数的第15行。

我的建议是,例如使用data[0]->kv来读取和记录“users”存储中的值,并使用data[1]->kv来读取和记录other存储中的值...


你能澄清一下你遇到了哪个错误吗? - Nagi
2个回答

1

约翰,

你的问题源于难以操作指向指针的指针。我们可以修复这段代码,但由于其复杂性,它可能会在以后的脚本中出现错误。

从长远来看,应该使用更简单的解决方案以避免出现错误。

附加到US_SERVER_DATA的结构可以变得更简单:

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

这是正确的方式: 使用calloc(sizeof(my_struct));来分配内存,并将此结构附加到US_SERVER_DATA指针上。
然后,在G-WAN处理程序的init()调用中完成所有这些操作(或在gwan/main.c维护脚本中,甚至在最近添加的gwan/init.c脚本中),您将拥有独占访问权(一个单线程正在进行初始化),并且可以根据需要攻击G-WAN KV存储(以及其他对象)。
如果稍后G-WAN servlets或handlers修改这些结构指针,则必须对指针本身使用锁、自旋锁等或原子变量。
希望这能帮助到您。

1

我只是将包含我需要的所有kv存储的kv存储附加到持久性指针上。G-WAN kv很快,而且记录数很少,不应该影响性能。

  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 是一个自定义宏。

谢谢你的帮助,你的解决方案有效。但是你是否意味着它在性能方面比Gil提出的解决方案不够优化?(顺便说一下,我没能让那个解决方案起作用)因为我可能需要同时处理大量数据。问候。 - John S
在我的解决方案中,每当我想要访问我的blog_db kv时,我都必须执行查找(*blog_db = (kv_t *) kv_get(kv_db[0], "blog_db", 7);)。而在Gil的解决方案中,他直接访问它,因为它只是结构体中的一个字段。所以,我的解决方案显然不够优化。 - Nagi
顺便提一下,在这种情况下,您的数据集大小(每个kv存储的大小)是无关紧要的,因为我的解决方案所关注的是kv存储的数量。无论如何,如果您有太多的kv存储,您可能需要重新考虑您的设计。可以考虑使用键前缀合并kv存储(例如:用户kv使用“user_db:”前缀,“帖子kv”使用“blog_db:”前缀等)。 - Nagi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接