summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane1999-05-17 00:25:34 +0000
committerTom Lane1999-05-17 00:25:34 +0000
commit1332c1e14404407c9a106bf7096e8f58b16dc566 (patch)
tree523343f9485b4fc7cae696786787bfaccaf49b83 /src/backend
parentc686be8d5687f5e31df0a97ee52ccfe5842071b5 (diff)
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.
Diffstat (limited to 'src/backend')
-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
3 files changed, 74 insertions, 34 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;