aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>1999-05-17 00:25:34 +0000
committerTom Lane <tgl@sss.pgh.pa.us>1999-05-17 00:25:34 +0000
commit1332c1e14404407c9a106bf7096e8f58b16dc566 (patch)
tree523343f9485b4fc7cae696786787bfaccaf49b83
parentc686be8d5687f5e31df0a97ee52ccfe5842071b5 (diff)
downloadpostgresql-1332c1e14404407c9a106bf7096e8f58b16dc566.tar.gz
postgresql-1332c1e14404407c9a106bf7096e8f58b16dc566.zip
Change GEQO optimizer to release memory after each gene
is evaluated. This bounds memory usage to something reasonable even when many tables are being joined.
-rw-r--r--src/backend/optimizer/geqo/geqo_eval.c60
-rw-r--r--src/backend/optimizer/geqo/geqo_main.c34
-rw-r--r--src/backend/optimizer/geqo/geqo_params.c14
-rw-r--r--src/include/optimizer/geqo.h25
4 files changed, 84 insertions, 49 deletions
diff --git a/src/backend/optimizer/geqo/geqo_eval.c b/src/backend/optimizer/geqo/geqo_eval.c
index 093d09ba975..31a77f46e4a 100644
--- a/src/backend/optimizer/geqo/geqo_eval.c
+++ b/src/backend/optimizer/geqo/geqo_eval.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_eval.c,v 1.36 1999/05/16 19:45:00 tgl Exp $
+ * $Id: geqo_eval.c,v 1.37 1999/05/17 00:25:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -36,6 +36,7 @@
#include "utils/palloc.h"
#include "utils/elog.h"
+#include "utils/portal.h"
#include "optimizer/internal.h"
#include "optimizer/paths.h"
@@ -49,6 +50,38 @@
#include "optimizer/geqo.h"
/*
+ * Variables set by geqo_eval_startup for use within a single GEQO run
+ */
+static MemoryContext geqo_eval_context;
+
+/*
+ * geqo_eval_startup:
+ * Must be called during geqo_main startup (before geqo_eval may be called)
+ *
+ * The main thing we need to do here is prepare a private memory context for
+ * allocation of temp storage used while constructing a path in geqo_eval().
+ * Since geqo_eval() will be called many times, we can't afford to let all
+ * that memory go unreclaimed until end of statement. We use a special
+ * named portal to hold the context, so that it will be freed even if
+ * we abort via elog(ERROR). The working data is allocated in the portal's
+ * heap memory context.
+ */
+void
+geqo_eval_startup(void)
+{
+#define GEQO_PORTAL_NAME "<geqo workspace>"
+ Portal geqo_portal = GetPortalByName(GEQO_PORTAL_NAME);
+
+ if (!PortalIsValid(geqo_portal)) {
+ /* First time through (within current transaction, that is) */
+ geqo_portal = CreatePortal(GEQO_PORTAL_NAME);
+ Assert(PortalIsValid(geqo_portal));
+ }
+
+ geqo_eval_context = (MemoryContext) PortalGetHeapMemory(geqo_portal);
+}
+
+/*
* geqo_eval
*
* Returns cost of a query tree as an individual of the population.
@@ -56,23 +89,30 @@
Cost
geqo_eval(Query *root, Gene *tour, int num_gene)
{
- RelOptInfo *joinrel;
- Cost fitness;
- List *temp;
+ MemoryContext oldcxt;
+ RelOptInfo *joinrel;
+ Cost fitness;
+ List *savelist;
+
+ /* preserve root->join_rel_list, which gimme_tree changes */
+ savelist = root->join_rel_list;
- /* remember root->join_rel_list ... */
- /* because root->join_rel_list will be changed during the following */
- temp = listCopy(root->join_rel_list);
+ /* create a temporary allocation context for the path construction work */
+ oldcxt = MemoryContextSwitchTo(geqo_eval_context);
+ StartPortalAllocMode(DefaultAllocMode, 0);
- /* joinrel is readily processed query tree -- left-sided ! */
+ /* construct the best path for the given combination of relations */
joinrel = gimme_tree(root, tour, 0, num_gene, NULL);
/* compute fitness */
fitness = (Cost) joinrel->cheapestpath->path_cost;
- root->join_rel_list = temp;
+ /* restore join_rel_list */
+ root->join_rel_list = savelist;
- pfree(joinrel);
+ /* release all the memory acquired within gimme_tree */
+ EndPortalAllocMode();
+ MemoryContextSwitchTo(oldcxt);
return fitness;
}
diff --git a/src/backend/optimizer/geqo/geqo_main.c b/src/backend/optimizer/geqo/geqo_main.c
index 76beb7c2495..2cedda675bd 100644
--- a/src/backend/optimizer/geqo/geqo_main.c
+++ b/src/backend/optimizer/geqo/geqo_main.c
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo_main.c,v 1.14 1999/02/18 04:55:54 momjian Exp $
+ * $Id: geqo_main.c,v 1.15 1999/05/17 00:25:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -70,44 +70,31 @@ geqo(Query *root)
Chromosome *momma;
Chromosome *daddy;
Chromosome *kid;
-
+ int number_of_rels;
+ Pool *pool;
+ int pool_size,
+ number_generations,
+ status_interval;
+ Gene *best_tour;
+ RelOptInfo *best_rel;
#if defined(ERX)
Edge *edge_table; /* list of edges */
int edge_failures = 0;
float difference;
-
#endif
-
#if defined(CX) || defined(PX) || defined(OX1) || defined(OX2)
City *city_table; /* list of cities */
-
#endif
-
#if defined(CX)
int cycle_diffs = 0;
int mutations = 0;
-
#endif
-
- int number_of_rels;
-
- Pool *pool;
- int pool_size,
- number_generations,
- status_interval;
-
- Gene *best_tour;
- RelOptInfo *best_rel;
-
-/* Plan *best_plan; */
-
-
/* set tour size */
number_of_rels = length(root->base_rel_list);
/* set GA parameters */
- geqo_params(number_of_rels);/* out of "$PGDATA/pg_geqo" file */
+ geqo_params(number_of_rels); /* read "$PGDATA/pg_geqo" file */
pool_size = PoolSize;
number_generations = Generations;
status_interval = 10;
@@ -115,6 +102,9 @@ geqo(Query *root)
/* seed random number generator */
srandom(RandomSeed);
+/* initialize plan evaluator */
+ geqo_eval_startup();
+
/* allocate genetic pool memory */
pool = alloc_pool(pool_size, number_of_rels);
diff --git a/src/backend/optimizer/geqo/geqo_params.c b/src/backend/optimizer/geqo/geqo_params.c
index 1c664c1b3b1..130b6355ac6 100644
--- a/src/backend/optimizer/geqo/geqo_params.c
+++ b/src/backend/optimizer/geqo/geqo_params.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
-* $Id: geqo_params.c,v 1.14 1999/02/15 03:22:01 momjian Exp $
+* $Id: geqo_params.c,v 1.15 1999/05/17 00:25:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -45,6 +45,16 @@
#include "storage/fd.h"
+/*
+ * Parameter values read from the config file (or defaulted) are stored here
+ * by geqo_params().
+ */
+int PoolSize;
+int Generations;
+long RandomSeed;
+double SelectionBias;
+
+
#define POOL_TAG "Pool_Size"
#define TRIAL_TAG "Generations"
#define RAND_TAG "Random_Seed"
@@ -77,7 +87,7 @@ geqo_params(int string_length)
char *conf_file;
-/* these static variables are used to signal that a value has been set */
+ /* these flag variables signal that a value has been set from the file */
int pool_size = 0;
int number_trials = 0;
int random_seed = 0;
diff --git a/src/include/optimizer/geqo.h b/src/include/optimizer/geqo.h
index 9a4c61d4a05..aba1d86096b 100644
--- a/src/include/optimizer/geqo.h
+++ b/src/include/optimizer/geqo.h
@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: geqo.h,v 1.13 1999/02/18 04:55:54 momjian Exp $
+ * $Id: geqo.h,v 1.14 1999/05/17 00:25:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -56,27 +56,22 @@
#define SELECTION_BIAS 2.0 /* selective pressure within population */
/* should be 1.5 <= SELECTION_BIAS <= 2.0 */
-int PoolSize;
-int Generations;
+/* parameter values set in geqo_params.c */
+extern int PoolSize;
+extern int Generations;
+extern long RandomSeed;
+extern double SelectionBias;
-long RandomSeed; /* defaults to (long) time(NULL) in
- * geqo_params.c */
-double SelectionBias;
-
-/* logarithmic base for rel->size decrease in case of long
- queries that cause an integer overflow; used in geqo_eval.c */
-
-#define GEQO_LOG_BASE 1.5 /* should be 1.0 < GEQO_LOG_BASE <= 2.0 */
- /* ^^^ */
-
-/* geqo prototypes */
+/* routines in geqo_main.c */
extern RelOptInfo *geqo(Query *root);
+/* routines in geqo_params.c */
extern void geqo_params(int string_length);
+/* routines in geqo_eval.c */
+extern void geqo_eval_startup(void);
extern Cost geqo_eval(Query *root, Gene *tour, int num_gene);
extern RelOptInfo *gimme_tree(Query *root, Gene *tour, int rel_count,
int num_gene, RelOptInfo *old_rel);
-
#endif /* GEQO_H */