Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Постоянное множественное хранилище типа "ключ-значение" GWAN

Автор вопроса: John SОтветов: 2

Я хочу записать ключ-значение в постоянном режиме, но когда я хочу использовать 2 или более разных хранилища, это не работает.

Вот мой сценарий:

    ...
    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 = "[email protected]";
          item.flags = 0;
          kv_add(data[0]->kv, &item);

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

Эта ошибка находится в строке 15 с функцией kv_init ().

Я хотел бы, например, использовать data [0] -> kv для чтения и записи значения в магазине "users" и использовать data [1] -> kv для чтения и записи значения в другом хранилище ...

  • Можете уточнить, какую ошибку вы получаете? Nagi 27.04.2014

ckey-valuekey-value-storeg-wan

Ответы

Ответ 1 · рейтинг 1 · Nagi

Я просто присоединяю хранилище 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 - настраиваемый макрос)

Ответ 2 · рейтинг 1 · Gil

Джон,

Ваша проблема связана с трудностью играть с указателями на указатели. Мы могли бы исправить этот код, но он, вероятно, сломается позже в ваших скриптах из-за своей сложности.

В долгосрочной перспективе следует использовать более простое решение, чтобы избежать ошибок.

Структуру, прикрепленную к 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.

Затем, если вы делаете все это в вызове init() обработчика G-WAN (или в gwan/main.c сценарии обслуживания, или даже в недавно добавленном gwan/init.c сценарии), у вас будет монопольный доступ (инициализация выполняется одним потоком), и вы получите иметь возможность атаковать магазины G-WAN KV (и другие объекты) по мере необходимости.

Если позже сервлеты или обработчики G-WAN изменяют эти указатели на структуру, вам придется использовать блокировку, спин-блокировку и т. Д. Или атомарные переменные для самих указателей.

Надеюсь это поможет.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы