[MEDIUM] implement the URI hash algorithm

Guillaume Dallaire contributed the URI hashing algorithm for
use with proxy-caches. It provides the advantage of optimizing
the cache hit rate.
diff --git a/include/proto/backend.h b/include/proto/backend.h
index b4c641e..f0295b0 100644
--- a/include/proto/backend.h
+++ b/include/proto/backend.h
@@ -2,7 +2,7 @@
   include/proto/backend.h
   Functions prototypes for the backend.
 
-  Copyright (C) 2000-2006 Willy Tarreau - w@1wt.eu
+  Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
   
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -116,6 +116,36 @@
 	return px->srv_map[h];
 }
 
+/* 
+ * This function tries to find a running server for the proxy <px> following
+ * the URI hash method. In order to optimize cache hits, the hash computation
+ * ends at the question mark. Depending on the number of active/backup servers,
+ * it will either look for active servers, or for backup servers.
+ * If any server is found, it will be returned. If no valid server is found,
+ * NULL is returned.
+ *
+ * This code was contributed by Guillaume Dallaire, who also selected this hash
+ * algorithm out of a tens because it gave him the best results.
+ *
+ */
+static inline struct server *get_server_uh(struct proxy *px, char *uri, int uri_len)
+{
+	unsigned long hash = 0;
+	int c;
+
+	if (px->srv_map_sz == 0)
+		return NULL;
+
+	while (uri_len--) {
+		c = *uri++;
+		if (c == '?')
+			break;
+		hash = c + (hash << 6) + (hash << 16) - hash;
+	}
+
+	return px->srv_map[hash % px->srv_map_sz];
+}
+
 
 #endif /* _PROTO_BACKEND_H */
 
diff --git a/include/types/backend.h b/include/types/backend.h
index d6079ad..e2d4efc 100644
--- a/include/types/backend.h
+++ b/include/types/backend.h
@@ -49,7 +49,6 @@
 #define PR_O_USE_ALL_BK 0x00100000      /* load-balance between backup servers */
 #define PR_O_FORCE_CLO  0x00200000      /* enforce the connection close immediately after server response */
 #define PR_O_BALANCE_SH 0x00400000      /* balance on source IP hash */
-#define PR_O_BALANCE    (PR_O_BALANCE_RR | PR_O_BALANCE_SH)
 #define PR_O_ABRT_CLOSE 0x00800000      /* immediately abort request when client closes */
 #define PR_O_SSL3_CHK   0x01000000      /* use SSLv3 CLIENT_HELLO packets for server health */
 
@@ -58,6 +57,8 @@
 #define	PR_O_TPXY_CLI	0x06000000	/* bind to the client's IP+port when connect()ing */
 #define	PR_O_TPXY_MASK	0x06000000	/* bind to a non-local address when connect()ing */
 #define	PR_O_TCPSPLICE	0x08000000      /* delegate data transfer to linux kernel's tcp_splice */
+#define PR_O_BALANCE_UH 0x10000000      /* balance on URI hash */
+#define PR_O_BALANCE    (PR_O_BALANCE_RR | PR_O_BALANCE_SH | PR_O_BALANCE_UH)
 
 
 #endif /* _TYPES_BACKEND_H */