From: Ben Collins Date: Mon, 18 Oct 1999 23:44:44 +0000 (+0000) Subject: * implemented stat cache for better performance X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e8883ff1ea0688bd0a85ca8c540cff344badbdc0;p=dpkg * implemented stat cache for better performance * fix typo in last commit for Makefile.am --- diff --git a/ChangeLog b/ChangeLog index d966768b..8b1ba574 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +Mon Oct 18 18:40:35 EDT 1999 Ben Collins + + * Reimplemented a better *stat cache for the removal checking code, + this helps a lot when doing upgrades where the packages are a lot + different in layout. Note, I tested the first way and this new way + against package foo (version 1 & 2) each had 5000 files (different + in version 2 than in version 1). basically this meant the old way + needed to do about 2.5 million lstats, and the new way only needs + 10,000 lstats. This sped it up about %6000 percent (the old way took + over 1 hour on a 333Mhz, the new way was 2 minutes and 20 seconds). + Note that this is an extreme case since most per package upgrades + a) don't have 5000 files + b) don't have all the files different + * Increased largemem auto detection to >= 24megs, since it's not uncommon + for dpkg to actually use 16megs of ram all on its own when using the + largemem setting (old minimum was 16megs) + Mon Oct 18 09:25:30 EDT 1999 Ben Collins * Add mipseb to the archtable too, since mips and mipseb are diff --git a/Makefile.am b/Makefile.am index 236ee9c5..d41b65eb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,7 +45,7 @@ MAINTAINERCLEANFILES = libtool DISTDEBFILES = 50dpkg-dev.el changelog control copyright \ dev-README postinst preinst prerm rules \ - shlibs shlibs.default.templates shlibs.local + shlibs shlibs.default.template shlibs.local MAINTCLEANFILES = Makefile.in aclocal.m4 config.guess \ config.h.in config.sub configure install-sh \ diff --git a/debian/changelog b/debian/changelog index eeb1411b..644c5e0f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -37,6 +37,12 @@ dpkg (1.4.1.17) unstable; urgency=low * Removed shlibs.default.i386. It's now a template for arch porting to Debian/dpkg, we install it still, if there exists a file matching the arch + * Reimplemented a better *stat cache for the removal checking code, + this helps a lot when doing upgrades where the packages are a lot + different in layout + * Increased largemem auto detection to >= 24megs, since it's not uncommon + for dpkg to actually use 16megs of ram all on its own when using the + largemem setting (old minimum was 16megs) -- Wichert Akkerman UNRELEASED diff --git a/main/filesdb.c b/main/filesdb.c index bc4e1b1f..e1897e0d 100644 --- a/main/filesdb.c +++ b/main/filesdb.c @@ -495,8 +495,8 @@ static int autodetect_largemem(void) { #ifdef HAVE_SYSINFO struct sysinfo info; if (sysinfo(&info)) return 0; - if (info.freeram + (info.sharedram>>2) + (info.bufferram>>2) < 16384*1024 && - info.totalram < 16384*1024) + if (info.freeram + (info.sharedram>>2) + (info.bufferram>>2) < 24576*1024 && + info.totalram < 24576*1024) return 0; #endif return 1; @@ -515,6 +515,7 @@ void filesdbinit(void) { for (fnn= bins[i]; fnn; fnn= fnn->next) { fnn->flags= 0; fnn->oldhash= 0; + fnn->filestat= 0; } break; case -1: @@ -523,6 +524,7 @@ void filesdbinit(void) { fnn= fnn->next) { fnn->flags= 0; fnn->oldhash= 0; + fnn->filestat= 0; } break; default: @@ -608,6 +610,7 @@ static struct filenamenode *findnamenode_low(const char *name) { traverse->here->packages= 0; traverse->here->flags= 0; traverse->here->divert= 0; + traverse->here->filestat= 0; n= strlen(name)+2; if (namesarealeft < n) { @@ -658,6 +661,7 @@ struct filenamenode *findnamenode_high(const char *name) { newnode->flags= 0; newnode->next= 0; newnode->divert= 0; + newnode->filestat= 0; *pointerp= newnode; nfiles++; diff --git a/main/filesdb.h b/main/filesdb.h index 7a3ecf29..99bd405d 100644 --- a/main/filesdb.h +++ b/main/filesdb.h @@ -62,6 +62,7 @@ struct filenamenode { fnnf_no_atomic_overwrite= 000020, /* >=1 instance is a dir, cannot rename over */ } flags; /* Set to zero when a new node is created. */ const char *oldhash; /* valid iff this namenode is in the newconffiles list */ + struct stat *filestat; }; struct fileinlist { diff --git a/main/processarc.c b/main/processarc.c index 83459208..3403f365 100644 --- a/main/processarc.c +++ b/main/processarc.c @@ -599,7 +599,7 @@ void process_archive(const char *filename) { * the process a little leaner. We are only worried about new ones * since ones that stayed the same don't really apply here. */ - struct stat oldfs, newfs; + struct stat oldfs; int donotrm = 0; /* If we can't stat the old or new file, or it's a directory, * we leave it up to the normal code @@ -608,10 +608,17 @@ void process_archive(const char *filename) { "upgrade/downgrade", fnamevb.buf); if (!lstat(fnamevb.buf, &oldfs) && !S_ISDIR(oldfs.st_mode)) { for (cfile = newfileslist; cfile; cfile = cfile->next) { - if (lstat(cfile->namenode->name, &newfs) || S_ISDIR(newfs.st_mode)) - continue; - if (oldfs.st_dev == newfs.st_dev && - oldfs.st_ino == newfs.st_ino) { + if (!cfile->namenode->filestat) { + cfile->namenode->filestat = (struct stat *) nfmalloc(sizeof(struct stat)); + if (lstat(cfile->namenode->name, cfile->namenode->filestat)) { + cfile->namenode->filestat= 0; + continue; + } + } + if (S_ISDIR(cfile->namenode->filestat->st_mode)) + continue; + if (oldfs.st_dev == cfile->namenode->filestat->st_dev && + oldfs.st_ino == cfile->namenode->filestat->st_ino) { donotrm = 1; debug(dbg_eachfile, "process_archive: not removing %s, since it matches %s", fnamevb.buf, cfile->namenode->name);