| 2391 | } |
| 2392 | |
| 2393 | static void zdiffAlgorithm1(zsetopsrc *src, long setnum, zset *dstzset, size_t *maxelelen, size_t *totelelen) { |
| 2394 | /* DIFF Algorithm 1: |
| 2395 | * |
| 2396 | * We perform the diff by iterating all the elements of the first set, |
| 2397 | * and only adding it to the target set if the element does not exist |
| 2398 | * into all the other sets. |
| 2399 | * |
| 2400 | * This way we perform at max N*M operations, where N is the size of |
| 2401 | * the first set, and M the number of sets. |
| 2402 | * |
| 2403 | * There is also a O(K*log(K)) cost for adding the resulting elements |
| 2404 | * to the target set, where K is the final size of the target set. |
| 2405 | * |
| 2406 | * The final complexity of this algorithm is O(N*M + K*log(K)). */ |
| 2407 | int j; |
| 2408 | zsetopval zval; |
| 2409 | zskiplistNode *znode; |
| 2410 | sds tmp; |
| 2411 | |
| 2412 | /* With algorithm 1 it is better to order the sets to subtract |
| 2413 | * by decreasing size, so that we are more likely to find |
| 2414 | * duplicated elements ASAP. */ |
| 2415 | qsort(src+1,setnum-1,sizeof(zsetopsrc),zuiCompareByRevCardinality); |
| 2416 | |
| 2417 | memset(&zval, 0, sizeof(zval)); |
| 2418 | zuiInitIterator(&src[0]); |
| 2419 | while (zuiNext(&src[0],&zval)) { |
| 2420 | double value; |
| 2421 | int exists = 0; |
| 2422 | |
| 2423 | for (j = 1; j < setnum; j++) { |
| 2424 | /* It is not safe to access the zset we are |
| 2425 | * iterating, so explicitly check for equal object. |
| 2426 | * This check isn't really needed anymore since we already |
| 2427 | * check for a duplicate set in the zsetChooseDiffAlgorithm |
| 2428 | * function, but we're leaving it for future-proofing. */ |
| 2429 | if (src[j].subject == src[0].subject || |
| 2430 | zuiFind(&src[j],&zval,&value)) { |
| 2431 | exists = 1; |
| 2432 | break; |
| 2433 | } |
| 2434 | } |
| 2435 | |
| 2436 | if (!exists) { |
| 2437 | tmp = zuiNewSdsFromValue(&zval); |
| 2438 | znode = zslInsert(dstzset->zsl,zval.score,tmp); |
| 2439 | dictAdd(dstzset->dict,tmp,&znode->score); |
| 2440 | if (sdslen(tmp) > *maxelelen) *maxelelen = sdslen(tmp); |
| 2441 | (*totelelen) += sdslen(tmp); |
| 2442 | } |
| 2443 | } |
| 2444 | zuiClearIterator(&src[0]); |
| 2445 | } |
| 2446 | |
| 2447 | |
| 2448 | static void zdiffAlgorithm2(zsetopsrc *src, long setnum, zset *dstzset, size_t *maxelelen, size_t *totelelen) { |
no test coverage detected