Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
convert pkg_option and pkg_conflicts to khash
Baptiste Daroussin committed 9 years ago
commit ba73c4cfb0b5b77bd9d6d08162b58a27bb0f14cf
parent e44f42c
6 files changed +64 -85
modified libpkg/pkg.c
@@ -513,22 +513,6 @@ pkg_set_from_file(struct pkg *pkg, pkg_attr attr, const char *path, bool trimcr)
	return (ret);
}

-
int
-
pkg_options(const struct pkg *pkg, struct pkg_option **o)
-
{
-
	assert(pkg != NULL);
-

-
	HASH_NEXT(pkg->options, (*o));
-
}
-

-
int
-
pkg_conflicts(const struct pkg *pkg, struct pkg_conflict **c)
-
{
-
	assert(pkg != NULL);
-

-
	HASH_NEXT(pkg->conflicts, (*c));
-
}
-

#define pkg_each(name, type, field)		\
int						\
pkg_##name(const struct pkg *p, type **t) {	\
@@ -546,6 +530,8 @@ pkg_each(dirs, struct pkg_dir, dirs);
pkg_each(files, struct pkg_file, files);
pkg_each(deps, struct pkg_dep, depends);
pkg_each(rdeps, struct pkg_dep, rdepends);
+
pkg_each(options, struct pkg_option, options);
+
pkg_each(conflicts, struct pkg_conflict, conflicts);

#define pkg_each_hash(name, htype, type, attrib)	\
int							\
@@ -998,11 +984,7 @@ pkg_addoption(struct pkg *pkg, const char *key, const char *value)
	   value. */

	pkg_debug(2,"Pkg> adding options: %s = %s", key, value);
-
	HASH_FIND_STR(pkg->options, key, o);
-
	if (o == NULL) {
-
		o = xcalloc(1, sizeof(*o));
-
		o->key = xstrdup(key);
-
	} else if ( o->value != NULL) {
+
	if (kh_contains(pkg_options, pkg->optionshash, key)) {
		if (developer_mode) {
			pkg_emit_error("duplicate options listing: %s, fatal (developer mode)", key);
			return (EPKG_FATAL);
@@ -1011,9 +993,11 @@ pkg_addoption(struct pkg *pkg, const char *key, const char *value)
			return (EPKG_OK);
		}
	}
-

+
	o = xcalloc(1, sizeof(*o));
+
	o->key = xstrdup(key);
	o->value = xstrdup(value);
-
	HASH_ADD_KEYPTR(hh, pkg->options, o->key, strlen(o->key), o);
+
	kh_safe_add(pkg_options, pkg->optionshash, o, o->key);
+
	LL_APPEND(pkg->options, o);

	return (EPKG_OK);
}
@@ -1034,11 +1018,7 @@ pkg_addoption_default(struct pkg *pkg, const char *key,
	   could be a default value or description for an option but
	   no actual value. */

-
	HASH_FIND_STR(pkg->options, key, o);
-
	if (o == NULL) {
-
		o = xcalloc(1, sizeof(*o));
-
		o->key = xstrdup(key);
-
	} else if ( o->default_value != NULL) {
+
	if (kh_contains(pkg_options, pkg->optionshash, key)) {
		if (developer_mode) {
			pkg_emit_error("duplicate default value for option: %s, fatal (developer mode)", key);
			return (EPKG_FATAL);
@@ -1047,10 +1027,11 @@ pkg_addoption_default(struct pkg *pkg, const char *key,
			return (EPKG_OK);
		}
	}
-

+
	o = xcalloc(1, sizeof(*o));
+
	o->key = xstrdup(key);
	o->default_value = xstrdup(default_value);
-
	HASH_ADD_KEYPTR(hh, pkg->options, o->default_value,
-
	    strlen(o->default_value), o);
+
	kh_safe_add(pkg_options, pkg->optionshash, o, o->key);
+
	LL_APPEND(pkg->options, o);

	return (EPKG_OK);
}
@@ -1070,11 +1051,7 @@ pkg_addoption_description(struct pkg *pkg, const char *key,
	   is already set. Which implies there could be a default
	   value or description for an option but no actual value. */

-
	HASH_FIND_STR(pkg->options, key, o);
-
	if (o == NULL) {
-
		o = xcalloc(1, sizeof(*o));
-
		o->key = xstrdup(key);
-
	} else if ( o->description != NULL) {
+
	if (kh_contains(pkg_options, pkg->optionshash, key)) {
		if (developer_mode) {
			pkg_emit_error("duplicate description for option: %s, fatal (developer mode)", key);
			return (EPKG_FATAL);
@@ -1084,9 +1061,11 @@ pkg_addoption_description(struct pkg *pkg, const char *key,
		}
	}

+
	o = xcalloc(1, sizeof(*o));
+
	o->key = xstrdup(key);
	o->description = xstrdup(description);
-
	HASH_ADD_KEYPTR(hh, pkg->options, o->description,
-
	    strlen(o->description), o);
+
	kh_safe_add(pkg_options, pkg->optionshash, o, o->key);
+
	LL_APPEND(pkg->options, o);

	return (EPKG_OK);
}
@@ -1143,16 +1122,17 @@ pkg_addconflict(struct pkg *pkg, const char *uniqueid)
	assert(pkg != NULL);
	assert(uniqueid != NULL && uniqueid[0] != '\0');

-
	HASH_FIND_STR(pkg->conflicts, __DECONST(char *, uniqueid), c);
-
	/* silently ignore duplicates in case of conflicts */
-
	if (c != NULL)
+
	if (kh_contains(pkg_conflicts, pkg->conflictshash, uniqueid)) {
+
		/* silently ignore duplicates in case of conflicts */
		return (EPKG_OK);
+
	}

	c = xcalloc(1, sizeof(*c));
	c->uid = xstrdup(uniqueid);
	pkg_debug(3, "Pkg: add a new conflict origin: %s, with %s", pkg->uid, uniqueid);

-
	HASH_ADD_KEYPTR(hh, pkg->conflicts, c->uid, strlen(c->uid), c);
+
	kh_safe_add(pkg_conflicts, pkg->conflictshash, c, c->uid);
+
	LL_APPEND(pkg->conflicts, c);

	return (EPKG_OK);
}
@@ -1247,7 +1227,7 @@ pkg_list_count(const struct pkg *pkg, pkg_list list)
	case PKG_RDEPS:
		return (kh_count(pkg->rdepshash));
	case PKG_OPTIONS:
-
		return (HASH_COUNT(pkg->options));
+
		return (kh_count(pkg->optionshash));
	case PKG_FILES:
		return (kh_count(pkg->filehash));
	case PKG_DIRS:
@@ -1261,7 +1241,7 @@ pkg_list_count(const struct pkg *pkg, pkg_list list)
	case PKG_SHLIBS_PROVIDED:
		return (kh_count(pkg->shlibs_provided));
	case PKG_CONFLICTS:
-
		return (HASH_COUNT(pkg->conflicts));
+
		return (kh_count(pkg->conflictshash));
	case PKG_PROVIDES:
		return (kh_count(pkg->provides));
	case PKG_REQUIRES:
@@ -1291,7 +1271,8 @@ pkg_list_free(struct pkg *pkg, pkg_list list) {
		pkg->flags &= ~PKG_LOAD_RDEPS;
		break;
	case PKG_OPTIONS:
-
		HASH_FREE(pkg->options, pkg_option_free);
+
		LL_FREE(pkg->options, pkg_option_free);
+
		kh_destroy_pkg_options(pkg->optionshash);
		pkg->flags &= ~PKG_LOAD_OPTIONS;
		break;
	case PKG_FILES:
@@ -1323,7 +1304,8 @@ pkg_list_free(struct pkg *pkg, pkg_list list) {
		pkg->flags &= ~PKG_LOAD_SHLIBS_PROVIDED;
		break;
	case PKG_CONFLICTS:
-
		HASH_FREE(pkg->conflicts, pkg_conflict_free);
+
		LL_FREE(pkg->conflicts, pkg_conflict_free);
+
		kh_destroy_pkg_conflicts(pkg->conflictshash);
		pkg->flags &= ~PKG_LOAD_CONFLICTS;
		break;
	case PKG_PROVIDES:
modified libpkg/pkg_cudf.c
@@ -111,7 +111,7 @@ cudf_emit_pkg(struct pkg *pkg, int version, FILE *f,
		struct pkg_job_universe_item *conflicts_chain)
{
	struct pkg_dep *dep;
-
	struct pkg_conflict *conflict, *ctmp;
+
	struct pkg_conflict *conflict;
	struct pkg_job_universe_item *u;
	char *buf;
	int column = 0, ver;
@@ -149,14 +149,14 @@ cudf_emit_pkg(struct pkg *pkg, int version, FILE *f,
	}

	column = 0;
-
	if (HASH_COUNT(pkg->conflicts) > 0 ||
+
	if (kh_count(pkg->conflictshash) > 0 ||
			(conflicts_chain->next != NULL &&
			conflicts_chain->next->priority != INT_MIN)) {
		if (fprintf(f, "conflicts: ") < 0)
			return (EPKG_FATAL);
-
		HASH_ITER(hh, pkg->conflicts, conflict, ctmp) {
+
		LL_FOREACH(pkg->conflicts, conflict) {
			if (cudf_print_element(f, conflict->uid,
-
					(conflict->hh.next != NULL), &column) < 0) {
+
					(conflict->next != NULL), &column) < 0) {
				return (EPKG_FATAL);
			}
		}
modified libpkg/pkg_jobs_conflicts.c
@@ -126,7 +126,7 @@ int
pkg_conflicts_request_resolve(struct pkg_jobs *j)
{
	struct pkg_job_request *req, *rtmp, *found;
-
	struct pkg_conflict *c, *ctmp;
+
	struct pkg_conflict *c;
	struct pkg_conflict_chain *chain;
	struct pkg_job_universe_item *unit;

@@ -135,7 +135,7 @@ pkg_conflicts_request_resolve(struct pkg_jobs *j)
		if (req->skip)
			continue;

-
		HASH_ITER(hh, req->item->pkg->conflicts, c, ctmp) {
+
		LL_FOREACH(req->item->pkg->conflicts, c) {
			unit = pkg_jobs_universe_find(j->universe, c->uid);
			if (unit != NULL) {
				HASH_FIND_STR(j->request_add, unit->pkg->uid, found);
@@ -162,16 +162,16 @@ pkg_conflicts_request_resolve(struct pkg_jobs *j)
void
pkg_conflicts_register(struct pkg *p1, struct pkg *p2, enum pkg_conflict_type type)
{
-
	struct pkg_conflict *c1, *c2, *test;
+
	struct pkg_conflict *c1, *c2;

	c1 = xcalloc(1, sizeof(*c1));
	c2 = xcalloc(1, sizeof(*c2));

	c1->type = c2->type = type;
-
	HASH_FIND_STR(p1->conflicts, p2->uid, test);
-
	if (test == NULL) {
+
	if (!kh_contains(pkg_conflicts, p1->conflictshash, p2->uid)) {
		c1->uid = xstrdup(p2->uid);
-
		HASH_ADD_KEYPTR(hh, p1->conflicts, c1->uid, strlen(c1->uid), c1);
+
		kh_safe_add(pkg_conflicts, p1->conflictshash, c1, c1->uid);
+
		LL_APPEND(p1->conflicts, c1);
		pkg_debug(2, "registering conflict between %s(%s) and %s(%s)",
				p1->uid, p1->type == PKG_INSTALLED ? "l" : "r",
				p2->uid, p2->type == PKG_INSTALLED ? "l" : "r");
@@ -179,10 +179,10 @@ pkg_conflicts_register(struct pkg *p1, struct pkg *p2, enum pkg_conflict_type ty
		pkg_conflict_free(c1);
	}

-
	HASH_FIND_STR(p2->conflicts, p1->uid, test);
-
	if (test == NULL) {
+
	if (!kh_contains(pkg_conflicts, p2->conflictshash, p1->uid)) {
		c2->uid = xstrdup(p1->uid);
-
		HASH_ADD_KEYPTR(hh, p2->conflicts, c2->uid, strlen(c2->uid), c2);
+
		kh_safe_add(pkg_conflicts, p2->conflictshash, c2, c2->uid);
+
		LL_APPEND(p2->conflicts, c2);
		pkg_debug(2, "registering conflict between %s(%s) and %s(%s)",
				p2->uid, p2->type == PKG_INSTALLED ? "l" : "r",
				p1->uid, p1->type == PKG_INSTALLED ? "l" : "r");
@@ -207,7 +207,6 @@ static bool
pkg_conflicts_need_conflict(struct pkg_jobs *j, struct pkg *p1, struct pkg *p2)
{
	struct pkg_file *fcur;
-
	struct pkg_conflict *c1, *c2;

	if (pkgdb_ensure_loaded(j->db, p1, PKG_LOAD_FILES|PKG_LOAD_DIRS) != EPKG_OK ||
			pkgdb_ensure_loaded(j->db, p2, PKG_LOAD_FILES|PKG_LOAD_DIRS)
@@ -225,9 +224,8 @@ pkg_conflicts_need_conflict(struct pkg_jobs *j, struct pkg *p1, struct pkg *p2)
	/*
	 * Check if we already have this conflict registered
	 */
-
	HASH_FIND_STR(p1->conflicts, p2->uid, c1);
-
	HASH_FIND_STR(p2->conflicts, p1->uid, c2);
-
	if (c1 != NULL && c2 != NULL)
+
	if (kh_contains(pkg_conflicts, p1->conflictshash, p2->uid) &&
+
	    kh_contains(pkg_conflicts, p2->conflictshash, p1->uid))
		return false;

	/*
@@ -256,9 +254,8 @@ pkg_conflicts_register_unsafe(struct pkg *p1, struct pkg *p2,
{
	struct pkg_conflict *c1, *c2;

-
	HASH_FIND_STR(p1->conflicts, p2->uid, c1);
-
	HASH_FIND_STR(p2->conflicts, p1->uid, c2);
-

+
	kh_find(pkg_conflicts, p1->conflictshash, p2->uid, c1);
+
	kh_find(pkg_conflicts, p2->conflictshash, p1->uid, c2);
	if (c1 == NULL) {
		c1 = xcalloc(1, sizeof(*c1));
		c1->type = type;
@@ -268,7 +265,8 @@ pkg_conflicts_register_unsafe(struct pkg *p1, struct pkg *p2,
			c1->digest = xstrdup(p2->digest);
		}

-
		HASH_ADD_KEYPTR(hh, p1->conflicts, c1->uid, strlen(c1->uid), c1);
+
		kh_safe_add(pkg_conflicts, p1->conflictshash, c1, c1->uid);
+
		LL_APPEND(p1->conflicts, c1);
	}

	if (c2 == NULL) {
@@ -283,7 +281,8 @@ pkg_conflicts_register_unsafe(struct pkg *p1, struct pkg *p2,
			c2->digest = xstrdup(p1->digest);
		}

-
		HASH_ADD_KEYPTR(hh, p2->conflicts, c2->uid, strlen(c2->uid), c2);
+
		kh_safe_add(pkg_conflicts, p2->conflictshash, c2, c2->uid);
+
		LL_APPEND(p2->conflicts, c2);
	}

	pkg_debug(2, "registering conflict between %s(%s) and %s(%s) on path %s",
@@ -359,7 +358,6 @@ pkg_conflicts_check_local_path(const char *path, const char *uid,
	sqlite3_stmt *stmt;
	int ret;
	struct pkg *p = NULL;
-
	struct pkg_conflict *c;

	pkg_debug(4, "Pkgdb: running '%s'", sql_local_conflict);
	ret = sqlite3_prepare_v2(j->db->sqlite, sql_local_conflict, -1,
@@ -387,8 +385,7 @@ pkg_conflicts_check_local_path(const char *path, const char *uid,

		assert(strcmp(uid, p->uid) != 0);

-
		HASH_FIND_STR(p->conflicts, uid, c);
-
		if (c == NULL) {
+
		if (!kh_contains(pkg_conflicts, p->conflictshash, uid)) {
			/* We need to register the conflict between two universe chains */
			sqlite3_finalize(stmt);
			return (p);
@@ -433,7 +430,7 @@ pkg_conflicts_check_all_paths(struct pkg_jobs *j, const char *path,
		}

		/* Here we can have either collision or a real conflict */
-
		HASH_FIND_STR(it->pkg->conflicts, uid2, c);
+
		kh_find(pkg_conflicts, it->pkg->conflictshash, uid2, c);
		if (c != NULL || !pkg_conflicts_register_chain(j, it, cit->item, path)) {
			/*
			 * Collision found, change the key following the
modified libpkg/pkg_repo_create.c
@@ -73,6 +73,7 @@ struct digest_list_entry {

struct pkg_conflict_bulk {
	struct pkg_conflict *conflicts;
+
	kh_pkg_conflicts_t *conflictshash;
	char *file;
	UT_hash_handle hh;
};
@@ -92,7 +93,7 @@ pkg_repo_new_conflict(const char *uniqueid, struct pkg_conflict_bulk *bulk)
	new = xcalloc(1, sizeof(*new));
	new->uid = xstrdup(uniqueid);

-
	HASH_ADD_KEYPTR(hh, bulk->conflicts, new->uid, strlen(new->uid), new);
+
	kh_safe_add(pkg_conflicts, bulk->conflictshash, new, new->uid);
}

struct pkg_fts_item {
@@ -502,8 +503,6 @@ pkg_create_repo(char *path, const char *output_dir, bool filelist,
{
	FTS *fts = NULL;
	struct pkg_fts_item *fts_items = NULL, *fts_cur, *fts_start;
-

-
	struct pkg_conflict *c, *ctmp;
	struct pkg_conflict_bulk *conflicts = NULL, *curcb, *tmpcb;
	int num_workers, i, remaining_workers, remain, cur_jobs, remain_jobs, nworker;
	size_t len, tasks_per_worker, ntask;
@@ -739,11 +738,8 @@ pkg_create_repo(char *path, const char *output_dir, bool filelist,
	}
cleanup:
	HASH_ITER (hh, conflicts, curcb, tmpcb) {
-
		HASH_ITER (hh, curcb->conflicts, c, ctmp) {
-
			free(c->uid);
-
			HASH_DEL(curcb->conflicts, c);
-
			free(c);
-
		}
+
		LL_FREE(curcb->conflicts, pkg_conflict_free);
+
		kh_destroy_pkg_conflicts(curcb->conflictshash);
		HASH_DEL(conflicts, curcb);
		free(curcb);
	}
modified libpkg/pkg_solve.c
@@ -719,7 +719,7 @@ pkg_solve_process_universe_variable(struct pkg_solve_problem *problem,
		struct pkg_solve_variable *var)
{
	struct pkg_dep *dep;
-
	struct pkg_conflict *conflict, *ctmp;
+
	struct pkg_conflict *conflict;
	struct pkg *pkg;
	struct pkg_solve_variable *cur_var;
	struct pkg_jobs *j = problem->j;
@@ -753,7 +753,7 @@ pkg_solve_process_universe_variable(struct pkg_solve_problem *problem,
		}

		/* Conflicts */
-
		HASH_ITER(hh, pkg->conflicts, conflict, ctmp) {
+
		LL_FOREACH(pkg->conflicts, conflict) {
			if (pkg_solve_add_conflict_rule(problem, pkg, cur_var, conflict) !=
							EPKG_OK)
				continue;
modified libpkg/private/pkg.h
@@ -235,6 +235,8 @@ KHASH_MAP_INIT_STR(pkg_files, struct pkg_file *);
KHASH_MAP_INIT_STR(pkg_dirs, struct pkg_dir *);
KHASH_MAP_INIT_STR(pkg_config_files, struct pkg_config_file *);
KHASH_MAP_INIT_STR(strings, char *);
+
KHASH_MAP_INIT_STR(pkg_options, struct pkg_option *);
+
KHASH_MAP_INIT_STR(pkg_conflicts, struct pkg_conflict *);

struct pkg {
	bool		 direct;
@@ -279,12 +281,14 @@ struct pkg {
	struct pkg_file		*files;
	kh_pkg_dirs_t		*dirhash;
	struct pkg_dir		*dirs;
+
	kh_pkg_options_t	*optionshash;
	struct pkg_option	*options;
	kh_strings_t		*users;
	kh_strings_t		*groups;
	kh_strings_t		*shlibs_required;
	kh_strings_t		*shlibs_provided;
-
	struct pkg_conflict *conflicts;
+
	kh_pkg_conflicts_t	*conflictshash;
+
	struct pkg_conflict	*conflicts;
	kh_strings_t		*provides;
	kh_strings_t		*requires;
	kh_pkg_config_files_t	*config_files;
@@ -334,7 +338,7 @@ struct pkg_conflict {
	char *uid;
	char *digest;
	enum pkg_conflict_type type;
-
	UT_hash_handle	hh;
+
	struct pkg_conflict *next;
};

typedef enum {
@@ -384,7 +388,7 @@ struct pkg_option {
	char	*value;
	char	*default_value;
	char	*description;
-
	UT_hash_handle	hh;
+
	struct pkg_option *next;
};

struct http_mirror {