summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/geqo/minspantree.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/geqo/minspantree.c')
-rw-r--r--src/backend/optimizer/geqo/minspantree.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/src/backend/optimizer/geqo/minspantree.c b/src/backend/optimizer/geqo/minspantree.c
new file mode 100644
index 0000000000..4e4c2ad11b
--- /dev/null
+++ b/src/backend/optimizer/geqo/minspantree.c
@@ -0,0 +1,198 @@
+/*------------------------------------------------------------------------
+*
+* minspantree.c--
+* routine to sort a join graph which is including cycles
+*
+* Copyright (c) 1994, Regents of the University of California
+*
+*
+* IDENTIFICATION
+* $Header: /cvsroot/pgsql/src/backend/optimizer/geqo/Attic/minspantree.c,v 1.1 1997/02/19 12:57:50 scrappy Exp $
+*
+*-------------------------------------------------------------------------
+*/
+
+#include <values.h>
+
+#include "postgres.h"
+
+#include "nodes/pg_list.h"
+#include "nodes/relation.h"
+#include "nodes/primnodes.h"
+
+#include "utils/palloc.h"
+
+#include "optimizer/cost.h"
+
+/*
+ include "optimizer/geqo/tsp.h"
+ */
+
+#include "optimizer/geqo/geqo_gene.h"
+#include "optimizer/geqo/geqo.h"
+
+/*
+ * minspantree--
+ * The function minspantree computes the minimum spanning tree
+ * for a given number of nodes and a given distance function.
+ * For each pair of nodes found to be connected, a given
+ * function is called. Nodes are denoted by the integer numbers
+ * 1 .. number_of_joins, where number_of_joins is the number of nodes.
+*/
+
+void
+minspantree(Query *root, List *join_rels, Rel *garel)
+{
+ int number_of_rels = length(root->base_relation_list_);
+ int number_of_joins = length(join_rels);
+ int *connectto;
+ /* connectto[i] = 0, if node i is already connected */
+ /* to the tree, otherwise connectto[i] is the node */
+ /* nearest to i, which is already connected. */
+
+ Cost *disttoconnect; /* disttoconnect[i]: distance between i and connectto[i] */
+
+ Cost dist, /* temporary */
+ mindist; /* minimal distance between connected and unconnected node */
+
+ Cost mstlength = 0.0; /* the total length of the minimum spanning tree */
+
+ int count;
+ int n, /* newly attached node */
+ nextn, /* next node to be attached */
+ tempn;
+
+ int i, id1, id2;
+ List *r = NIL;
+ Rel *joinrel = NULL;
+ Rel **tmprel_array;
+
+
+ /* allocate memory for matrix tmprel_array[x][y] */
+ tmprel_array = (Rel **) palloc((number_of_rels+1)*sizeof(Rel *));
+ for (i=0; i<=number_of_rels; i++)
+ (tmprel_array[i] = (Rel *) palloc ((number_of_rels+1)*sizeof(Rel)));
+
+ /* read relations of join-relations into tmprel_array */
+
+ foreach(r, join_rels) {
+ joinrel = (Rel *)lfirst(r);
+ id1 = (int)lfirst(joinrel->relids);
+ id2 = (int)lsecond(joinrel->relids);
+
+ if (id1 > id2) {
+ tmprel_array[id2][id1] = *(Rel *)joinrel;
+ }
+ else {
+ tmprel_array[id1][id2] = *(Rel *)joinrel; /* ever reached? */
+ }
+ }
+
+ /* Trivial special cases handled first */
+ /* garel is global in "tsp.h" */
+
+ if (number_of_joins <= 2)
+ {
+ i=1;
+ foreach(r, join_rels) {
+ garel[i] = *(Rel *)lfirst(r);
+ i++;
+ }
+ }
+
+
+ else if (number_of_joins == 3)
+ {
+ Rel *rel12 = (Rel *) &tmprel_array[1][2];
+ Rel *rel13 = (Rel *) &tmprel_array[1][3];
+ Rel *rel23 = (Rel *) &tmprel_array[2][3];
+ if (rel12->cheapestpath->path_cost > rel13->cheapestpath->path_cost)
+ {
+ garel[1] = tmprel_array[1][3];
+ if (rel12->cheapestpath->path_cost > rel23->cheapestpath->path_cost)
+ {
+ garel[2] = tmprel_array[2][3];
+ }
+ else
+ {
+ garel[2] = tmprel_array[1][2];
+ }
+ }
+ else
+ {
+ garel[1] = tmprel_array[1][2];
+ if (rel13->cheapestpath->path_cost > rel23->cheapestpath->path_cost)
+ {
+ garel[2] = tmprel_array[2][3];
+ }
+ else
+ {
+ garel[2] = tmprel_array[1][3];
+ }
+ }
+ }
+
+
+ /* now the general case */
+ else
+ {
+ connectto = (int *) palloc((number_of_rels+1)*sizeof(int));
+ disttoconnect = (Cost *) palloc((number_of_rels+1)*sizeof(Cost));
+
+ nextn = 2;
+ for (tempn = 2; tempn <= number_of_rels; tempn++ )
+ {
+ connectto[tempn] = 1;
+ disttoconnect[tempn] = (Cost) MAXFLOAT;
+ }
+
+ joinrel = NULL;
+ n = 1;
+ i = 1;
+ for (count = 2; count <= number_of_rels; count++ )
+ {
+ connectto[n] = 0;
+ mindist = (Cost) MAXFLOAT;
+ for (tempn = 2; tempn <= number_of_rels; tempn++ )
+ {
+ if (connectto[tempn] != 0)
+ {
+ if (n > tempn) {
+ joinrel = (Rel *) &tmprel_array[tempn][n];
+ }
+ else {
+ joinrel = (Rel *) &tmprel_array[n][tempn];
+ }
+ dist = joinrel->cheapestpath->path_cost;
+
+ if (dist < disttoconnect[tempn])
+ {
+ disttoconnect[tempn] = dist;
+ connectto[tempn] = n;
+ }
+ if (disttoconnect[tempn] < mindist)
+ {
+ mindist = disttoconnect[tempn];
+ nextn = tempn;
+ }
+ }
+ }
+ n = nextn;
+ if (n > connectto[n]) {
+ garel[i] = tmprel_array[connectto[n]][n];
+ }
+ else {
+ garel[i] = tmprel_array[n][connectto[n]];
+ }
+ i++;
+ }
+
+ pfree(connectto);
+ pfree(disttoconnect);
+
+ }
+
+ for (i=0; i<=number_of_rels; i++) pfree(tmprel_array[i]);
+ pfree(tmprel_array);
+}
+