From f0609951b9fd2938c0f30853e0aa6b08b8698a88 Mon Sep 17 00:00:00 2001 From: Timo Teras Date: Thu, 27 Nov 2008 20:25:01 +0200 Subject: hash, db: use apk_blob_t and list_* --- src/database.c | 96 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 44 deletions(-) (limited to 'src/database.c') diff --git a/src/database.c b/src/database.c index 2376249..0795a0b 100644 --- a/src/database.c +++ b/src/database.c @@ -33,51 +33,53 @@ struct install_ctx { struct hlist_node **file_pkg_node; }; -static apk_hash_key pkg_name_get_key(apk_hash_item item) +static apk_blob_t pkg_name_get_key(apk_hash_item item) { - return ((struct apk_name *) item)->name; + return APK_BLOB_STR(((struct apk_name *) item)->name); } static const struct apk_hash_ops pkg_name_hash_ops = { .node_offset = offsetof(struct apk_name, hash_node), .get_key = pkg_name_get_key, - .hash_key = (apk_hash_f) apk_hash_string, - .compare = (apk_hash_compare_f) strcmp, + .hash_key = apk_blob_hash, + .compare = apk_blob_compare, .delete_item = (apk_hash_delete_f) apk_name_free, }; -static apk_hash_key pkg_info_get_key(apk_hash_item item) +static apk_blob_t pkg_info_get_key(apk_hash_item item) { - return ((struct apk_package *) item)->csum; + return APK_BLOB_BUF(((struct apk_package *) item)->csum); } -static int cmpcsum(apk_hash_key a, apk_hash_key b) +static unsigned long csum_hash(apk_blob_t csum) { - return memcmp(a, b, sizeof(csum_t)); + /* Checksum's highest bits have the most "randomness", use that + * directly as hash */ + return *(unsigned long *)csum.ptr; } static const struct apk_hash_ops pkg_info_hash_ops = { .node_offset = offsetof(struct apk_package, hash_node), .get_key = pkg_info_get_key, - .hash_key = (apk_hash_f) apk_hash_csum, - .compare = cmpcsum, + .hash_key = csum_hash, + .compare = apk_blob_compare, .delete_item = (apk_hash_delete_f) apk_pkg_free, }; -static apk_hash_key apk_db_dir_get_key(apk_hash_item item) +static apk_blob_t apk_db_dir_get_key(apk_hash_item item) { - return ((struct apk_db_dir *) item)->dirname; + return APK_BLOB_STR(((struct apk_db_dir *) item)->dirname); } static const struct apk_hash_ops dir_hash_ops = { .node_offset = offsetof(struct apk_db_dir, hash_node), .get_key = apk_db_dir_get_key, - .hash_key = (apk_hash_f) apk_hash_string, - .compare = (apk_hash_compare_f) strcmp, + .hash_key = apk_blob_hash, + .compare = apk_blob_compare, .delete_item = (apk_hash_delete_f) free, }; -struct apk_name *apk_db_get_name(struct apk_database *db, const char *name) +struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name) { struct apk_name *pn; @@ -89,7 +91,7 @@ struct apk_name *apk_db_get_name(struct apk_database *db, const char *name) if (pn == NULL) return NULL; - pn->name = strdup(name); + pn->name = apk_blob_cstr(name); apk_hash_insert(&db->available.names, pn); return pn; @@ -137,15 +139,12 @@ static struct apk_db_dir *apk_db_dir_get(struct apk_database *db, { struct apk_db_dir *dir; apk_blob_t bparent; - char *cstr; int i; if (name.len && name.ptr[name.len-1] == '/') name.len--; - cstr = apk_blob_cstr(name); - dir = (struct apk_db_dir *) apk_hash_get(&db->installed.dirs, cstr); - free(cstr); + dir = (struct apk_db_dir *) apk_hash_get(&db->installed.dirs, name); if (dir != NULL) return dir; @@ -249,7 +248,6 @@ static int apk_db_read_fdb(struct apk_database *db, struct apk_istream *is) struct apk_package *pkg = NULL; struct apk_db_dir *dir = NULL; struct apk_db_file *file = NULL; - struct hlist_node **pkg_node = &db->installed.packages.first; struct hlist_node **file_dir_node = NULL; struct hlist_node **file_pkg_node = NULL; @@ -281,10 +279,9 @@ static int apk_db_read_fdb(struct apk_database *db, struct apk_istream *is) l.len, l.ptr); return -1; } - if (!hlist_hashed(&pkg->installed_pkgs_list)) { + if (!list_hashed(&pkg->installed_pkgs_list)) { db->installed.stats.packages++; - hlist_add_after(&pkg->installed_pkgs_list, pkg_node); - pkg_node = &pkg->installed_pkgs_list.next; + list_add_tail(&pkg->installed_pkgs_list, &db->installed.packages); } dir = NULL; file_dir_node = NULL; @@ -336,11 +333,11 @@ static int apk_db_write_fdb(struct apk_database *db, int fd) struct apk_package *pkg; struct apk_db_dir *dir; struct apk_db_file *file; - struct hlist_node *c1, *c2; + struct hlist_node *c2; char buf[1024]; int n; - hlist_for_each_entry(pkg, c1, &db->installed.packages, installed_pkgs_list) { + list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) { n = 0; buf[n++] = 'P'; n += apk_hexdump_format(sizeof(buf)-n, &buf[n], @@ -392,10 +389,9 @@ static int apk_db_write_scriptdb(struct apk_database *db, int fd) struct apk_package *pkg; struct apk_script *script; struct apk_script_header hdr; - struct hlist_node *c1, *c2; + struct hlist_node *c2; - hlist_for_each_entry(pkg, c1, &db->installed.packages, - installed_pkgs_list) { + list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) { hlist_for_each_entry(script, c2, &pkg->scripts, script_list) { memcpy(hdr.csum, pkg->csum, sizeof(csum_t)); hdr.type = script->type; @@ -416,7 +412,8 @@ static int apk_db_read_scriptdb(struct apk_database *db, struct apk_istream *is) while (is->read(is, &hdr, sizeof(hdr)) == sizeof(hdr)) { pkg = apk_db_get_pkg(db, hdr.csum); - apk_pkg_add_script(pkg, is, hdr.type, hdr.size); + if (pkg != NULL) + apk_pkg_add_script(pkg, is, hdr.type, hdr.size); } return 0; @@ -485,6 +482,12 @@ static int apk_db_read_state(struct apk_database *db) is->close(is); } + blob = apk_blob_from_file("etc/apk/repositories"); + if (!APK_BLOB_IS_NULL(blob)) { + apk_blob_for_each_segment(blob, "\n", apk_db_add_repository, db); + free(blob.ptr); + } + return 0; } @@ -504,6 +507,7 @@ int apk_db_open(struct apk_database *db, const char *root) apk_hash_init(&db->available.names, &pkg_name_hash_ops, 1000); apk_hash_init(&db->available.packages, &pkg_info_hash_ops, 4000); apk_hash_init(&db->installed.dirs, &dir_hash_ops, 1000); + list_init(&db->installed.packages); if (root != NULL) { db->root = strdup(root); @@ -515,7 +519,7 @@ int apk_db_open(struct apk_database *db, const char *root) } } if (apk_repository != NULL) - apk_db_add_repository(db, apk_repository); + apk_db_add_repository(db, APK_BLOB_STR(apk_repository)); dirs = APK_BLOB_STR("etc:-etc/init.d"); apk_blob_for_each_segment(dirs, ":", add_protected_path, db); @@ -575,7 +579,7 @@ static void apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg) { struct apk_package *idb; - idb = apk_hash_get(&db->available.packages, pkg->csum); + idb = apk_hash_get(&db->available.packages, APK_BLOB_BUF(pkg->csum)); if (idb == NULL) { pkg->id = db->pkg_id++; apk_hash_insert(&db->available.packages, pkg); @@ -588,7 +592,8 @@ static void apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg) struct apk_package *apk_db_get_pkg(struct apk_database *db, csum_t sum) { - return apk_hash_get(&db->available.packages, sum); + return apk_hash_get(&db->available.packages, + APK_BLOB_PTR_LEN((void*) sum, sizeof(csum_t))); } int apk_db_pkg_add_file(struct apk_database *db, const char *file) @@ -603,7 +608,7 @@ int apk_db_pkg_add_file(struct apk_database *db, const char *file) return TRUE; } -int apk_db_index_read(struct apk_database *db, int fd, int repo) +int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo) { struct apk_package *pkg; char buf[1024]; @@ -612,7 +617,7 @@ int apk_db_index_read(struct apk_database *db, int fd, int repo) r = APK_BLOB_PTR_LEN(buf, 0); while (1) { - n = read(fd, &r.ptr[r.len], sizeof(buf) - r.len); + n = is->read(is, &r.ptr[r.len], sizeof(buf) - r.len); if (n <= 0) break; r.len += n; @@ -650,27 +655,29 @@ void apk_db_index_write(struct apk_database *db, int fd) apk_hash_foreach(&db->available.packages, write_index_entry, (void *) fd); } -int apk_db_add_repository(struct apk_database *db, const char *repo) +int apk_db_add_repository(apk_database_t _db, apk_blob_t repository) { + struct apk_database *db = _db.db; + struct apk_istream *is; char tmp[256]; - int fd, r; + int r; if (db->num_repos >= APK_MAX_REPOS) return -1; r = db->num_repos++; db->repos[r] = (struct apk_repository){ - .url = strdup(repo) + .url = apk_blob_cstr(repository) }; - snprintf(tmp, sizeof(tmp), "%s/APK_INDEX", repo); - fd = open(tmp, O_RDONLY); - if (fd < 0) { + snprintf(tmp, sizeof(tmp), "%s/APK_INDEX", db->repos[r].url); + is = apk_istream_from_file(tmp); + if (is == NULL) { apk_error("Failed to open index file %s", tmp); return -1; } - apk_db_index_read(db, fd, r); - close(fd); + apk_db_index_read(db, is, r); + is->close(is); return 0; } @@ -823,6 +830,7 @@ static void apk_db_purge_pkg(struct apk_database *db, db->installed.stats.files--; } db->installed.stats.packages--; + list_del(&pkg->installed_pkgs_list); } int apk_db_install_pkg(struct apk_database *db, @@ -883,7 +891,7 @@ int apk_db_install_pkg(struct apk_database *db, bs->close(bs, csum); db->installed.stats.packages++; - hlist_add_head(&newpkg->installed_pkgs_list, &db->installed.packages); + list_add_tail(&newpkg->installed_pkgs_list, &db->installed.packages); if (memcmp(csum, newpkg->csum, sizeof(csum)) != 0) apk_warning("%s-%s: checksum does not match", -- cgit v1.2.3-60-g2f50