Esempio n. 1
0
/* given a peer key/len/hashv, reverse engineer its hash function */
static int infer_hash_function(char *key, size_t keylen, uint32_t hashv)
{
    uint32_t ohashv;
    /* BER SAX FNV OAT JEN SFH */
    HASH_JEN(key,keylen,ohashv);
    if (ohashv == hashv) {
        return JEN;
    }
    HASH_BER(key,keylen,ohashv);
    if (ohashv == hashv) {
        return BER;
    }
    HASH_SFH(key,keylen,ohashv);
    if (ohashv == hashv) {
        return SFH;
    }
    HASH_SAX(key,keylen,ohashv);
    if (ohashv == hashv) {
        return SAX;
    }
    HASH_FNV(key,keylen,ohashv);
    if (ohashv == hashv) {
        return FNV;
    }
    HASH_OAT(key,keylen,ohashv);
    if (ohashv == hashv) {
        return OAT;
    }
    HASH_MUR(key,keylen,ohashv);
    if (ohashv == hashv) {
        return MUR;
    }
    return 0;
}
Esempio n. 2
0
File: nif.c Progetto: arekinath/e2qc
static ERL_NIF_TERM
get(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
	ERL_NIF_TERM atom;
	ErlNifBinary kbin;
	struct cache *c;
	struct cache_node *n;
	struct cache_incr_node *in;
	struct timespec now;
	int incrqs, hashv, bkt;
	ERL_NIF_TERM ret;
	ErlNifTid tid;

	if (!enif_is_atom(env, argv[0]))
		return enif_make_badarg(env);
	atom = argv[0];

	if (!enif_inspect_binary(env, argv[1], &kbin))
		return enif_make_badarg(env);

	if ((c = get_cache(atom))) {
		enif_rwlock_rlock(c->lookup_lock);
		HASH_FIND(hh, c->lookup, kbin.data, kbin.size, n);
		if (!n) {
			enif_rwlock_runlock(c->lookup_lock);
			__sync_add_and_fetch(&c->miss, 1);
			enif_consume_timeslice(env, 10);
			return enif_make_atom(env, "notfound");
		}

		if (n->expiry.tv_sec != 0) {
			clock_now(&now);
			if (n->expiry.tv_sec < now.tv_sec) {
				enif_rwlock_runlock(c->lookup_lock);
				__sync_add_and_fetch(&c->miss, 1);
				enif_consume_timeslice(env, 10);
				return enif_make_atom(env, "notfound");
			}
		}

		in = enif_alloc(sizeof(*in));
		memset(in, 0, sizeof(*in));
		in->node = n;
		__sync_add_and_fetch(&c->hit, 1);

		tid = enif_thread_self();
		HASH_SFH(&tid, sizeof(ErlNifTid), N_INCR_BKT, hashv, bkt);
		enif_mutex_lock(c->incr_lock[bkt]);
		TAILQ_INSERT_TAIL(&(c->incr_head[bkt]), in, entry);
		enif_mutex_unlock(c->incr_lock[bkt]);
		incrqs = __sync_add_and_fetch(&(c->incr_count), 1);

		ret = enif_make_resource_binary(env, n->val, n->val, n->vsize);
		enif_rwlock_runlock(c->lookup_lock);

		if (incrqs > 1024)
			enif_cond_broadcast(c->check_cond);

		enif_consume_timeslice(env, 20);

		return ret;

	}

	return enif_make_atom(env, "notfound");
}