Implements LPUSH/RPUSH/LPUSHX/RPUSHX. * 'xx': push if key exists. */
| 224 | /* Implements LPUSH/RPUSH/LPUSHX/RPUSHX. |
| 225 | * 'xx': push if key exists. */ |
| 226 | void pushGenericCommand(client *c, int where, int xx) { |
| 227 | int j; |
| 228 | |
| 229 | for (j = 2; j < c->argc; j++) { |
| 230 | if (sdslen(szFromObj(c->argv[j])) > LIST_MAX_ITEM_SIZE) { |
| 231 | addReplyError(c, "Element too large"); |
| 232 | return; |
| 233 | } |
| 234 | } |
| 235 | |
| 236 | robj *lobj = lookupKeyWrite(c->db, c->argv[1]); |
| 237 | if (checkType(c,lobj,OBJ_LIST)) return; |
| 238 | if (!lobj) { |
| 239 | if (xx) { |
| 240 | addReply(c, shared.czero); |
| 241 | return; |
| 242 | } |
| 243 | |
| 244 | lobj = createQuicklistObject(); |
| 245 | quicklistSetOptions((quicklist*)ptrFromObj(lobj), g_pserver->list_max_ziplist_size, |
| 246 | g_pserver->list_compress_depth); |
| 247 | dbAdd(c->db,c->argv[1],lobj); |
| 248 | } |
| 249 | |
| 250 | for (j = 2; j < c->argc; j++) { |
| 251 | listTypePush(lobj,c->argv[j],where); |
| 252 | g_pserver->dirty++; |
| 253 | } |
| 254 | |
| 255 | addReplyLongLong(c, listTypeLength(lobj)); |
| 256 | |
| 257 | const char *event = (where == LIST_HEAD) ? "lpush" : "rpush"; |
| 258 | signalModifiedKey(c,c->db,c->argv[1]); |
| 259 | notifyKeyspaceEvent(NOTIFY_LIST,event,c->argv[1],c->db->id); |
| 260 | } |
| 261 | |
| 262 | /* LPUSH <key> <element> [<element> ...] */ |
| 263 | void lpushCommand(client *c) { |
no test coverage detected