diff options
author | Timo Teras <timo.teras@iki.fi> | 2009-07-15 16:47:43 +0300 |
---|---|---|
committer | Timo Teras <timo.teras@iki.fi> | 2009-07-15 16:47:43 +0300 |
commit | 623bc9c5a820906e26c0cc52d0ab230c3c0bc1ab (patch) | |
tree | c918121336688cb0ce699c1521991643e1def381 /src/index.c | |
parent | ba76c5f48ae584c4085ef97fb16e5a6f72adfe25 (diff) | |
download | apk-tools-623bc9c5a820906e26c0cc52d0ab230c3c0bc1ab.tar.gz apk-tools-623bc9c5a820906e26c0cc52d0ab230c3c0bc1ab.tar.bz2 apk-tools-623bc9c5a820906e26c0cc52d0ab230c3c0bc1ab.tar.xz apk-tools-623bc9c5a820906e26c0cc52d0ab230c3c0bc1ab.zip |
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".
Diffstat (limited to 'src/index.c')
-rw-r--r-- | src/index.c | 92 |
1 files changed, 69 insertions, 23 deletions
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 = { |