MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / spopWithCountCommand

Function spopWithCountCommand

src/t_set.cpp:462–603  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

460#define SPOP_MOVE_STRATEGY_MUL 5
461
462void spopWithCountCommand(client *c) {
463 long l;
464 unsigned long count, size;
465 robj *set;
466
467 /* Get the count argument */
468 if (getPositiveLongFromObjectOrReply(c,c->argv[2],&l,NULL) != C_OK) return;
469 count = (unsigned long) l;
470
471 /* Make sure a key with the name inputted exists, and that it's type is
472 * indeed a set. Otherwise, return nil */
473 if ((set = lookupKeyWriteOrReply(c,c->argv[1],shared.emptyset[c->resp]))
474 == NULL || checkType(c,set,OBJ_SET)) return;
475
476 /* If count is zero, serve an empty set ASAP to avoid special
477 * cases later. */
478 if (count == 0) {
479 addReply(c,shared.emptyset[c->resp]);
480 return;
481 }
482
483 size = setTypeSize(set);
484
485 /* Generate an SPOP keyspace notification */
486 notifyKeyspaceEvent(NOTIFY_SET,"spop",c->argv[1],c->db->id);
487 g_pserver->dirty += (count >= size) ? size : count;
488
489 /* CASE 1:
490 * The number of requested elements is greater than or equal to
491 * the number of elements inside the set: simply return the whole set. */
492 if (count >= size) {
493 /* We just return the entire set */
494 sunionDiffGenericCommand(c,c->argv+1,1,NULL,SET_OP_UNION);
495
496 /* Delete the set as it is now empty */
497 dbDelete(c->db,c->argv[1]);
498 notifyKeyspaceEvent(NOTIFY_GENERIC,"del",c->argv[1],c->db->id);
499
500 /* Propagate this command as a DEL operation */
501 rewriteClientCommandVector(c,2,shared.del,c->argv[1]);
502 signalModifiedKey(c,c->db,c->argv[1]);
503 return;
504 }
505
506 /* Case 2 and 3 require to replicate SPOP as a set of SREM commands.
507 * Prepare our replication argument vector. Also send the array length
508 * which is common to both the code paths. */
509 robj *propargv[3];
510 propargv[0] = shared.srem;
511 propargv[1] = c->argv[1];
512 addReplySetLen(c,count);
513
514 /* Common iteration vars. */
515 const char *sdsele;
516 robj *objele;
517 int encoding;
518 int64_t llele = 0;
519 unsigned long remaining = size-count; /* Elements left after SPOP. */

Callers 1

spopCommandFunction · 0.85

Calls 15

lookupKeyWriteOrReplyFunction · 0.85
checkTypeFunction · 0.85
addReplyFunction · 0.85
setTypeSizeFunction · 0.85
notifyKeyspaceEventFunction · 0.85
sunionDiffGenericCommandFunction · 0.85
dbDeleteFunction · 0.85
signalModifiedKeyFunction · 0.85
addReplySetLenFunction · 0.85
setTypeRandomElementFunction · 0.85

Tested by

no test coverage detected