Move string hash function to librpmio and rename for namespacing

- There are places in rpmio and build that would benefit from hashing, but
  hashFunctionString() being internal to librpm has prevented that. Rename
  to rstrhash() to resemble the other foo in rpmstring.h for
  minimal namespacing as its now public function and update callers.
- Also mark the function as "pure" - it only looks at its arguments.
  This is one of the busiest functions in entire rpm so any optimization
  no matter how minor is well worth it.
- Hereby awarding hashFunctionString() with the grand prize for
  the Most Moved Around Function in rpm ;)
This commit is contained in:
Panu Matilainen 2011-03-10 09:00:07 +02:00
parent ba38b2551f
commit 805f7fd5af
10 changed files with 34 additions and 36 deletions

View File

@ -26,7 +26,7 @@ librpm_la_SOURCES = \
rpmdb.c rpmdb_internal.h \
fprint.c fprint.h tagname.c rpmtd.c \
cpio.c cpio.h depends.c order.c formats.c tagexts.c fsm.c fsm.h \
manifest.c manifest.h misc.c package.c \
manifest.c manifest.h package.c \
poptALL.c poptI.c poptQV.c psm.c query.c \
rpmal.c rpmal.h rpmchecksig.c rpmds.c rpmfi.c rpmfi_internal.h \
rpmgi.h rpmgi.c rpminstall.c rpmts_internal.h \

View File

@ -530,7 +530,7 @@ int rpmtsCheck(rpmts ts)
}
/* XXX FIXME: figure some kind of heuristic for the cache size */
dcache = depCacheCreate(5001, hashFunctionString, strcmp,
dcache = depCacheCreate(5001, rstrhash, strcmp,
(depCacheFreeKey)rfree, NULL);
/*

View File

@ -29,7 +29,7 @@ fingerPrintCache fpCacheCreate(int sizeHint)
fingerPrintCache fpc;
fpc = xmalloc(sizeof(*fpc));
fpc->ht = rpmFpEntryHashCreate(sizeHint, hashFunctionString, strcmp,
fpc->ht = rpmFpEntryHashCreate(sizeHint, rstrhash, strcmp,
(rpmFpEntryHashFreeKey)free,
(rpmFpEntryHashFreeData)free);
return fpc;
@ -195,8 +195,8 @@ unsigned int fpHashFunction(const fingerPrint * fp)
unsigned int hash = 0;
int j;
hash = hashFunctionString(fp->baseName);
if (fp->subDir) hash ^= hashFunctionString(fp->subDir);
hash = rstrhash(fp->baseName);
if (fp->subDir) hash ^= rstrhash(fp->subDir);
hash ^= ((unsigned)fp->entry->dev);
for (j=0; j<4; j++) hash ^= ((fp->entry->ino >> (8*j)) & 0xFF) << ((3-j)*8);

View File

@ -1,24 +0,0 @@
/**
* \file lib/misc.c
*/
#include "system.h"
#include "lib/misc.h"
#include "debug.h"
unsigned int hashFunctionString(const char * string)
{
/* Jenkins One-at-a-time hash */
unsigned int hash = 0xe4721b68;
while (*string != '\0') {
hash += *string;
hash += (hash << 10);
hash ^= (hash >> 6);
string++;
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}

View File

@ -24,9 +24,6 @@ char * rpmVerifyString(uint32_t verifyResult, const char *pad);
RPM_GNUC_INTERNAL
char * rpmFFlagsString(uint32_t fflags, const char *pad);
RPM_GNUC_INTERNAL
unsigned int hashFunctionString(const char * string);
typedef char * (*headerTagFormatFunction) (rpmtd td, char * formatPrefix);
typedef int (*headerTagTagFunction) (Header h, rpmtd td, headerGetFlags hgflags);

View File

@ -121,7 +121,7 @@ rpmal rpmalFree(rpmal al)
}
static unsigned int fileHash(struct fileNameEntry_s file){
return hashFunctionString(file.dirName) ^ hashFunctionString(file.baseName);
return rstrhash(file.dirName) ^ rstrhash(file.baseName);
}
static int fileCompare(struct fileNameEntry_s one, struct fileNameEntry_s two) {
@ -240,7 +240,7 @@ static void rpmalMakeIndex(rpmal al)
fileCnt += rpmfiFC(alp->fi);
}
al->providesHash = rpmalProvidesHashCreate(providesCnt/4+128, hashFunctionString,
al->providesHash = rpmalProvidesHashCreate(providesCnt/4+128, rstrhash,
strcmp, NULL, NULL);
al->fileHash = rpmalFileHashCreate(fileCnt/4+128, fileHash, fileCompare,
NULL, NULL);

View File

@ -23,7 +23,7 @@ const char * rpmugStashStr(const char *str)
const char *ret = NULL;
if (str) {
if (strStash == NULL) {
strStash = strCacheCreate(64, hashFunctionString, strcmp,
strStash = strCacheCreate(64, rstrhash, strcmp,
(strCacheFreeKey)rfree);
}

View File

@ -862,7 +862,7 @@ rpmdbMatchIterator rpmFindBaseNamesInDB(rpmts ts, uint64_t fileCount)
const char * baseName;
rpmStringSet baseNames = rpmStringSetCreate(fileCount,
hashFunctionString, strcmp, NULL);
rstrhash, strcmp, NULL);
mi = rpmdbNewIterator(rpmtsGetRdb(ts), RPMDBI_BASENAMES);

View File

@ -189,3 +189,20 @@ size_t rstrlcpy(char *dest, const char *src, size_t n)
return s - src - 1; /* count does not include NUL */
}
unsigned int rstrhash(const char * string)
{
/* Jenkins One-at-a-time hash */
unsigned int hash = 0xe4721b68;
while (*string != '\0') {
hash += *string;
hash += (hash << 10);
hash ^= (hash >> 6);
string++;
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}

View File

@ -172,6 +172,14 @@ char *rstrscat(char **dest, const char *arg, ...) RPM_GNUC_NULL_TERMINATED;
*/
size_t rstrlcpy(char *dest, const char *src, size_t n);
/** \ingroup rpmstring
* String hashing function
* @param string string to hash
* @return hash id
*/
RPM_GNUC_PURE
unsigned int rstrhash(const char * string);
#ifdef __cplusplus
}
#endif