[PATCH] Refactor: make a separate function to add files
Here's the second refactoring patch mentioned in "dpkg list-file performance".
===
Refactor: make a separate function to add files
Added private function _add_file_to_package for inserting a file to a
package's entries. The function takes a pos_hint to avoid an O(n^2) loop
when adding to the end of the list. (This is what the original code
does, so I have mirrored its behavior.)
Signed-off-by: David Benjamin <davidben@mit.edu>
---
src/filesdb.c | 77 ++++++++++++++++++++++++++++++++++++--------------------
1 files changed, 49 insertions(+), 28 deletions(-)
diff --git a/src/filesdb.c b/src/filesdb.c
index a437a40..e672e94 100644
--- a/src/filesdb.c
+++ b/src/filesdb.c
@@ -116,15 +116,59 @@ static void _erase_pkg_file_data(struct pkginfo *pkg) {
pkg->clientdata->files = NULL;
}
+ /* add a file to pkg. pos_hint is to help find the end of the list
+ */
+typedef struct fileinlist **fileinlist_hint;
+static fileinlist_hint _add_file_to_package(struct pkginfo *pkg, const char *file, enum fnnflags flags, fileinlist_hint pos_hint) {
+ struct fileinlist *newent;
+ struct filepackages *packageslump;
+ int putat;
+
+ ensure_package_clientdata(pkg);
+ if (pos_hint == NULL)
+ pos_hint = &pkg->clientdata->files;
+ /* Make sure we're at the end */
+ while ((*pos_hint) != NULL) {
+ pos_hint = &((*pos_hint)->next);
+ }
+
+ /* Create a new node */
+ newent = nfmalloc(sizeof(struct fileinlist));
+ newent->namenode = findnamenode(file, flags);
+ newent->next = NULL;
+ *pos_hint = newent;
+ pos_hint = &newent->next;
+
+ /* Add pkg to newent's package list */
+ packageslump = newent->namenode->packages;
+ putat = 0;
+ if (packageslump) {
+ for (; putat < PERFILEPACKAGESLUMP && packageslump->pkgs[putat];
+ putat++);
+ if (putat >= PERFILEPACKAGESLUMP)
+ packageslump = NULL;
+ }
+ if (!packageslump) {
+ packageslump = nfmalloc(sizeof(struct filepackages));
+ packageslump->more = newent->namenode->packages;
+ newent->namenode->packages = packageslump;
+ putat= 0;
+ }
+ packageslump->pkgs[putat]= pkg;
+ if (++putat < PERFILEPACKAGESLUMP)
+ packageslump->pkgs[putat] = NULL;
+
+ /* Return the position for the next guy */
+ return pos_hint;
+}
+
/* load the list of files in this package into memory, or update the
* list if it is there but stale
*/
void ensure_packagefiles_available(struct pkginfo *pkg) {
int fd;
const char *filelistfile;
- struct fileinlist **lendp, *newent;
- struct filepackages *packageslump;
- int putat;
+ fileinlist_hint lendp;
struct stat stat_buf;
char *loaded_list, *loaded_list_end, *thisline, *nextline, *ptr;
@@ -171,7 +215,7 @@ void ensure_packagefiles_available(struct pkginfo *pkg) {
fd_buf_copy(fd, loaded_list, stat_buf.st_size, _("files list for package `%.250s'"), pkg->name);
- lendp= &pkg->clientdata->files;
+ lendp = &pkg->clientdata->files;
thisline = loaded_list;
while (thisline < loaded_list_end) {
if (!(ptr = memchr(thisline, '\n', loaded_list_end - thisline)))
@@ -185,11 +229,7 @@ void ensure_packagefiles_available(struct pkginfo *pkg) {
if (ptr == thisline)
ohshit(_("files list file for package `%.250s' contains empty filename"),pkg->name);
*ptr = '\0';
- newent= nfmalloc(sizeof(struct fileinlist));
- newent->namenode= findnamenode(thisline, fnn_nocopy);
- newent->next = NULL;
- *lendp= newent;
- lendp= &newent->next;
+ lendp = _add_file_to_package(pkg, thisline, fnn_nocopy, lendp);
thisline = nextline;
}
}
@@ -199,25 +239,6 @@ void ensure_packagefiles_available(struct pkginfo *pkg) {
onerr_abort--;
- for (newent= pkg->clientdata->files; newent; newent= newent->next) {
- packageslump= newent->namenode->packages;
- putat= 0;
- if (packageslump) {
- for (; putat < PERFILEPACKAGESLUMP && packageslump->pkgs[putat];
- putat++);
- if (putat >= PERFILEPACKAGESLUMP)
- packageslump = NULL;
- }
- if (!packageslump) {
- packageslump= nfmalloc(sizeof(struct filepackages));
- packageslump->more= newent->namenode->packages;
- newent->namenode->packages= packageslump;
- putat= 0;
- }
- packageslump->pkgs[putat]= pkg;
- if (++putat < PERFILEPACKAGESLUMP)
- packageslump->pkgs[putat] = NULL;
- }
pkg->clientdata->fileslistvalid= 1;
}
--
1.6.3.3
Reply to: