jhash.h, rpmhash.c: switch to Jenkins One-at-a-time hash
This commit is contained in:
parent
6a9eae99c7
commit
6d4fea769d
@ -1525,7 +1525,7 @@ int rpmRunTransactions( rpmTransactionSet ts,
|
||||
int i, j;
|
||||
int ourrc = 0;
|
||||
struct availablePackage * alp;
|
||||
int totalFileCount = 0;
|
||||
unsigned int totalFileCount = 0;
|
||||
hashTable ht;
|
||||
TFI_t fi;
|
||||
struct diskspaceInfo * dip;
|
||||
@ -1773,7 +1773,7 @@ int rpmRunTransactions( rpmTransactionSet ts,
|
||||
#endif
|
||||
}
|
||||
|
||||
ht = htCreate(totalFileCount * 2, fpHashFunction, fpEqual);
|
||||
ht = htCreate(totalFileCount, fpHashFunction, fpEqual);
|
||||
fpc = fpCacheCreate(totalFileCount);
|
||||
|
||||
/* ===============================================
|
||||
|
@ -16,7 +16,7 @@ LIBPOPT = @LIBPOPT@
|
||||
|
||||
pkgincdir = $(pkgincludedir)
|
||||
pkginc_HEADERS = hdrinline.h rpmdb.h
|
||||
noinst_HEADERS = falloc.h fprint.h rpmhash.h
|
||||
noinst_HEADERS = falloc.h fprint.h rpmhash.h jhash.h
|
||||
|
||||
mylibpaths = -L$(top_builddir)/lib/.libs
|
||||
mylibs = -lrpm
|
||||
|
@ -10,12 +10,12 @@
|
||||
#include "fprint.h"
|
||||
#include "debug.h"
|
||||
|
||||
fingerPrintCache fpCacheCreate(int sizeHint)
|
||||
fingerPrintCache fpCacheCreate(unsigned int size)
|
||||
{
|
||||
fingerPrintCache fpc;
|
||||
|
||||
fpc = xmalloc(sizeof(*fpc));
|
||||
fpc->ht = htCreate(sizeHint * 2, hashFunctionString, hashEqualityString);
|
||||
fpc->ht = htCreate(size, hashFunctionString, hashEqualityString);
|
||||
return fpc;
|
||||
}
|
||||
|
||||
|
@ -87,10 +87,10 @@ int rpmdbFindFpList(/*@null@*/ rpmdb db, fingerPrint * fpList,
|
||||
|
||||
/**
|
||||
* Create finger print cache.
|
||||
* @param sizeHint number of elements expected
|
||||
* @param size number of elements expected
|
||||
* @return pointer to initialized fingerprint cache
|
||||
*/
|
||||
/*@only@*/ fingerPrintCache fpCacheCreate(int sizeHint)
|
||||
/*@only@*/ fingerPrintCache fpCacheCreate(unsigned int size)
|
||||
/*@*/;
|
||||
|
||||
/**
|
||||
|
80
rpmdb/jhash.h
Normal file
80
rpmdb/jhash.h
Normal file
@ -0,0 +1,80 @@
|
||||
#ifndef JHASH_H_
|
||||
#define JHASH_H_
|
||||
|
||||
/*
|
||||
* Jenkins One-at-a-time hash.
|
||||
* http://burtleburtle.net/bob/hash/doobs.html
|
||||
* Also used in perl, see PERL_HASH in hv.h.
|
||||
*/
|
||||
|
||||
static inline
|
||||
unsigned int jhashStringAppend(const char *str, unsigned int hash)
|
||||
{
|
||||
const char *p = str;
|
||||
while (*p) {
|
||||
hash += *p++;
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
hash += (hash << 15);
|
||||
return hash;
|
||||
}
|
||||
|
||||
static inline
|
||||
unsigned int jhashDataAppend(const void *data, unsigned int len,
|
||||
unsigned int hash)
|
||||
{
|
||||
const char *p = data;
|
||||
while (len--) {
|
||||
hash += *p++;
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
hash += (hash << 15);
|
||||
return hash;
|
||||
}
|
||||
|
||||
static inline
|
||||
unsigned int jhashInit(void)
|
||||
{
|
||||
/* The golden ratio really is an arbitrary value.
|
||||
* Its purpose is to avoid mapping all zeros to all zeros. */
|
||||
return 0x9e3779b9;
|
||||
}
|
||||
|
||||
static inline
|
||||
unsigned int jhashString(const char *str)
|
||||
{
|
||||
return jhashStringAppend(str, jhashInit());
|
||||
}
|
||||
|
||||
static inline
|
||||
unsigned int jhashData(const void *data, unsigned int len)
|
||||
{
|
||||
return jhashDataAppend(data, len, jhashInit());
|
||||
}
|
||||
|
||||
/*
|
||||
* The best hash table sizes are powers of 2.
|
||||
*/
|
||||
|
||||
static inline
|
||||
unsigned int jhashSize(unsigned int size)
|
||||
{
|
||||
if (size < 16)
|
||||
return 8;
|
||||
/* 640K ought to be enough for anybody. */
|
||||
if (size >= (1 << 20))
|
||||
return (1 << 20);
|
||||
/* Round down to proper power of 2.
|
||||
* See Perl_hv_ksplit in hv.c. */
|
||||
while ((size & (1 + ~size)) != size)
|
||||
size &= ~(size & (1 + ~size));
|
||||
return size;
|
||||
}
|
||||
|
||||
#endif
|
@ -8,6 +8,8 @@
|
||||
#include "rpmhash.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "jhash.h"
|
||||
|
||||
typedef struct hashBucket_s * hashBucket;
|
||||
|
||||
/**
|
||||
@ -22,7 +24,7 @@ struct hashBucket_s {
|
||||
/**
|
||||
*/
|
||||
struct hashTable_s {
|
||||
int numBuckets; /*!< number of hash buckets */
|
||||
unsigned int numBuckets; /*!< number of hash buckets */
|
||||
hashBucket * buckets; /*!< hash bucket array */
|
||||
hashFunctionType fn; /*!< generate hash value for key */
|
||||
hashEqualityType eq; /*!< compare hash keys for equality */
|
||||
@ -42,7 +44,7 @@ hashBucket findEntry(hashTable ht, const void * key)
|
||||
hashBucket b;
|
||||
|
||||
/*@-modunconnomods@*/
|
||||
hash = ht->fn(key) % ht->numBuckets;
|
||||
hash = ht->fn(key) & (ht->numBuckets - 1);
|
||||
b = ht->buckets[hash];
|
||||
|
||||
while (b && b->key && ht->eq(b->key, key))
|
||||
@ -59,30 +61,18 @@ int hashEqualityString(const void * key1, const void * key2)
|
||||
return strcmp(k1, k2);
|
||||
}
|
||||
|
||||
unsigned int hashFunctionString(const void * string)
|
||||
unsigned int hashFunctionString(const void *str)
|
||||
{
|
||||
char xorValue = 0;
|
||||
char sum = 0;
|
||||
short len;
|
||||
int i;
|
||||
const char * chp = string;
|
||||
|
||||
len = strlen(string);
|
||||
for (i = 0; i < len; i++, chp++) {
|
||||
xorValue ^= *chp;
|
||||
sum += *chp;
|
||||
}
|
||||
|
||||
return ((((unsigned)len) << 16) + (((unsigned)sum) << 8) + xorValue);
|
||||
return jhashString(str);
|
||||
}
|
||||
|
||||
hashTable htCreate(int numBuckets, hashFunctionType fn, hashEqualityType eq)
|
||||
hashTable htCreate(unsigned int size, hashFunctionType fn, hashEqualityType eq)
|
||||
{
|
||||
hashTable ht;
|
||||
|
||||
ht = xmalloc(sizeof(*ht));
|
||||
ht->numBuckets = numBuckets;
|
||||
ht->buckets = xcalloc(numBuckets, sizeof(*ht->buckets));
|
||||
ht->numBuckets = jhashSize(size);
|
||||
ht->buckets = xcalloc(ht->numBuckets, sizeof(*ht->buckets));
|
||||
/*@-assignexpose@*/
|
||||
ht->fn = fn;
|
||||
ht->eq = eq;
|
||||
@ -93,7 +83,7 @@ hashTable htCreate(int numBuckets, hashFunctionType fn, hashEqualityType eq)
|
||||
|
||||
void htAddEntry(hashTable ht, const void * key, const void * data)
|
||||
{
|
||||
unsigned int hash = ht->fn(key) % ht->numBuckets;
|
||||
unsigned int hash = ht->fn(key) & (ht->numBuckets - 1);
|
||||
hashBucket b = ht->buckets[hash];
|
||||
hashBucket *b_addr = ht->buckets + hash;
|
||||
|
||||
|
@ -46,12 +46,12 @@ typedef void *(*hashFreeDataType) (const void *data);
|
||||
|
||||
/**
|
||||
* Create hash table.
|
||||
* @param numBuckets number of hash buckets
|
||||
* @param size number of elements expected
|
||||
* @param fn function to generate hash value for key
|
||||
* @param eq function to compare hash keys for equality
|
||||
* @return pointer to initialized hash table
|
||||
*/
|
||||
hashTable htCreate(int numBuckets, hashFunctionType fn, hashEqualityType eq)
|
||||
hashTable htCreate(unsigned int size, hashFunctionType fn, hashEqualityType eq)
|
||||
/*@*/;
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user