Exemple #1
0
int main(int argc, char **argv)
{

    dict *d;
    dictEntry *e;
    d = dictCreate(&hashtype, NULL);
    if (dictAdd(d, "keys", "value") == DICT_OK)
    {
        printf("Add value OK\n");
    }
    else{
        printf("Add value fail\n");
        return -1;
    };
    e = dictFind(d, "keys");
    if (e)
    {
        printf("found: %s\n", e->v);
    }
    else{
        printf("not found\n");
    }

    return 0;
}
Exemple #2
0
void 
engine_document_found(Engine *engine, DocBuf *buffer) {  
  unsigned int hash_code = buffer->hash_code;
  if (!hash_code) {
    hash_code = pstrhash(&buffer->doc);
  }
  DocRef dr = { &buffer->doc, engine->stream->written, buffer->doc.len, hash_code };
  if(engine->doc_set && dictFind(engine->doc_set, &dr)){
    engine->error = "duplicate document rejected";
    if(engine->after_on_document) {
      engine->after_on_document->handler(engine->after_on_document, engine);
    }
  } else {
    engine->error = NULL;
    dr.tmp = NULL;
    engine_append_journal(engine, &buffer->doc);
    ring_buffer_append_pstring(engine->stream, &buffer->doc);
  	ring_buffer_append(engine->docs, &dr, sizeof(dr));
    long doc_id = engine_last_document_id(engine);
    _engine_apply_ints(engine, buffer, doc_id);
    if(engine->after_on_document) {
      engine->after_on_document->handler(engine->after_on_document, engine);
    }
  	engine_percolate(engine, buffer, doc_id);
  	engine_index(engine, buffer, doc_id);
    if(engine->doc_set) dictAdd(engine->doc_set, &dr, NULL);
	}
}
Exemple #3
0
/* Add the specified value into a set.
 *
 * If the value was already member of the set, nothing is done and 0 is
 * returned, otherwise the new element is added and 1 is returned. */
int setTypeAdd(robj *subject, sds value) {
    long long llval;
    if (subject->encoding == OBJ_ENCODING_HT) {
        dict *ht = subject->ptr;
        dictEntry *de = dictAddRaw(ht,value);
        if (de) {
            dictSetKey(ht,de,sdsdup(value));
            dictSetVal(ht,de,NULL);
            return 1;
        }
    } else if (subject->encoding == OBJ_ENCODING_INTSET) {
        if (isSdsRepresentableAsLongLong(value,&llval) == C_OK) {
            uint8_t success = 0;
            subject->ptr = intsetAdd(subject->ptr,llval,&success);
            if (success) {
                /* Convert to regular set when the intset contains
                 * too many entries. */
                if (intsetLen(subject->ptr) > server.set_max_intset_entries)
                    setTypeConvert(subject,OBJ_ENCODING_HT);
                return 1;
            }
        } else {
            /* Failed to get integer from object, convert to regular set. */
            setTypeConvert(subject,OBJ_ENCODING_HT);

            /* The set *was* an intset and this value is not integer
             * encodable, so dictAdd should always work. */
            serverAssert(dictAdd(subject->ptr,sdsdup(value),NULL) == DICT_OK);
            return 1;
        }
    } else {
        serverPanic("Unknown set encoding");
    }
    return 0;
}
Exemple #4
0
const set *dbCreate(const sds setName)
{
    set *newSet = NULL;

    if (NULL == setName || 0 == strlen(setName))
    {
        return NULL;
    }

    if (NULL == (newSet = setCreate()))
        return NULL;

    lockWrite(sets);

    if (DICT_OK != dictAdd(sets, setName, newSet))
    {
        unlockWrite(sets);
        setDestroy(newSet);
        return NULL;
    }

    if (0 != registerSyncObject(newSet) && 1 != syncObjectIsRegistered(newSet))
    {
        unlockWrite(sets);
        dictDelete(sets, setName);
        setDestroy(newSet);
        return NULL;
    }

    unlockWrite(sets);
    return newSet;
}
Exemple #5
0
static int getTableId(int owner, uint64_t *table_id)
{
    struct dictEntry *entry = dictFind(global.tables, (void*)(intptr_t)owner);
    if (entry) {
        *table_id = dictGetUnsignedIntegerVal(entry);
        return WHEAT_OK;
    } else {
        char name[256];
        int l = sprintf(name, "%s_%d", hostname, owner);
        name[l] = '\0';
        Status s = rc_getTableId(global.client, name, table_id);
        if (s != STATUS_OK) {
            if (s == STATUS_TABLE_DOESNT_EXIST) {
                wheatLog(WHEAT_DEBUG, "%s table %s not exists, create it, s", __func__, name);
                s = rc_createTable(global.client, name, 1);
                if (s != STATUS_OK) {
                    wheatLog(WHEAT_WARNING, "%s failed to create table %s: %s", __func__, name, statusToString(s));
                    return WHEAT_WRONG;
                }
                s = rc_getTableId(global.client, name, table_id);
            }
            if (s != STATUS_OK) {
                wheatLog(WHEAT_WARNING, "%s failed to get table %s: %s", __func__, name, statusToString(s));
                return WHEAT_WRONG;
            }
        }
        dictAdd(global.tables, name, (void*)(intptr_t)(*table_id));
        return WHEAT_OK;
    }
}
Exemple #6
0
/* Set a client in blocking mode for the specified key, with the specified
 * timeout */
void blockForKeys(redisClient *c, robj **keys, int numkeys, time_t timeout) {
    dictEntry *de;
    list *l;
    int j;

    c->blocking_keys = zmalloc(sizeof(robj*)*numkeys);
    c->blocking_keys_num = numkeys;
    c->blockingto = timeout;
    for (j = 0; j < numkeys; j++) {
        /* Add the key in the client structure, to map clients -> keys */
        c->blocking_keys[j] = keys[j];
        incrRefCount(keys[j]);

        /* And in the other "side", to map keys -> clients */
        de = dictFind(c->db->blocking_keys,keys[j]);
        if (de == NULL) {
            int retval;

            /* For every key we take a list of clients blocked for it */
            l = listCreate();
            retval = dictAdd(c->db->blocking_keys,keys[j],l);
            incrRefCount(keys[j]);
            redisAssert(retval == DICT_OK);
        } else {
            l = dictGetEntryVal(de);
        }
        listAddNodeTail(l,c);
    }
    /* Mark the client as a blocked client */
    c->flags |= REDIS_BLOCKED;
    server.blpop_blocked_clients++;
}
Exemple #7
0
/* Add the key to the DB. It's up to the caller to increment the reference
 * counte of the value if needed.
 *
 * The program is aborted if the key already exists. */
void dbAdd(redisDb *db, robj *key, robj *val) {
    sds copy = sdsdup(key->ptr);
    int retval = dictAdd(db->dict, copy, val);

    redisAssertWithInfo(NULL,key,retval == REDIS_OK);
    if (server.cluster_enabled) SlotToKeyAdd(key);
}
Exemple #8
0
/* Define a lua function with the specified function name and body.
 * The function name musts be a 2 characters long string, since all the
 * functions we defined in the Lua context are in the form:
 *
 *   f_<hex sha1 sum>
 *
 * On success REDIS_OK is returned, and nothing is left on the Lua stack.
 * On error REDIS_ERR is returned and an appropriate error is set in the
 * client context. */
int luaCreateFunction(redisClient *c, lua_State *lua, char *funcname, robj *body) {
    sds funcdef = sdsempty();

    funcdef = sdscat(funcdef,"function ");
    funcdef = sdscatlen(funcdef,funcname,42);
    funcdef = sdscatlen(funcdef,"() ",3);
    funcdef = sdscatlen(funcdef,body->ptr,sdslen(body->ptr));
    funcdef = sdscatlen(funcdef," end",4);

    if (luaL_loadbuffer(lua,funcdef,sdslen(funcdef),"@user_script")) {
        addReplyErrorFormat(c,"Error compiling script (new function): %s\n",
            lua_tostring(lua,-1));
        lua_pop(lua,1);
        sdsfree(funcdef);
        return REDIS_ERR;
    }
    sdsfree(funcdef);
    if (lua_pcall(lua,0,0,0)) {
        addReplyErrorFormat(c,"Error running script (new function): %s\n",
            lua_tostring(lua,-1));
        lua_pop(lua,1);
        return REDIS_ERR;
    }

    /* We also save a SHA1 -> Original script map in a dictionary
     * so that we can replicate / write in the AOF all the
     * EVALSHA commands as EVAL using the original script. */
    {
        int retval = dictAdd(server.lua_scripts,
                             sdsnewlen(funcname+2,40),body);
        redisAssertWithInfo(c,NULL,retval == DICT_OK);
        incrRefCount(body);
    }
    return REDIS_OK;
}
//如果有client因为等待一个key被push而被阻塞,那么将这个key放入ready_keys,key哈希表中
void signalListAsReady(redisDb *db, robj *key) {
    readyList *rl;

    /* No clients blocking for this key? No need to queue it. */
    //如果在key不是正处于阻塞状态的键则返回
    if (dictFind(db->blocking_keys,key) == NULL) return;

    /* Key was already signaled? No need to queue it again. */
    //key已经是ready_keys链表里的键,则返回
    if (dictFind(db->ready_keys,key) != NULL) return;

    /* Ok, we need to queue this key into server.ready_keys. */
    //接下来需要将key添加到ready_keys中
    //分配一个readyList结构的空间,该结构记录要解除client的阻塞状态的键
    rl = zmalloc(sizeof(*rl));
    rl->key = key;  //设置要解除的键
    rl->db = db;    //设置所在数据库
    incrRefCount(key);
    //将rl添加到server.ready_keys的末尾
    listAddNodeTail(server.ready_keys,rl);

    /* We also add the key in the db->ready_keys dictionary in order
     * to avoid adding it multiple times into a list with a simple O(1)
     * check. */
    //再讲key添加到ready_keys哈希表中,防止重复添加
    incrRefCount(key);
    serverAssert(dictAdd(db->ready_keys,key,NULL) == DICT_OK);
}
Exemple #10
0
struct ProcessInfo *newProcess(pid_t pid) {
    struct ProcessInfo *p = zmalloc(sizeof(struct ProcessInfo));
    memset(p, 0 ,sizeof(struct ProcessInfo));
    p->pid = pid;
    dictAdd(server.process, &pid, p);
    return p;
}
Exemple #11
0
/* Convert the set to specified encoding. The resulting dict (when converting
 * to a hash table) is presized to hold the number of elements in the original
 * set. */
void setTypeConvert(robj *setobj, int enc) {
    setTypeIterator *si;
    redisAssertWithInfo(NULL,setobj,setobj->type == REDIS_SET &&
                             setobj->encoding == REDIS_ENCODING_INTSET);

    if (enc == REDIS_ENCODING_HT) {
        int64_t intele;
        dict *d = dictCreate(&setDictType,NULL);
        robj *element;

        /* Presize the dict to avoid rehashing */
        dictExpand(d,intsetLen(setobj->ptr));

        /* To add the elements we extract integers and create redis objects */
        si = setTypeInitIterator(setobj);
        while (setTypeNext(si,&element,&intele) != -1) {
            element = createStringObjectFromLongLong(intele);
            redisAssertWithInfo(NULL,element,
                                dictAdd(d,element,NULL) == DICT_OK);
        }
        setTypeReleaseIterator(si);

        setobj->encoding = REDIS_ENCODING_HT;
        zfree(setobj->ptr);
        setobj->ptr = d;
    } else {
        redisPanic("Unsupported set conversion");
    }
}
Exemple #12
0
int main(int argc, char *argv[]) 
{
    int ret;
    dict *d = dictCreate(&testDictType, NULL);
    assert(d);
    Key_t *k = (Key_t*)malloc(sizeof(*k)); 
    k->laddr = 112;
    k->raddr = 112;
    k->lport = 1123;
    k->rport = 3306;

    Val_t *v = (Val_t*)malloc(sizeof(*v)); 
    v->v = malloc(100);
    snprintf(v->v, 100, "%s", "abcdefg");
    
    ret = dictAdd(d, k, v);
    assert(ret == DICT_OK);

    Val_t *v2 = dictFetchValue(d, k);

    assert(0 == strcmp(v2->v, v->v));

    printf("%d-%s-%s\n", ret, v->v, v2->v);

    dictPrintStats(d);

    dictDelete(d, k);

    dictPrintStats(d);

    dictRelease(d);

    return 0;
}
static int
conf_key_value_insert(dict *org, sds key, conf_value *cv)
{
    if(key == NULL){
        log_error("ERROR: Value in conf file has no key");
        return RMT_ERROR;
    }

    if(cv == NULL){
        log_error("ERROR: Key %s in conf file has no value", key);
        return RMT_ERROR;
    }

    if(org == NULL){
        log_error("ERROR: Key %s in conf file has no organization", 
            key);
        return RMT_ERROR;
    }
    
    if(dictAdd(org,key,cv) != DICT_OK){
        log_error("ERROR: Key %s in organization of conf file is duplicate", key);
        return RMT_ERROR;
    }

    return RMT_OK;
}
Exemple #14
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 = latency;
        return;
    }

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

    ts->idx++;
    if (ts->idx == LATENCY_TS_LEN) ts->idx = 0;
}
Exemple #15
0
/* Add the key to the DB. It's up to the caller to increment the reference
 * counter of the value if needed.
 *
 * The program is aborted if the key already exists. */
void dbAdd(redisDb *db, robj *key, robj *val) {
    sds copy = sdsdup(key->ptr);
    int retval = dictAdd(db->dict, copy, val);

    serverAssertWithInfo(NULL,key,retval == C_OK);
    if (val->type == OBJ_LIST) signalListAsReady(db, key);
    if (server.cluster_enabled) slotToKeyAdd(key);
 }
Exemple #16
0
ResultIterator *
engine_search(Engine *engine, Query *query) {
  long max = engine_last_document_id(engine)+1;
  ResultIterator *iter = malloc(sizeof(ResultIterator));
  iter->query = query;
  if(query->callback->id < 0) query->callback->id = engine->query_id++;
  iter->engine = engine;
  iter->doc_id = max;
  iter->initialized = false;
  iter->cursors = dictCreate(getTermPlistCursorDict(), 0);
  iter->subs = malloc(sizeof(sub_iterator*) * query->count);
  iter->count = query->count;
  DEBUG("Constructing cursor");
  for(int i = 0; i < query->count; i++) {
    conjunction_t *cj = query->conjunctions[i];
    iter->subs[i] = malloc(sizeof(sub_iterator));
    iter->subs[i]->doc_id = max;
    iter->subs[i]->cursors = malloc(sizeof(PlistCursor*) * cj->count);
    iter->subs[i]->negateds = malloc(cj->count * sizeof(int));
    iter->subs[i]->state = malloc(sizeof(long) * cj->count);
    iter->subs[i]->initialized = false;
    iter->subs[i]->count = cj->count;
    for(int j = 0; j < cj->count; j++) {
      Term *term = &cj->terms[j];
      Cursor *cursor = dictFetchValue(iter->cursors, term);
      if(cursor == NULL) {
        switch(term->type) {
        case CATCHALL:
          //its an inverted null, handled later
          break;
        case NUMERIC:
          DEBUG("Making numeric subcursor");
          RingBuffer *rb = dictFetchValue(engine->ints, &term->field);
          cursor = rb == NULL ? NULL : &ring_buffer_predicate_int_cursor_new(rb, sizeof(int), term->text.val[0], term->offset)->as_cursor;
          break;
        case TEXT:
          DEBUG("Making plist subcursor for %.*s:%.*s", term->field.len, term->field.val, term->text.len, term->text.val);
          Plist *pl = lrw_dict_get(engine->term_dictionary, term);
          cursor = pl == NULL ? NULL : &plist_cursor_new(pl)->as_cursor;
          if(!pl) {
            DEBUG("term not found: using null cursor");
          }
          dictAdd(iter->cursors, term, cursor);
          break;
        default: 
          assert(0);
        }
      } else {
        DEBUG("Reusing subcursor");
      }
      // catchall is inverted not-found
      iter->subs[i]->negateds[j] = (int) ((term->type == CATCHALL) ? !term->negated : term->negated);
      iter->subs[i]->cursors[j] = cursor;
      iter->subs[i]->state[j] = max;
    }
  }
  return iter; 
}
Exemple #17
0
int insertDMCFS(columnFamilyStore *cfs)
{
	if(!cfs)
		return -1;
	if(dictAdd(g_dataModel.cfsHashTable, cfs, NULL)
			== DICT_OK)
		return 0;
	return -1;
}
void DXDB_populateCommandTable(dict *server_commands) {
    //printf("addDXDBfunctions: %p\n", server_commands);
    int numcommands = sizeof(DXDBCommandTable)/sizeof(struct redisCommand);
    for (int j = 0; j < numcommands; j++) {
        struct redisCommand *c = DXDBCommandTable + j;
        int retval = dictAdd(server_commands, sdsnew(c->name), c);
        assert(retval == DICT_OK);
    }
}
Exemple #19
0
int addLookupEntry(char *key, char *value, unsigned char type)
{
	lookupKey *lookKey = zmalloc(sizeof(lookupKey));
	lookKey->name = strdup(key);
	lookKey->type = type;
	lookup_log(LOG_DEBUG, "table add %s,%d\n", key, type);
	dictAdd(dt, (void *)lookKey, (void *)value);
	return 0;
}
Exemple #20
0
static fdi_t mapFDToIndex(aeEventLoop *eventLoop, socket_t s)
{
    fdi_t fdi = getNextFDIAvailable(eventLoop);
    if (dictAdd(eventLoop->fdiMap->map, (void *)s, (void *)fdi) != DICT_OK)
    {
        return INVALID_FDI;
    }
    return fdi;
}
Exemple #21
0
static void _requestSetHeader(http_connection_t * conn)
{
    if (conn->last_was_value && conn->current_header_key_length > 0) {
        TOUPPER(conn->current_header_key);
        TOLOWER(conn->current_header_value);
        dictAdd(conn->request->headers, conn->current_header_key, conn->current_header_value);
        conn->current_header_key_length = 0;
        conn->current_header_value_length = 0;
    }
}
Exemple #22
0
/* 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) {
    if (dictFind(db->dict,key->ptr) == NULL) {
        sds copy = sdsdup(key->ptr);
        dictAdd(db->dict, copy, val);
        return 1;
    } else {
        dictReplace(db->dict, key->ptr, val);
        return 0;
    }
}
Exemple #23
0
/* Set a client in blocking mode for the specified key (list or stream), with
 * the specified timeout. The 'type' argument is BLOCKED_LIST or BLOCKED_STREAM
 * depending on the kind of operation we are waiting for an empty key in
 * order to awake the client. The client is blocked for all the 'numkeys'
 * keys as in the 'keys' argument. When we block for stream keys, we also
 * provide an array of streamID structures: clients will be unblocked only
 * when items with an ID greater or equal to the specified one is appended
 * to the stream. */
void blockForKeys(client *c, int btype, robj **keys, int numkeys, mstime_t timeout, robj *target, streamID *ids) {
    dictEntry *de;
    list *l;
    int j;

    c->bpop.timeout = timeout;
    c->bpop.target = target;

    if (target != NULL) incrRefCount(target);

    for (j = 0; j < numkeys; j++) {
        /* The value associated with the key name in the bpop.keys dictionary
         * is NULL for lists, or the stream ID for streams. */
        void *key_data = NULL;
        if (btype == BLOCKED_STREAM) {
            key_data = zmalloc(sizeof(streamID));
            memcpy(key_data,ids+j,sizeof(streamID));
        }

        /* If the key already exists in the dictionary ignore it. */
        if (dictAdd(c->bpop.keys,keys[j],key_data) != DICT_OK) {
            zfree(key_data);
            continue;
        }
        incrRefCount(keys[j]);

        /* And in the other "side", to map keys -> clients */
        de = dictFind(c->db->blocking_keys,keys[j]);
        if (de == NULL) {
            int retval;

            /* For every key we take a list of clients blocked for it */
            l = listCreate();
            retval = dictAdd(c->db->blocking_keys,keys[j],l);
            incrRefCount(keys[j]);
            serverAssertWithInfo(c,keys[j],retval == DICT_OK);
        } else {
            l = dictGetVal(de);
        }
        listAddNodeTail(l,c);
    }
    blockClient(c,btype);
}
Exemple #24
0
int initStaticFile(struct protocol *p)
{
    int args, i, ret;
    wstr extensions, indexes;
    struct configuration *conf = getConfiguration("file-maxsize");
    MaxFileSize = conf->target.val;

    conf = getConfiguration("allowed-extension");
    extensions = wstrNew(conf->target.ptr);
    if (wstrIndex(extensions, '*') != -1) {
        AllowExtensions = NULL;
    } else {
        AllowExtensions = dictCreate(&wstrDictType);

        wstr *argvs = wstrNewSplit(extensions, ",", 1, &args);
        if (!argvs) {
            wheatLog(WHEAT_WARNING, "init Static File failed");
            return WHEAT_WRONG;
        }

        for (i = 0; i < args; ++i) {
            ret = dictAdd(AllowExtensions, wstrNew(argvs[i]), wstrNew("allowed"));
            if (ret == DICT_WRONG)
                break;
        }

        wstrFreeSplit(argvs, args);
    }
    wstrFree(extensions);

    conf = getConfiguration("directory-index");
    if (conf->target.ptr) {
        indexes = wstrNew(conf->target.ptr);
        DirectoryIndex = createList();
        listSetFree(DirectoryIndex, (void (*)(void*))wstrFree);
        wstr *argvs = wstrNewSplit(indexes, ",", 1, &args);
        if (!argvs) {
            wheatLog(WHEAT_WARNING, "split failed");
            return WHEAT_WRONG;
        }

        for (i = 0; i < args; ++i) {
            appendToListTail(DirectoryIndex, wstrNew(argvs[i]));
            if (ret == DICT_WRONG)
                break;
        }

        wstrFreeSplit(argvs, args);
    } else {
        DirectoryIndex = NULL;
    }

    IfModifiedSince = wstrNew(IF_MODIFIED_SINCE);
    return WHEAT_OK;
}
// keys是一个key的数组,个数为numkeys个
// timeout保存超时时间
// target保存解除阻塞时的key对象,用于BRPOPLPUSH函数
// 根据给定的key将client阻塞
void blockForKeys(client *c, robj **keys, int numkeys, mstime_t timeout, robj *target) {
    dictEntry *de;
    list *l;
    int j;

    //设置超时时间和target
    c->bpop.timeout = timeout;
    c->bpop.target = target;

    //增加target的引用计数
    if (target != NULL) incrRefCount(target);

    //将当前client的numkeys个key设置为阻塞
    for (j = 0; j < numkeys; j++) {
        /* If the key already exists in the dict ignore it. */
        //bpop.keys记录所有造成client阻塞的键
        //将要阻塞的键放入bpop.keys字典中
        if (dictAdd(c->bpop.keys,keys[j],NULL) != DICT_OK) continue;
        //当前的key引用计数加1
        incrRefCount(keys[j]);

        /* And in the other "side", to map keys -> clients */
        //db->blocking_keys是一个字典,字典的键为bpop.keys中的一个键,值是一个列表,保存着所有被该键阻塞的client
        //当前造成client被阻塞的键有没有当前的key
        de = dictFind(c->db->blocking_keys,keys[j]);
        if (de == NULL) {   //没有当前的key,添加进去
            int retval;

            /* For every key we take a list of clients blocked for it */
            //创建一个列表
            l = listCreate();
            //将造成阻塞的键和列表添加到db->blocking_keys字典中
            retval = dictAdd(c->db->blocking_keys,keys[j],l);
            incrRefCount(keys[j]);
            serverAssertWithInfo(c,keys[j],retval == DICT_OK);
        } else {    //如果已经有了,则当前key的值保存起来,值是一个列表
            l = dictGetVal(de);
        }
        listAddNodeTail(l,c);   //将当前client加入到阻塞的client的列表
    }
    blockClient(c,BLOCKED_LIST);    //阻塞client
}
Exemple #26
0
static int setCommand(char *key, valObject *val) {
    int ret = -1,dbindex = -1;
    dbindex = chrtoint(key)%(THREADCNT);
    pthread_mutex_lock(&lock[dbindex]);
    ret = dictAdd(db[dbindex], key, val);
    pthread_mutex_unlock(&lock[dbindex]);
    if(ret < 0)
        return ret;
    else
        return -1;
}
Exemple #27
0
/* Add the key to the DB. If the key already exists REDIS_ERR is returned,
 * otherwise REDIS_OK is returned, and the caller should increment the
 * refcount of 'val'. */
int dbAdd(redisDb *db, robj *key, robj *val) {
    /* Perform a lookup before adding the key, as we need to copy the
     * key value. */
    if (dictFind(db->dict, key->ptr) != NULL) {
        return REDIS_ERR;
    } else {
        sds copy = sdsdup(key->ptr);
        dictAdd(db->dict, copy, val);
        return REDIS_OK;
    }
}
Exemple #28
0
/* Create a counter and add it to server.counters. */
counter *counterCreate(sds name) {
    counter *cntr = zcalloc(sizeof(counter) + (sizeof(long double) * server.history_size));
    cntr->name      = sdsdup(name);
    cntr->shards    = listCreate();
    cntr->history   = (long double*)(cntr + 1);
    cntr->precision = server.default_precision;

    serverAssert(dictAdd(server.counters, cntr->name, cntr) == DICT_OK);

    return cntr;
}
Exemple #29
0
/* Try to garbage collect the job. */
void tryJobGC(job *job) {
    if (job->state != JOB_STATE_ACKED) return;

    int dummy_ack = dictSize(job->nodes_delivered) == 0;
    serverLog(LL_VERBOSE,"GC %.42s", job->id);

    /* Don't overflow the count, it's only useful for the exponential delay.
     * Actually we'll keep trying forever. */
    if (job->gc_retry != JOB_GC_RETRY_COUNT_MAX) job->gc_retry++;

    /* nodes_confirmed is used in order to store all the nodes that have the
     * job in ACKed state, so that the job can be evicted when we are
     * confident the job will not be reissued. */
    if (job->nodes_confirmed == NULL) {
        job->nodes_confirmed = dictCreate(&clusterNodesDictType,NULL);
        dictAdd(job->nodes_confirmed,myself->name,myself);
    }

    /* Check ASAP if we already reached all the nodes. This special case
     * here is mainly useful when the job replication factor is 1, so
     * there is no SETACK to send, nor GOTCAK to receive.
     *
     * Also check if this is a dummy ACK but the cluster size is now 1:
     * in such a case we don't have other nodes to send SETACK to, we can
     * just remove the ACK. Note that dummy ACKs are not created at all
     * if the cluster size is 1, but this code path may be entered as a result
     * of the cluster getting resized to a single node. */
    int all_nodes_reached =
        (!dummy_ack) &&
        (dictSize(job->nodes_delivered) == dictSize(job->nodes_confirmed));
    int dummy_ack_single_node = dummy_ack && server.cluster->size == 1;

    if (all_nodes_reached || dummy_ack_single_node) {
        serverLog(LL_VERBOSE,
            "Deleting %.48s: all nodes reached in tryJobGC()",
            job->id);
        unregisterJob(job);
        freeJob(job);
        return;
    }

    /* Send a SETACK message to all the nodes that may have a message but are
     * still not listed in the nodes_confirmed hash table. However if this
     * is a dummy ACK (created by ACKJOB command acknowledging a job we don't
     * know) we have to broadcast the SETACK to everybody in search of the
     * owner. */
    dict *targets = dictSize(job->nodes_delivered) == 0 ?
                    server.cluster->nodes : job->nodes_delivered;
    dictForeach(targets,de)
        clusterNode *node = dictGetVal(de);
        if (dictFind(job->nodes_confirmed,node->name) == NULL)
            clusterSendSetAck(node,job);
    dictEndForeach
}
Exemple #30
0
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));
}