getrangeCommand这个函数没看的太明白,但大致知道意思:
- void getrangeCommand(client *c) {
- robj *o;
- long long start, end;
- char *str, llbuf[32];
- size_t strlen;
-
- if (getLongLongFromObjectOrReply(c,c->argv[2],&start,NULL) != C_OK)
- return;
- if (getLongLongFromObjectOrReply(c,c->argv[3],&end,NULL) != C_OK)
- return;
- if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptybulk)) == NULL ||
- checkType(c,o,OBJ_STRING)) return;
-
- if (o->encoding == OBJ_ENCODING_INT) {
- str = llbuf;
- strlen = ll2string(llbuf,sizeof(llbuf),(long)o->ptr);
- } else {
- str = o->ptr;
- strlen = sdslen(str);
- }
-
- /* Convert negative indexes */
- if (start < 0 && end < 0 && start > end) {
- addReply(c,shared.emptybulk);
- return;
- }
- if (start < 0) start = strlen+start;
- if (end < 0) end = strlen+end;
- if (start < 0) start = 0;
- if (end < 0) end = 0;
- if ((unsigned long long)end >= strlen) end = strlen-1;
-
- /* Precondition: end >= 0 && end < strlen, so the only condition where
- * nothing can be returned is: start > end. */
- if (start > end || strlen == 0) {
- addReply(c,shared.emptybulk);
- } else {
- addReplyBulkCBuffer(c,(char*)str+start,end-start+1);
- }
- }
-
- void mgetCommand(client *c) {
- int j;
-
- addReplyArrayLen(c,c->argc-1);
- for (j = 1; j < c->argc; j++) {
- robj *o = lookupKeyRead(c->db,c->argv[j]);
- if (o == NULL) {
- addReplyNull(c);
- } else {
- if (o->type != OBJ_STRING) {
- addReplyNull(c);
- } else {
- addReplyBulk(c,o);
- }
- }
- }
- }
-
- void msetGenericCommand(client *c, int nx) {
- int j;
-
- if ((c->argc % 2) == 0) {
- addReplyError(c,"wrong number of arguments for MSET");
- return;
- }
-
- /* Handle the NX flag. The MSETNX semantic is to return zero and don't
- * set anything if at least one key already exists. */
- if (nx) {
- for (j = 1; j < c->argc; j += 2) {
- if (lookupKeyWrite(c->db,c->argv[j]) != NULL) {
- addReply(c, shared.czero);
- return;
- }
- }
- }
-
- for (j = 1; j < c->argc; j += 2) {
- c->argv[j+1] = tryObjectEncoding(c->argv[j+1]);
- setKey(c,c->db,c->argv[j],c->argv[j+1]);
- notifyKeyspaceEvent(NOTIFY_STRING,"set",c->argv[j],c->db->id);
- }
- server.dirty += (c->argc-1)/2;
- addReply(c, nx ? shared.cone : shared.ok);
- }
-
- void msetCommand(client *c) {
- msetGenericCommand(c,0);
- }
-
- void msetnxCommand(client *c) {
- msetGenericCommand(c,1);
- }
-
- void incrDecrCommand(client *c, long long incr) {
- long long value, oldvalue;
- robj *o, *new;
-
- o = lookupKeyWrite(c->db,c->argv[1]);
- if (checkType(c,o,OBJ_STRING)) return;
- if (getLongLongFromObjectOrReply(c,o,&value,NULL) != C_OK) return;
-
- oldvalue = value;
- if ((incr < 0 && oldvalue < 0 && incr < (LLONG_MIN-oldvalue)) ||
- (incr > 0 && oldvalue > 0 && incr > (LLONG_MAX-oldvalue))) {
- addReplyError(c,"increment or decrement would overflow");
- return;
- }
- value += incr;
-
- if (o && o->refcount == 1 && o->encoding == OBJ_ENCODING_INT &&
- (value < 0 || value >= OBJ_SHARED_INTEGERS) &&
- value >= LONG_MIN && value <= LONG_MAX)
- {
- new = o;
- o->ptr = (void*)((long)value);
- } else {
- new = createStringObjectFromLongLongForValue(value);
- if (o) {
- dbOverwrite(c->db,c->argv[1],new);
- } else {
- dbAdd(c->db,c->argv[1],new);
- }
- }
- signalModifiedKey(c,c->db,c->argv[1]);
- notifyKeyspaceEvent(NOTIFY_STRING,"incrby",c->argv[1],c->db->id);
- server.dirty++;
- addReply(c,shared.colon);
- addReply(c,new);
- addReply(c,shared.crlf);
- }