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; }
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); } }
/* 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; }
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; }
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; } }
/* 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++; }
/* 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); }
/* 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); }
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; }
/* 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"); } }
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; }
/* 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; }
/* 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); }
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; }
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); } }
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; }
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; }
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; } }
/* 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; } }
/* 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); }
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 }
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; }
/* 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; } }
/* 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; }
/* 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 }
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)); }