summaryrefslogtreecommitdiffstats
path: root/src/index.c
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 /src/index.c
parentba76c5f48ae584c4085ef97fb16e5a6f72adfe25 (diff)
downloadapk-tools-623bc9c5a820906e26c0cc52d0ab230c3c0bc1ab.tar.bz2
apk-tools-623bc9c5a820906e26c0cc52d0ab230c3c0bc1ab.tar.xz
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.c92
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 = {