3737#include "partutils.h"
3838#include "stream.h"
3939
40+ #define DEFAULT_EXCHANGE_STARTUP_COST 100.0
41+ #define DEFAULT_TRANSFER_TUPLE_COST 0.01
42+
4043
4144static CustomPathMethods exchange_path_methods ;
4245static CustomScanMethods exchange_plan_methods ;
@@ -401,9 +404,13 @@ add_exchange_paths(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry
401404 }
402405}
403406
407+ #include "optimizer/cost.h"
408+
404409static void
405- cost_exchange (PlannerInfo * root , RelOptInfo * baserel , Path * path )
410+ cost_exchange (PlannerInfo * root , RelOptInfo * baserel , ExchangePath * expath )
406411{
412+ Path * subpath ;
413+
407414 if (baserel -> pages == 0 && baserel -> tuples == 0 )
408415 {
409416 baserel -> pages = 10 ;
@@ -414,11 +421,53 @@ cost_exchange(PlannerInfo *root, RelOptInfo *baserel, Path *path)
414421
415422 /* Estimate baserel size as best we can with local statistics. */
416423// set_baserel_size_estimates(root, baserel);
424+ subpath = cstmSubPath1 (expath );
425+ expath -> cp .path .rows = baserel -> tuples ;
426+ expath -> cp .path .startup_cost = subpath -> startup_cost ;
427+ switch (expath -> mode )
428+ {
429+ case EXCH_GATHER :
430+ expath -> cp .path .startup_cost += DEFAULT_EXCHANGE_STARTUP_COST ;
431+ expath -> cp .path .rows = subpath -> rows * expath -> altrel .nparts ;
432+ break ;
433+ case EXCH_STEALTH :
434+ expath -> cp .path .rows = subpath -> rows ;
435+ break ;
436+ case EXCH_BROADCAST :
437+ expath -> cp .path .startup_cost += DEFAULT_EXCHANGE_STARTUP_COST ;
438+ expath -> cp .path .rows = subpath -> rows * expath -> altrel .nparts ;
439+ break ;
440+ case EXCH_SHUFFLE :
441+ {
442+ double local_rows ;
443+ double received_rows ;
444+ double send_rows ;
445+ int instances ;
446+ Path * path = & expath -> cp .path ;
447+
448+ path -> startup_cost += DEFAULT_EXCHANGE_STARTUP_COST ;
449+ path -> total_cost += path -> startup_cost ;
417450
418- /* Now I do not want to think about cost estimations. */
419- path -> rows = baserel -> tuples ;
420- path -> startup_cost = 0.1 ;
421- path -> total_cost = 0.1 ;
451+ /*
452+ * We count on perfect balance of tuple distribution:
453+ * If we have N instances, M tuples from subtree, than we send up to
454+ * local subtree M/N tuples, send to network [M-M/N] tuples and same to
455+ * receive.
456+ */
457+ path -> rows = subpath -> rows ;
458+ instances = expath -> altrel .nparts > 0 ? expath -> altrel .nparts : 2 ;
459+ send_rows = path -> rows - (path -> rows /instances );
460+ received_rows = send_rows ;
461+ local_rows = path -> rows /instances ;
462+ path -> total_cost += (send_rows + local_rows ) * DEFAULT_CPU_TUPLE_COST ;
463+ path -> total_cost += (received_rows ) * DEFAULT_CPU_TUPLE_COST * 4. ;
464+ }
465+ break ;
466+ default :
467+ elog (FATAL , "Unknown EXCHANGE mode." );
468+ }
469+
470+ expath -> cp .path .total_cost = 0.1 ;
422471}
423472
424473/*
@@ -663,8 +712,6 @@ create_exchange_path(PlannerInfo *root, RelOptInfo *rel, Path *children,
663712 pathnode -> parallel_workers = 0 ; /* permanently */
664713 pathnode -> pathkeys = NIL ;
665714
666- cost_exchange (root , rel , pathnode ); /* Change at next step*/
667-
668715 path -> flags = 0 ;
669716 /* Contains only one path */
670717 path -> custom_paths = lappend (path -> custom_paths , children );
@@ -675,6 +722,7 @@ create_exchange_path(PlannerInfo *root, RelOptInfo *rel, Path *children,
675722 memcpy (& epath -> altrel , rel , sizeof (RelOptInfo ));
676723 epath -> exchange_counter = exchange_counter ++ ;
677724 epath -> mode = mode ;
725+ cost_exchange (root , rel , epath ); /* Change at next step*/
678726
679727 return epath ;
680728}
0 commit comments