index: reuse existing index (fixes #25)

replace the old 'delete' option, with 'index'. the idea is that
one can provide existing index files to take cached meta-data of
the package from (assumes package has not been modified if index is
newer, and package size has not changed).

this way one always gives the list of .apk files to include in
the new index, and the old index is used only as "cache".
cute-signatures
Timo Teras 2009-07-15 16:47:43 +03:00
parent ba76c5f48a
commit 623bc9c5a8
2 changed files with 70 additions and 24 deletions

View File

@ -991,7 +991,7 @@ static int write_index_entry(apk_hash_item item, void *ctx)
struct apk_package *pkg = (struct apk_package *) item;
int r;
if (pkg->repos != 0)
if (pkg->filename == NULL)
return 0;
r = apk_pkg_write_index_entry(pkg, iwctx->os);

View File

@ -20,8 +20,8 @@ struct counts {
};
struct index_ctx {
const char *index_file;
int delete;
const char *index;
time_t index_mtime;
};
static int index_parse(void *ctx, int optch, int optindex, const char *optarg)
@ -29,9 +29,8 @@ static int index_parse(void *ctx, int optch, int optindex, const char *optarg)
struct index_ctx *ictx = (struct index_ctx *) ctx;
switch (optch) {
case 'd':
ictx->index_file = optarg;
ictx->delete = 1;
case 'x':
ictx->index = optarg;
break;
default:
return -1;
@ -42,13 +41,17 @@ static int index_parse(void *ctx, int optch, int optindex, const char *optarg)
static int index_read_file(struct apk_database *db, struct index_ctx *ictx)
{
struct apk_bstream *bs;
struct apk_file_info fi;
int r;
if (ictx->index_file == NULL)
if (ictx->index == NULL)
return 0;
bs = apk_bstream_from_istream(apk_bstream_gunzip(apk_bstream_from_url(ictx->index_file), 1));
if (apk_file_get_info(ictx->index, APK_CHECKSUM_NONE, &fi) < 0)
return -1;
ictx->index_mtime = fi.mtime;
bs = apk_bstream_from_istream(apk_bstream_gunzip(apk_bstream_from_url(ictx->index), 1));
if (bs == NULL)
return -1;
r = apk_db_index_read(db, bs, -1);
r = apk_db_index_read(db, bs, 0);
bs->close(bs, NULL);
return r;
}
@ -76,25 +79,67 @@ static int index_main(void *ctx, int argc, char **argv)
struct apk_database db;
struct counts counts = {0};
struct apk_ostream *os;
int total, i, j;
struct apk_file_info fi;
int total, i, j, found, newpkgs = 0;
struct index_ctx *ictx = (struct index_ctx *) ctx;
apk_db_open(&db, NULL, APK_OPENF_READ);
index_read_file(&db, ictx);
if (index_read_file(&db, ictx) < 0) {
apk_db_close(&db);
apk_error("The index is corrupt, or of unknown format.");
return -1;
}
for (i = 0; i < argc; i++) {
if (ictx->delete) {
if (apk_file_get_info(argv[i], APK_CHECKSUM_NONE, &fi) < 0) {
apk_warning("File '%s' is unaccessible", argv[i]);
continue;
}
found = FALSE;
do {
struct apk_name *name;
name = apk_db_query_name(&db, APK_BLOB_STR(argv[i]));
char *fname, *fend;
apk_blob_t bname, bver;
/* Check if index is newer than package */
if (ictx->index == NULL || ictx->index_mtime < fi.mtime)
break;
/* Check that it looks like a package name */
fname = strrchr(argv[i], '/');
if (fname == NULL)
fname = argv[i];
else
fname++;
fend = strstr(fname, ".apk");
if (fend == NULL)
break;
if (apk_pkg_parse_name(APK_BLOB_PTR_PTR(fname, fend-1),
&bname, &bver) < 0)
break;
/* If we have it in the old index already? */
name = apk_db_query_name(&db, bname);
if (name == NULL || name->pkgs == NULL)
continue;
/* apk_db_index_write() will only print the pkgs
where repos == 0. We prevent to write the given
packages by setting repos to non-zero */
for (j = 0; j < name->pkgs->num; j++)
name->pkgs->item[j]->repos = -1;
} else
break;
for (j = 0; j < name->pkgs->num; j++) {
struct apk_package *pkg = name->pkgs->item[j];
if (apk_blob_compare(bver, APK_BLOB_STR(pkg->version)) != 0)
continue;
if (pkg->size != fi.size)
continue;
pkg->filename = strdup(argv[i]);
found = TRUE;
break;
}
} while (0);
if (!found) {
apk_db_pkg_add_file(&db, argv[i]);
newpkgs++;
}
}
os = apk_ostream_to_fd(STDOUT_FILENO);
@ -108,15 +153,16 @@ static int index_main(void *ctx, int argc, char **argv)
apk_warning("Total of %d unsatisfiable package "
"names. Your repository maybe broken.",
counts.unsatisfied);
apk_message("Index has %d packages", total);
apk_message("Index has %d packages (of which %d are new)",
total, newpkgs);
return 0;
}
static struct apk_option index_options[] = {
{ 'd', "delete",
"Read existing INDEXFILE and delete the listed FILEs from it",
required_argument, "INDEXFILE" },
{ 'x', "index", "Read INDEX to speed up new index creation by reusing "
"the information from an old index",
required_argument, "INDEX" },
};
static struct apk_applet apk_index = {