summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2009-07-15 16:47:43 +0300
committerTimo Teras <timo.teras@iki.fi>2009-07-15 16:47:43 +0300
commit623bc9c5a820906e26c0cc52d0ab230c3c0bc1ab (patch)
treec918121336688cb0ce699c1521991643e1def381
parentba76c5f48ae584c4085ef97fb16e5a6f72adfe25 (diff)
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".
-rw-r--r--src/database.c2
-rw-r--r--src/index.c92
2 files changed, 70 insertions, 24 deletions
diff --git a/src/database.c b/src/database.c
index c80e9a9..80b6fc3 100644
--- a/src/database.c
+++ b/src/database.c
@@ -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);
diff --git a/src/index.c b/src/index.c
index b938984..62460f7 100644
--- a/src/index.c
+++ b/src/index.c
@@ -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 = {