From: Alexey Tourbin <at@altlinux.ru> To: devel@lists.altlinux.org Subject: Re: [devel] changelogs for apt repo Date: Sun, 18 May 2008 06:07:51 +0400 Message-ID: <20080518020751.GD9319@solemn.turbinal> (raw) In-Reply-To: <20080517190034.GA9319@solemn.turbinal> <20080517053427.GJ19126@solemn.turbinal> [-- Attachment #1: Type: text/plain, Size: 12785 bytes --] On Sat, May 17, 2008 at 09:34:27AM +0400, Alexey Tourbin wrote: > Теперь остаётся выяснить, сколько это занимает места. > > Обычная генерация сизифа: > > $ cp -prs /ALT/Sisyphus/x86_64 /ALT/Sisyphus/noarch . > $ rm -f x86_64/base/* noarch/base/* > $ PATH=$PWD:$PATH genbasedir --topdir=$PWD x86_64 > $ PATH=$PWD:$PATH genbasedir --topdir=$PWD noarch > $ du -bk x86_64/base/pkglist.classic.bz2 noarch/base/pkglist.classic.bz2 > 2421 x86_64/base/pkglist.classic.bz2 > 1049 noarch/base/pkglist.classic.bz2 > $ > > Генерация с опцией --changelog-since=2007-01-01: > > $ PATH=$PWD:$PATH genbasedir --topdir=$PWD --changelog-since=2007-01-01 x86_64 > $ PATH=$PWD:$PATH genbasedir --topdir=$PWD --changelog-since=2007-01-01 noarch > $ du -bk x86_64/base/pkglist.classic.bz2 noarch/base/pkglist.classic.bz2 > 3536 x86_64/base/pkglist.classic.bz2 > 1302 noarch/base/pkglist.classic.bz2 > $ > > Таким образом, размер скачиваемого при 'apt-get update' заметно > увеличивается (примерно на треть). Я считаю это приемлемой платой > за удовольствие просмотреть changelog пакета ДО скачивания и установки. On Sat, May 17, 2008 at 11:00:34PM +0400, Alexey Tourbin wrote: > Какая плата тебя бы устроила? Думаю что плату можно будет немного > уменьшить, если сначала отсортировать пакеты по %{SOURCERPM}, а уже > потом выгонять хедеры. Тогда bzip2 лучше сожмёт одинаковые changelog'и > подряд идущих подпакетов. Я сделал предварительную реализацию сортировки по %{SOURCERPM}. Результаты теперь такие: $ PATH=$PWD:$PATH genbasedir --topdir=$PWD x86_64 $ PATH=$PWD:$PATH genbasedir --topdir=$PWD noarch $ du -bk x86_64/base/pkglist.classic.bz2 noarch/base/pkglist.classic.bz2 2384 x86_64/base/pkglist.classic.bz2 1048 noarch/base/pkglist.classic.bz2 $ $ PATH=$PWD:$PATH genbasedir --topdir=$PWD --changelog-since=2007-01-01 x86_64 $ PATH=$PWD:$PATH genbasedir --topdir=$PWD --changelog-since=2007-01-01 noarch $ du -bk x86_64/base/pkglist.classic.bz2 noarch/base/pkglist.classic.bz2 3306 x86_64/base/pkglist.classic.bz2 1300 noarch/base/pkglist.classic.bz2 $ Из этого видно следующее: для noarch пакетов переупорядочивание по %{SOURCERPM} почти ничего не дает. Это связано с тем, что noarch пакеты реже распиливают, а при распиливании названия подпакетов реже отличаются по префиксу (то есть глобального переупорядочивания, которое может повысить степень сжатия, как напр. в случае с lib%name и %name, не происходит). Для x86_64 экономия заметна даже без генерации changelog'ов (2421/2384 = 1.6%, за счёт лучшего совпадения других атрибутов подпакетов), а особенно с changelog'ом (3536/3306 = 7%, за счёт лучшего сжатия одинаковых changelog'ов подряд идущих подпакетов). В принципе выгаданные несколько процентов позволяют мне с большей уверенностью говорить о включении changelog'ов в репозитарий, хотя общая картина остаётся скорее прежней: если включить changelog'и по предложенной схеме, то размер скачиваемого при 'apt-get update' увеличивается примерно на треть. Вот патч на genpkglist.cc, я его плохо проверил, но вроде работает. У меня уже патч на патче сидит и я пока не знаю как его лучше приложить к тому что есть. --- apt-0.5.15lorg2/tools/genpkglist.cc- 2008-05-18 00:48:01 +0400 +++ apt-0.5.15lorg2/tools/genpkglist.cc 2008-05-18 05:14:06 +0400 @@ -320,7 +320,7 @@ done: } bool copyFields(Header h, Header newHeader, - FILE *idxfile, const char *directory, char *filename, + FILE *idxfile, const char *directory, const char *filename, unsigned filesize, map<string,UpdateInfo> &updateInfo, bool fullFileList) { @@ -460,99 +460,34 @@ void usage() cerr << " one preceding entry (if available)" <<endl; } - - -#ifndef HAVE_SCANDIR -// from glibc 1.09.1 mod'd by jmik, ins'd by asm, fix'd by sbi -int alphasort(const void * a, const void * b) +static void progress(int cur, int total) { - return strcmp ((*(struct dirent **) a)->d_name, - (*(struct dirent **) b)->d_name); + if (cur > 1) + printf("\b\b\b\b\b\b\b\b\b\b"); + printf(" %04i/%04i", cur, total); + fflush(stdout); } -int scandir(const char * dir, struct dirent *** namelist, - int (* select)(struct dirent *), - int (* cmp)(const void *, const void *)) +struct rpmfile { + const char *basename; + const char *sourcerpm; +}; +static +int rpmfilecmp(const void *a, const void *b) { - DIR *dp = opendir (dir); - struct dirent **v = NULL; - size_t vsize = 0, i; - struct dirent *d; - int save; - - if (dp == NULL) - return -1; - - save = errno; - errno = 0; - - i = 0; - while ((d = readdir (dp)) != NULL) - { - if (select == NULL || (*select) (d)) - { - if (i == vsize) - { - struct dirent **newv; - if (vsize == 0) - vsize = 10; - else - vsize *= 2; - newv = (struct dirent **) realloc (v, vsize * sizeof (*v)); - if (newv == NULL) - { - lose: - errno = ENOMEM; - break; - } - v = newv; - } - - v[i] = (struct dirent *) malloc (d->d_reclen); - if (v[i] == NULL) - goto lose; - - // *v[i++] = *d; - memcpy(v[i], d, d->d_reclen); - i++; - } - } - - v[i] = NULL; - - if (errno != 0) - { - save = errno; - (void) closedir (dp); - while (i > 0) - free (v[--i]); - free (v); - errno = save; - return -1; - } - - (void) closedir (dp); - errno = save; - - /* Sort the list if we have a comparison function to sort with. */ - if (cmp != NULL) - qsort (v, i, sizeof (struct dirent *), cmp); - - *namelist = v; - return i; + const struct rpmfile *A = (struct rpmfile *)a; + const struct rpmfile *B = (struct rpmfile *)b; + int cmp = strcmp(A->sourcerpm, B->sourcerpm); + if (cmp) + return cmp; + return strcmp(A->basename, B->basename); } -// end of new stuff from glibc -#endif /* !HAVE_SCANDIR */ - int main(int argc, char ** argv) { string rpmsdir; string pkglist_path; - FD_t outfd, fd; - struct dirent **dirEntries; - int entry_no, entry_cur; map<string,UpdateInfo> updateInfo; CachedMD5 *md5cache; char *op_dir; @@ -561,13 +496,13 @@ int main(int argc, char ** argv) char *op_update = NULL; long /* time_t */ changelog_since = 0; FILE *idxfile; - int i; bool fullFileList = false; bool progressBar = false; const char *pkgListSuffix = NULL; bool pkgListAppend = false; setlocale(LC_ALL, "C"); + int i; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "--index") == 0) { i++; @@ -674,14 +609,16 @@ int main(int argc, char ** argv) string dirtag = "RPMS." + string(op_suf); - entry_no = scandir(rpmsdir.c_str(), &dirEntries, selectDirent, alphasort); - if (entry_no < 0) { - cerr << "genpkglist: error opening directory " << rpmsdir << ":" - << strerror(errno); - return 1; + if (chdir(rpmsdir.c_str())) { + perror(rpmsdir.c_str()); + exit(1); + } + + glob_t gl; + if (glob("*.rpm", 0, NULL, &gl)) { + cerr << rpmsdir << "/" << "*.rpm: glob failed" <<endl; + exit(1); } - - chdir(rpmsdir.c_str()); if (pkgListSuffix != NULL) pkglist_path = pkglist_path + "/base/pkglist." + pkgListSuffix; @@ -689,6 +626,7 @@ int main(int argc, char ** argv) pkglist_path = pkglist_path + "/base/pkglist." + op_suf; + FD_t outfd; if (pkgListAppend == true && FileExists(pkglist_path)) { outfd = fdOpen(pkglist_path.c_str(), O_WRONLY|O_APPEND, 0644); } else { @@ -711,30 +649,54 @@ int main(int argc, char ** argv) int isSource; #endif - if (!fullFileList) { - // ALT: file list cannot be stripped in a dumb manner -- this is going - // to produce unmet dependencies. First pass is required to initialize - // certain data structures. - for (entry_cur = 0; entry_cur < entry_no; entry_cur++) { - if (progressBar) { - if (entry_cur) - printf("\b\b\b\b\b\b\b\b\b\b"); - printf(" %04i/%04i", entry_cur + 1, entry_no); - fflush(stdout); - } + struct rpmfile *rpms = new struct rpmfile[gl.gl_pathc]; + int ix, n = 0; + + for (ix = 0; ix < gl.gl_pathc; ix++) { + if (progressBar) + progress(ix+1, gl.gl_pathc); + + const char *basename = gl.gl_pathv[ix]; + FD_t fd = Fopen(basename, "r"); + if (!fd) { + cerr << "Warning: " << basename << ": " << strerror(errno) <<endl; + continue; + } - fd = fdOpen(dirEntries[entry_cur]->d_name, O_RDONLY, 0666); - if (!fd) - continue; int rc; Header h; #if RPM_VERSION >= 0x040100 rc = rpmReadPackageFile(ts, fd, dirEntries[entry_cur]->d_name, &h); - if (rc == RPMRC_OK || rc == RPMRC_NOTTRUSTED || rc == RPMRC_NOKEY) { + if (rc == RPMRC_OK || rc == RPMRC_NOTTRUSTED || rc == RPMRC_NOKEY) #else rc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL); - if (rc == 0) { + if (rc == 0) #endif + { + ; // good + } + else { + cerr << "Warning: " << basename << ": cannot read package header" <<endl; + continue; + } + + const char *sourcerpm; + rc = headerGetEntry(h, RPMTAG_SOURCERPM, NULL, (void**)&sourcerpm, NULL); + if (!(rc == 1)) { + cerr << "Warning: " << basename << ": no SOURCERPM tag" <<endl; + continue; + } + + sourcerpm = strdup(sourcerpm); + assert(sourcerpm); + rpms[n].basename = basename; + rpms[n].sourcerpm = sourcerpm; + n++; + + // ALT: file list cannot be stripped in a dumb manner -- this is going + // to produce unmet dependencies. First pass is required to initialize + // certain data structures. + if (!fullFileList) { // path-like Requires int_32 reqtype = 0; const char **requires = NULL; @@ -776,37 +738,35 @@ int main(int argc, char ** argv) headerFreeTag(h, dn, (rpmTagType)dnt); headerFreeTag(h, di, (rpmTagType)dit); - headerFree(h); } + headerFree(h); Fclose(fd); - } } - for (entry_cur = 0; entry_cur < entry_no; entry_cur++) { + + qsort(rpms, n, sizeof(struct rpmfile), rpmfilecmp); + + for (ix = 0; ix < n; ix++) { struct stat sb; - if (progressBar) { - if (entry_cur) - printf("\b\b\b\b\b\b\b\b\b\b"); - printf(" %04i/%04i", entry_cur + 1, entry_no); - fflush(stdout); - } + if (progressBar) + progress(ix+1, n); - if (stat(dirEntries[entry_cur]->d_name, &sb) < 0) { - cerr << "\nWarning: " << strerror(errno) << ": " << - dirEntries[entry_cur]->d_name << endl; - continue; + const char *basename = rpms[ix].basename; + + if (stat(basename, &sb) < 0) { + cerr << "Fatal: " << basename << ": " << strerror(errno) <<endl; + exit(1); } { Header h; int rc; - fd = fdOpen(dirEntries[entry_cur]->d_name, O_RDONLY, 0666); + FD_t fd = Fopen(basename, "r"); if (!fd) { - cerr << "\nWarning: " << strerror(errno) << ": " << - dirEntries[entry_cur]->d_name << endl; - continue; + cerr << "Fatal: " << basename << ": " << strerror(errno) <<endl; + exit(1); } #if RPM_VERSION >= 0x040100 @@ -822,14 +782,13 @@ int main(int argc, char ** argv) newHeader = headerNew(); copyFields(h, newHeader, idxfile, dirtag.c_str(), - dirEntries[entry_cur]->d_name, + basename, sb.st_size, updateInfo, fullFileList); if (changelog_since > 0) copyChangelog(changelog_since, h, newHeader); - md5cache->MD5ForFile(string(dirEntries[entry_cur]->d_name), - sb.st_mtime, md5); + md5cache->MD5ForFile(string(basename), sb.st_mtime, md5); headerAddEntry(newHeader, CRPMTAG_MD5, RPM_STRING_TYPE, md5, 1); headerWrite(outfd, newHeader, HEADER_MAGIC_YES); @@ -837,8 +796,8 @@ int main(int argc, char ** argv) headerFree(newHeader); headerFree(h); } else { - cerr << "\nWarning: Skipping malformed RPM: " << - dirEntries[entry_cur]->d_name << endl; + cerr << "Fatal: " << basename << ": cannot read package header" <<endl; + exit(1); } Fclose(fd); } [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
next prev parent reply other threads:[~2008-05-18 2:07 UTC|newest] Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top 2008-05-17 5:34 Alexey Tourbin 2008-05-17 9:50 ` Евгений Терешков 2008-05-17 12:06 ` Alexey Gladkov 2008-05-17 13:23 ` Andrey Rahmatullin 2008-05-17 13:54 ` Alexey Gladkov 2008-05-17 19:00 ` Alexey Tourbin 2008-05-17 20:01 ` Led 2008-05-17 19:55 ` Andrey Rahmatullin 2008-05-17 21:16 ` Led 2008-05-17 21:09 ` Andrey Rahmatullin 2008-05-18 6:34 ` Kirill Maslinsky 2008-05-17 20:50 ` Alexey Tourbin 2008-05-17 21:58 ` Alexey Gladkov 2008-05-17 21:46 ` Andrey Rahmatullin 2008-05-17 22:14 ` Alexey Gladkov 2008-05-17 22:00 ` Andrey Rahmatullin 2008-05-17 22:21 ` Alexey Gladkov 2008-05-17 22:10 ` Andrey Rahmatullin 2008-05-17 22:32 ` Alexey Gladkov 2008-05-17 22:45 ` Sergey Bolshakov 2008-05-17 23:03 ` Alexey Tourbin 2008-05-19 4:02 ` Ildar Mulyukov 2008-05-19 4:53 ` Alexey Tourbin 2008-05-19 10:26 ` Ildar Mulyukov 2008-05-19 10:35 ` Andrey Rahmatullin 2008-05-19 10:41 ` Pavlov Konstantin 2008-05-19 10:43 ` Andrey Rahmatullin 2008-05-19 10:53 ` Aleksey Avdeev 2008-05-20 12:27 ` Alexander Bokovoy 2008-05-18 2:07 ` Alexey Tourbin [this message] 2008-05-18 2:25 ` Alexey Tourbin 2008-05-18 9:26 ` Alexey Gladkov 2008-05-18 21:35 ` Alexey Tourbin 2008-05-18 22:26 ` Alexey Gladkov 2008-05-20 2:34 ` Alexey Morozov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20080518020751.GD9319@solemn.turbinal \ --to=at@altlinux.ru \ --cc=devel@lists.altlinux.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
ALT Linux Team development discussions This inbox may be cloned and mirrored by anyone: git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \ devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru public-inbox-index devel Example config snippet for mirrors. Newsgroup available over NNTP: nntp://lore.altlinux.org/org.altlinux.lists.devel AGPL code for this site: git clone https://public-inbox.org/public-inbox.git