diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2012-09-19 13:01:59 +0300 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2012-09-19 13:14:21 +0300 |
commit | 921be290fc5d9479a554936d5b3c546154af1871 (patch) | |
tree | 08fec18371847aa689e1eae7f5b4a64ef93bdd66 /lib/fprint.c | |
parent | 0c1e3ec94df2b769fb2d6b77dbe5eca5e41f3d09 (diff) | |
download | rpm-921be290fc5d9479a554936d5b3c546154af1871.tar.gz |
Eliminate strdup() in doLookupId()
- Take advantage of the length-aware pool string->id lookup to avoid
the need to copy and locally modify the canonized dirname. Makes
the code cleaner and a little bit faster too.
- There are further possibilities in this direction, canonDir()
could return an id instead of malloced memory but that doesn't
remove the need for temporary bugg^H^Hffer to clean up the dir.
Diffstat (limited to 'lib/fprint.c')
-rw-r--r-- | lib/fprint.c | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/lib/fprint.c b/lib/fprint.c index 8cb68e83a..04344506f 100644 --- a/lib/fprint.c +++ b/lib/fprint.c @@ -174,31 +174,24 @@ static int doLookupId(fingerPrintCache cache, rpmsid dirNameId, rpmsid baseNameId, fingerPrint *fp) { - char * end; /* points to the '\0' at the end of "buf" */ struct stat sb; - char *buf = NULL; const struct fprintCacheEntry_s * cacheHit; char *cdn = canonDir(cache->pool, dirNameId); - const char *rootDir = "/"; - size_t cdnl; - - memset(fp, 0, sizeof(*fp)); + rpmsid fpId; + size_t fpLen; + if (cdn == NULL) goto exit; /* XXX only if realpath() above fails */ - cdnl = strlen(cdn); - buf = xstrdup(cdn); - end = buf + cdnl; + memset(fp, 0, sizeof(*fp)); + fpId = rpmstrPoolId(cache->pool, cdn, 1); + fpLen = rpmstrPoolStrlen(cache->pool, fpId);; while (1) { - /* buf contents change through end ptr, requiring rehash on each loop */ - const char *fpDir = (*buf != '\0') ? buf : rootDir; - rpmsid fpId = rpmstrPoolId(cache->pool, fpDir, 1); - /* as we're stating paths here, we want to follow symlinks */ cacheHit = cacheContainsDirectory(cache, fpId); if (cacheHit != NULL) { fp->entry = cacheHit; - } else if (!stat(fpDir, &sb)) { + } else if (!stat(rpmstrPoolStr(cache->pool, fpId), &sb)) { struct fprintCacheEntry_s * newEntry = xmalloc(sizeof(* newEntry)); newEntry->ino = sb.st_ino; @@ -210,7 +203,7 @@ static int doLookupId(fingerPrintCache cache, } if (fp->entry) { - const char * subDir = cdn + (end - buf) - 1; + const char * subDir = cdn + fpLen - 1; /* XXX don't bother saving '/' as subdir */ if (subDir[0] == '\0' || (subDir[0] == '/' && subDir[1] == '\0')) subDir = NULL; @@ -221,16 +214,17 @@ static int doLookupId(fingerPrintCache cache, } /* stat of '/' just failed! */ - if (fpDir == rootDir) + if (fpLen == 1) abort(); - end--; - while ((end > buf) && *(end-1) != '/') end--; - *end = '\0'; + /* Find the parent directory and its id for the next round */ + fpLen--; + while (fpLen > 1 && cdn[fpLen-1] != '/') + fpLen--; + fpId = rpmstrPoolIdn(cache->pool, cdn, fpLen, 1); } exit: - free(buf); free(cdn); /* XXX TODO: failure from eg realpath() should be returned and handled */ return 0; |