Beispiel #1
0
felist *listLast(felist *l) {
  felist *t, *o;

  t = l;
  while ((o = listNext(t)) != NULL) t = o;
  return t;
}  
Beispiel #2
0
/* Watch for the specified key */
void watchForKey(redisClient *c, robj *key) {
    list *clients = NULL;
    listIter li;
    listNode *ln;
    watchedKey *wk;

    /* Check if we are already watching for this key */
    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 */
    }
    /* This key is not already watched in this DB. Let's add it */
    clients = dictFetchValue(c->db->watched_keys,key);
    if (!clients) { 
        clients = listCreate();
        dictAdd(c->db->watched_keys,key,clients);
        incrRefCount(key);
    }
    listAddNodeTail(clients,c);
    /* Add the new key to the lits of keys watched by this client */
    wk = zmalloc(sizeof(*wk));
    wk->key = key;
    wk->db = c->db;
    incrRefCount(key);
    listAddNodeTail(c->watched_keys,wk);
}
Beispiel #3
0
void replicationFeedMonitors(list *monitors, int dictid, robj **argv, int argc) {
    listNode *ln;
    listIter li;
    int j;
    sds cmdrepr = sdsnew("+");
    robj *cmdobj;
    struct timeval tv;

    gettimeofday(&tv,NULL);
    cmdrepr = sdscatprintf(cmdrepr,"%ld.%06ld ",(long)tv.tv_sec,(long)tv.tv_usec);
    if (dictid != 0) cmdrepr = sdscatprintf(cmdrepr,"(db %d) ", dictid);

    for (j = 0; j < argc; j++) {
        if (argv[j]->encoding == REDIS_ENCODING_INT) {
            cmdrepr = sdscatprintf(cmdrepr, "\"%ld\"", (long)argv[j]->ptr);
        } else {
            cmdrepr = sdscatrepr(cmdrepr,(char*)argv[j]->ptr,
                        sdslen(argv[j]->ptr));
        }
        if (j != argc-1)
            cmdrepr = sdscatlen(cmdrepr," ",1);
    }
    cmdrepr = sdscatlen(cmdrepr,"\r\n",2);
    cmdobj = createObject(REDIS_STRING,cmdrepr);

    listRewind(monitors,&li);
    while((ln = listNext(&li))) {
        redisClient *monitor = ln->value;
        addReply(monitor,cmdobj);
    }
    decrRefCount(cmdobj);
}
void replicationFeedSlaves(list *slaves, int dictid, robj **argv, int argc) {
    listNode *ln;
    listIter li;
    int j;

    listRewind(slaves,&li);
    while((ln = listNext(&li))) {
        redisClient *slave = ln->value;

        /* Don't feed slaves that are still waiting for BGSAVE to start */
        if (slave->replstate == REDIS_REPL_WAIT_BGSAVE_START) continue;

        /* Feed slaves that are waiting for the initial SYNC (so these commands
         * are queued in the output buffer until the intial SYNC completes),
         * or are already in sync with the master. */
        if (slave->slaveseldb != dictid) {
            robj *selectcmd;

            if (dictid >= 0 && dictid < REDIS_SHARED_SELECT_CMDS) {
                selectcmd = shared.select[dictid];
                incrRefCount(selectcmd);
            } else {
                selectcmd = createObject(REDIS_STRING,
                    sdscatprintf(sdsempty(),"select %d\r\n",dictid));
            }
            addReply(slave,selectcmd);
            decrRefCount(selectcmd);
            slave->slaveseldb = dictid;
        }
        addReplyMultiBulkLen(slave,argc);
        for (j = 0; j < argc; j++) addReplyBulk(slave,argv[j]);
    }
}
Beispiel #5
0
uint8_t Calendar::listForDay(uint8_t maxNumber, Event::Occurrence intoArray[], const DateTime & dt)
{
	DateTime startOfDay = dt.startOfDay();
	DateTime justBeforeDayStart = startOfDay - Chronos::Span::Seconds(1);
	// Event::Occurrence * allVals = new Event::Occurrence[maxNumber];
	/*if (! allVals)
	{
		CHRONOS_DEBUG_OUTLN("listForDay: Couldn't allocate space for list?");
		return 0;
	}
	*/


	uint8_t numNext = listNext(maxNumber, intoArray, justBeforeDayStart);
	uint8_t numFound = 0;
	for (uint8_t i=0; i< numNext; i++)
	{

		if (intoArray[i].start.sameDateAs(startOfDay))
		{
			numFound++;
		}
	}

	return numFound;

}
Beispiel #6
0
/// 复制整个链表
list *listDup(list *orig)
{
    list *copy;
    listIter *iter;
    listNode *node;

    if ((copy = listCreate()) == NULL)
        return NULL;
    copy->dup = orig->dup;
    copy->free = orig->free;
    copy->match = orig->match;
    iter = listGetIterator(orig, AL_START_HEAD);
    while((node = listNext(iter)) != NULL) {
        void *value;

        if (copy->dup) {
            value = copy->dup(node->value);
            if (value == NULL) {
                listRelease(copy);
                listReleaseIterator(iter);
                return NULL;
            }
        } else
            value = node->value;
        if (listAddNodeTail(copy, value) == NULL) {
            listRelease(copy);
            listReleaseIterator(iter);
            return NULL;
        }
    }
    listReleaseIterator(iter);
    return copy;
}
Beispiel #7
0
/* 关键字搜索Node结点此时用到了list的match方法了 */
listNode *listSearchKey(list *list, void *key)
{
    listIter *iter;
    listNode *node;
	
	//获取迭代器
    iter = listGetIterator(list, AL_START_HEAD);
    while((node = listNext(iter)) != NULL) {
    	//遍历循环
        if (list->match) {
        	//如果定义了list的match方法,则调用match方法
            if (list->match(node->value, key)) {
            	//如果方法返回true,则代表找到结点,释放迭代器
                listReleaseIterator(iter);
                return node;
            }
        } else {
        	//如果没有定义list 的match方法,则直接比较函数指针
            if (key == node->value) {
            	//如果相等,则代表找到结点,释放迭代器
                listReleaseIterator(iter);
                return node;
            }
        }
    }
    listReleaseIterator(iter);
    return NULL;
}
Beispiel #8
0
/* Duplicate the whole list. On out of memory NULL is returned.
 * On success a copy of the original list is returned.
 *
 * The 'Dup' method set with listSetDupMethod() function is used
 * to copy the node value. Otherwise the same pointer value of
 * the original node is used as value of the copied node.
 *
 * The original list both on success or error is never modified. */
list *listDup(list *orig)
{
    list *copy;
    listIter iter;
    listNode *node;

    if ((copy = listCreate()) == NULL)
        return NULL;
    copy->dup = orig->dup;
    copy->free = orig->free;
    copy->match = orig->match;
    listRewind(orig, &iter);
    while((node = listNext(&iter)) != NULL) {
        void *value;

        if (copy->dup) {
            value = copy->dup(node->value);
            if (value == NULL) {
                listRelease(copy);
                return NULL;
            }
        } else
            value = node->value;
        if (listAddNodeTail(copy, value) == NULL) {
            listRelease(copy);
            return NULL;
        }
    }
    return copy;
}
Beispiel #9
0
void closeTimedoutClients(void) {
    redisClient *c;
    listNode *ln;
    time_t now = time(NULL);
    listIter li;

    listRewind(server.clients,&li);
    while ((ln = listNext(&li)) != NULL) {
        c = listNodeValue(ln);
        if (server.maxidletime &&
            !(c->flags & REDIS_SLAVE) &&    /* no timeout for slaves */
            !(c->flags & REDIS_MASTER) &&   /* no timeout for masters */
            dictSize(c->pubsub_channels) == 0 && /* no timeout for pubsub */
            listLength(c->pubsub_patterns) == 0 &&
            (now - c->lastinteraction > server.maxidletime))
        {
            redisLog(REDIS_VERBOSE,"Closing idle client");
            freeClient(c);
        } else if (c->flags & REDIS_BLOCKED) {
            if (c->blockingto != 0 && c->blockingto < now) {
                addReply(c,shared.nullmultibulk);
                unblockClientWaitingData(c);
            }
        }
    }
}
Beispiel #10
0
list *listSearchKey(list *list, void *key)
/*{{{*/
{
    listIter *iter;
    listNode *node;

    iter = listGetIterator(list, AL_START_HEAD);
    while((node = listNext(iter)) != NULL)
    {
        if(list->match)
        {
            if(list->match(node->value, key))
            {
                listReleaseIterator(iter);
                return node;
            }
        }
        else
        {
            //如果match函数不存在,理论上讲是比较不了
            //这时候只需要看地址就行了
            if(key == node->value)
            {
                listReleaseIterator(iter);
                return node;
            }
        }
    }
    listReleaseIterator(iter);
    return NULL;
}
Beispiel #11
0
/* Search the list for a node matching a given key.
 * The match is performed using the 'match' method
 * set with listSetMatchMethod(). If no 'match' method
 * is set, the 'value' pointer of every node is directly
 * compared with the 'key' pointer.
 *
 * On success the first matching node pointer is returned
 * (search starts from head). If no matching node exists
 * NULL is returned. */
listNode *listSearchKey(list *pList, void *key)
{
    listIter *iter = listGetIterator(pList, DL_START_HEAD);
    listNode *node = listNext(iter);
    while(node != NULL)
    {
        if (pList->match)
        {
            if (pList->match(node->value, key))
            {
                listReleaseIterator(iter);
                return node;
            }
        }
        else
        {
            if (key == node->value)
            {
                listReleaseIterator(iter);
                return node;
            }
        }
    }
    listReleaseIterator(iter);
    return NULL;
}
Beispiel #12
0
/*
 * Write a log message out to all output channels.
 */
static void log_output(Logger *logger)
{
    LOG_Output *out;

    for (out = listHead(&logger->outputs); out; out = listNext(out)) {
        pthread_mutex_lock(&out->output);

        switch(out->type) {
        case LOG_OT_UDP:
        case LOG_OT_TCP:
        case LOG_OT_FD:
            tcpWrite(out->u.fd, bufGet(&logger->scratch),
                    bufLen(&logger->scratch));
            break;
        case LOG_OT_FILE:
        case LOG_OT_FP:
            fwrite(bufGet(&logger->scratch),
                    bufLen(&logger->scratch), 1, out->u.fp);
            fflush(out->u.fp);
            break;
        case LOG_OT_SYSLOG:
            syslog(out->u.priority, "%s", bufGet(&logger->scratch));
            break;
        }

        pthread_mutex_unlock(&out->output);
    }
}
Beispiel #13
0
void freeClient(vuiClient *c) {
    listNode *ln;
    listIter *it;
    cJSON *json;

    /* Free the query buffer */
    sdsfree(c->querybuf);
    sdsfree(c->querymsg);
    sdsfree(c->res.body);
    sdsfree(c->res.reason);
    sdsfree(c->res.buf);

    /* Close socket, unregister events, and remove list of replies and
     * accumulated arguments. */
    if (c->fd != -1) {
        aeDeleteFileEvent(server.el,c->fd,AE_READABLE);
        aeDeleteFileEvent(server.el,c->fd,AE_WRITABLE);
        close(c->fd);
    }
    it = listGetIterator(c->jsons, AL_START_HEAD);

    while((ln = listNext(it)))
    {
        json = (cJSON *)ln->value;
        cJSON_Delete(json);
        listDelNode(c->jsons, ln);
    }
    listRelease(c->jsons);
    listReleaseIterator(it);


    zfree(c);
    server.client = NULL;
}
Beispiel #14
0
static void calculate_bm25(fts_t *fts, list *indices, dict_t *scores) {
    listIter *iter;
    listNode *node;
    unsigned long doc_size = fts_size(fts);
    unsigned long list_size = listLength(indices);
    doc_size = doc_size ? doc_size : 1;
    double avgdl = (fts->len * 1.0) / doc_size;

    iter = listGetIterator(indices, AL_START_HEAD);
    while((node = listNext(iter)) != NULL) {
        index_item_t *idx = node->value;
        int dl = idx->doc->len;
        fts_doc_score_t *fds = dict_get(scores, idx->doc->title->ptr);
        if (!fds) {
            fds = rr_malloc(sizeof(*fds));
            fds->doc = idx->doc;
            fds->score = .0f;
            dict_set(scores, idx->doc->title->ptr, fds);
        }
        double idf = log((doc_size - list_size + 0.5) / (list_size + 0.5));
        double tf = idx->tf * (BM25_K + 1) / (idx->tf + BM25_K * (1 - BM25_B + BM25_B*dl/avgdl));
        fds->score += tf * idf;
    }
    listReleaseIterator(iter);
}
Beispiel #15
0
/*
 *Function   : mlistNext
 *Description: define 'next'element in the list in mlist
 *Parameters : hlist - mlist handle
 *             list  - list number to get 'next' element
 *             location - location after which to get 'next' element
 *Return     : 'next' element in the list
 */
int     mlistNext       (HLIST hlist, int list, int location)
{
    mListDesc *mlist=(mListDesc*)listGetElem(hlist, list);
    if (!mlist) return RVERROR;
    if (location==mlist->tail) return RVERROR;
    return listNext(hlist, location);
}
Beispiel #16
0
/* Search the list for a node matching a given key.
 * The match is performed using the 'match' method
 * set with listSetMatchMethod(). If no 'match' method
 * is set, the 'value' pointer of every node is directly
 * compared with the 'key' pointer.
 *
 * On success the first matching node pointer is returned
 * (search starts from head). If no matching node exists
 * NULL is returned. */
listNode *listSearchKey(list *list, void *key)
{
    listIter *iter;
    listNode *node;

    //遍历整个链表
    iter = listGetIterator(list, AL_START_HEAD);
    while((node = listNext(iter)) != NULL) {
        //如果有比较的回调函数,调用该函数
        if (list->match) {
            if (list->match(node->value, key)) {
                listReleaseIterator(iter);
                return node;
            }
        } else {
            //否则比较两个value是否相同
            if (key == node->value) {
                listReleaseIterator(iter);
                return node;
            }
        }
    }
    //也就是默认的match函数就是比较两个value是否相等
    listReleaseIterator(iter);
    return NULL;
}
// 撤销对这个客户端的所有 WATCH
// 清除 EXEC dirty FLAG 的任务由调用者完成
void unwatchAllKeys(redisClient *c) {
    listIter li;
    listNode *ln;

    // 没有 WATCHED KEY ,直接返回
    if (listLength(c->watched_keys) == 0) return;

    listRewind(c->watched_keys,&li);
    while((ln = listNext(&li))) {
        list *clients;
        watchedKey *wk;

        /* Lookup the watched key -> clients list and remove the client
         * from the list */
        // 将当前客户端从监视 KEY 的链表中移除
        wk = listNodeValue(ln);
        clients = dictFetchValue(wk->db->watched_keys, wk->key);
        redisAssertWithInfo(c,NULL,clients != NULL);
        listDelNode(clients,listSearchKey(clients,c));

        /* Kill the entry at all if this was the only client */
        // 如果监视 KEY 的只有这个客户端
        // 那么将链表从字典中删除
        if (listLength(clients) == 0)
            dictDelete(wk->db->watched_keys, wk->key);

        /* Remove this watched key from the client->watched list */
        // 还需要将 KEY 从 client->watched_keys 链表中移除
        listDelNode(c->watched_keys,ln);
        decrRefCount(wk->key);
        zfree(wk);
    }
}
Beispiel #18
0
int luaworkDoDir(lua_State *L,const char *path, char *err) {
    int ret = UGOK;
    sds relpath = sdsempty();
    list *queue = listCreate();
    listNode *node=NULL;
    listIter *iter = NULL;

    if (xfilelistdir(path, "*.lua", queue) == UGERR) {
        luaworkSetError(err, "list files for %s failed", path);
        ret = UGERR;
        goto END;
    }

    iter = listGetIterator(queue, AL_START_HEAD);

    while ((node=listNext(iter))!=NULL) {
        const char *filename = (char *) (node->value);
        sdsclear(relpath);
        relpath = sdscatprintf(relpath, "%s/%s", path, filename);
        ret = luaworkDoFile(L, relpath, err);
        if (ret != UGOK) break;
    }

    listReleaseIterator(iter);
END:
    listRelease(queue);
    sdsfree(relpath);
    return ret;

}
Beispiel #19
0
void aio_submit_queue()
{
    int rv;
    struct aiocb *cb;
    if (0 == listLength(aio_queue))
        return;

    listIter *it;
    listNode *nd;
    it = listGetIterator(aio_queue, AL_START_HEAD);
    while ((nd = listNext(it)))
    {
        cb = (struct aiocb *)nd->value;
        cb->retries += 1;
        rv = aio_submit(cb);
        if (0 == rv)
        {
            listDelNode(aio_queue, nd);
        }
        else if (-2 == rv)
        {
            break;
        }

    }

end:
    zfree(it);

}
/*	取消客户端所订阅的所有模式,最后返回退订的模式数量	*/
int pubsubUnsubscribeAllPatterns(redisClient *c, int notify) {
    listNode *ln;
    listIter li;
    int count = 0;

    // 获取c->pubsub_patterns链表迭代器
    listRewind(c->pubsub_patterns,&li);
    // 遍历客户端订阅的模式链表,逐一退订
    while ((ln = listNext(&li)) != NULL) {
        robj *pattern = ln->value;
        // 统计退订的模式数量
        count += pubsubUnsubscribePattern(c,pattern,notify);
    }

    // 如果count == 0,说明客户端没有订阅任何模式,回复客户端
    if (notify && count == 0) {
        /* We were subscribed to nothing? Still reply to the client. */
        addReply(c,shared.mbulkhdr[3]);
        addReply(c,shared.punsubscribebulk);
        addReply(c,shared.nullbulk);
        addReplyLongLong(c,dictSize(c->pubsub_channels)+
                       listLength(c->pubsub_patterns));
    }
    return count;
}
// 取消客户端对所有的键的监视,清理 EXEC dirty 标识状态由调用者决定
void unwatchAllKeys(client *c) {
    listIter li;
    listNode *ln;
    // 如果客户端没有监视key则直接返回
    if (listLength(c->watched_keys) == 0) return;
    listRewind(c->watched_keys,&li);
    // 遍历客户端监视的key
    while((ln = listNext(&li))) {
        list *clients;
        watchedKey *wk;

        /* Lookup the watched key -> clients list and remove the client
         * from the list */
        wk = listNodeValue(ln);
        // 从数据库中的watched_keys字典中查找出监视key的client
        clients = dictFetchValue(wk->db->watched_keys, wk->key);
        serverAssertWithInfo(c,NULL,clients != NULL);
        // 从client的链表中删除当前client节点
        listDelNode(clients,listSearchKey(clients,c));
        /* Kill the entry at all if this was the only client */
        // 如果client链表为空,标识给key没有被监视
        if (listLength(clients) == 0)
            // 从数据库的watched_keys中删除该key
            dictDelete(wk->db->watched_keys, wk->key);
        /* Remove this watched key from the client->watched list */
        // 从客户端的watched_keys中删除该节点
        listDelNode(c->watched_keys,ln);
        decrRefCount(wk->key);
        zfree(wk);
    }
}
Beispiel #22
0
void* listRemove(SList* list, int index)
{
	void* res = NULL;
	if(list)
	{
		listHead(list);
		if(!listEmpty(list))
		{
			if(index == 0)
			{
				SListNode* to_delete = list->head;
				list->head = list->head->next;
				res = to_delete->data;
				free(to_delete);
			}
			else
			{
				int i = 1;
				while(listNext(list) && i != index-1) ++i;

				if( i == index-1)
				{
					// l'element existe
					SListNode* to_delete = list->curr->next;
					list->curr->next = list->curr->next->next;
					res = to_delete->data;
					free(to_delete);
				}
			}
		}
	}
	return res;
}
/* Unsubscribe from all the patterns. Return the number of patterns the
 * client was subscribed from. 
 *
 * 退订客户端 c 订阅的所有模式。
 *
 * 返回被退订模式的数量。
 */
int pubsubUnsubscribeAllPatterns(redisClient *c, int notify) {
    listNode *ln;
    listIter li;
    int count = 0;

    // 迭代客户端订阅模式的链表
    listRewind(c->pubsub_patterns,&li);
    while ((ln = listNext(&li)) != NULL) {
        robj *pattern = ln->value;

        // 退订,并计算退订数
        count += pubsubUnsubscribePattern(c,pattern,notify);
    }

    // 如果在执行这个函数时,客户端没有订阅任何模式,
    // 那么向客户端发送回复
    if (notify && count == 0) {
        /* We were subscribed to nothing? Still reply to the client. */
        addReply(c,shared.mbulkhdr[3]);
        addReply(c,shared.punsubscribebulk);
        addReply(c,shared.nullbulk);
        addReplyLongLong(c,dictSize(c->pubsub_channels)+
                       listLength(c->pubsub_patterns));
    }

    // 退订总数
    return count;
}
Beispiel #24
0
/* Remove the 'key' from the list of blocked keys for a given client.
 *
 * The function returns 1 when there are no longer blocking keys after
 * the current one was removed (and the client can be unblocked). */
int dontWaitForSwappedKey(redisClient *c, robj *key) {
    list *l;
    listNode *ln;
    listIter li;
    struct dictEntry *de;

    /* The key object might be destroyed when deleted from the c->io_keys
     * list (and the "key" argument is physically the same object as the
     * object inside the list), so we need to protect it. */
    incrRefCount(key);

    /* Remove the key from the list of keys this client is waiting for. */
    listRewind(c->io_keys,&li);
    while ((ln = listNext(&li)) != NULL) {
        if (equalStringObjects(ln->value,key)) {
            listDelNode(c->io_keys,ln);
            break;
        }
    }
    redisAssert(ln != NULL);

    /* Remove the client form the key => waiting clients map. */
    de = dictFind(c->db->io_keys,key);
    redisAssert(de != NULL);
    l = dictGetEntryVal(de);
    ln = listSearchKey(l,c);
    redisAssert(ln != NULL);
    listDelNode(l,ln);
    if (listLength(l) == 0)
        dictDelete(c->db->io_keys,key);

    decrRefCount(key);
    return listLength(c->io_keys) == 0;
}
Beispiel #25
0
/* compare should return -1 on lesser, 0 on equal and 1 on greater */
List listGetVal(List root, void* val, int (*compare)(const void*, const void*))
{
    List element = listBegin(root);
    for (; element && element->v && compare(element->v, val) != 0; element = listNext(element))
        ;
    return element;
}
int _msg_check(const char *file, int line, rmtContext *ctx, struct msg *msg, int panic)
{
    struct mbuf *mbuf;
    listIter *iter;
    listNode *node;
    uint32_t total_mbuf_len = 0;
    int err = 0;
    
    if (msg == NULL) {
        return RMT_ERROR;
    }

    //check msg length
    iter = listGetIterator(msg->data, AL_START_HEAD);
    while ((node = listNext(iter)) != NULL) {
        mbuf = listNodeValue(node);
        total_mbuf_len += mbuf_length(mbuf);

        if (mbuf->pos < mbuf->start) {
            _log(file, line, 0, "MSG CHECK Error: mbuf->pos(%p) < mbuf->start(%p)", 
                mbuf->pos, mbuf->start);
            err = 1;
        }

        if (mbuf->pos > mbuf->last) {
            _log(file, line, 0, "MSG CHECK Error: mbuf->pos(%p) > mbuf->last(%p)", 
                mbuf->pos, mbuf->last);
            err = 1;
        }
    }
    listReleaseIterator(iter);
    
    if (msg->mlen != total_mbuf_len) {
        _log(file, line, 0, "MSG CHECK Error: msg->mlen(%u) != total_mbuf_len(%u)", 
            msg->mlen, total_mbuf_len);
        err = 1;
    }

    if (msg->request == 1) {
        if (memcmp(ctx->cmd, RMT_CMD_REDIS_MIGRATE, 
            MIN(sdslen(ctx->cmd),strlen(RMT_CMD_REDIS_MIGRATE))) == 0 && 
            msg->noreply != ctx->noreply) {
            _log(file, line, 0, "MSG CHECK Error: msg->noreply(%u) != ctx->noreply(%d)", 
                msg->noreply, ctx->noreply);
            err = 1;
        }
    }

    if (err) goto error;
    
    return RMT_OK;
    
error:
    MSG_DUMP(msg, LOG_ERR, 0);
    if (panic) {
        rmt_stacktrace(1);
        abort();
    }
    return RMT_ERROR;
}
Beispiel #27
0
/* Unwatch all the keys watched by this client. To clean the EXEC dirty
 * flag is up to the caller. */
void unwatchAllKeys(redisClient *c) {
    listIter li;
    listNode *ln;

    if (listLength(c->watched_keys) == 0) return;
    listRewind(c->watched_keys,&li);
    while((ln = listNext(&li))) {
        list *clients;
        watchedKey *wk;

        /* Lookup the watched key -> clients list and remove the client
         * from the list */
        wk = listNodeValue(ln);
        clients = dictFetchValue(wk->db->watched_keys, wk->key);
        redisAssert(clients != NULL);
        listDelNode(clients,listSearchKey(clients,c));
        /* Kill the entry at all if this was the only client */
        if (listLength(clients) == 0)
            dictDelete(wk->db->watched_keys, wk->key);
        /* Remove this watched key from the client->watched list */
        listDelNode(c->watched_keys,ln);
        decrRefCount(wk->key);
        zfree(wk);
    }
}
Beispiel #28
0
/*
 *Function   : mlistHead
 *Description: define 1st (head) element in the list in mlist
 *Parameters : hlist - mlist handle
 *             list  - list number to get 'next' element
 *Return     : 1st (head) element in the list
 */
int     mlistHead       (HLIST hlist, int list)
{
    mListDesc *mlist=(mListDesc*)listGetElem(hlist, list);
    if (!mlist) return RVERROR;
    if (!mlist->count) return RVERROR;
    return listNext(hlist, list);
}
Beispiel #29
0
static void glueReplyBuffersIfNeeded(redisClient *c) {
    int copylen = 0;
    char buf[GLUEREPLY_UP_TO];
    listNode *ln;
    listIter li;
    robj *o;

    listRewind(c->reply,&li);
    while((ln = listNext(&li))) {
        int objlen;

        o = ln->value;
        objlen = sdslen(o->ptr);
        if (copylen + objlen <= GLUEREPLY_UP_TO) {
            memcpy(buf+copylen,o->ptr,objlen);
            copylen += objlen;
            listDelNode(c->reply,ln);
        } else {
            if (copylen == 0) return;
            break;
        }
    }
    /* Now the output buffer is empty, add the new single element */
    o = createObject(REDIS_STRING,sdsnewlen(buf,copylen));
    listAddNodeHead(c->reply,o);
}
Beispiel #30
0
felist *listCopy(felist *srcfirstnode, size_t nodesize) {
  felist *prevnode = NULL;
  felist *currnode = srcfirstnode;
  felist *result = NULL;

  if(srcfirstnode == NULL) return NULL;
  
  while(currnode != NULL) {
    felist *newnode = (felist *) malloc(sizeof(felist));
    newnode->prev = prevnode;
    if(prevnode == NULL) { 
      result = newnode;
    }
    else {
      prevnode->next = newnode;
    }
    newnode->next = NULL;
    newnode->node = (void *) malloc(nodesize);
    memcpy(newnode->node, currnode->node, nodesize);
  
    prevnode = newnode;
    currnode = listNext(currnode);
  }
  return result;
}