xbps-repo: made 'genindex' code run ~60% faster than before!

Rather than externalizing the package index plist file to storage every
time a package is registered, only do it one time once all packages
have been processed. Creating an index with 700 pkgs now takes 14s
in a VM, where before it took 39s. As consequence of this, the 'add-pkgidx'
target is no longer relevant or useful, remove it.

--HG--
extra : convert_revision : xtraeme%40gmail.com-20091118053439-ct1chn4hdeir1pdo
This commit is contained in:
Juan RP
2009-11-18 06:34:39 +01:00
parent cc6417b9bf
commit f859663a4b
4 changed files with 67 additions and 56 deletions

View File

@ -73,15 +73,15 @@ out:
} }
int int
xbps_repo_addpkg_index(const char *pkgdir, const char *file) xbps_repo_addpkg_index(prop_dictionary_t idxdict, const char *file)
{ {
prop_dictionary_t newpkgd, idxdict, curpkgd; prop_dictionary_t newpkgd, curpkgd;
prop_array_t pkgar; prop_array_t pkgar;
struct archive *ar; struct archive *ar;
struct archive_entry *entry; struct archive_entry *entry;
struct stat st; struct stat st;
const char *pkgname, *version, *regver; const char *pkgname, *version, *regver;
char *sha256, *plist, *filen = NULL, *tmpfilen = NULL; char *sha256, *filen = NULL, *tmpfilen = NULL;
int rv = 0; int rv = 0;
assert(file != NULL); assert(file != NULL);
@ -112,19 +112,12 @@ xbps_repo_addpkg_index(const char *pkgdir, const char *file)
goto out1; goto out1;
} }
/* Get existing or create repo index dictionary */ /* Get package array in repo index file */
idxdict = repoidx_getdict(pkgdir); pkgar = prop_dictionary_get(idxdict, "packages");
if (idxdict == NULL) { if (pkgar == NULL) {
rv = errno; rv = errno;
goto out1; goto out1;
} }
plist = xbps_get_pkg_index_plist(pkgdir);
if (plist == NULL) {
prop_dictionary_remove(idxdict, "packages");
rv = ENOMEM;
goto out2;
}
/* /*
* Open the binary package and read the props.plist * Open the binary package and read the props.plist
* into a buffer. * into a buffer.
@ -156,10 +149,11 @@ xbps_repo_addpkg_index(const char *pkgdir, const char *file)
prop_dictionary_get_cstring_nocopy(curpkgd, prop_dictionary_get_cstring_nocopy(curpkgd,
"version", &regver); "version", &regver);
if (xbps_cmpver(version, regver) <= 0) { if (xbps_cmpver(version, regver) <= 0) {
printf("Skipping %s. Version %s already " printf("W: skipping %s. %s-%s already "
"registered.\n", filen, regver); "registered.\n", filen, pkgname, regver);
prop_object_release(newpkgd); prop_object_release(newpkgd);
archive_read_data_skip(ar); archive_read_data_skip(ar);
rv = EEXIST;
break; break;
} }
/* /*
@ -199,32 +193,19 @@ xbps_repo_addpkg_index(const char *pkgdir, const char *file)
/* /*
* Add dictionary into the index and update package count. * Add dictionary into the index and update package count.
*/ */
pkgar = prop_dictionary_get(idxdict, "packages");
if (pkgar == NULL) {
prop_object_release(newpkgd);
rv = errno;
break;
}
if (!xbps_add_obj_to_array(pkgar, newpkgd)) { if (!xbps_add_obj_to_array(pkgar, newpkgd)) {
prop_object_release(newpkgd); prop_object_release(newpkgd);
rv = EINVAL; rv = EINVAL;
break; break;
} }
prop_dictionary_set_uint64(idxdict, "total-pkgs", prop_dictionary_set_uint64(idxdict, "total-pkgs",
prop_array_count(pkgar)); prop_array_count(pkgar));
if (!prop_dictionary_externalize_to_file(idxdict, plist)) {
rv = errno;
break;
}
printf("Registered %s-%s in package index.\n", printf("Registered %s-%s in package index.\n",
pkgname, version); pkgname, version);
printf("\033[1A\033[K");
break; break;
} }
free(plist);
out2:
prop_object_release(idxdict);
out1: out1:
archive_read_finish(ar); archive_read_finish(ar);
out: out:
@ -236,16 +217,32 @@ out:
int int
xbps_repo_genindex(const char *pkgdir) xbps_repo_genindex(const char *pkgdir)
{ {
prop_dictionary_t idxdict = NULL;
struct dirent *dp; struct dirent *dp;
DIR *dirp; DIR *dirp;
struct utsname un; struct utsname un;
char *binfile, *path; uint64_t npkgcnt = 0;
char *binfile, *path, *plist;
size_t i; size_t i;
int rv = 0; int rv = 0;
bool foundpkg = false; bool registered_newpkgs = false, foundpkg = false;
if (uname(&un) == -1) if (uname(&un) == -1)
return errno; return errno;
/*
* Create or read existing package index plist file.
*/
idxdict = repoidx_getdict(pkgdir);
if (idxdict == NULL)
return errno;
plist = xbps_get_pkg_index_plist(pkgdir);
if (plist == NULL) {
prop_object_release(idxdict);
return errno;
}
/* /*
* Iterate over the known architecture directories to find * Iterate over the known architecture directories to find
* binary packages. * binary packages.
@ -256,8 +253,10 @@ xbps_repo_genindex(const char *pkgdir)
continue; continue;
path = xbps_xasprintf("%s/%s", pkgdir, archdirs[i]); path = xbps_xasprintf("%s/%s", pkgdir, archdirs[i]);
if (path == NULL) if (path == NULL) {
prop_object_release(idxdict);
return errno; return errno;
}
dirp = opendir(path); dirp = opendir(path);
if (dirp == NULL) { if (dirp == NULL) {
@ -279,22 +278,48 @@ xbps_repo_genindex(const char *pkgdir)
if (binfile == NULL) { if (binfile == NULL) {
(void)closedir(dirp); (void)closedir(dirp);
free(path); free(path);
prop_object_release(idxdict);
free(plist);
return errno; return errno;
} }
rv = xbps_repo_addpkg_index(pkgdir, binfile); rv = xbps_repo_addpkg_index(idxdict, binfile);
free(binfile); free(binfile);
if (rv != 0) { if (rv == EEXIST)
continue;
else if (rv != 0) {
(void)closedir(dirp); (void)closedir(dirp);
free(path); free(path);
prop_object_release(idxdict);
free(plist);
return rv; return rv;
} }
registered_newpkgs = true;
} }
(void)closedir(dirp); (void)closedir(dirp);
free(path); free(path);
} }
if (foundpkg == false) if (foundpkg == false) {
/* No packages were found in directory */
rv = ENOENT; rv = ENOENT;
} else {
/*
* Show total count registered packages.
*/
prop_dictionary_get_uint64(idxdict, "total-pkgs", &npkgcnt);
printf("%ju packages registered in package index.\n", npkgcnt);
/*
* Don't write plist file if no packages were registered.
*/
if (registered_newpkgs == false)
return rv;
/*
* If any package was registered in package index, write
* plist file to storage.
*/
if (!prop_dictionary_externalize_to_file(idxdict, plist))
rv = errno;
}
return rv; return rv;
} }

View File

@ -27,6 +27,6 @@
#define _XBPS_REPO_INDEX_H_ #define _XBPS_REPO_INDEX_H_
int xbps_repo_genindex(const char *); int xbps_repo_genindex(const char *);
int xbps_repo_addpkg_index(const char *, const char *); int xbps_repo_addpkg_index(prop_dictionary_t, const char *);
#endif /* !_XBPS_REPO_INDEX_H_ */ #endif /* !_XBPS_REPO_INDEX_H_ */

View File

@ -49,10 +49,9 @@ usage(void)
{ {
printf("Usage: xbps-repo [options] [action] [arguments]\n\n" printf("Usage: xbps-repo [options] [action] [arguments]\n\n"
" Available actions:\n" " Available actions:\n"
" add, add-pkgidx, genindex, list, remove, search, show\n" " add, genindex, list, remove, search, show\n"
" Actions with arguments:\n" " Actions with arguments:\n"
" add\t\t<URI>\n" " add\t\t<URI>\n"
" add-pkgidx\t<repo> <binpkg>\n"
" genindex\t<path>\n" " genindex\t<path>\n"
" remove\t<URI>\n" " remove\t<URI>\n"
" search\t<string>\n" " search\t<string>\n"
@ -69,7 +68,6 @@ usage(void)
" $ xbps-repo remove /path/to/directory\n" " $ xbps-repo remove /path/to/directory\n"
" $ xbps-repo search klibc\n" " $ xbps-repo search klibc\n"
" $ xbps-repo show klibc\n" " $ xbps-repo show klibc\n"
" $ xbps-repo add-pkgidx /pkgdir /pkgdir/noarch/foo.xbps\n"
" $ xbps-repo genindex /pkgdir\n"); " $ xbps-repo genindex /pkgdir\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -147,6 +145,7 @@ add_repository(const char *uri, bool remote)
if (!sanitize_localpath(idxstr, uri)) if (!sanitize_localpath(idxstr, uri))
return errno; return errno;
printf("Fetching remote package index at %s...\n", uri);
rv = xbps_sync_repository_pkg_index(idxstr); rv = xbps_sync_repository_pkg_index(idxstr);
if (rv != 0) if (rv != 0)
return rv; return rv;
@ -301,15 +300,6 @@ main(int argc, char **argv)
rv = xbps_repo_genindex(argv[1]); rv = xbps_repo_genindex(argv[1]);
exit(rv); exit(rv);
} else if (strcasecmp(argv[0], "add-pkgidx") == 0) {
/* Add a binary package into a package repository. */
if (argc != 3)
usage();
rv = xbps_repo_addpkg_index(argv[1], argv[2]);
if (rv != 0)
exit(rv);
} else if (strcasecmp(argv[0], "sync") == 0) { } else if (strcasecmp(argv[0], "sync") == 0) {
/* Syncs the pkg index file from a remote repo */ /* Syncs the pkg index file from a remote repo */
if (argc != 2) if (argc != 2)

View File

@ -43,16 +43,12 @@ Please note that all targets are *case insensitive*.
Local (by specifying a *directory*) and remote (by specifiying an Local (by specifying a *directory*) and remote (by specifiying an
*HTTP/HTTPS/FTP URL*) repositories can be specified. *HTTP/HTTPS/FTP URL*) repositories can be specified.
*add-pkgidx* '/path/to/local/repo' '/path/to/local/repo/arch/binpkg'::
Adds the binary package 'binpkg' as specified in the second argument
into the package index of a local repository as specified in the
first argument. Please note that 'binpkg' must also live in the same
local repository, you need to specify the full path to the file.
*genindex* '/path/to/local/repo':: *genindex* '/path/to/local/repo'::
Generates a package index for a local repository as specified in Generates a package index for a local repository as specified in
its argument. The same argument should be used for the *add* its argument. It will look for archives with *.xbps* extension
and *remove* targets. and will only add it into the index if version is newer than the one
available in the index. The same argument should be used for the *add*
and *remove* targets.
*list*:: *list*::
Lists all currently registered repositories in repository pool. Lists all currently registered repositories in repository pool.