Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
add: attempt to further improve pkg add performances
Baptiste Daroussin committed 11 months ago
commit 009e7a876c43c478ee23851480c6aa9bd9acfe30
parent 61a8a83
6 files changed +74 -8
modified libpkg/pkg.c
@@ -1749,6 +1749,8 @@ pkgs_sort(pkgs_t *pkgs)
	qsort(pkgs->d, pkgs->len, sizeof(pkgs->d[0]), pkgs_cmp);
}

+
DEFINE_VEC_INSERT_SORTED_FUNC(pkgs_t, pkgs, struct pkg *, pkgs_cmp)
+

struct pkg **
pkgs_search(pkgs_t *pkgs, char *el)
{
modified libpkg/pkg/vec.h
@@ -55,7 +55,7 @@

#define vec_push(v, _d)                                            \
	do {                                                          \
-
		if ((v)->len + 1 > (v)->cap) {                            \
+
		if ((v)->len >= (v)->cap) {                            \
			if ((v)->cap == 0)                              \
				(v)->cap = 1;                          \
			else                                          \
@@ -82,6 +82,35 @@
#define vec_len(v) \
	(v)->len

+
#define DEFINE_VEC_INSERT_SORTED_PROTO(type, name, element_type) \
+
	element_type *name##_insert_sorted(type *v, element_type el)
+

+
#define DEFINE_VEC_INSERT_SORTED_FUNC(type, _name, element_type, compare_func) \
+
	element_type *_name##_insert_sorted(type *v, element_type el) { \
+
		/* Verify if the element already exists */ \
+
		if (v->len > 0) { \
+
			type *found = bsearch(&el, v->d, v->len, sizeof(element_type), compare_func); \
+
			if (found != NULL){ \
+
				return (found); \
+
			} \
+
		} \
+
		if (v->len >= v->cap) { \
+
			v->cap = (v->cap == 0) ? 1 : v->cap * 2; \
+
			v->d = realloc(v->d, v->cap * sizeof(element_type)); \
+
			if (v->d == NULL) \
+
				abort(); \
+
		} \
+
		/* Find where to insert */ \
+
		size_t i; \
+
		for (i = v->len; i > 0 && compare_func(&v->d[i - 1], &el) > 0; i--) { \
+
			v->d[i] = v->d[i - 1]; \
+
		} \
+
		v->d[i] = el; \
+
		v->len++; \
+
		return (NULL); \
+
	}
+

typedef vec_t(char *) charv_t;
typedef vec_t(const char *) c_charv_t;
+

#endif
modified libpkg/pkg_add.c
@@ -1085,7 +1085,7 @@ static bool
should_append_pkg(pkgs_t *localpkgs, struct pkg *p)
{
	/* only keep the highest version is we fine one */
-
	struct pkg **lp = pkgs_search(localpkgs, p->name);
+
	struct pkg **lp = pkgs_insert_sorted(localpkgs, p);
	if (lp != NULL) {
		if (pkg_version_cmp((*lp)->version, p->version) == -1) {
			pkg_free(*lp);
@@ -1094,9 +1094,6 @@ should_append_pkg(pkgs_t *localpkgs, struct pkg *p)
		}
		return (false);
	}
-
	/* none found we should append */
-
	vec_push(localpkgs, p);
-
	pkgs_sort(localpkgs);
	return (true);
}

modified libpkg/private/pkg.h
@@ -242,6 +242,7 @@ struct pkg {
typedef tll(struct pkg *) pkg_chain_t;
typedef vec_t(struct pkg *) pkgs_t;

+
DEFINE_VEC_INSERT_SORTED_PROTO(pkgs_t, pkgs, struct pkg *);
struct pkg **pkgs_search(pkgs_t *, char *);
void pkgs_sort(pkgs_t *);

modified tests/Makefile.autosetup
@@ -8,6 +8,7 @@ TESTS= \
	pkg_add_dir_to_del \
	pkg_printf \
	pkg_validation \
+
	pkg \
	plist \
	lua \
	ssh \
@@ -118,6 +119,7 @@ pkg_elf_OBJS= lib/pkg_elf.o
hash_OBJS=	lib/hash.o
shlibs_OBJS=	lib/shlibs.o
kv_OBJS=	lib/kv.o
+
pkg_OBJS=	lib/pkg.o

SRCS=	\
	$(packing_OBJS:.o=.c) \
@@ -137,6 +139,7 @@ SRCS= \
	$(hash_OBJS:.o=.c) \
	$(shlibs_OBJS:.o=.c) \
	$(kv_OBJS:.o=.c) \
+
	$(pkg_OBJS:.o=.c)

include $(MK)/common.mk

modified tests/lib/pkg.c
@@ -1,7 +1,41 @@
#include <atf-c.h>
-
#include <pkg.h>
+
#include <private/pkg.h>

-
void
-
test_pkg(void)
+
ATF_TC_WITHOUT_HEAD(pkgs_insert_sorted);
+
ATF_TC_BODY(pkgs_insert_sorted, tc)
{
+
	pkgs_t pkgs = vec_init();
+

+
	ATF_REQUIRE_EQ_MSG(pkgs.d, NULL, "vec_init failed");
+
	ATF_REQUIRE_EQ_MSG(pkgs.cap, 0, "vec_init failed");
+
	ATF_REQUIRE_EQ_MSG(pkgs.len, 0, "vec_init failed");
+

+
	struct pkg *p;
+

+
	ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_FILE));
+
	ATF_REQUIRE(p != NULL);
+
	p->name = xstrdup("name1");
+
	ATF_REQUIRE_EQ(pkgs_insert_sorted(&pkgs, p), NULL);
+
	ATF_REQUIRE_EQ_MSG(pkgs.len, 1, "Fail to insert");
+

+
	p = NULL;
+
	ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_FILE));
+
	p->name = xstrdup("name1");
+
	ATF_REQUIRE_MSG(pkgs_insert_sorted(&pkgs, p) !=  NULL, "Collision not detected");
+

+
	free(p->name);
+
	p->name = xstrdup("aname1");
+

+
	ATF_REQUIRE_EQ(pkgs_insert_sorted(&pkgs, p), NULL);
+
	ATF_REQUIRE_EQ_MSG(pkgs.len, 2, "Fail to insert");
+

+
	ATF_REQUIRE_STREQ(pkgs.d[0]->name, "aname1");
+
	ATF_REQUIRE_STREQ(pkgs.d[1]->name, "name1");
+
}
+

+
ATF_TP_ADD_TCS(tp)
+
{
+
	ATF_TP_ADD_TC(tp, pkgs_insert_sorted);
+

+
	return (atf_no_error());
}