summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2012-09-18 06:01:43 +0300
committerPanu Matilainen <pmatilai@redhat.com>2012-09-18 06:11:37 +0300
commit4c75ab28b804e182bfd258b2caf54caf1e8e70be (patch)
tree3c810b2a832d1a9ad770708372e7f3abc75e073f
parent0927ab855e415a2823e1852d1497885e4903fad7 (diff)
downloadrpm-4c75ab28b804e182bfd258b2caf54caf1e8e70be.tar.gz
rpm-4c75ab28b804e182bfd258b2caf54caf1e8e70be.tar.bz2
rpm-4c75ab28b804e182bfd258b2caf54caf1e8e70be.zip
Make pool string->id operations properly length-aware
- Allow looking up and inserting partial key strings, this is useful in various cases where previously a local copy was needed for \0-terminating the key in the caller. - Take advantage of rstrlenhash() in rpmstrPoolId(), previously the length was only interesting when adding so we wasted a strlen() on every call when the string was already in the pool.
-rw-r--r--rpmio/rpmstrpool.c60
1 files changed, 41 insertions, 19 deletions
diff --git a/rpmio/rpmstrpool.c b/rpmio/rpmstrpool.c
index 589f06d92..d29fbefdd 100644
--- a/rpmio/rpmstrpool.c
+++ b/rpmio/rpmstrpool.c
@@ -191,18 +191,6 @@ static poolHash poolHashFree(poolHash ht)
return NULL;
}
-static rpmsid poolHashGetHEntry(rpmstrPool pool, const char * key, unsigned int keyHash)
-{
- poolHash ht = pool->hash;
- unsigned int hash = keyHash % ht->numBuckets;
- poolHashBucket b = ht->buckets[hash];
-
- while (b && strcmp(rpmstrPoolStr(pool, b->keyid), key))
- b = b->next;
-
- return (b == NULL) ? 0 : b->keyid;
-}
-
static void poolHashPrintStats(poolHash ht)
{
int i;
@@ -337,24 +325,58 @@ static rpmsid rpmstrPoolPut(rpmstrPool pool, const char *s, size_t slen, unsigne
return pool->offs_size;
}
-rpmsid rpmstrPoolIdn(rpmstrPool pool, const char *s, size_t slen, int create)
+static rpmsid rpmstrPoolGet(rpmstrPool pool, const char * key, size_t keylen,
+ unsigned int keyHash)
+{
+ poolHash ht = pool->hash;
+ unsigned int hash = keyHash % ht->numBuckets;
+ poolHashBucket b;
+ const char * s;
+
+ for (b = ht->buckets[hash]; b != NULL; b = b->next) {
+ s = rpmstrPoolStr(pool, b->keyid);
+ /* pool string could be longer than keylen, require exact matche */
+ if (strncmp(s, key, keylen) == 0 && s[keylen] == '\0')
+ break;
+ }
+
+ return (b == NULL) ? 0 : b->keyid;
+}
+
+static inline rpmsid strn2id(rpmstrPool pool, const char *s, size_t slen,
+ unsigned int hash, int create)
{
rpmsid sid = 0;
- if (pool && pool->hash && s) {
- unsigned int hash = rstrhash(s);
- sid = poolHashGetHEntry(pool, s, hash);
- if (sid == 0 && create && !pool->frozen) {
+ if (pool && pool->hash) {
+ sid = rpmstrPoolGet(pool, s, slen, hash);
+ if (sid == 0 && create && !pool->frozen)
sid = rpmstrPoolPut(pool, s, slen, hash);
- }
}
+ return sid;
+}
+rpmsid rpmstrPoolIdn(rpmstrPool pool, const char *s, size_t slen, int create)
+{
+ rpmsid sid = 0;
+
+ if (s != NULL) {
+ unsigned int hash = rstrnhash(s, slen);
+ sid = strn2id(pool, s, slen, hash, create);
+ }
return sid;
}
rpmsid rpmstrPoolId(rpmstrPool pool, const char *s, int create)
{
- return rpmstrPoolIdn(pool, s, strlen(s), create);
+ rpmsid sid = 0;
+
+ if (s != NULL) {
+ size_t slen;
+ unsigned int hash = rstrlenhash(s, &slen);
+ sid = strn2id(pool, s, slen, hash, create);
+ }
+ return sid;
}
const char * rpmstrPoolStr(rpmstrPool pool, rpmsid sid)