atomic_hash icon indicating copy to clipboard operation
atomic_hash copied to clipboard

请问get一个存在的key操作,是有一定概率get不到么?

Open taotaoo opened this issue 6 years ago • 5 comments

taotaoo avatar Apr 11 '18 12:04 taotaoo

没有竞争当然不会get不到。有竞争的话,对方抢先删除了,或者超时了,就会Get不到 -- 这取决于你是否把这一瞬间定义为代码逻辑的时间先后。

divfor avatar Apr 12 '18 04:04 divfor

是这样的,我测试了一下查询一定存在的key,查询的这个key肯定不会被删除或者ttl,但是还是存在很大的概率查询不到。

taotaoo avatar May 31 '18 07:05 taotaoo

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#include "atomic_hash.h"

#define COMMON_SUCCESS 1
#define COMMON_FAIL 0

#define CHANNEL_TOKEN_LEN 8
#define MAX_NODE 10000000
#define TTL 660000

static hash_t *dict;

static int cb_add_token(void *data, void *arg)
{
    if (arg)
        *((void **)arg) = data;
    return PLEASE_DO_NOT_CHANGE_TTL;
}

static int cb_dup_token(void *data, void *arg)
{
    if (arg)
        *((void **)arg) = data;
    return PLEASE_DO_NOT_CHANGE_TTL;
}

static int cb_get_token(void *data, void *arg)
{
    if (arg)
        *((void **)arg) = data;
    return PLEASE_SET_TTL_TO_DEFAULT;
}

static int cb_del_token(void *data, void *arg)
{
    free(data);
    data = NULL;
    return PLEASE_REMOVE_HASH_NODE;
}

static int cb_ttl_token(void *data, void *arg)
{
    free(data);
    data = NULL;
    return PLEASE_REMOVE_HASH_NODE;
}

int init_dict()
{
    dict = atomic_hash_create(10000000, TTL);
    dict->on_add = cb_add_token;
    dict->on_dup = cb_dup_token;
    dict->on_get = cb_get_token;
    dict->on_del = cb_del_token;
    dict->on_ttl = cb_ttl_token;

    return COMMON_SUCCESS;
}

int add_data()
{
    int i = 0;
    for (; i < MAX_NODE; i++)
    {
        uint64_t kkk = (uint64_t)i;
        uint64_t *data = (uint64_t *)malloc(sizeof(uint64_t));
        memcpy(data, &kkk, sizeof(uint64_t));
        int ret = atomic_hash_add(dict, &kkk, sizeof(uint64_t), data, TTL, NULL, NULL);
        if (ret != 0)
        {
            return ret;
        }
    }
    return 0;
}

void loop_get(void *arg)
{
    int index = (int)arg;
    int total = MAX_NODE;
    int failed = 0;
    int i;
    for (i = 0; i < total; i++)
    {
        int key = i;
        uint64_t kkk = (uint64_t)key;
        uint64_t *retv = NULL;
        int ret = atomic_hash_get(dict, &kkk, sizeof(uint64_t), NULL, &retv);
        if (ret != 0 || retv == NULL)
        {
            failed++;
        }
    }
    printf("atomic hash get total %d, failed %d.\n", total, failed);
}

inline unsigned long now_ms()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
}

void main()
{
    init_dict();

    unsigned long start = now_ms();
    int ret = add_data();
    if (ret != 0)
    {
        return;
    }
    unsigned long end = now_ms();
    printf("add took: %lums.\n", end - start);
    start = end;

#define THREAD_NUM 10
    pthread_t ids[THREAD_NUM];
    int i = 0;
    for (; i < THREAD_NUM; i++)
    {
        pthread_create(&ids[i], NULL, (void *)loop_get, (void *)i);
    }
    for (i = 0; i < THREAD_NUM; i++)
    {
        pthread_join(ids[i], NULL);
    }
    end = now_ms();
    printf("get took: %lums.\n", end - start);
    atomic_hash_stats(dict, 0);
    printf("threads finish.\n");
}

taotaoo avatar May 31 '18 07:05 taotaoo

上边是我测试的代码

taotaoo avatar May 31 '18 07:05 taotaoo

我没看懂代码逻辑,只是简单debug了一下,发现每次nohit都是在同一块逻辑出跳出的,于是我加了一个重试,就不会再有nohit的情况了。麻烦您看一下加的是否有问题。

  •        if (((hv).x != (v).x) && (--__l == 0)) return 0; /* already released or reused */\
    

taotaoo avatar May 31 '18 07:05 taotaoo