From: Pavan Deolasee Date: Wed, 13 Jan 2016 04:50:39 +0000 (+0530) Subject: Select a node randomly from a list of available nodes for reading from X-Git-Tag: XL9_5_R1BETA1~103 X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=c8a2abaa6202f38042b8557089c8da6c2559b495;p=postgres-xl.git Select a node randomly from a list of available nodes for reading from replicated tables This fixes a bug in FQS logic where it would always pick up the same node for reading --- diff --git a/src/backend/pgxc/locator/locator.c b/src/backend/pgxc/locator/locator.c index ca34cef849..6a4fd155b8 100644 --- a/src/backend/pgxc/locator/locator.c +++ b/src/backend/pgxc/locator/locator.c @@ -96,6 +96,8 @@ static int locate_static(Locator *self, Datum value, bool isnull, bool *hasprimary); static int locate_roundrobin(Locator *self, Datum value, bool isnull, bool *hasprimary); +static int locate_modulo_random(Locator *self, Datum value, bool isnull, + bool *hasprimary); static int locate_hash_insert(Locator *self, Datum value, bool isnull, bool *hasprimary); static int locate_hash_select(Locator *self, Datum value, bool isnull, @@ -1020,7 +1022,8 @@ createLocator(char locatorType, RelationAccessType accessType, } else { - locator->locatefunc = locate_roundrobin; + /* SELECT, use random node.. */ + locator->locatefunc = locate_modulo_random; locator->nodeMap = nodeMap; switch (locator->listType) { @@ -1261,6 +1264,46 @@ locate_roundrobin(Locator *self, Datum value, bool isnull, return 1; } +/* + * Each time return one node, in a random manner + * This is similar to locate_modulo_select, but that + * function does not use a random modulo.. + */ +static int +locate_modulo_random(Locator *self, Datum value, bool isnull, + bool *hasprimary) +{ + int offset; + + if (hasprimary) + *hasprimary = false; + + Assert(self->nodeCount > 0); + offset = compute_modulo(abs(rand()), self->nodeCount); + switch (self->listType) + { + case LOCATOR_LIST_NONE: + ((int *) self->results)[0] = offset; + break; + case LOCATOR_LIST_INT: + ((int *) self->results)[0] = + ((int *) self->nodeMap)[offset]; + break; + case LOCATOR_LIST_OID: + ((Oid *) self->results)[0] = + ((Oid *) self->nodeMap)[offset]; + break; + case LOCATOR_LIST_POINTER: + ((void **) self->results)[0] = + ((void **) self->nodeMap)[offset]; + break; + case LOCATOR_LIST_LIST: + /* Should never happen */ + Assert(false); + break; + } + return 1; +} /* * Calculate hash from supplied value and use modulo by nodeCount as an index