@@ -65,9 +65,10 @@ typedef struct CombinationGenerator
6565 int current ; /* index of the next combination to return */
6666 int ncombinations ; /* number of combinations (size of array) */
6767 int * combinations ; /* array of pre-built combinations */
68+ int method ;
6869} CombinationGenerator ;
6970
70- static CombinationGenerator * generator_init (int n , int k );
71+ static CombinationGenerator * generator_init (int n , int k , int method );
7172static void generator_free (CombinationGenerator * state );
7273static int * generator_next (CombinationGenerator * state );
7374static void generate_combinations (CombinationGenerator * state );
@@ -91,7 +92,9 @@ statext_ndistinct_build(double totalrows, StatsBuildData *data)
9192 int k ;
9293 int itemcnt ;
9394 int numattrs = data -> nattnums ;
94- int numcombs = num_combinations (numattrs );
95+ int numcombs = (data -> method == EXTSTAT_METHOD_COMBS ) ?
96+ num_combinations (numattrs ) :
97+ (numattrs - 1 );
9598
9699 result = palloc (offsetof(MVNDistinct , items ) +
97100 numcombs * sizeof (MVNDistinctItem ));
@@ -106,7 +109,7 @@ statext_ndistinct_build(double totalrows, StatsBuildData *data)
106109 CombinationGenerator * generator ;
107110
108111 /* generate combinations of K out of N elements */
109- generator = generator_init (numattrs , k );
112+ generator = generator_init (numattrs , k , data -> method );
110113
111114 while ((combination = generator_next (generator )))
112115 {
@@ -586,7 +589,7 @@ num_combinations(int n)
586589 * generating them on the fly.
587590 */
588591static CombinationGenerator *
589- generator_init (int n , int k )
592+ generator_init (int n , int k , int method )
590593{
591594 CombinationGenerator * state ;
592595
@@ -595,7 +598,10 @@ generator_init(int n, int k)
595598 /* allocate the generator state as a single chunk of memory */
596599 state = (CombinationGenerator * ) palloc (sizeof (CombinationGenerator ));
597600
598- state -> ncombinations = n_choose_k (n , k );
601+ if (method == EXTSTAT_METHOD_LINEAR )
602+ state -> ncombinations = 1 ;
603+ else
604+ state -> ncombinations = n_choose_k (n , k );
599605
600606 /* pre-allocate space for all combinations */
601607 state -> combinations = (int * ) palloc (sizeof (int ) * k * state -> ncombinations );
@@ -605,13 +611,23 @@ generator_init(int n, int k)
605611 state -> n = n ;
606612
607613 /* now actually pre-generate all the combinations of K elements */
608- generate_combinations (state );
614+ if (method == EXTSTAT_METHOD_LINEAR )
615+ {
616+ int i ;
617+
618+ for (i = 0 ; i < k ; i ++ )
619+ state -> combinations [i ] = i ;
620+ }
621+ else
622+ {
623+ generate_combinations (state );
609624
610- /* make sure we got the expected number of combinations */
611- Assert (state -> current == state -> ncombinations );
625+ /* make sure we got the expected number of combinations */
626+ Assert (state -> current == state -> ncombinations );
612627
613- /* reset the number, so we start with the first one */
614- state -> current = 0 ;
628+ /* reset the number, so we start with the first one */
629+ state -> current = 0 ;
630+ }
615631
616632 return state ;
617633}
0 commit comments