【Redis源碼】mset命令

簡(jiǎn)介
通過(guò)set、setex等命令只能設置單個(gè)字符串到數據庫,當我們想一次性設置多個(gè)字符串時(shí),可以使用mset或msetnx命令來(lái)解決。
格式:
mset key value [key value ...]
msetnx key value [key value ...]
mset 命令
如果某個(gè)給定key已經(jīng)存在,則mset會(huì )將原key的value值覆蓋,而msetnx是當所有的key都不存在時(shí)才可以寫(xiě)入數據庫。mset和msetnx底層都是調用的msetGenericCommand函數,不過(guò)第2個(gè)參數mset的傳參為0,msetnx傳參為1,msetGenericCommand的函數定義如下:
void msetGenericCommand(client *c, int nx)
通過(guò)命令的格式看出,key和value是成對出現的,加上第一個(gè)mset參數,批量設置必須保證命令行參數為奇數。
當nx參數為1時(shí),需要遍歷每個(gè)key在數據庫中是否存在,當有任意一個(gè)key存在時(shí),表示參數不合法,會(huì )報錯退出:
if (nx) {
for (j = 1; j < c->argc; j += 2) {
if (lookupKeyWrite(c->db,c->argv[j]) != NULL) {
addReply(c, shared.czero);
return;
}
}
}
當把多個(gè)key-value設置入數據庫時(shí),同樣為了節省內存考慮,需要調用tryObjectEncoding函數將每個(gè)value編碼。編碼完成之后,依次將key-value添加到數據庫中。注意mset和msetex不能設置超時(shí)時(shí)間,所以程序中不需要考慮expire。
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);
}
評論
0 評論