aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/geqo/geqo_params.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/geqo/geqo_params.c')
-rw-r--r--src/backend/optimizer/geqo/geqo_params.c323
1 files changed, 323 insertions, 0 deletions
diff --git a/src/backend/optimizer/geqo/geqo_params.c b/src/backend/optimizer/geqo/geqo_params.c
new file mode 100644
index 00000000000..47c56ba333f
--- /dev/null
+++ b/src/backend/optimizer/geqo/geqo_params.c
@@ -0,0 +1,323 @@
+/*------------------------------------------------------------------------
+*
+* geqo_params.c--
+* routines for determining necessary genetic optimization parameters
+*
+* Copyright (c) 1994, Regents of the University of California
+*
+* $Id: geqo_params.c,v 1.1 1997/02/19 12:57:20 scrappy Exp $
+*
+*-------------------------------------------------------------------------
+*/
+
+/* contributed by:
+ =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
+ * Martin Utesch * Institute of Automatic Control *
+ = = University of Mining and Technology =
+ * utesch@aut.tu-freiberg.de * Freiberg, Germany *
+ =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <math.h>
+
+#include "postgres.h"
+#include "miscadmin.h"
+
+#include "nodes/pg_list.h"
+#include "nodes/relation.h"
+#include "nodes/primnodes.h"
+
+#include "utils/palloc.h"
+#include "utils/elog.h"
+
+#include "optimizer/internal.h"
+#include "optimizer/paths.h"
+#include "optimizer/pathnode.h"
+#include "optimizer/clauses.h"
+#include "optimizer/cost.h"
+
+#include "optimizer/geqo_gene.h"
+#include "optimizer/geqo.h"
+
+#define POOL_TAG "Pool_Size"
+#define TRIAL_TAG "Generations"
+#define RAND_TAG "Random_Seed"
+#define BIAS_TAG "Selection_Bias"
+
+#define EFFORT_TAG "Effort" /* optimization effort and */
+#define LOW "low" /* corresponding tags */
+#define MEDIUM "medium"
+#define HIGH "high"
+
+#define MAX_TOKEN 80 /* Maximum size of one token in the *
+ * configuration file */
+
+static int gimme_pool_size(int string_length);
+static int gimme_number_generations(int pool_size, int effort);
+static int next_token(FILE *, char *, int);
+
+/*
+ * geqo_param--
+ * get ga parameters out of "$PGDATA/pg_geqo" file.
+ */
+void
+geqo_params(int string_length)
+{
+ int i;
+
+ char buf[MAX_TOKEN];
+ FILE *file;
+
+ char *conf_file;
+
+/* these static variables are used to signal that a value has been set */
+ int pool_size = 0;
+ int number_trials = 0;
+ int random_seed = 0;
+ int selection_bias = 0;
+ int effort = 0;
+
+
+ /* put together the full pathname to the config file */
+ conf_file =
+ (char *) palloc((strlen(DataDir)+strlen(GEQO_FILE)+2)*sizeof(char));
+
+ sprintf(conf_file, "%s/%s", DataDir, GEQO_FILE);
+
+ /* open the config file */
+ file = fopen(conf_file, "r");
+ if (file)
+ {
+ /*
+ * empty and comment line stuff
+ */
+ while ((i = next_token(file, buf, sizeof(buf))) != EOF)
+ {
+ /* If only token on the line, ignore */
+ if (i == '\n') continue;
+
+ /* Comment -- read until end of line then next line */
+ if (buf[0] == '#')
+ {
+ while (next_token(file, buf, sizeof(buf)) == 0) ;
+ continue;
+ }
+
+ /*
+ * get ga parameters by parsing
+ */
+
+ /*------------------------------------------------- pool size */
+ if ( strcmp(buf, POOL_TAG) == 0 )
+ {
+ i = next_token(file, buf, sizeof(buf)); /* get next token */
+
+ if (i != EOF) /* only ignore if we got no text at all */
+ {
+ if (sscanf (buf, "%d", &PoolSize) == 1) pool_size = 1;
+ }
+
+ }
+
+ /*------------------------------------------------- number of trials */
+ else if ( strcmp(buf, TRIAL_TAG) == 0 )
+ {
+ i = next_token(file, buf, sizeof(buf));
+
+ if (i != EOF)
+ {
+ if (sscanf (buf, "%d", &Generations) == 1) number_trials = 1;
+ }
+
+ }
+
+ /*------------------------------------------------- optimization effort */
+ else if ( strcmp(buf, EFFORT_TAG) == 0 )
+ {
+ i = next_token(file, buf, sizeof(buf));
+
+ if (i != EOF)
+ {
+ if (strcmp (buf, LOW) == 0) effort = LOW_EFFORT;
+ else if (strcmp (buf, MEDIUM) == 0) effort = MEDIUM_EFFORT;
+ else if (strcmp (buf, HIGH) == 0) effort = HIGH_EFFORT;
+ }
+
+ }
+
+ /*------------------------------------------- random seed */
+ else if ( strcmp(buf, RAND_TAG) == 0 )
+ {
+ i = next_token(file, buf, sizeof(buf));
+
+ if (i != EOF)
+ {
+ if (sscanf (buf, "%ld", &RandomSeed) == 1) random_seed = 1;
+ }
+
+ }
+
+ /*------------------------------------------- selection bias */
+ else if ( strcmp(buf, BIAS_TAG) == 0 )
+ {
+ i = next_token(file, buf, sizeof(buf));
+
+ if (i != EOF)
+ {
+ if (sscanf (buf, "%f", &SelectionBias) == 1) selection_bias = 1;
+ }
+
+ }
+
+ /* unrecognized tags */
+ else
+ {
+ if (i != EOF)
+ {
+ }
+
+ elog(DEBUG,"geqo_params: unknown parameter type \"%s\"\nin file \'%s\'", buf, conf_file);
+
+ /* if not at end-of-line, keep reading til we are */
+ while (i == 0) i = next_token(file, buf, sizeof(buf));
+ }
+ }
+
+ fclose(file);
+
+ pfree(conf_file);
+ }
+
+ else
+ {
+ elog(DEBUG,"geqo_params: ga parameter file\n\'%s\'\ndoes not exist or permissions are not setup correctly", conf_file);
+ }
+
+ /*
+ * parameter checkings follow
+ */
+
+ /**************** PoolSize: essential ****************/
+ if ( !(pool_size) )
+ {
+ PoolSize = gimme_pool_size(string_length);
+
+ elog(DEBUG,"geqo_params: no pool size specified;\nusing computed value of %d", PoolSize);
+ }
+
+
+ /**************** Effort: essential ****************/
+ if ( !(effort) )
+ {
+ if (PoolSize == MAX_POOL)
+ effort = HIGH_EFFORT;
+ else
+ effort = MEDIUM_EFFORT;
+
+ elog(DEBUG,"geqo_params: no optimization effort specified;\nusing value of %d", effort);
+
+ }
+
+ /**************** Generations: essential ****************/
+ if ( !(number_trials) )
+ {
+ Generations = gimme_number_generations(PoolSize, effort);
+
+ elog(DEBUG,"geqo_params: no number of trials specified;\nusing computed value of %d", Generations);
+
+ }
+
+ /* RandomSeed: */
+ if ( !(random_seed) )
+ {
+ RandomSeed = (long) time(NULL);
+
+ elog(DEBUG,"geqo_params: no random seed specified;\nusing computed value of %ld", RandomSeed);
+ }
+
+ /* SelectionBias: */
+ if ( !(selection_bias) )
+ {
+ SelectionBias = SELECTION_BIAS;
+
+ elog(DEBUG,"geqo_params: no selection bias specified;\nusing default value of %f", SelectionBias);
+ }
+
+}
+
+
+/*
+ * Grab one token out of fp. Defined as the next string of non-whitespace
+ * in the file. After we get the token, continue reading until EOF, end of
+ * line or the next token. If it's the last token on the line, return '\n'
+ * for the value. If we get EOF before reading a token, return EOF. In all
+ * other cases return 0.
+ */
+static int
+next_token(FILE *fp, char *buf, int bufsz)
+{
+ int c;
+ char *eb = buf+(bufsz-1);
+
+ /* Discard inital whitespace */
+ while (isspace(c = getc(fp))) ;
+
+ /* EOF seen before any token so return EOF */
+ if (c == EOF) return -1;
+
+ /* Form a token in buf */
+ do {
+ if (buf < eb) *buf++ = c;
+ c = getc(fp);
+ } while (!isspace(c) && c != EOF);
+ *buf = '\0';
+
+ /* Discard trailing tabs and spaces */
+ while (c == ' ' || c == '\t') c = getc(fp);
+
+ /* Put back the char that was non-whitespace (putting back EOF is ok) */
+ (void) ungetc(c, fp);
+
+ /* If we ended with a newline, return that, otherwise return 0 */
+ return (c == '\n' ? '\n' : 0);
+}
+
+/* gimme_pool_size--
+ * compute good estimation for pool size
+ * according to number of involved rels in a query
+ */
+static int
+gimme_pool_size(int string_length)
+{
+ double exponent;
+ double size;
+
+ exponent = (double) string_length + 1.0;
+
+ size = pow (2.0, exponent);
+
+ if (size < MIN_POOL) {
+ return (MIN_POOL);
+ }
+ else if (size > MAX_POOL) {
+ return (MAX_POOL);
+ }
+ else
+ return ( (int) ceil(size) );
+}
+
+/* gimme_number_generations--
+ * compute good estimation for number of generations size
+ * for convergence
+ */
+static int
+gimme_number_generations(int pool_size, int effort)
+{
+ int number_gens;
+
+ number_gens = (int) ceil ( geqo_log((double) pool_size, 2.0) );
+
+ return (effort * number_gens);
+}