From: Willy Tarreau Date: Wed, 24 Nov 2010 13:01:45 +0000 (+0100) Subject: [CLEANUP] hash: move the avalanche hash code globally available X-Git-Tag: v1.5-dev8~360 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4c14eaa0d4e1a9338da8aeb254de51fe47d17ed3;p=thirdparty%2Fhaproxy.git [CLEANUP] hash: move the avalanche hash code globally available We'll use this hash at other places, let's make it globally available. The function has also been renamed because its "chash_hash" name was not appropriate. --- diff --git a/include/common/standard.h b/include/common/standard.h index bdb6ec0fba..3990e6ffab 100644 --- a/include/common/standard.h +++ b/include/common/standard.h @@ -442,4 +442,28 @@ const char *quote_arg(const char *ptr); /* returns an operator among STD_OP_* for string or < 0 if unknown */ int get_std_op(const char *str); +/* hash a 32-bit integer to another 32-bit integer */ +extern unsigned int full_hash(unsigned int a); +static inline unsigned int __full_hash(unsigned int a) +{ + /* This function is one of Bob Jenkins' full avalanche hashing + * functions, which when provides quite a good distribution for little + * input variations. The result is quite suited to fit over a 32-bit + * space with enough variations so that a randomly picked number falls + * equally before any server position. + * Check http://burtleburtle.net/bob/hash/integer.html for more info. + */ + a = (a+0x7ed55d16) + (a<<12); + a = (a^0xc761c23c) ^ (a>>19); + a = (a+0x165667b1) + (a<<5); + a = (a+0xd3a2646c) ^ (a<<9); + a = (a+0xfd7046c5) + (a<<3); + a = (a^0xb55a4f09) ^ (a>>16); + + /* ensure values are better spread all around the tree by multiplying + * by a large prime close to 3/4 of the tree. + */ + return a * 3221225473U; +} + #endif /* _COMMON_STANDARD_H */ diff --git a/src/lb_chash.c b/src/lb_chash.c index 58c029a4ad..a2582f0680 100644 --- a/src/lb_chash.c +++ b/src/lb_chash.c @@ -7,7 +7,7 @@ * robin because we'll use it to replace the previous map-based implementation * which offered both algorithms. * - * Copyright 2000-2009 Willy Tarreau + * Copyright 2000-2010 Willy Tarreau * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -27,28 +28,6 @@ #include #include -static inline unsigned int chash_hash(unsigned int a) -{ - /* This function is one of Bob Jenkins' full avalanche hashing - * functions, which when provides quite a good distribution for little - * input variations. The result is quite suited to fit over a 32-bit - * space with enough variations so that a randomly picked number falls - * equally before any server position. - * Check http://burtleburtle.net/bob/hash/integer.html for more info. - */ - a = (a+0x7ed55d16) + (a<<12); - a = (a^0xc761c23c) ^ (a>>19); - a = (a+0x165667b1) + (a<<5); - a = (a+0xd3a2646c) ^ (a<<9); - a = (a+0xfd7046c5) + (a<<3); - a = (a^0xb55a4f09) ^ (a>>16); - - /* ensure values are better spread all around the tree by multiplying - * by a large prime close to 3/4 of the tree. - */ - return a * 3221225473U; -} - /* Return next tree node after which must still be in the tree, or be * NULL. Lookup wraps around the end to the beginning. If the next node is the * same node, return NULL. This is designed to find a valid next node before @@ -292,7 +271,7 @@ struct server *chash_get_server_hash(struct proxy *p, unsigned int hash) else return NULL; - hash = chash_hash(hash); + hash = full_hash(hash); /* find the node after and the node before */ next = eb32_lookup_ge(root, hash); @@ -418,7 +397,7 @@ void chash_init_server_tree(struct proxy *p) for (node = 0; node < srv->lb_nodes_tot; node++) { srv->lb_nodes[node].server = srv; - srv->lb_nodes[node].node.key = chash_hash(srv->puid * SRV_EWGHT_RANGE + node); + srv->lb_nodes[node].node.key = full_hash(srv->puid * SRV_EWGHT_RANGE + node); } if (srv_is_usable(srv->state, srv->eweight)) diff --git a/src/standard.c b/src/standard.c index 60f5af1f5d..1ab2194128 100644 --- a/src/standard.c +++ b/src/standard.c @@ -1106,6 +1106,12 @@ int get_std_op(const char *str) return ret; } +/* hash a 32-bit integer to another 32-bit integer */ +unsigned int full_hash(unsigned int a) +{ + return __full_hash(a); +} + /* * Local variables: * c-indent-level: 8