OSDN Git Service

Change GEQO optimizer to release memory after each gene
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 17 May 1999 00:25:34 +0000 (00:25 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 17 May 1999 00:25:34 +0000 (00:25 +0000)
is evaluated.  This bounds memory usage to something reasonable even
when many tables are being joined.

src/backend/optimizer/geqo/geqo_eval.c
src/backend/optimizer/geqo/geqo_main.c
src/backend/optimizer/geqo/geqo_params.c
src/include/optimizer/geqo.h

index 093d09b..31a77f4 100644 (file)
@@ -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"
 #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.
 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;
 }
index 76beb7c..2cedda6 100644 (file)
@@ -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);
 
index 1c664c1..130b635 100644 (file)
@@ -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 $
 *
 *-------------------------------------------------------------------------
 */
 
 #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;
index 9a4c61d..aba1d86 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 #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 */