diff --git a/lib/fprint.c b/lib/fprint.c index 03987e8f57..41fc1b5799 100644 --- a/lib/fprint.c +++ b/lib/fprint.c @@ -4,6 +4,8 @@ #include "system.h" +#include + #include /* for rpmCleanPath */ #include #include @@ -17,35 +19,12 @@ #include "debug.h" #include -/* Create new hash table type rpmFpEntryHash */ -#define HASHTYPE rpmFpEntryHash -#define HTKEYTYPE rpmsid -#define HTDATATYPE const struct fprintCacheEntry_s * -#include "rpmhash.H" -#include "rpmhash.C" -#undef HASHTYPE -#undef HTKEYTYPE -#undef HTDATATYPE - -/* Create by-fingerprint hash table */ -#define HASHTYPE rpmFpHash -#define HTKEYTYPE const fingerPrint * -#define HTDATATYPE struct rpmffi_s -#include "rpmhash.H" -#include "rpmhash.C" -#undef HASHTYPE -#undef HTKEYTYPE -#undef HTDATATYPE static unsigned int sidHash(rpmsid sid) { return sid; } -static int sidCmp(rpmsid a, rpmsid b) -{ - return (a != b); -} /** * Finger print cache entry. @@ -63,7 +42,7 @@ struct fprintCacheEntry_s { * Associates a trailing sub-directory and final base name with an existing * directory finger print. */ -struct fingerPrint_s { +struct fingerPrint { /*! directory finger print entry (the directory path is stat(2)-able */ const struct fprintCacheEntry_s * entry; /*! trailing sub-directory path (directories that are not stat(2)-able */ @@ -79,6 +58,42 @@ struct fingerPrint_s { ((a).subDirId == (b).subDirId) \ ) +/* Hash value for a finger print pointer, based on dev and inode only! */ +struct fpHash +{ + size_t operator() (const fingerPrint *fp) const + { + unsigned int hash = 0; + int j; + + hash = sidHash(fp->baseNameId); + if (fp->subDirId) hash ^= sidHash(fp->subDirId); + + hash ^= ((unsigned)fp->entry->dev); + for (j=0; j<4; j++) hash ^= ((fp->entry->ino >> (8*j)) & 0xFF) << ((3-j)*8); + + return hash; + } +}; + +struct fpEqual +{ + bool operator()(const fingerPrint * k1, const fingerPrint * k2) const + { + /* If the addresses are the same, so are the values. */ + if (k1 == k2) + return true; + + /* Otherwise, compare fingerprints by value. */ + if (FP_EQUAL(*k1, *k2)) + return true; + return false; + } +}; + +using rpmFpEntryHash = std::unordered_multimap; +using rpmFpHash = std::unordered_map; + /** * Finger print cache. */ @@ -91,8 +106,6 @@ struct fprintCache_s { fingerPrintCache fpCacheCreate(int sizeHint, rpmstrPool pool) { fingerPrintCache fpc = new fprintCache_s {}; - fpc->ht = rpmFpEntryHashCreate(sizeHint, sidHash, sidCmp, - NULL, (rpmFpEntryHashFreeData)free); fpc->pool = (pool != NULL) ? rpmstrPoolLink(pool) : rpmstrPoolCreate(); return fpc; } @@ -100,8 +113,6 @@ fingerPrintCache fpCacheCreate(int sizeHint, rpmstrPool pool) fingerPrintCache fpCacheFree(fingerPrintCache cache) { if (cache) { - cache->ht = rpmFpEntryHashFree(cache->ht); - cache->fp = rpmFpHashFree(cache->fp); cache->pool = rpmstrPoolFree(cache->pool); delete cache; } @@ -117,10 +128,9 @@ fingerPrintCache fpCacheFree(fingerPrintCache cache) static const struct fprintCacheEntry_s * cacheContainsDirectory( fingerPrintCache cache, rpmsid dirId) { - const struct fprintCacheEntry_s ** data; - - if (rpmFpEntryHashGetEntry(cache->ht, dirId, &data, NULL, NULL)) - return data[0]; + auto entry = cache->ht.find(dirId); + if (entry != cache->ht.end()) + return &entry->second; return NULL; } @@ -177,15 +187,13 @@ static int doLookupId(fingerPrintCache cache, if (cacheHit != NULL) { fp->entry = cacheHit; } else if (!stat(rpmstrPoolStr(cache->pool, fpId), &sb)) { - struct fprintCacheEntry_s * newEntry = - (struct fprintCacheEntry_s *)xmalloc(sizeof(* newEntry)); - - newEntry->ino = sb.st_ino; - newEntry->dev = sb.st_dev; - newEntry->dirId = fpId; - fp->entry = newEntry; - - rpmFpEntryHashAddEntry(cache->ht, fpId, fp->entry); + struct fprintCacheEntry_s newEntry = { + .dirId = fpId, + .dev = sb.st_dev, + .ino = sb.st_ino, + }; + auto ret = cache->ht.insert({fpId, newEntry}); + fp->entry = &ret->second; } if (fp->entry) { @@ -243,39 +251,6 @@ int fpLookupId(fingerPrintCache cache, return doLookupId(cache, dirNameId, baseNameId, *fp); } -/** - * Return hash value for a finger print. - * Hash based on dev and inode only! - * @param fp pointer to finger print entry - * @return hash value - */ -static unsigned int fpHashFunction(const fingerPrint * fp) -{ - unsigned int hash = 0; - int j; - - hash = sidHash(fp->baseNameId); - if (fp->subDirId) hash ^= sidHash(fp->subDirId); - - hash ^= ((unsigned)fp->entry->dev); - for (j=0; j<4; j++) hash ^= ((fp->entry->ino >> (8*j)) & 0xFF) << ((3-j)*8); - - return hash; -} - -int fpEqual(const fingerPrint * k1, const fingerPrint * k2) -{ - /* If the addresses are the same, so are the values. */ - if (k1 == k2) - return 0; - - /* Otherwise, compare fingerprints by value. */ - if (FP_EQUAL(*k1, *k2)) - return 0; - return 1; - -} - const char * fpEntryDir(fingerPrintCache cache, fingerPrint *fp) { const char * dn = NULL; @@ -292,7 +267,7 @@ dev_t fpEntryDev(fingerPrintCache cache, fingerPrint *fp) int fpLookupEquals(fingerPrintCache cache, fingerPrint *fp, const char * dirName, const char * baseName) { - struct fingerPrint_s ofp; + struct fingerPrint ofp; doLookup(cache, dirName, baseName, &ofp); return FP_EQUAL(*fp, ofp); } @@ -300,7 +275,7 @@ int fpLookupEquals(fingerPrintCache cache, fingerPrint *fp, int fpLookupEqualsId(fingerPrintCache cache, fingerPrint *fp, rpmsid dirNameId, rpmsid baseNameId) { - struct fingerPrint_s ofp; + struct fingerPrint ofp; doLookupId(cache, dirNameId, baseNameId, &ofp); return FP_EQUAL(*fp, ofp); } @@ -338,13 +313,9 @@ fingerPrint * fpLookupList(fingerPrintCache cache, rpmstrPool pool, /* Check file for to be installed symlinks in their path and correct their fp */ static void fpLookupSubdir(rpmFpHash symlinks, fingerPrintCache fpc, fingerPrint *fp) { - struct fingerPrint_s current_fp; + struct fingerPrint current_fp; const char *currentsubdir; size_t lensubDir, bnStart, bnEnd; - - struct rpmffi_s * recs; - int numRecs; - int i; int symlinkcount = 0; for (;;) { @@ -369,11 +340,11 @@ static void fpLookupSubdir(rpmFpHash symlinks, fingerPrintCache fpc, fingerPrint currentsubdir + bnStart, bnEnd - bnStart, 1); - rpmFpHashGetEntry(symlinks, ¤t_fp, &recs, &numRecs, NULL); - - for (i = 0; i < numRecs; i++) { - rpmfiles foundfi = rpmteFiles(recs[i].p); - char const *linktarget = rpmfilesFLink(foundfi, recs[i].fileno); + auto range = symlinks.equal_range(¤t_fp); + for (auto it = range.first; it != range.second; ++it) { + const rpmffi_s & rec = it->second; + rpmfiles foundfi = rpmteFiles(rec.p); + char const *linktarget = rpmfilesFLink(foundfi, rec.fileno); char *link; rpmsid linkId; @@ -429,12 +400,15 @@ static void fpLookupSubdir(rpmFpHash symlinks, fingerPrintCache fpc, fingerPrint } fingerPrint * fpCacheGetByFp(fingerPrintCache cache, - struct fingerPrint_s * fp, int ix, - struct rpmffi_s ** recs, int * numRecs) + struct fingerPrint * fp, int ix, + std::vector & recs) { - if (rpmFpHashGetEntry(cache->fp, fp + ix, recs, numRecs, NULL)) + auto range = cache->fp.equal_range(fp + ix); + if (range.first != range.second) { + for (auto it = range.first; it != range.second; ++it) + recs.push_back(it->second); return fp + ix; - else + } else return NULL; } @@ -447,11 +421,7 @@ void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount) int i, fc; int havesymlinks = 0; - if (fpc->fp == NULL) - fpc->fp = rpmFpHashCreate(fileCount/2 + 10001, fpHashFunction, fpEqual, - NULL, NULL); - - rpmFpHash symlinks = rpmFpHashCreate(fileCount/16+16, fpHashFunction, fpEqual, NULL, NULL); + rpmFpHash symlinks; /* populate the fingerprints of all packages in the transaction */ /* also create a hash of all symlinks in the new packages */ @@ -478,7 +448,7 @@ void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount) continue; ffi.p = p; ffi.fileno = i; - rpmFpHashAddEntry(symlinks, fpList + i, ffi); + symlinks.insert({fpList + i, ffi}); havesymlinks = 1; } } @@ -516,14 +486,12 @@ void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount) } ffi.p = p; ffi.fileno = i; - rpmFpHashAddEntry(fpc->fp, fpList + i, ffi); + fpc->fp.insert({fpList + i, ffi}); lastfp = fpList + i; } (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); rpmfilesFree(fi); } rpmtsiFree(pi); - - rpmFpHashFree(symlinks); } diff --git a/lib/fprint.h b/lib/fprint.h index 87fc619d5a..8816b86681 100644 --- a/lib/fprint.h +++ b/lib/fprint.h @@ -6,16 +6,14 @@ * Identify a file name path by a unique "finger print". */ +#include #include /** */ typedef struct fprintCache_s * fingerPrintCache; -/** - * @todo Convert to pointer and make abstract. - */ -typedef struct fingerPrint_s fingerPrint; +struct fingerPrint; struct rpmffi_s { rpmte p; @@ -41,8 +39,8 @@ fingerPrintCache fpCacheFree(fingerPrintCache cache); RPM_GNUC_INTERNAL fingerPrint * fpCacheGetByFp(fingerPrintCache cache, - struct fingerPrint_s * fp, int ix, - struct rpmffi_s ** recs, int * numRecs); + struct fingerPrint * fp, int ix, + std::vector & recs); RPM_GNUC_INTERNAL void fpCachePopulate(fingerPrintCache cache, rpmts ts, int fileCount); @@ -88,16 +86,6 @@ int fpLookupId(fingerPrintCache cache, rpmsid dirNameId, rpmsid BaseNameId, fingerPrint **fp); -/** - * Compare two finger print entries. - * This routine is exactly equivalent to the FP_EQUAL macro. - * @param key1 finger print 1 - * @param key2 finger print 2 - * @return result of comparing key1 and key2 - */ -RPM_GNUC_INTERNAL -int fpEqual(const fingerPrint * key1, const fingerPrint * key2); - /** * Return finger prints of an array of file paths. * @param cache pointer to fingerprint cache diff --git a/lib/rpmfi.c b/lib/rpmfi.c index 83ad47b999..a3d8ad4704 100644 --- a/lib/rpmfi.c +++ b/lib/rpmfi.c @@ -105,7 +105,7 @@ struct rpmfiles_s { rpmfiFlags fiflags; /*!< file info set control flags */ - struct fingerPrint_s * fps; /*!< File fingerprint(s). */ + struct fingerPrint * fps; /*!< File fingerprint(s). */ int digestalgo; /*!< File digest algorithm */ uint32_t *signatureoffs; /*!< File signature offsets */ @@ -829,7 +829,7 @@ int rpmfilesStat(rpmfiles fi, int ix, int flags, struct stat *sb) return rc; } -struct fingerPrint_s *rpmfilesFps(rpmfiles fi) +struct fingerPrint *rpmfilesFps(rpmfiles fi) { return (fi != NULL) ? fi->fps : NULL; } diff --git a/lib/rpmfi_internal.h b/lib/rpmfi_internal.h index 81902c35a2..d3fa598fed 100644 --- a/lib/rpmfi_internal.h +++ b/lib/rpmfi_internal.h @@ -79,7 +79,7 @@ RPM_GNUC_INTERNAL rpmsid rpmfilesODNId(rpmfiles fi, int jx); RPM_GNUC_INTERNAL -struct fingerPrint_s *rpmfilesFps(rpmfiles fi); +struct fingerPrint *rpmfilesFps(rpmfiles fi); /** \ingroup rpmfi * Check if the file in new package, in old package and on the disk have the same contents. diff --git a/lib/transaction.c b/lib/transaction.c index 572fb2761e..1453bc782e 100644 --- a/lib/transaction.c +++ b/lib/transaction.c @@ -504,13 +504,12 @@ static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfi fingerPrint * fpList = rpmfilesFps(fi); for (i = 0; i < fc; i++) { - struct fingerPrint_s * fiFps; + struct fingerPrint * fiFps; int otherPkgNum, otherFileNum; rpmfiles otherFi; rpmte otherTe; rpmfileAttrs FFlags; - struct rpmffi_s * recs; - int numRecs; + vector recs; rpm_loff_t fileSize; int nlink; const int *links; @@ -528,7 +527,7 @@ static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfi * will be installed and removed so the records for an overlapped * files will be sorted in exactly the same order. */ - fiFps = fpCacheGetByFp(fpc, fpList, i, &recs, &numRecs); + fiFps = fpCacheGetByFp(fpc, fpList, i, recs); /* * If this package is being added, look only at other packages @@ -557,7 +556,7 @@ static void handleOverlappedFiles(rpmts ts, fingerPrintCache fpc, rpmte p, rpmfi * files when directory symlinks are present. Don't compare a file * with itself though... */ - for (j = 0; j < numRecs && !(recs[j].p == p && recs[j].fileno == i); j++) + for (j = 0; j < recs.size() && !(recs[j].p == p && recs[j].fileno == i); j++) {}; /* Find what the previous disposition of this file was. */ @@ -1087,8 +1086,7 @@ void checkInstalledFiles(rpmts ts, uint64_t fileCount, fingerPrintCache fpc) /* loop over all interesting files in that package */ do { int fpIx; - struct rpmffi_s * recs; - int numRecs; + vector recs; const char * dirName; const char * baseName; @@ -1111,9 +1109,9 @@ void checkInstalledFiles(rpmts ts, uint64_t fileCount, fingerPrintCache fpc) } /* search for files in the transaction with same finger print */ - fpCacheGetByFp(fpc, fpp, fpIx, &recs, &numRecs); + fpCacheGetByFp(fpc, fpp, fpIx, recs); - for (j = 0; j < numRecs; j++) { + for (j = 0; j < recs.size(); j++) { p = recs[j].p; fi = rpmteFiles(p); fs = rpmteGetFileStates(p); diff --git a/misc/rpmhash.C b/misc/rpmhash.C deleted file mode 100644 index 7ed96efb72..0000000000 --- a/misc/rpmhash.C +++ /dev/null @@ -1,309 +0,0 @@ -/** - * \file lib/rpmhash.c - * Hash table implemenation - */ - -#include "system.h" -#include -#include "debug.h" - -#define Bucket JOIN(HASHTYPE,Buket) -#define Bucket_s JOIN(HASHTYPE,Buket_s) - -typedef struct Bucket_s * Bucket; - -/** - */ -struct Bucket_s { - Bucket next; /*!< pointer to next item in bucket */ - HTKEYTYPE key; /*!< hash key */ -#ifdef HTDATATYPE - int dataCount; /*!< data entries */ - HTDATATYPE data[1]; /*!< data - grows by resizing whole bucket */ -#endif -}; - -/** - */ -struct HASHSTRUCT { - int numBuckets; /*!< number of hash buckets */ - Bucket * buckets; /*!< hash bucket array */ - hashFunctionType fn; /*!< generate hash value for key */ - hashEqualityType eq; /*!< compare hash keys for equality */ - hashFreeKey freeKey; - int bucketCount; /*!< number of used buckets */ - int keyCount; /*!< number of keys */ -#ifdef HTDATATYPE - int dataCount; /*!< number of data entries */ - hashFreeData freeData; -#endif -}; - -/** - * Find entry in hash table. - * @param ht pointer to hash table - * @param key pointer to key value - * @param keyHash key hash - * @return pointer to hash bucket of key (or NULL) - */ -static -Bucket HASHPREFIX(findEntry)(HASHTYPE ht, HTKEYTYPE key, unsigned int keyHash) -{ - unsigned int hash = keyHash % ht->numBuckets; - Bucket b = ht->buckets[hash]; - - while (b && ht->eq(b->key, key)) - b = b->next; - - return b; -} - -HASHTYPE HASHPREFIX(Create)(int numBuckets, - hashFunctionType fn, hashEqualityType eq, - hashFreeKey freeKey -#ifdef HTDATATYPE -, hashFreeData freeData -#endif -) -{ - HASHTYPE ht; - - ht = (HASHTYPE)xmalloc(sizeof(*ht)); - ht->numBuckets = numBuckets > 11 ? numBuckets : 11; - ht->buckets = (Bucket *)xcalloc(ht->numBuckets, sizeof(*ht->buckets)); - ht->freeKey = freeKey; -#ifdef HTDATATYPE - ht->freeData = freeData; - ht->dataCount = 0; -#endif - ht->fn = fn; - ht->eq = eq; - ht->bucketCount = ht->keyCount = 0; - return ht; -} - -static void HASHPREFIX(Resize)(HASHTYPE ht, int numBuckets) { - Bucket * buckets = (Bucket *)xcalloc(numBuckets, sizeof(*ht->buckets)); - - for (int i=0; inumBuckets; i++) { - Bucket b = ht->buckets[i]; - Bucket nextB; - while (b != NULL) { - unsigned int hash = ht->fn(b->key) % numBuckets; - nextB = b->next; - b->next = buckets[hash]; - buckets[hash] = b; - b = nextB; - } - } - free(ht->buckets); - ht->buckets = buckets; - ht->numBuckets = numBuckets; -} - -unsigned int HASHPREFIX(KeyHash)(HASHTYPE ht, HTKEYTYPE key) -{ - return ht->fn(key); -} - -void HASHPREFIX(AddHEntry)(HASHTYPE ht, HTKEYTYPE key, unsigned int keyHash -#ifdef HTDATATYPE -, HTDATATYPE data -#endif -) -{ - unsigned int hash = keyHash % ht->numBuckets; - Bucket b = ht->buckets[hash]; -#ifdef HTDATATYPE - Bucket * b_addr = ht->buckets + hash; -#endif - - if (b == NULL) { - ht->bucketCount += 1; - } - - while (b && ht->eq(b->key, key)) { -#ifdef HTDATATYPE - b_addr = &(b->next); -#endif - b = b->next; - } - - if (b == NULL) { - ht->keyCount += 1; - b = (Bucket)xmalloc(sizeof(*b)); - b->key = key; -#ifdef HTDATATYPE - b->dataCount = 1; - b->data[0] = data; -#endif - b->next = ht->buckets[hash]; - ht->buckets[hash] = b; - } -#ifdef HTDATATYPE - else { - if (ht->freeKey) - ht->freeKey(key); - // resizing bucket TODO: increase exponentially - // Bucket_s already contains space for one dataset - b = *b_addr = xrealloc( - b, sizeof(*b) + sizeof(b->data[0]) * (b->dataCount)); - // though increasing dataCount after the resize - b->data[b->dataCount++] = data; - } - ht->dataCount += 1; -#endif - if (ht->keyCount > ht->numBuckets) { - HASHPREFIX(Resize)(ht, ht->numBuckets * 2); - } -} - -void HASHPREFIX(AddEntry)(HASHTYPE ht, HTKEYTYPE key -#ifdef HTDATATYPE -, HTDATATYPE data -#endif -) -{ -#ifdef HTDATATYPE - HASHPREFIX(AddHEntry)(ht, key, ht->fn(key), data); -#else - HASHPREFIX(AddHEntry)(ht, key, ht->fn(key)); -#endif -} - -void HASHPREFIX(Empty)( HASHTYPE ht) -{ - Bucket b, n; - int i; - - if (ht->bucketCount == 0) return; - - for (i = 0; i < ht->numBuckets; i++) { - b = ht->buckets[i]; - if (b == NULL) - continue; - ht->buckets[i] = NULL; - - do { - n = b->next; - if (ht->freeKey) - b->key = ht->freeKey(b->key); -#ifdef HTDATATYPE - if (ht->freeData) { - int j; - for (j=0; j < b->dataCount; j++ ) { - b->data[j] = ht->freeData(b->data[j]); - } - } -#endif - b = _free(b); - } while ((b = n) != NULL); - } - ht->bucketCount = 0; - ht->keyCount = 0; -#ifdef HTDATATYPE - ht->dataCount = 0; -#endif -} - -HASHTYPE HASHPREFIX(Free)(HASHTYPE ht) -{ - if (ht==NULL) - return ht; - HASHPREFIX(Empty)(ht); - ht->buckets = _free(ht->buckets); - ht = _free(ht); - - return NULL; -} - -int HASHPREFIX(HasHEntry)(HASHTYPE ht, HTKEYTYPE key, unsigned int keyHash) -{ - Bucket b; - - if (!(b = HASHPREFIX(findEntry)(ht, key, keyHash))) return 0; else return 1; -} - -int HASHPREFIX(HasEntry)(HASHTYPE ht, HTKEYTYPE key) -{ - return HASHPREFIX(HasHEntry)(ht, key, ht->fn(key)); -} - -int HASHPREFIX(GetHEntry)(HASHTYPE ht, HTKEYTYPE key, unsigned int keyHash, -#ifdef HTDATATYPE - HTDATATYPE** data, int * dataCount, -#endif - HTKEYTYPE* tableKey) -{ - Bucket b; - int rc = ((b = HASHPREFIX(findEntry)(ht, key, keyHash)) != NULL); - -#ifdef HTDATATYPE - if (data) - *data = rc ? b->data : NULL; - if (dataCount) - *dataCount = rc ? b->dataCount : 0; -#endif - if (tableKey && rc) - *tableKey = b->key; - - return rc; -} - -int HASHPREFIX(GetEntry)(HASHTYPE ht, HTKEYTYPE key, -#ifdef HTDATATYPE - HTDATATYPE** data, int * dataCount, -#endif - HTKEYTYPE* tableKey) -{ - return HASHPREFIX(GetHEntry)(ht, key, ht->fn(key), -#ifdef HTDATATYPE - data, dataCount, -#endif - tableKey); -} - -unsigned int HASHPREFIX(NumBuckets)(HASHTYPE ht) { - return ht->numBuckets; -} - -unsigned int HASHPREFIX(UsedBuckets)(HASHTYPE ht) { - return ht->bucketCount; -} - -unsigned int HASHPREFIX(NumKeys)(HASHTYPE ht) { - return ht->keyCount; -} - -#ifdef HTDATATYPE -unsigned int HASHPREFIX(NumData)(HASHTYPE ht) { - return ht->dataCount; -} -#endif - - -void HASHPREFIX(PrintStats)(HASHTYPE ht) { - int i; - Bucket bucket; - - int hashcnt=0, bucketcnt=0, datacnt=0; - int maxbuckets=0; - - for (i=0; inumBuckets; i++) { - int buckets = 0; - for (bucket=ht->buckets[i]; bucket; bucket=bucket->next){ - buckets++; -#ifdef HTDATATYPE - datacnt += bucket->dataCount; -#endif - } - if (maxbuckets < buckets) maxbuckets = buckets; - if (buckets) hashcnt++; - bucketcnt += buckets; - } - fprintf(stderr, "Hashsize: %i\n", ht->numBuckets); - fprintf(stderr, "Hashbuckets: %i\n", hashcnt); - fprintf(stderr, "Keys: %i\n", bucketcnt); - fprintf(stderr, "Values: %i\n", datacnt); - fprintf(stderr, "Max Keys/Bucket: %i\n", maxbuckets); -} diff --git a/misc/rpmhash.H b/misc/rpmhash.H deleted file mode 100644 index 4d6e17af53..0000000000 --- a/misc/rpmhash.H +++ /dev/null @@ -1,174 +0,0 @@ -/** - * \file lib/rpmhash.h - * Hash table implemenation. - */ - -#include -// Hackery to make sure that macros get expanded -#define __JOIN(a,b) a##b -#define JOIN(a,b) __JOIN(a,b) -#define HASHPREFIX(name) JOIN(HASHTYPE,name) -#define HASHSTRUCT JOIN(HASHTYPE,_s) - -typedef struct HASHSTRUCT * HASHTYPE; - -/* function pointer types to deal with the datatypes the hash works with */ - -#define hashFunctionType JOIN(HASHTYPE,HashFunctionType) -#define hashEqualityType JOIN(HASHTYPE,HashEqualityType) -#define hashFreeKey JOIN(HASHTYPE,FreeKey) - -typedef unsigned int (*hashFunctionType) (HTKEYTYPE string); -typedef int (*hashEqualityType) (HTKEYTYPE key1, HTKEYTYPE key2); -typedef HTKEYTYPE (*hashFreeKey) (HTKEYTYPE); - -#ifdef HTDATATYPE -#define hashFreeData JOIN(HASHTYPE,FreeData) -typedef HTDATATYPE (*hashFreeData) (HTDATATYPE); -#endif - -/** - * Create hash table. - * If keySize > 0, the key is duplicated within the table (which costs - * memory, but may be useful anyway. - * @param numBuckets number of hash buckets - * @param fn function to generate hash value for key - * @param eq function to compare hash keys for equality - * @param freeKey function to free the keys or NULL - * @param freeData function to free the data or NULL - * @return pointer to initialized hash table - */ -RPM_GNUC_INTERNAL -HASHTYPE HASHPREFIX(Create)(int numBuckets, - hashFunctionType fn, hashEqualityType eq, - hashFreeKey freeKey -#ifdef HTDATATYPE -, hashFreeData freeData -#endif -); - -/** - * Destroy hash table. - * @param ht pointer to hash table - * @return NULL always - */ -RPM_GNUC_INTERNAL -HASHTYPE HASHPREFIX(Free)( HASHTYPE ht); - -/** - * Remove all entries from the hash table. - * @param ht pointer to hash table - */ -RPM_GNUC_INTERNAL -void HASHPREFIX(Empty)(HASHTYPE ht); - -/** - * Calculate hash for key. - * @param @ht pointer to hash table - * @param @key key - */ -RPM_GNUC_INTERNAL -unsigned int HASHPREFIX(KeyHash)(HASHTYPE ht, HTKEYTYPE key); - -/** - * Add item to hash table. - * @param ht pointer to hash table - * @param key key - * @param data data value - */ -RPM_GNUC_INTERNAL -void HASHPREFIX(AddEntry)(HASHTYPE ht, HTKEYTYPE key -#ifdef HTDATATYPE -, HTDATATYPE data -#endif -); - -/* Add item to hash table with precalculated key hash. */ -RPM_GNUC_INTERNAL -void HASHPREFIX(AddHEntry)(HASHTYPE ht, HTKEYTYPE key, unsigned int keyHash -#ifdef HTDATATYPE -, HTDATATYPE data -#endif -); - -/** - * Retrieve item from hash table. - * @param ht pointer to hash table - * @param key key value - * @retval data address to store data value from bucket - * @retval dataCount address to store data value size from bucket - * @retval tableKey address to store key value from bucket (may be NULL) - * @return 1 on success, 0 if the item is not found. - */ -RPM_GNUC_INTERNAL -int HASHPREFIX(GetEntry)(HASHTYPE ht, HTKEYTYPE key, -#ifdef HTDATATYPE - HTDATATYPE** data, - int * dataCount, -#endif - HTKEYTYPE* tableKey); - -/* Retrieve item from hash table with precalculated key hash. */ -RPM_GNUC_INTERNAL -int HASHPREFIX(GetHEntry)(HASHTYPE ht, HTKEYTYPE key, unsigned int keyHash, -#ifdef HTDATATYPE - HTDATATYPE** data, - int * dataCount, -#endif - HTKEYTYPE* tableKey); - -/** - * Check for key in hash table. - * @param ht pointer to hash table - * @param key key value - * @return 1 if the key is present, 0 otherwise - */ -RPM_GNUC_INTERNAL -int HASHPREFIX(HasEntry)(HASHTYPE ht, HTKEYTYPE key); - -/* Check for key in hash table with precalculated key hash. */ -RPM_GNUC_INTERNAL -int HASHPREFIX(HasHEntry)(HASHTYPE ht, HTKEYTYPE key, unsigned int keyHash); - -/** - * How many buckets are currently allocated (result is implementation - * dependent) - * @param ht pointer to hash table - * @result number of buckets allocated - */ -RPM_GNUC_INTERNAL -unsigned int HASHPREFIX(NumBuckets)(HASHTYPE ht); - -/** - * How many buckets are used (result is implementation dependent) - * @param ht pointer to hash table - * @result number of buckets used - */ -RPM_GNUC_INTERNAL -unsigned int HASHPREFIX(UsedBuckets)(HASHTYPE ht); - -/** - * How many (unique) keys have been added to the hash table - * @param ht pointer to hash table - * @result number of unique keys - */ -RPM_GNUC_INTERNAL -unsigned int HASHPREFIX(NumKeys)(HASHTYPE ht); - -#ifdef HTDATATYPE -/** - * How many data entries have been added to the hash table - * @param ht pointer to hash table - * @result number of data entries - */ -RPM_GNUC_INTERNAL -unsigned int HASHPREFIX(NumData)(HASHTYPE ht); -#endif - -/** - * Print statistics about the hash to stderr - * This is for debugging only - * @param ht pointer to hash table - */ -RPM_GNUC_INTERNAL -void HASHPREFIX(PrintStats)(HASHTYPE ht);