diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2012-09-18 06:01:43 +0300 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2012-09-18 06:11:37 +0300 |
commit | 4c75ab28b804e182bfd258b2caf54caf1e8e70be (patch) | |
tree | 3c810b2a832d1a9ad770708372e7f3abc75e073f | |
parent | 0927ab855e415a2823e1852d1497885e4903fad7 (diff) | |
download | rpm-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.c | 60 |
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) |