mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-12 09:10:16 +00:00
2004-07-09 Paul Jakma <paul@dishone.st>
* jhash.{c,h}: New files. Bob Jenkins' public domain hashing function, as implemented in linux kernel by David Miller.
This commit is contained in:
parent
5510e83b39
commit
b9790b34c8
@ -2,6 +2,8 @@
|
||||
|
||||
* Merge Kunihiro's 'show route-map' change and add
|
||||
compatibility aliases for route-map continue
|
||||
* jhash.{c,h}: New files. Bob Jenkins' public domain hashing
|
||||
function, as implemented in linux kernel by David Miller.
|
||||
|
||||
2004-07-09 Juris Kalnins <juris@mt.lv>
|
||||
|
||||
|
@ -11,7 +11,7 @@ libzebra_la_SOURCES = \
|
||||
sockunion.c prefix.c thread.c if.c memory.c buffer.c table.c hash.c \
|
||||
filter.c routemap.c distribute.c stream.c str.c log.c plist.c \
|
||||
zclient.c sockopt.c smux.c md5.c if_rmap.c keychain.c privs.c \
|
||||
debug.c sigevent.c pqueue.c
|
||||
debug.c sigevent.c pqueue.c jhash.c
|
||||
|
||||
libzebra_la_DEPENDENCIES = @LIB_REGEX@
|
||||
|
||||
@ -22,7 +22,7 @@ pkginclude_HEADERS = \
|
||||
memory.h network.h prefix.h routemap.h distribute.h sockunion.h \
|
||||
str.h stream.h table.h thread.h vector.h version.h vty.h zebra.h \
|
||||
plist.h zclient.h sockopt.h smux.h md5-gnu.h if_rmap.h keychain.h \
|
||||
privs.h debug.h sigevent.h pqueue.h
|
||||
privs.h debug.h sigevent.h pqueue.h jhash.h
|
||||
|
||||
EXTRA_DIST = regex.c regex-gnu.h
|
||||
|
||||
|
170
lib/jhash.c
Normal file
170
lib/jhash.c
Normal file
@ -0,0 +1,170 @@
|
||||
/* jhash.h: Jenkins hash support.
|
||||
*
|
||||
* Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net)
|
||||
*
|
||||
* http://burtleburtle.net/bob/hash/
|
||||
*
|
||||
* These are the credits from Bob's sources:
|
||||
*
|
||||
* lookup2.c, by Bob Jenkins, December 1996, Public Domain.
|
||||
* hash(), hash2(), hash3, and mix() are externally useful functions.
|
||||
* Routines to test the hash are included if SELF_TEST is defined.
|
||||
* You can use this free for any purpose. It has no warranty.
|
||||
*
|
||||
* Copyright (C) 2003 David S. Miller (davem@redhat.com)
|
||||
*
|
||||
* I've modified Bob's hash to be useful in the Linux kernel, and
|
||||
* any bugs present are surely my fault. -DaveM
|
||||
*/
|
||||
|
||||
#include "zebra.h"
|
||||
#include "jhash.h"
|
||||
|
||||
/* The golden ration: an arbitrary value */
|
||||
#define JHASH_GOLDEN_RATIO 0x9e3779b9
|
||||
|
||||
/* NOTE: Arguments are modified. */
|
||||
#define __jhash_mix(a, b, c) \
|
||||
{ \
|
||||
a -= b; a -= c; a ^= (c>>13); \
|
||||
b -= c; b -= a; b ^= (a<<8); \
|
||||
c -= a; c -= b; c ^= (b>>13); \
|
||||
a -= b; a -= c; a ^= (c>>12); \
|
||||
b -= c; b -= a; b ^= (a<<16); \
|
||||
c -= a; c -= b; c ^= (b>>5); \
|
||||
a -= b; a -= c; a ^= (c>>3); \
|
||||
b -= c; b -= a; b ^= (a<<10); \
|
||||
c -= a; c -= b; c ^= (b>>15); \
|
||||
}
|
||||
|
||||
/* The most generic version, hashes an arbitrary sequence
|
||||
* of bytes. No alignment or length assumptions are made about
|
||||
* the input key.
|
||||
*/
|
||||
u_int32_t
|
||||
jhash (void *key, u_int32_t length, u_int32_t initval)
|
||||
{
|
||||
u_int32_t a, b, c, len;
|
||||
u_int8_t *k = key;
|
||||
|
||||
len = length;
|
||||
a = b = JHASH_GOLDEN_RATIO;
|
||||
c = initval;
|
||||
|
||||
while (len >= 12)
|
||||
{
|
||||
a +=
|
||||
(k[0] + ((u_int32_t) k[1] << 8) + ((u_int32_t) k[2] << 16) +
|
||||
((u_int32_t) k[3] << 24));
|
||||
b +=
|
||||
(k[4] + ((u_int32_t) k[5] << 8) + ((u_int32_t) k[6] << 16) +
|
||||
((u_int32_t) k[7] << 24));
|
||||
c +=
|
||||
(k[8] + ((u_int32_t) k[9] << 8) + ((u_int32_t) k[10] << 16) +
|
||||
((u_int32_t) k[11] << 24));
|
||||
|
||||
__jhash_mix (a, b, c);
|
||||
|
||||
k += 12;
|
||||
len -= 12;
|
||||
}
|
||||
|
||||
c += length;
|
||||
switch (len)
|
||||
{
|
||||
case 11:
|
||||
c += ((u_int32_t) k[10] << 24);
|
||||
case 10:
|
||||
c += ((u_int32_t) k[9] << 16);
|
||||
case 9:
|
||||
c += ((u_int32_t) k[8] << 8);
|
||||
case 8:
|
||||
b += ((u_int32_t) k[7] << 24);
|
||||
case 7:
|
||||
b += ((u_int32_t) k[6] << 16);
|
||||
case 6:
|
||||
b += ((u_int32_t) k[5] << 8);
|
||||
case 5:
|
||||
b += k[4];
|
||||
case 4:
|
||||
a += ((u_int32_t) k[3] << 24);
|
||||
case 3:
|
||||
a += ((u_int32_t) k[2] << 16);
|
||||
case 2:
|
||||
a += ((u_int32_t) k[1] << 8);
|
||||
case 1:
|
||||
a += k[0];
|
||||
};
|
||||
|
||||
__jhash_mix (a, b, c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/* A special optimized version that handles 1 or more of u_int32_ts.
|
||||
* The length parameter here is the number of u_int32_ts in the key.
|
||||
*/
|
||||
u_int32_t
|
||||
jhash2 (u_int32_t * k, u_int32_t length, u_int32_t initval)
|
||||
{
|
||||
u_int32_t a, b, c, len;
|
||||
|
||||
a = b = JHASH_GOLDEN_RATIO;
|
||||
c = initval;
|
||||
len = length;
|
||||
|
||||
while (len >= 3)
|
||||
{
|
||||
a += k[0];
|
||||
b += k[1];
|
||||
c += k[2];
|
||||
__jhash_mix (a, b, c);
|
||||
k += 3;
|
||||
len -= 3;
|
||||
}
|
||||
|
||||
c += length * 4;
|
||||
|
||||
switch (len)
|
||||
{
|
||||
case 2:
|
||||
b += k[1];
|
||||
case 1:
|
||||
a += k[0];
|
||||
};
|
||||
|
||||
__jhash_mix (a, b, c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/* A special ultra-optimized versions that knows they are hashing exactly
|
||||
* 3, 2 or 1 word(s).
|
||||
*
|
||||
* NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally
|
||||
* done at the end is not done here.
|
||||
*/
|
||||
u_int32_t
|
||||
jhash_3words (u_int32_t a, u_int32_t b, u_int32_t c, u_int32_t initval)
|
||||
{
|
||||
a += JHASH_GOLDEN_RATIO;
|
||||
b += JHASH_GOLDEN_RATIO;
|
||||
c += initval;
|
||||
|
||||
__jhash_mix (a, b, c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
jhash_2words (u_int32_t a, u_int32_t b, u_int32_t initval)
|
||||
{
|
||||
return jhash_3words (a, b, 0, initval);
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
jhash_1word (u_int32_t a, u_int32_t initval)
|
||||
{
|
||||
return jhash_3words (a, 0, 0, initval);
|
||||
}
|
44
lib/jhash.h
Normal file
44
lib/jhash.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* jhash.h: Jenkins hash support.
|
||||
*
|
||||
* Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net)
|
||||
*
|
||||
* http://burtleburtle.net/bob/hash/
|
||||
*
|
||||
* These are the credits from Bob's sources:
|
||||
*
|
||||
* lookup2.c, by Bob Jenkins, December 1996, Public Domain.
|
||||
* hash(), hash2(), hash3, and mix() are externally useful functions.
|
||||
* Routines to test the hash are included if SELF_TEST is defined.
|
||||
* You can use this free for any purpose. It has no warranty.
|
||||
*
|
||||
* Copyright (C) 2003 David S. Miller (davem@redhat.com)
|
||||
*
|
||||
* I've modified Bob's hash to be useful in the Linux kernel, and
|
||||
* any bugs present are surely my fault. -DaveM
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_JHASH_H
|
||||
#define _QUAGGA_JHASH_H
|
||||
|
||||
/* The most generic version, hashes an arbitrary sequence
|
||||
* of bytes. No alignment or length assumptions are made about
|
||||
* the input key.
|
||||
*/
|
||||
u_int32_t jhash(void *key, u_int32_t length, u_int32_t initval);
|
||||
|
||||
/* A special optimized version that handles 1 or more of u_int32_ts.
|
||||
* The length parameter here is the number of u_int32_ts in the key.
|
||||
*/
|
||||
u_int32_t jhash2(u_int32_t *k, u_int32_t length, u_int32_t initval);
|
||||
|
||||
/* A special ultra-optimized versions that knows they are hashing exactly
|
||||
* 3, 2 or 1 word(s).
|
||||
*
|
||||
* NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally
|
||||
* done at the end is not done here.
|
||||
*/
|
||||
u_int32_t jhash_3words(u_int32_t a, u_int32_t b, u_int32_t c, u_int32_t initval);
|
||||
u_int32_t jhash_2words(u_int32_t a, u_int32_t b, u_int32_t initval);
|
||||
u_int32_t jhash_1word(u_int32_t a, u_int32_t initval);
|
||||
|
||||
#endif /* _QUAGGA_JHASH_H */
|
Loading…
Reference in New Issue
Block a user