• 博客访问： 1356833
• 博文数量： 172
• 博客积分： 0
• 博客等级： 民兵
• 技术积分： 2251
• 用 户 组： 普通用户
• 注册时间： 2016-12-21 22:26

90后空巢老码农

2021年（14）

2020年（56）

2019年（54）

2018年（47）

2017年（1）

2019-03-26 17:02:32

1. 设置命令

1. #define OBJ_SET_NO_FLAGS 0
2. #define OBJ_SET_NX (1<<0) /* Set if key not exists. */
3. #define OBJ_SET_XX (1<<1) /* Set if key exists. */
4. #define OBJ_SET_EX (1<<2) /* Set if time in seconds is given */
5. #define OBJ_SET_PX (1<<3) /* Set if time in ms in given */

1. /* SET key value [NX] [XX] [EX <seconds>] [PX <milliseconds>] */
2. void setCommand(client *c) {
3.     int j;
4.     robj *expire = NULL;
5.     int unit = UNIT_SECONDS;
6.     int flags = OBJ_SET_NO_FLAGS;

7.     for (j = 3; j < c->argc; j++) {
8.         char *a = c->argv[j]->ptr;
9.         robj *next = (j == c->argc-1) ? NULL : c->argv[j+1];

10.         if ((a[0] == 'n' || a[0] == 'N') &&
11.             (a[1] == 'x' || a[1] == 'X') && a[2] == '\0' &&
12.             !(flags & OBJ_SET_XX))
13.         {
14.             flags |= OBJ_SET_NX;
15.         } else if ((a[0] == 'x' || a[0] == 'X') &&
16.                    (a[1] == 'x' || a[1] == 'X') && a[2] == '\0' &&
17.                    !(flags & OBJ_SET_NX))
18.         {
19.             flags |= OBJ_SET_XX;
20.         } else if ((a[0] == 'e' || a[0] == 'E') &&
21.                    (a[1] == 'x' || a[1] == 'X') && a[2] == '\0' &&
22.                    !(flags & OBJ_SET_PX) && next)
23.         {
24.             flags |= OBJ_SET_EX;
25.             unit = UNIT_SECONDS;
26.             expire = next;
27.             j++;
28.         } else if ((a[0] == 'p' || a[0] == 'P') &&
29.                    (a[1] == 'x' || a[1] == 'X') && a[2] == '\0' &&
30.                    !(flags & OBJ_SET_EX) && next)
31.         {
32.             flags |= OBJ_SET_PX;
33.             unit = UNIT_MILLISECONDS;
34.             expire = next;
35.             j++;
36.         } else {
38.             return;
39.         }
40.     }

41.     c->argv[2] = tryObjectEncoding(c->argv[2]);
42.     setGenericCommand(c,flags,c->argv[1],c->argv[2],expire,unit,NULL,NULL);
43. }

1. void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire, int unit, robj *ok_reply, robj *abort_reply) {
2.     long long milliseconds = 0; /* initialized to avoid any harmness warning */

3.     if (expire) {
4.         if (getLongLongFromObjectOrReply(c, expire, &milliseconds, NULL) != C_OK)
5.             return;
6.         if (milliseconds <= 0) {
8.             return;
9.         }
10.         if (unit == UNIT_SECONDS) milliseconds *= 1000;
11.     }

12.     if ((flags & OBJ_SET_NX && lookupKeyWrite(c->db,key) != NULL) ||
13.         (flags & OBJ_SET_XX && lookupKeyWrite(c->db,key) == NULL))
14.     {
16.         return;
17.     }
18.     setKey(c->db,key,val);
19.     server.dirty++;
20.     if (expire) setExpire(c,c->db,key,mstime()+milliseconds);
21.     notifyKeyspaceEvent(NOTIFY_STRING,"set",key,c->db->id);
22.     if (expire) notifyKeyspaceEvent(NOTIFY_GENERIC,
23.         "expire",key,c->db->id);
25. }

get操作就相对没那么复杂，只需要调用底层的查找就行了

1. int getGenericCommand(client *c) {
2.     robj *o;

3.     if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL)
4.         return C_OK;

5.     if (o->type != OBJ_STRING) {