| 2446 | |
| 2447 | |
| 2448 | static 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 | |
| 2505 | static int zsetChooseDiffAlgorithm(zsetopsrc *src, long setnum) { |
no test coverage detected