Beispiel #1
0
/* Add the specified sample to the specified time series "event".
 * This function is usually called via latencyAddSampleIfNeeded(), that
 * is a macro that only adds the sample if the latency is higher than
 * server.latency_monitor_threshold. */
void latencyAddSample(char *event, mstime_t latency) {
    struct latencyTimeSeries *ts = dictFetchValue(server.latency_events,event);
    time_t now = time(NULL);
    int prev;

    /* Create the time series if it does not exist. */
    if (ts == NULL) {
        ts = zmalloc(sizeof(*ts));
        ts->idx = 0;
        ts->max = 0;
        memset(ts->samples,0,sizeof(ts->samples));
        dictAdd(server.latency_events,zstrdup(event),ts);
    }

    /* If the previous sample is in the same second, we update our old sample
     * if this latency is > of the old one, or just return. */
    prev = (ts->idx + LATENCY_TS_LEN - 1) % LATENCY_TS_LEN;
    if (ts->samples[prev].time == now) {
        if (latency > ts->samples[prev].latency)
            ts->samples[prev].latency = (int32_t)latency;
        return;
    }

    ts->samples[ts->idx].time = (int32_t)time(NULL);
    ts->samples[ts->idx].latency = (int32_t)latency;
    if (latency > ts->max) ts->max = (int32_t)latency;

    ts->idx++;
    if (ts->idx == LATENCY_TS_LEN) ts->idx = 0;
}
Beispiel #2
0
/* Unblock a client that's waiting in a blocking operation such as BLPOP.
 * You should never call this function directly, but unblockClient() instead. */
void unblockClientWaitingData(client *c) {
    dictEntry *de;
    dictIterator *di;
    list *l;

    serverAssertWithInfo(c,NULL,dictSize(c->bpop.keys) != 0);
    di = dictGetIterator(c->bpop.keys);
    /* The client may wait for multiple keys, so unblock it for every key. */
    while((de = dictNext(di)) != NULL) {
        robj *key = dictGetKey(de);

        /* Remove this client from the list of clients waiting for this key. */
        l = dictFetchValue(c->db->blocking_keys,key);
        serverAssertWithInfo(c,key,l != NULL);
        listDelNode(l,listSearchKey(l,c));
        /* If the list is empty we need to remove it to avoid wasting memory */
        if (listLength(l) == 0)
            dictDelete(c->db->blocking_keys,key);
    }
    dictReleaseIterator(di);

    /* Cleanup the client structure */
    dictEmpty(c->bpop.keys,NULL);
    if (c->bpop.target) {
        decrRefCount(c->bpop.target);
        c->bpop.target = NULL;
    }
    if (c->bpop.xread_group) {
        decrRefCount(c->bpop.xread_group);
        decrRefCount(c->bpop.xread_consumer);
        c->bpop.xread_group = NULL;
        c->bpop.xread_consumer = NULL;
    }
}
Beispiel #3
0
/* 分析某个时间Event的延时结果,结果信息存入latencyStats结构体中 */
void analyzeLatencyForEvent(char *event, struct latencyStats *ls) {
    struct latencyTimeSeries *ts = dictFetchValue(server.latency_events,event);
    int j;
    uint64_t sum;
	
	//初始化延时统计结果结构体的变量
    ls->all_time_high = ts ? ts->max : 0;
    ls->avg = 0;
    ls->min = 0;
    ls->max = 0;
    ls->mad = 0;
    ls->samples = 0;
    ls->period = 0;
    if (!ts) return;

    /* First pass, populate everything but the MAD. */
    sum = 0;
    for (j = 0; j < LATENCY_TS_LEN; j++) {
        if (ts->samples[j].time == 0) continue;
        ls->samples++;
        if (ls->samples == 1) {
            ls->min = ls->max = ts->samples[j].latency;
        } else {
        	//找出延时最大和最小的延时时间
            if (ls->min > ts->samples[j].latency)
                ls->min = ts->samples[j].latency;
            if (ls->max < ts->samples[j].latency)
                ls->max = ts->samples[j].latency;
        }
        sum += ts->samples[j].latency;

        /* Track the oldest event time in ls->period. */
        if (ls->period == 0 || ts->samples[j].time < ls->period)
        	//最早的延时记录点的创建时间
            ls->period = ts->samples[j].time;
    }

    /* So far avg is actually the sum of the latencies, and period is
     * the oldest event time. We need to make the first an average and
     * the second a range of seconds. */
    if (ls->samples) {
        ls->avg = sum / ls->samples;
        ls->period = time(NULL) - ls->period;
        if (ls->period == 0) ls->period = 1;
    }

    /* Second pass, compute MAD. */
    //计算平均相对误差,与平均延时相比
    sum = 0;
    for (j = 0; j < LATENCY_TS_LEN; j++) {
        int64_t delta;

        if (ts->samples[j].time == 0) continue;
        delta = (int64_t)ls->avg - ts->samples[j].latency;
        if (delta < 0) delta = -delta;
        sum += delta;
    }
    if (ls->samples) ls->mad = sum / ls->samples;
}
Beispiel #4
0
void *cacheFetch(ccache *c, sds key) {
    cacheEntry *ce = (cacheEntry *)dictFetchValue(c->data,key);
    if(ce) {
        listMoveNodeToTail(c->accesslist,ce->ln);
        return ce->val;
    }
    return NULL;
}
Beispiel #5
0
cacheEntry *cacheFind(ccache *c, sds key) {
    cacheEntry *ce = dictFetchValue(c->data,key);
    if(ce == NULL) {
        ce = cacheAdd(c,sdsdup(key),NULL);
        cacheSendMessage(c,ce,CACHE_REQUEST_NEW);
    }
    return ce;
}
Beispiel #6
0
struct redisCommand *lookupCommandByCString(char *s) {
    struct redisCommand *cmd;
    sds name = sdsnew(s);

    cmd = dictFetchValue(server.commands, name);
    sdsfree(name);
    return cmd;
}
Beispiel #7
0
const set *dbGet(const sds setName)
{
    const set *result = NULL;
    lockRead(sets);
    result = (const set *) dictFetchValue(sets, setName);
    unlockRead(sets);
    return result;
}
Beispiel #8
0
char* findLookupVal(char *key, unsigned char type)
{
	lookup_log(LOG_DEBUG, "table find %s,%d\n", key, type);
	lookupKey find;
	find.name = key;
	find.type = type;
	char *val = (char *)dictFetchValue(dt, &find);
	return val;
}
Beispiel #9
0
/* LATENCY command implementations.
 *
 * LATENCY SAMPLES: return time-latency samples for the specified event.
 * LATENCY LATEST: return the latest latency for all the events classes.
 * LATENCY DOCTOR: returns an human readable analysis of instance latency.
 * LATENCY GRAPH: provide an ASCII graph of the latency of the specified event.
 */
void latencyCommand(client *c) {
    struct latencyTimeSeries *ts;

    if (!strcasecmp(c->argv[1]->ptr,"history") && c->argc == 3) {
        /* LATENCY HISTORY <event> */
        ts = dictFetchValue(server.latency_events,c->argv[2]->ptr);
        if (ts == NULL) {
            addReplyMultiBulkLen(c,0);
        } else {
            latencyCommandReplyWithSamples(c,ts);
        }
    } else if (!strcasecmp(c->argv[1]->ptr,"graph") && c->argc == 3) {
        /* LATENCY GRAPH <event> */
        sds graph;
        dictEntry *de;
        char *event;

        de = dictFind(server.latency_events,c->argv[2]->ptr);
        if (de == NULL) goto nodataerr;
        ts = dictGetVal(de);
        event = dictGetKey(de);

        graph = latencyCommandGenSparkeline(event,ts);
        addReplyBulkCString(c,graph);
        sdsfree(graph);
    } else if (!strcasecmp(c->argv[1]->ptr,"latest") && c->argc == 2) {
        /* LATENCY LATEST */
        latencyCommandReplyWithLatestEvents(c);
    } else if (!strcasecmp(c->argv[1]->ptr,"doctor") && c->argc == 2) {
        /* LATENCY DOCTOR */
        sds report = createLatencyReport();

        addReplyBulkCBuffer(c,report,sdslen(report));
        sdsfree(report);
    } else if (!strcasecmp(c->argv[1]->ptr,"reset") && c->argc >= 2) {
        /* LATENCY RESET */
        if (c->argc == 2) {
            addReplyLongLong(c,latencyResetEvent(NULL));
        } else {
            int j, resets = 0;

            for (j = 2; j < c->argc; j++)
                resets += latencyResetEvent(c->argv[j]->ptr);
            addReplyLongLong(c,resets);
        }
    } else {
        addReply(c,shared.syntaxerr);
    }
    return;

nodataerr:
    /* Common error when the user asks for an event we have no latency
     * information about. */
    addReplyErrorFormat(c,
        "No samples available for event '%s'", (char*) c->argv[2]->ptr);
}
/* PUBSUB command for Pub/Sub introspection. */
void pubsubCommand(redisClient *c) {

	// 处理PUBSUB CHANNELS [pattern]命令
    if (!strcasecmp(c->argv[1]->ptr,"channels") &&
        (c->argc == 2 || c->argc ==3))
    {
        /* PUBSUB CHANNELS [<pattern>] */
        // 获取pattern参数,如果没有则为NULL
        sds pat = (c->argc == 2) ? NULL : c->argv[2]->ptr;
        dictIterator *di = dictGetIterator(server.pubsub_channels);
        dictEntry *de;
        long mblen = 0;
        void *replylen;

        replylen = addDeferredMultiBulkLength(c);
        // 遍历server.pubsub_channels字典
        while((de = dictNext(di)) != NULL) {
        	// 取出当前频道channel
            robj *cobj = dictGetKey(de);
            sds channel = cobj->ptr;

            // 如果没有给定pattern参数,则打印出所有频道
            // 如果给定pattern参数,则打印出与pattern参数相匹配的频道
            if (!pat || stringmatchlen(pat, sdslen(pat),
                                       channel, sdslen(channel),0))
            {
                addReplyBulk(c,cobj);
                mblen++;
            }
        }
        dictReleaseIterator(di);
        setDeferredMultiBulkLength(c,replylen,mblen);
    } 
    // 处理PUBSUB NUMSUB [Channel_1 ... Channel_N]命令
    else if (!strcasecmp(c->argv[1]->ptr,"numsub") && c->argc >= 2) {
        /* PUBSUB NUMSUB [Channel_1 ... Channel_N] */
        int j;

        addReplyMultiBulkLen(c,(c->argc-2)*2);
        for (j = 2; j < c->argc; j++) {
            list *l = dictFetchValue(server.pubsub_channels,c->argv[j]);

            addReplyBulk(c,c->argv[j]);
            addReplyLongLong(c,l ? listLength(l) : 0);
        }
    } 
    // 处理PUBSUB NUMPA命令
    else if (!strcasecmp(c->argv[1]->ptr,"numpat") && c->argc == 2) {
        /* PUBSUB NUMPAT */
        addReplyLongLong(c,listLength(server.pubsub_patterns));
    } else {
        addReplyErrorFormat(c,
            "Unknown PUBSUB subcommand or wrong number of arguments for '%s'",
            (char*)c->argv[1]->ptr);
    }
}
Beispiel #11
0
int process_trigglecmd(sds name)
{

    //int i=0;
    struct triggleCmd *p=(struct triggleCmd *)dictFetchValue(server.bridge_db.triggle_cmds, name);



    return (p==NULL)?-1:p->event; 
}
Beispiel #12
0
Datei: engine.c Projekt: fizx/sit
void
engine_set_int(Engine *engine, long doc_id, pstring *field, int value) {
  //FIXME?!
  RingBuffer *rb = dictFetchValue(engine->ints, field);
  assert(field);
  if(rb == NULL) {
    rb = ring_buffer_new(engine->ints_capacity);
    dictAdd(engine->ints, field, rb);
  }
  ring_buffer_put(rb, doc_id * sizeof(int), &value, sizeof(int));
}
Beispiel #13
0
void cacheDelete(ccache* c, sds key) {
    cacheEntry *ce = (cacheEntry *)dictFetchValue(c->data,key);
    /* Master reply by setting val to an object.
     * We do not delete cache entry until the master reply
     */
    if(ce&&ce->val)
    {
        cacheSendMessage(c,sdsdup(key),CACHE_REQUEST_OLD);
        listDelNode(c->accesslist,ce->ln);
        dictDelete(c->data,key);
    }
}
Beispiel #14
0
Datei: engine.c Projekt: fizx/sit
int *
engine_get_int(Engine *engine, long doc_id, pstring *field) {
  RingBuffer *rb = dictFetchValue(engine->ints, field);
  long off = doc_id * sizeof(int);
  if(rb == NULL ||
    (off + sizeof(int) > rb->written) ||
    (off < rb->written - rb->capacity)
    ) {
    return NULL;
  } else {
    return (int *) &rb->buffer[off % rb->capacity];
  }
}
Beispiel #15
0
/* Handle a response to a given request. if this is a quorum setting, choose the
 * right response. Then make sure all the requests are satisfied in a fragmented
 * request scenario and then use the post coalesce logic to cook up a combined
 * response
 */
static rstatus_t
client_handle_response(struct conn *conn, msgid_t reqid, struct msg *rsp)
{
    ASSERT_LOG(!rsp->peer, "response %lu:%lu has peer set",
               rsp->id, rsp->parent_id);

    // now the handler owns the response.
    ASSERT(conn->type == CONN_CLIENT);
    // Fetch the original request
    struct msg *req = dictFetchValue(conn->outstanding_msgs_dict, &reqid);
    if (!req) {
        log_notice("looks like we already cleanedup the request for %d", reqid);
        rsp_put(rsp);
        return DN_OK;
    }
    // we have to submit the response irrespective of the unref status.
    rstatus_t status = msg_handle_response(req, rsp);
    if (conn->waiting_to_unref) {
        // dont care about the status.
        if (req->awaiting_rsps)
            return DN_OK;
        // all responses received
        dictDelete(conn->outstanding_msgs_dict, &reqid);
        log_info("Putting req %d", req->id);
        req_put(req);
        client_unref_internal_try_put(conn);
        return DN_OK;
    }
    if (status == DN_NOOPS) {
        // by now the response is dropped
        if (!req->awaiting_rsps) {
            // if we have sent the response for this request or the connection
            // is closed and we are just waiting to drain off the messages.
            if (req->rsp_sent) {
                dictDelete(conn->outstanding_msgs_dict, &reqid);
                log_info("Putting req %d", req->id);
                req_put(req);
            }
        }
    } else if (status == DN_OK) {
        g_pre_coalesce(req->selected_rsp);
        if (req_done(conn, req)) {
            struct context *ctx = conn_to_ctx(conn);
            status = event_add_out(ctx->evb, conn);
            if (status != DN_OK) {
                conn->err = errno;
            }
        }
    }
    return status;
}
Beispiel #16
0
void* cache_get(qqCache* qc,const void* key){
    void* lookup;
    void* die_key;
    void* dewrappedVal;
    size_t valsize;
    lookup = dictFetchValue(qc->dict,key);
    if(lookup==NULL){   // not hit
        return NULL;
    }else{
        dewrappedVal=qc->type->dewrapValue(lookup);
        access(lookup,lookup,NULL,NULL);
        return dewrappedVal;
    }
}
Beispiel #17
0
Datei: db.c Projekt: andmej/redis
/* If the key does not exist, this is just like dbAdd(). Otherwise
 * the value associated to the key is replaced with the new one.
 *
 * On update (key already existed) 0 is returned. Otherwise 1. */
int dbReplace(redisDb *db, robj *key, robj *val) {
    robj *oldval;
    int retval;

    if ((oldval = dictFetchValue(db->dict,key->ptr)) == NULL) {
        sds copy = sdsdup(key->ptr);
        dictAdd(db->dict, copy, val);
        retval = 1;
    } else {
        dictReplace(db->dict, key->ptr, val);
        retval = 0;
    }
    if (server.ds_enabled) cacheSetKeyMayExist(db,key);
    return retval;
}
Beispiel #18
0
void redis_fetch(dict *d, int times)
{
    int i, j;
    char buf[20];
    sds key, val;

    srand(1992);
    for (i = 0; i < times; ++i) {
        j = rand() % times;
        snprintf(buf, 20, "key%d", j);
        key = sdsnew(buf);

        assert(dictFetchValue(d, key));
        sdsfree(key);
    }
}
Beispiel #19
0
rcommand *DXDB_lookupCommand(sds name) {
    struct redisCommand *cmd = dictFetchValue(server.commands, name);
    if (server.alc.WebServerMode > 0) {
        // called during load in whitelist
        if (!server.alc.CurrClient)                     return cmd;
        // feed from master
        if (server.alc.CurrClient == server.master)     return cmd;
        // lua already internal
        if (server.alc.CurrClient == server.lua_client) return cmd;
        if (!server.alc.CurrClient->InternalRequest) {
            if (isWhiteListedIp(server.alc.CurrClient)) return cmd;
            return cmd ? (cmd->proc == luafuncCommand) ? cmd : NULL : NULL;
        }
    }
    return cmd;
}
Beispiel #20
0
int dbRemove(const sds setName)
{
    int result = DICT_OK;
    set *s = NULL;
    lockWrite(sets);
    s = (set *) dictFetchValue(sets, setName);
    if (NULL != s)
    {
        unregisterSyncObject(s);
        if (!s->registered)
            setDestroy(s);
        result = dictDelete(sets, setName);
    }
    unlockWrite(sets);
    return result;
}
Beispiel #21
0
/*
 * PUBSUB 命令, 内省命令
 */
void pubsubCommand(redisClient *c) {
    if (!strcasecmp(c->argv[1]->ptr,"channels") &&
        (c->argc == 2 || c->argc ==3))              //列出当前活跃的频道,每个频道至少有一个订阅者,订阅模式的客户端不计算在内
    {
        /* PUBSUB CHANNELS [<pattern>] */
        sds pat = (c->argc == 2) ? NULL : c->argv[2]->ptr;
        dictIterator *di = dictGetIterator(server.pubsub_channels);
        dictEntry *de;
        long mblen = 0;
        void *replylen;

        replylen = addDeferredMultiBulkLength(c);
        while((de = dictNext(di)) != NULL) {
            robj *cobj = dictGetKey(de);
            sds channel = cobj->ptr;

            if (!pat || stringmatchlen(pat, sdslen(pat),
                                       channel, sdslen(channel),0))
            {
                addReplyBulk(c,cobj);
                mblen++;
            }
        }
        dictReleaseIterator(di);
        setDeferredMultiBulkLength(c,replylen,mblen);
    } else if (!strcasecmp(c->argv[1]->ptr,"numsub") && c->argc >= 2) {     //返回给定频道的订阅者数量,订阅模式的客户端不计算在内
        /* PUBSUB NUMSUB [Channel_1 ... Channel_N] */
        int j;

        addReplyMultiBulkLen(c,(c->argc-2)*2);
        for (j = 2; j < c->argc; j++) {
            list *l = dictFetchValue(server.pubsub_channels,c->argv[j]);

            addReplyBulk(c,c->argv[j]);
            addReplyLongLong(c,l ? listLength(l) : 0);
        }
    } else if (!strcasecmp(c->argv[1]->ptr,"numpat") && c->argc == 2) {     //返回订阅模式的数量
        /* PUBSUB NUMPAT */
        addReplyLongLong(c,listLength(server.pubsub_patterns));
    } else {
        addReplyErrorFormat(c,
            "Unknown PUBSUB subcommand or wrong number of arguments for '%s'",
            (char*)c->argv[1]->ptr);
    }
}
Beispiel #22
0
/* "Touch" a key, so that if this key is being WATCHed by some client the
 * next EXEC will fail. */
void touchWatchedKey(redisDb *db, robj *key) {
    list *clients;
    listIter li;
    listNode *ln;

    if (dictSize(db->watched_keys) == 0) return;
    clients = dictFetchValue(db->watched_keys, key);
    if (!clients) return;

    /* Mark all the clients watching this key as REDIS_DIRTY_CAS */
    /* Check if we are already watching for this key */
    listRewind(clients,&li);
    while((ln = listNext(&li))) {
        redisClient *c = listNodeValue(ln);

        c->flags |= REDIS_DIRTY_CAS;
    }
}
Beispiel #23
0
void _masterProcessStatus() {
    /* Check if status is expired */
    unsigned long now = time(NULL);
    if(next_master_refresh_time < now) {
        objSds *value = dictFetchValue(master_cache,statusQuery);
        if(value) {
            sds oldptr = value->ptr;
            /* Re-asign the value */
            value->ptr = _masterGetStatus();
            sdsfree(oldptr);
            next_master_refresh_time = now + MASTER_STATUS_REFRESH_PERIOD;
        }
        else {
            ulog(CCACHE_WARNING,"master cache %s not found",statusQuery);
            next_master_refresh_time = now + MASTER_STATUS_REFRESH_PERIOD*1000;
        }
    }
}
Beispiel #24
0
void _masterProcessCacheNew(ccache *c){
    cacheEntry *ce;
    while((ce=cacheGetMessage(c,CACHE_REQUEST_NEW)) != NULL)
    {
        master_numjob++;
        sds key = ce->de->key;
        objSds *value = dictFetchValue(master_cache,key);
        if(!value) {
            REPORT_MASTER_ADD_KEY(key);
            value = objSdsCreate();
            /* Add cache entry to waiting list */
            objSdsAddWaitingEntry(value,ce);
            /* Add entry to master cache */
            sds mkey = sdsdup(key); /* master must have its own key for its own cache */
            /* Every when accept new ce, the obj ref is increased */
            objSdsAddRef(value);
            dictAdd(master_cache,mkey,value);
            /* New IO Job */
            bioPushGeneralJob(mkey);
            OBJ_REPORT_REF(value);
        }
        else {
            switch(value->state) {
            case OBJSDS_WAITING:
                /* Every when accept new ce, the obj ref is increased */
                objSdsAddRef(value);
                objSdsAddWaitingEntry(value,ce);
                break;
            case OBJSDS_OK:
                ce->val = value->ptr;
                /* Every when accept new ce, the obj ref is increased */
                objSdsAddRef(value);
                /* Reply slave cache about the available data */
                cacheSendMessage(c,ce,CACHE_REPLY_NEW);
                break;
            default:
                /* Error Unknown Object State */
                break;
            }
            OBJ_REPORT_REF(value);
        }
    }
}
Beispiel #25
0
/* COMMAND <subcommand> <args> */
void commandCommand(client *c) {
    dictIterator *di;
    dictEntry *de;

    if (c->argc == 1) {
        addReplyMultiBulkLen(c, dictSize(server.commands));
        di = dictGetIterator(server.commands);
        while ((de = dictNext(di)) != NULL) {
            addReplyCommand(c, dictGetVal(de));
        }
        dictReleaseIterator(di);
    } else if (!strcasecmp(c->argv[1]->ptr, "info")) {
        int i;
        addReplyMultiBulkLen(c, c->argc-2);
        for (i = 2; i < c->argc; i++) {
            addReplyCommand(c, dictFetchValue(server.commands, c->argv[i]->ptr));
        }
    } else if (!strcasecmp(c->argv[1]->ptr, "count") && c->argc == 2) {
        addReplyLongLong(c, dictSize(server.commands));
    } else if (!strcasecmp(c->argv[1]->ptr,"getkeys") && c->argc >= 3) {
        struct redisCommand *cmd = lookupCommand(c->argv[2]->ptr);
        int *keys, numkeys, j;

        if (!cmd) {
            addReplyErrorFormat(c,"Invalid command specified");
            return;
        } else if ((cmd->arity > 0 && cmd->arity != c->argc-2) ||
                   ((c->argc-2) < -cmd->arity))
        {
            addReplyError(c,"Invalid number of arguments specified for command");
            return;
        }

        keys = getKeysFromCommand(cmd,c->argv+2,c->argc-2,&numkeys);
        addReplyMultiBulkLen(c,numkeys);
        for (j = 0; j < numkeys; j++) addReplyBulk(c,c->argv[keys[j]+2]);
        getKeysFreeResult(keys);
    } else {
        addReplyError(c, "Unknown subcommand or wrong number of arguments.");
        return;
    }
}
Beispiel #26
0
/*
 * 监视给定 key
 *
 * T = O(N)
 */
void watchForKey(redisClient *c, robj *key)
{
    list *clients = NULL;
    listIter li;
    listNode *ln;
    watchedKey *wk;

    /* Check if we are already watching for this key */
    // 检查该 key 是否已经被 WATCH
    // (出现在 WATCH 命令调用时一个 key 被输入多次的情况)
    // 如果是的话,直接返回
    // O(N)
    listRewind(c->watched_keys,&li);
    while((ln = listNext(&li)))
    {
        wk = listNodeValue(ln);
        if (wk->db == c->db && equalStringObjects(key,wk->key))
            return; /* Key already watched */
    }

    // key 未被监视
    // 根据 key ,将客户端加入到 DB 的监视 key 字典中
    /* This key is not already watched in this DB. Let's add it */
    // O(1)
    clients = dictFetchValue(c->db->watched_keys,key);
    if (!clients)
    {
        clients = listCreate();
        dictAdd(c->db->watched_keys,key,clients);
        incrRefCount(key);
    }
    listAddNodeTail(clients,c);

    // 将 key 添加到客户端的监视列表中
    /* Add the new key to the lits of keys watched by this client */
    // O(1)
    wk = zmalloc(sizeof(*wk));
    wk->key = key;
    wk->db = c->db;
    incrRefCount(key);
    listAddNodeTail(c->watched_keys,wk);
}
Beispiel #27
0
static void
slotsmgrt_close_socket(sds host, sds port) {
    sds name = sdsempty();
    name = sdscatlen(name, host, sdslen(host));
    name = sdscatlen(name, ":", 1);
    name = sdscatlen(name, port, sdslen(port));

    slotsmgrt_sockfd *pfd = dictFetchValue(server.slotsmgrt_cached_sockfds, name);
    if (pfd == NULL) {
        redisLog(REDIS_WARNING, "slotsmgrt: close target %s:%s again", host, port);
        sdsfree(name);
        return;
    } else {
        redisLog(REDIS_WARNING, "slotsmgrt: close target %s:%s", host, port);
    }
    dictDelete(server.slotsmgrt_cached_sockfds, name);
    close(pfd->fd);
    zfree(pfd);
    sdsfree(name);
}
Beispiel #28
0
void _masterProcessCacheOld(ccache *c){
    sds old_key;
    while((old_key=cacheGetMessage(c,CACHE_REQUEST_OLD)) != NULL)
    {
        master_numjob++;
        objSds *value = dictFetchValue(master_cache,old_key);
        if(value) {
            objSdsSubRef(value);
            OBJ_REPORT_REF(value);
            /* No ae thread use this entry anymore */
            if(value->ref == 1) {
                printf("mem freed\n");
                master_total_mem -= sdslen(value->ptr);
                /* TODO: send free mem task to background job threads */
                dictDelete(master_cache,old_key);
            }
        }
        sdsfree(old_key);
    }
}
Beispiel #29
0
redisKeyInfo *lookupRedisKeyInfo( const char *cmd ) {
    static dict *commands;
    /* Command table. sds string -> command struct pointer. */
    dictType commandTableDictType = {
        dictSdsCaseHash,           /* hash function */
        NULL,                      /* key dup */
        NULL,                      /* val dup */
        dictSdsKeyCaseCompare,     /* key compare */
        dictSdsDestructor,         /* key destructor */
        NULL                       /* val destructor */
    };


    if( commands == NULL ) {
        commands = dictCreate(&commandTableDictType,NULL);
        loadCommandTable(commands);
    }

    return dictFetchValue(commands, cmd);
}
Beispiel #30
0
static void database_worker_save(uv_work_t * req)
{
    save_t * saving = (save_t *) req->data;
    json_t * obj = saving->data;
    json_t * result;
    short short_insert = 0;

    LOCK
        if (!(result = dictFetchValue(db, saving->channel))) {
            result = json_array();
            short_insert = 1;
        }
        json_array_append(result, obj);
        if (json_array_size(result) > config->web_history) {
            json_array_remove(result, 0);
        }
        if (short_insert) {
            dictAdd(db, saving->channel, result);
        }
    RELEASE
}