| 2503 | } |
| 2504 | |
| 2505 | static int zsetChooseDiffAlgorithm(zsetopsrc *src, long setnum) { |
| 2506 | int j; |
| 2507 | |
| 2508 | /* Select what DIFF algorithm to use. |
| 2509 | * |
| 2510 | * Algorithm 1 is O(N*M + K*log(K)) where N is the size of the |
| 2511 | * first set, M the total number of sets, and K is the size of the |
| 2512 | * result set. |
| 2513 | * |
| 2514 | * Algorithm 2 is O(L + (N-K)log(N)) where L is the total number of elements |
| 2515 | * in all the sets, N is the size of the first set, and K is the size of the |
| 2516 | * result set. |
| 2517 | * |
| 2518 | * We compute what is the best bet with the current input here. */ |
| 2519 | long long algo_one_work = 0; |
| 2520 | long long algo_two_work = 0; |
| 2521 | |
| 2522 | for (j = 0; j < setnum; j++) { |
| 2523 | /* If any other set is equal to the first set, there is nothing to be |
| 2524 | * done, since we would remove all elements anyway. */ |
| 2525 | if (j > 0 && src[0].subject == src[j].subject) { |
| 2526 | return 0; |
| 2527 | } |
| 2528 | |
| 2529 | algo_one_work += zuiLength(&src[0]); |
| 2530 | algo_two_work += zuiLength(&src[j]); |
| 2531 | } |
| 2532 | |
| 2533 | /* Algorithm 1 has better constant times and performs less operations |
| 2534 | * if there are elements in common. Give it some advantage. */ |
| 2535 | algo_one_work /= 2; |
| 2536 | return (algo_one_work <= algo_two_work) ? 1 : 2; |
| 2537 | } |
| 2538 | |
| 2539 | static void zdiff(zsetopsrc *src, long setnum, zset *dstzset, size_t *maxelelen, size_t *totelelen) { |
| 2540 | /* Skip everything if the smallest input is empty. */ |