66 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
77 * Portions Copyright (c) 1994, Regents of the University of California
88 *
9- * $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_selection.c,v 1.25 2009/07/16 20:55:44 tgl Exp $
9+ * $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_selection.c,v 1.26 2009/07/24 15:03:07 tgl Exp $
1010 *
1111 *-------------------------------------------------------------------------
1212 */
4242#include "optimizer/geqo_random.h"
4343#include "optimizer/geqo_selection.h"
4444
45- static int linear (PlannerInfo * root ,int max ,double bias );
45+ static int linear_rand (PlannerInfo * root ,int max ,double bias );
4646
4747
4848/*
@@ -57,21 +57,29 @@ geqo_selection(PlannerInfo *root, Chromosome *momma, Chromosome *daddy,
5757int first ,
5858second ;
5959
60- first = linear (root ,pool -> size ,bias );
61- second = linear (root ,pool -> size ,bias );
60+ first = linear_rand (root ,pool -> size ,bias );
61+ second = linear_rand (root ,pool -> size ,bias );
6262
63+ /*
64+ * Ensure we have selected different genes, except if pool size is only
65+ * one, when we can't.
66+ *
67+ * This code has been observed to hang up in an infinite loop when the
68+ * platform's implementation of erand48() is broken. We consider that a
69+ * feature: it lets you know you'd better fix the random-number generator.
70+ */
6371if (pool -> size > 1 )
6472{
6573while (first == second )
66- second = linear (root ,pool -> size ,bias );
74+ second = linear_rand (root ,pool -> size ,bias );
6775}
6876
6977geqo_copy (root ,momma ,& pool -> data [first ],pool -> string_length );
7078geqo_copy (root ,daddy ,& pool -> data [second ],pool -> string_length );
7179}
7280
7381/*
74- *linear
82+ *linear_rand
7583 * generates random integer between 0 and input max number
7684 * using input linear bias
7785 *
@@ -81,7 +89,7 @@ geqo_selection(PlannerInfo *root, Chromosome *momma, Chromosome *daddy,
8189 * bias = (prob of first rule) / (prob of middle rule)
8290 */
8391static int
84- linear (PlannerInfo * root ,int pool_size ,double bias )
92+ linear_rand (PlannerInfo * root ,int pool_size ,double bias )
8593{
8694double index ;/* index between 0 and pop_size */
8795double max = (double )pool_size ;