// LTRIM key start stop // LTRIM命令实现 void ltrimCommand(client *c) { robj *o; long start, end, llen, ltrim, rtrim; //将字符串类型起始地址start和结束地址end转换为long类型保存在start和end中 //如果任意失败,则直接返回 if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != C_OK) || (getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != C_OK)) return; // 以读操作取出key大小的value值,如果value对象不是列表类型,直接返回 if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.ok)) == NULL || checkType(c,o,OBJ_LIST)) return; //获取列表元素数量 llen = listTypeLength(o); /* convert negative indexes */ // 将负数范围转换成合法范围 if (start < 0) start = llen+start; if (end < 0) end = llen+end; if (start < 0) start = 0; /* Invariant: start >= 0, so this test will be true when end < 0. * The range is empty when start > end or start >= length. */ //不合理的范围,移除所有的元素 if (start > end || start >= llen) { /* Out of range start or start > end result in empty list */ ltrim = llen; rtrim = 0; } else { if (end >= llen) end = llen-1; //end值不能超过元素个数 ltrim = start; //左边界 rtrim = llen-end-1; //右边界 } /* Remove list elements to perform the trim */ //只对编码为quicklist类型的value对象操作 if (o->encoding == OBJ_ENCODING_QUICKLIST) { quicklistDelRange(o->ptr,0,ltrim); //删除左边界以左的所有元素 quicklistDelRange(o->ptr,-rtrim,rtrim); //删除左边界以右的所有元素 } else { serverPanic("Unknown list encoding"); } //发送"ltrim"事件通知 notifyKeyspaceEvent(NOTIFY_LIST,"ltrim",c->argv[1],c->db->id); //如果将所有元素全部删除完了 if (listTypeLength(o) == 0) { //从数据库中删除该key dbDelete(c->db,c->argv[1]); //发送"del"时间通知 notifyKeyspaceEvent(NOTIFY_GENERIC,"del",c->argv[1],c->db->id); } //当数据库的键被改动,则会调用该函数发送信号 signalModifiedKey(c->db,c->argv[1]); //更新脏键 server.dirty++; //发送ok信息给client addReply(c,shared.ok); }
void ltrimCommand(client *c) { robj *o; long start, end, llen, ltrim, rtrim; if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != C_OK) || (getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != C_OK)) return; if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.ok)) == NULL || checkType(c,o,OBJ_LIST)) return; llen = listTypeLength(o); /* convert negative indexes */ if (start < 0) start = llen+start; if (end < 0) end = llen+end; if (start < 0) start = 0; /* Invariant: start >= 0, so this test will be true when end < 0. * The range is empty when start > end or start >= length. */ if (start > end || start >= llen) { /* Out of range start or start > end result in empty list */ ltrim = llen; rtrim = 0; } else { if (end >= llen) end = llen-1; ltrim = start; rtrim = llen-end-1; } /* Remove list elements to perform the trim */ if (o->encoding == OBJ_ENCODING_QUICKLIST) { quicklistDelRange(o->ptr,0,ltrim); quicklistDelRange(o->ptr,-rtrim,rtrim); } else { serverPanic("Unknown list encoding"); } notifyKeyspaceEvent(NOTIFY_LIST,"ltrim",c->argv[1],c->db->id); if (listTypeLength(o) == 0) { dbDelete(c->db,c->argv[1]); notifyKeyspaceEvent(NOTIFY_GENERIC,"del",c->argv[1],c->db->id); } signalModifiedKey(c->db,c->argv[1]); server.dirty++; addReply(c,shared.ok); }