Add commentary about Cygwin's broken erand48, per report from Andrew Dunstan.

This commit is contained in:
Tom Lane 2009-07-24 15:03:07 +00:00
parent dc7aa36521
commit 655473a7cd
3 changed files with 20 additions and 10 deletions

3
configure vendored
View File

@ -19085,7 +19085,8 @@ esac
fi fi
# Cygwin's erand48 sometimes hangs, so force use of ours # Cygwin's erand48() is broken (always returns zero) in some releases,
# so force use of ours.
if test "$PORTNAME" = "cygwin"; then if test "$PORTNAME" = "cygwin"; then
case " $LIBOBJS " in case " $LIBOBJS " in
*" erand48.$ac_objext "* ) ;; *" erand48.$ac_objext "* ) ;;

View File

@ -1,5 +1,5 @@
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
dnl $PostgreSQL: pgsql/configure.in,v 1.606 2009/07/23 23:50:29 adunstan Exp $ dnl $PostgreSQL: pgsql/configure.in,v 1.607 2009/07/24 15:03:07 tgl Exp $
dnl dnl
dnl Developers, please strive to achieve this order: dnl Developers, please strive to achieve this order:
dnl dnl
@ -1289,7 +1289,8 @@ if test "$PORTNAME" = "solaris"; then
AC_LIBOBJ(getopt) AC_LIBOBJ(getopt)
fi fi
# Cygwin's erand48 sometimes hangs, so force use of ours # Cygwin's erand48() is broken (always returns zero) in some releases,
# so force use of ours.
if test "$PORTNAME" = "cygwin"; then if test "$PORTNAME" = "cygwin"; then
AC_LIBOBJ(erand48) AC_LIBOBJ(erand48)
fi fi

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_selection.c,v 1.25 2009/07/16 20:55:44 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_selection.c,v 1.26 2009/07/24 15:03:07 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -42,7 +42,7 @@
#include "optimizer/geqo_random.h" #include "optimizer/geqo_random.h"
#include "optimizer/geqo_selection.h" #include "optimizer/geqo_selection.h"
static int linear(PlannerInfo *root, int max, double bias); static int linear_rand(PlannerInfo *root, int max, double bias);
/* /*
@ -57,13 +57,21 @@ geqo_selection(PlannerInfo *root, Chromosome *momma, Chromosome *daddy,
int first, int first,
second; second;
first = linear(root, pool->size, bias); first = linear_rand(root, pool->size, bias);
second = linear(root, pool->size, bias); second = linear_rand(root, pool->size, bias);
/*
* Ensure we have selected different genes, except if pool size is only
* one, when we can't.
*
* This code has been observed to hang up in an infinite loop when the
* platform's implementation of erand48() is broken. We consider that a
* feature: it lets you know you'd better fix the random-number generator.
*/
if (pool->size > 1) if (pool->size > 1)
{ {
while (first == second) while (first == second)
second = linear(root, pool->size, bias); second = linear_rand(root, pool->size, bias);
} }
geqo_copy(root, momma, &pool->data[first], pool->string_length); geqo_copy(root, momma, &pool->data[first], pool->string_length);
@ -71,7 +79,7 @@ geqo_selection(PlannerInfo *root, Chromosome *momma, Chromosome *daddy,
} }
/* /*
* linear * linear_rand
* generates random integer between 0 and input max number * generates random integer between 0 and input max number
* using input linear bias * using input linear bias
* *
@ -81,7 +89,7 @@ geqo_selection(PlannerInfo *root, Chromosome *momma, Chromosome *daddy,
* bias = (prob of first rule) / (prob of middle rule) * bias = (prob of first rule) / (prob of middle rule)
*/ */
static int static int
linear(PlannerInfo *root, int pool_size, double bias) linear_rand(PlannerInfo *root, int pool_size, double bias)
{ {
double index; /* index between 0 and pop_size */ double index; /* index between 0 and pop_size */
double max = (double) pool_size; double max = (double) pool_size;