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

Function zdiffAlgorithm2

src/t_zset.cpp:2448–2503  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2446
2447
2448static void zdiffAlgorithm2(zsetopsrc *src, long setnum, zset *dstzset, size_t *maxelelen, size_t *totelelen) {
2449 /* DIFF Algorithm 2:
2450 *
2451 * Add all the elements of the first set to the auxiliary set.
2452 * Then remove all the elements of all the next sets from it.
2453 *
2454
2455 * This is O(L + (N-K)log(N)) where L is the sum of all the elements in every
2456 * set, N is the size of the first set, and K is the size of the result set.
2457 *
2458 * Note that from the (L-N) dict searches, (N-K) got to the zsetRemoveFromSkiplist
2459 * which costs log(N)
2460 *
2461 * There is also a O(K) cost at the end for finding the largest element
2462 * size, but this doesn't change the algorithm complexity since K < L, and
2463 * O(2L) is the same as O(L). */
2464 int j;
2465 int cardinality = 0;
2466 zsetopval zval;
2467 zskiplistNode *znode;
2468 sds tmp;
2469
2470 for (j = 0; j < setnum; j++) {
2471 if (zuiLength(&src[j]) == 0) continue;
2472
2473 memset(&zval, 0, sizeof(zval));
2474 zuiInitIterator(&src[j]);
2475 while (zuiNext(&src[j],&zval)) {
2476 if (j == 0) {
2477 tmp = zuiNewSdsFromValue(&zval);
2478 znode = zslInsert(dstzset->zsl,zval.score,tmp);
2479 dictAdd(dstzset->dict,tmp,&znode->score);
2480 cardinality++;
2481 } else {
2482 tmp = zuiSdsFromValue(&zval);
2483 if (zsetRemoveFromSkiplist(dstzset, tmp)) {
2484 cardinality--;
2485 }
2486 }
2487
2488 /* Exit if result set is empty as any additional removal
2489 * of elements will have no effect. */
2490 if (cardinality == 0) break;
2491 }
2492 zuiClearIterator(&src[j]);
2493
2494 if (cardinality == 0) break;
2495 }
2496
2497 /* Redize dict if needed after removing multiple elements */
2498 if (htNeedsResize(dstzset->dict)) dictResize(dstzset->dict);
2499
2500 /* Using this algorithm, we can't calculate the max element as we go,
2501 * we have to iterate through all elements to find the max one after. */
2502 *maxelelen = zsetDictGetMaxElementLength(dstzset->dict, totelelen);
2503}
2504
2505static int zsetChooseDiffAlgorithm(zsetopsrc *src, long setnum) {

Callers 1

zdiffFunction · 0.85

Calls 12

zuiLengthFunction · 0.85
zuiInitIteratorFunction · 0.85
zuiNextFunction · 0.85
zuiNewSdsFromValueFunction · 0.85
zslInsertFunction · 0.85
zuiSdsFromValueFunction · 0.85
zsetRemoveFromSkiplistFunction · 0.85
zuiClearIteratorFunction · 0.85
htNeedsResizeFunction · 0.85
dictResizeFunction · 0.85
dictAddFunction · 0.70

Tested by

no test coverage detected