memcached_1.4.14之process_get_command解析
来源:互联网 发布:ica 似然最大算法 编辑:程序博客网 时间:2024/05/17 05:26
/* ntokens is overwritten here... shrug.. */static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens, bool return_cas) { char *key; size_t nkey; int i = 0; item *it; //需要get的key值 = key_token->value token_t *key_token = &tokens[KEY_TOKEN]; char *suffix; assert(c != NULL); //key_token->value != NULL //遇到command结束标识符'\0'时跳出循环 do { //针对多个key的情况,一个key处理结束时跳出循环 while(key_token->length != 0) { key = key_token->value; nkey = key_token->length; //key最大长度250 if(nkey > KEY_MAX_LENGTH) { out_string(c, "CLIENT_ERROR bad command line format"); return; } it = item_get(key, nkey); //stat详细信息开启 if (settings.detail_enabled) { stats_prefix_record_get(key, nkey, NULL != it); } if (it) { //isize:ilist大小,超出ilist大小时重新分配 if (i >= c->isize) { item **new_list = realloc(c->ilist, sizeof(item *) * c->isize * 2); if (new_list) { c->isize *= 2; c->ilist = new_list; } else {//分配失败,移除it,放入回收槽slot中。 item_remove(it); break; } } /* * Construct the response. Each hit adds three elements to the * outgoing data list: * "VALUE " * key * " " + flags + " " + data length + "\r\n" + data (with \r\n) */ //使用gets命令 if (return_cas) { MEMCACHED_COMMAND_GET(c->sfd, ITEM_key(it), it->nkey, it->nbytes, ITEM_get_cas(it)); /* Goofy mid-flight realloc. */ if (i >= c->suffixsize) { char **new_suffix_list = realloc(c->suffixlist, sizeof(char *) * c->suffixsize * 2); if (new_suffix_list) { c->suffixsize *= 2; c->suffixlist = new_suffix_list; } else { item_remove(it); break; } } suffix = cache_alloc(c->thread->suffix_cache); if (suffix == NULL) { out_string(c, "SERVER_ERROR out of memory making CAS suffix"); item_remove(it); return; } *(c->suffixlist + i) = suffix; //suffix:代表cas的版本号,包括\r\n int suffix_len = snprintf(suffix, SUFFIX_SIZE, " %llu\r\n", (unsigned long long)ITEM_get_cas(it)); //ITEM_suffix(it),指向flag,nsuffix包括flag+data length + \r\n if (add_iov(c, "VALUE ", 6) != 0 || add_iov(c, ITEM_key(it), it->nkey) != 0 || add_iov(c, ITEM_suffix(it), it->nsuffix - 2) != 0 || //减去\r\n,则不换行,版本号紧跟着flags+length add_iov(c, suffix, suffix_len) != 0 || add_iov(c, ITEM_data(it), it->nbytes) != 0) { item_remove(it); break; } } else { MEMCACHED_COMMAND_GET(c->sfd, ITEM_key(it), it->nkey, it->nbytes, ITEM_get_cas(it)); if (add_iov(c, "VALUE ", 6) != 0 || add_iov(c, ITEM_key(it), it->nkey) != 0 || add_iov(c, ITEM_suffix(it), it->nsuffix + it->nbytes) != 0) { item_remove(it); break; } } if (settings.verbose > 1) fprintf(stderr, ">%d sending key %s\n", c->sfd, ITEM_key(it)); /* item_get() has incremented it->refcount for us */ pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.slab_stats[it->slabs_clsid].get_hits++; c->thread->stats.get_cmds++; pthread_mutex_unlock(&c->thread->stats.mutex); item_update(it);//访问时间超过60秒更新下时间,放到LRU header //将it放入ilist,等待返回给client *(c->ilist + i) = it; i++; } else { pthread_mutex_lock(&c->thread->stats.mutex); c->thread->stats.get_misses++; c->thread->stats.get_cmds++; pthread_mutex_unlock(&c->thread->stats.mutex); MEMCACHED_COMMAND_GET(c->sfd, key, nkey, -1, 0); } key_token++; } /* * If the command string hasn't been fully processed, get the next set * of tokens. */ //get多个key时,解析剩余的key if(key_token->value != NULL) { ntokens = tokenize_command(key_token->value, tokens, MAX_TOKENS); key_token = tokens; } } while(key_token->value != NULL); c->icurr = c->ilist; c->ileft = i; if (return_cas) { c->suffixcurr = c->suffixlist; c->suffixleft = i; } if (settings.verbose > 1) fprintf(stderr, ">%d END\n", c->sfd); /* If the loop was terminated because of out-of-memory, it is not reliable to add END\r\n to the buffer, because it might not end in \r\n. So we send SERVER_ERROR instead. */ if (key_token->value != NULL || add_iov(c, "END\r\n", 5) != 0 || (IS_UDP(c->transport) && build_udp_headers(c) != 0)) { out_string(c, "SERVER_ERROR out of memory writing get response"); } else { conn_set_state(c, conn_mwrite); c->msgcurr = 0; } return;}
转载前请标明出处,谢谢!
- memcached_1.4.14之process_get_command解析
- memcached源代码之process_get_command add_msghdr iov
- memcached_1 初始学习
- XML解析之DOM解析
- XML解析之SAX解析
- XML解析之SAX解析
- xml解析之DOM4j解析
- xml解析之pull解析
- XML解析之DOM解析
- xml解析之----DOM解析
- iOS解析之Json解析
- xml解析之pull解析
- XML解析之SAX解析
- XML解析之DOM解析
- Xml 解析之pull解析
- XML解析之DOM解析
- XML解析之SAX解析
- XML解析之jdom解析
- ios从rgb数据生成UIImage
- c++和c#比较
- 解析C# Socket编程实现访问网络的原理
- 2012国内外云实践之企业总名单---job
- 使用STL的next_permutation函数生成全排列(C++)
- memcached_1.4.14之process_get_command解析
- Lucene学习笔记(3)-索引操作
- Velocity中的ComparisonDateTool、MathTool、NumberTool、SortTool、EscapeTool工具
- android 调试方法
- sql server 2012新分页方式
- lstrlenWInternal链接错误
- MVC的Action执行前后的四个事件
- IOS 控件 UIButton button
- XeTeX 使用 bibtex 参考文献