minspantree.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:5k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*------------------------------------------------------------------------
  2. *
  3. * minspantree.c
  4. *  routine to sort a join graph which is including cycles
  5. *
  6. * Copyright (c) 1994, Regents of the University of California
  7. *
  8. *
  9. * IDENTIFICATION
  10. *  $Header: /usr/local/cvsroot/pgsql/src/backend/optimizer/geqo/minspantree.c,v 1.12.2.1 1999/08/02 05:57:07 scrappy Exp $
  11. *
  12. *-------------------------------------------------------------------------
  13. */
  14. #include <values.h>
  15. #include "postgres.h"
  16. #include "nodes/pg_list.h"
  17. #include "nodes/primnodes.h"
  18. #include "nodes/relation.h"
  19. #include "optimizer/cost.h"
  20. #include "optimizer/geqo/geqo.h"
  21. #include "optimizer/geqo/geqo_gene.h"
  22. /*
  23.  * minspantree
  24.  *  The function minspantree computes the minimum spanning tree
  25.  * for a given number of nodes and a given distance function.
  26.  * For each pair of nodes found to be connected, a given
  27.  * function is called. Nodes are denoted by the integer numbers
  28.  * 1 .. number_of_joins, where number_of_joins is the number of nodes.
  29. */
  30. void
  31. minspantree(Query *root, List *join_rels, RelOptInfo *garel)
  32. {
  33. int number_of_rels = length(root->base_rel_list);
  34. int number_of_joins = length(join_rels);
  35. int    *connectto;
  36. /* connectto[i] = 0, if node i is already connected  */
  37. /* to the tree, otherwise connectto[i] is the node  */
  38. /* nearest to i, which is already connected.    */
  39. Cost    *disttoconnect; /* disttoconnect[i]: distance between i
  40.  * and connectto[i] */
  41. Cost dist, /* temporary */
  42. mindist; /* minimal distance between connected and
  43.  * unconnected node */
  44. Cost mstlength = 0.0;/* the total length of the minimum
  45.  * spanning tree */
  46. int count;
  47. int n, /* newly attached node */
  48. nextn, /* next node to be attached */
  49. tempn;
  50. int i,
  51. id1,
  52. id2;
  53. List    *r = NIL;
  54. RelOptInfo *joinrel = NULL;
  55. RelOptInfo **tmprel_array;
  56. /* allocate memory for matrix tmprel_array[x][y] */
  57. tmprel_array = (RelOptInfo **) palloc((number_of_rels + 1) * sizeof(RelOptInfo *));
  58. for (i = 0; i <= number_of_rels; i++)
  59. (tmprel_array[i] = (RelOptInfo *) palloc((number_of_rels + 1) * sizeof(RelOptInfo)));
  60. /* read relations of join-relations into tmprel_array */
  61. foreach(r, join_rels)
  62. {
  63. joinrel = (RelOptInfo *) lfirst(r);
  64. id1 = (int) lfirst(joinrel->relids);
  65. id2 = (int) lsecond(joinrel->relids);
  66. if (id1 > id2)
  67. tmprel_array[id2][id1] = *(RelOptInfo *) joinrel;
  68. else
  69. {
  70. tmprel_array[id1][id2] = *(RelOptInfo *) joinrel; /* ever reached? */
  71. }
  72. }
  73. /* Trivial special cases handled first */
  74. /* garel is global in "tsp.h" */
  75. if (number_of_joins <= 2)
  76. {
  77. i = 1;
  78. foreach(r, join_rels)
  79. {
  80. garel[i] = *(RelOptInfo *) lfirst(r);
  81. i++;
  82. }
  83. }
  84. else if (number_of_joins == 3)
  85. {
  86. RelOptInfo *rel12 = (RelOptInfo *) &tmprel_array[1][2];
  87. RelOptInfo *rel13 = (RelOptInfo *) &tmprel_array[1][3];
  88. RelOptInfo *rel23 = (RelOptInfo *) &tmprel_array[2][3];
  89. if (rel12->cheapestpath->path_cost > rel13->cheapestpath->path_cost)
  90. {
  91. garel[1] = tmprel_array[1][3];
  92. if (rel12->cheapestpath->path_cost > rel23->cheapestpath->path_cost)
  93. garel[2] = tmprel_array[2][3];
  94. else
  95. garel[2] = tmprel_array[1][2];
  96. }
  97. else
  98. {
  99. garel[1] = tmprel_array[1][2];
  100. if (rel13->cheapestpath->path_cost > rel23->cheapestpath->path_cost)
  101. garel[2] = tmprel_array[2][3];
  102. else
  103. garel[2] = tmprel_array[1][3];
  104. }
  105. }
  106. /* now the general case */
  107. else
  108. {
  109. connectto = (int *) palloc((number_of_rels + 1) * sizeof(int));
  110. disttoconnect = (Cost *) palloc((number_of_rels + 1) * sizeof(Cost));
  111. nextn = 2;
  112. for (tempn = 2; tempn <= number_of_rels; tempn++)
  113. {
  114. connectto[tempn] = 1;
  115. disttoconnect[tempn] = (Cost) MAXFLOAT;
  116. }
  117. joinrel = NULL;
  118. n = 1;
  119. i = 1;
  120. for (count = 2; count <= number_of_rels; count++)
  121. {
  122. connectto[n] = 0;
  123. mindist = (Cost) MAXFLOAT;
  124. for (tempn = 2; tempn <= number_of_rels; tempn++)
  125. {
  126. if (connectto[tempn] != 0)
  127. {
  128. if (n > tempn)
  129. joinrel = (RelOptInfo *) &tmprel_array[tempn][n];
  130. else
  131. joinrel = (RelOptInfo *) &tmprel_array[n][tempn];
  132. dist = joinrel->cheapestpath->path_cost;
  133. if (dist < disttoconnect[tempn])
  134. {
  135. disttoconnect[tempn] = dist;
  136. connectto[tempn] = n;
  137. }
  138. if (disttoconnect[tempn] < mindist)
  139. {
  140. mindist = disttoconnect[tempn];
  141. nextn = tempn;
  142. }
  143. }
  144. }
  145. n = nextn;
  146. if (n > connectto[n])
  147. garel[i] = tmprel_array[connectto[n]][n];
  148. else
  149. garel[i] = tmprel_array[n][connectto[n]];
  150. i++;
  151. }
  152. pfree(connectto);
  153. pfree(disttoconnect);
  154. }
  155. for (i = 0; i <= number_of_rels; i++)
  156. pfree(tmprel_array[i]);
  157. pfree(tmprel_array);
  158. }