The zunionInterDiffGenericCommand() function is called in order to implement the * following commands: ZUNION, ZINTER, ZDIFF, ZUNIONSTORE, ZINTERSTORE, ZDIFFSTORE. * * 'numkeysIndex' parameter position of key number. for ZUNION/ZINTER/ZDIFF command, * this value is 1, for ZUNIONSTORE/ZINTERSTORE/ZDIFFSTORE command, this value is 2. * * 'op' SET_OP_INTER, SET_OP_UNION or SET_OP_DIFF. */
| 2573 | * 'op' SET_OP_INTER, SET_OP_UNION or SET_OP_DIFF. |
| 2574 | */ |
| 2575 | void zunionInterDiffGenericCommand(client *c, robj *dstkey, int numkeysIndex, int op) { |
| 2576 | int i, j; |
| 2577 | long setnum; |
| 2578 | int aggregate = REDIS_AGGR_SUM; |
| 2579 | zsetopsrc *src; |
| 2580 | zsetopval zval; |
| 2581 | sds tmp; |
| 2582 | size_t maxelelen = 0, totelelen = 0; |
| 2583 | robj *dstobj; |
| 2584 | zset *dstzset; |
| 2585 | zskiplistNode *znode; |
| 2586 | int withscores = 0; |
| 2587 | |
| 2588 | /* expect setnum input keys to be given */ |
| 2589 | if ((getLongFromObjectOrReply(c, c->argv[numkeysIndex], &setnum, NULL) != C_OK)) |
| 2590 | return; |
| 2591 | |
| 2592 | if (setnum < 1) { |
| 2593 | addReplyErrorFormat(c, |
| 2594 | "at least 1 input key is needed for %s", c->cmd->name); |
| 2595 | return; |
| 2596 | } |
| 2597 | |
| 2598 | /* test if the expected number of keys would overflow */ |
| 2599 | if (setnum > (c->argc-(numkeysIndex+1))) { |
| 2600 | addReplyErrorObject(c,shared.syntaxerr); |
| 2601 | return; |
| 2602 | } |
| 2603 | |
| 2604 | /* read keys to be used for input */ |
| 2605 | src = zcalloc(sizeof(zsetopsrc) * setnum); |
| 2606 | for (i = 0, j = numkeysIndex+1; i < setnum; i++, j++) { |
| 2607 | robj *obj = dstkey ? |
| 2608 | lookupKeyWrite(c->db,c->argv[j]) : |
| 2609 | lookupKeyRead(c->db,c->argv[j]); |
| 2610 | if (obj != NULL) { |
| 2611 | if (obj->type != OBJ_ZSET && obj->type != OBJ_SET) { |
| 2612 | zfree(src); |
| 2613 | addReplyErrorObject(c,shared.wrongtypeerr); |
| 2614 | return; |
| 2615 | } |
| 2616 | |
| 2617 | src[i].subject = obj; |
| 2618 | src[i].type = obj->type; |
| 2619 | src[i].encoding = obj->encoding; |
| 2620 | } else { |
| 2621 | src[i].subject = NULL; |
| 2622 | } |
| 2623 | |
| 2624 | /* Default all weights to 1. */ |
| 2625 | src[i].weight = 1.0; |
| 2626 | } |
| 2627 | |
| 2628 | /* parse optional extra arguments */ |
| 2629 | if (j < c->argc) { |
| 2630 | int remaining = c->argc - j; |
| 2631 | |
| 2632 | while (remaining) { |
no test coverage detected