From 6f27f1c2fc6aef17eeb10201f9cf48e20b81a037 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Tue, 16 Apr 2013 07:14:10 +0300 Subject: [PATCH] Optimize lookupPackage() a bit - Remember the name of sub-packages in the Package struct, avoiding the need for headerGetString() in a loop, and also avoid unnecessary strdup() in the case name is not a partial one. - Somewhat hysterically, this more than halves the time to parse the infamous texlive.spec on my laptop: the parse time is down from 10.2s to 4.9s. (cherry picked from commit 9929459f9967ecfe0a05d557bc42531944faa70a) --- build/parsePreamble.c | 7 ++++--- build/rpmbuild_internal.h | 4 +++- build/spec.c | 24 +++++++++++++----------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/build/parsePreamble.c b/build/parsePreamble.c index 9db0264..f1ac764 100644 --- a/build/parsePreamble.c +++ b/build/parsePreamble.c @@ -973,8 +973,6 @@ int parsePreamble(rpmSpec spec, int initialPackage) char *NVR = NULL; char lang[BUFSIZ]; - pkg = newPackage(&spec->packages); - if (! initialPackage) { /* There is one option to %package: or -n */ if (parseSimplePart(spec->line, &name, &flag)) { @@ -996,10 +994,13 @@ int parsePreamble(rpmSpec spec, int initialPackage) } else NVR = xstrdup(name); free(name); + pkg = newPackage(NVR, &spec->packages); headerPutString(pkg->header, RPMTAG_NAME, NVR); } else { NVR = xstrdup("(main package)"); - spec->sourcePackage = newPackage(NULL); + pkg = newPackage(NULL, &spec->packages); + spec->sourcePackage = newPackage(NULL, NULL); + } if ((rc = readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) { diff --git a/build/rpmbuild_internal.h b/build/rpmbuild_internal.h index 6e7e796..c560cf7 100644 --- a/build/rpmbuild_internal.h +++ b/build/rpmbuild_internal.h @@ -85,6 +85,7 @@ struct rpmSpec_s { * The structure used to store values for a package. */ struct Package_s { + char * name; Header header; rpmds ds; /*!< Requires: N = EVR */ rpmds requires; @@ -323,11 +324,12 @@ rpmRC lookupPackage(rpmSpec spec, const char * name, int flag, /** \ingroup rpmbuild * Create and initialize package control structure. + * @param name package name for sub-packages (or NULL) * @param pkglist package list pointer to append to (or NULL) * @return package control structure */ RPM_GNUC_INTERNAL -Package newPackage(Package * pkglist); +Package newPackage(const char *name, Package * pkglist); /** \ingroup rpmbuild * Post-build processing for binary package(s). diff --git a/build/spec.c b/build/spec.c index a37ace7..affd8e6 100644 --- a/build/spec.c +++ b/build/spec.c @@ -60,7 +60,6 @@ struct Source * freeSources(struct Source * s) rpmRC lookupPackage(rpmSpec spec, const char *name, int flag,Package *pkg) { - const char *pname; char *fullName = NULL; Package p; @@ -71,29 +70,28 @@ rpmRC lookupPackage(rpmSpec spec, const char *name, int flag,Package *pkg) return RPMRC_OK; } - /* Construct package name */ + /* Construct partial package name */ if (flag == PART_SUBNAME) { - pname = headerGetString(spec->packages->header, RPMTAG_NAME); - rasprintf(&fullName, "%s-%s", pname, name); - } else { - fullName = xstrdup(name); + rasprintf(&fullName, "%s-%s", + headerGetString(spec->packages->header, RPMTAG_NAME), name); + name = fullName; } - /* Locate package with fullName */ + /* Locate package the name */ for (p = spec->packages; p != NULL; p = p->next) { - pname = headerGetString(p->header, RPMTAG_NAME); - if (pname && (rstreq(fullName, pname))) { + if (p->name && (rstreq(name, p->name))) { break; } } - free(fullName); + if (fullName != name) + free(fullName); if (pkg) *pkg = p; return ((p == NULL) ? RPMRC_FAIL : RPMRC_OK); } -Package newPackage(Package *pkglist) +Package newPackage(const char *name, Package *pkglist) { Package p = xcalloc(1, sizeof(*p)); p->header = headerNew(); @@ -103,6 +101,9 @@ Package newPackage(Package *pkglist) p->fileFile = NULL; p->policyList = NULL; + if (name) + p->name = xstrdup(name); + if (pkglist) { if (*pkglist == NULL) { *pkglist = p; @@ -145,6 +146,7 @@ static Package freePackage(Package pkg) pkg->icon = freeSources(pkg->icon); pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles); + free(pkg->name); free(pkg); return NULL; } -- 2.7.4