From: Michael Tremer Date: Tue, 28 Feb 2023 17:15:02 +0000 (+0000) Subject: packagelist: Refactor the whole thing X-Git-Tag: 0.9.29~370 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1892ea0aefd04bba5ce49f487265136a92a9d9f7;p=pakfire.git packagelist: Refactor the whole thing Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/util.c b/src/_pakfire/util.c index a5d282fa0..3f2cc0ebb 100644 --- a/src/_pakfire/util.c +++ b/src/_pakfire/util.c @@ -34,8 +34,9 @@ PyObject* PyList_FromPackageList(struct pakfire_packagelist* packagelist) { PyObject* list = PyList_New(0); - int count = pakfire_packagelist_count(packagelist); - for (int i = 0; i < count; i++) { + const size_t length = pakfire_packagelist_length(packagelist); + + for (size_t i = 0; i < length; i++) { struct pakfire_package* package = pakfire_packagelist_get(packagelist, i); PyObject* item = new_package(&PackageType, package); diff --git a/src/libpakfire/include/pakfire/packagelist.h b/src/libpakfire/include/pakfire/packagelist.h index 12ce3e435..015bc4894 100644 --- a/src/libpakfire/include/pakfire/packagelist.h +++ b/src/libpakfire/include/pakfire/packagelist.h @@ -30,8 +30,7 @@ int pakfire_packagelist_create(struct pakfire_packagelist** list, struct pakfire struct pakfire_packagelist* pakfire_packagelist_ref(struct pakfire_packagelist* list); struct pakfire_packagelist* pakfire_packagelist_unref(struct pakfire_packagelist* list); -size_t pakfire_packagelist_count(struct pakfire_packagelist* list); -void pakfire_packagelist_sort(struct pakfire_packagelist* list); +size_t pakfire_packagelist_length(struct pakfire_packagelist* list); struct pakfire_package* pakfire_packagelist_get(struct pakfire_packagelist* list, unsigned int index); int pakfire_packagelist_push(struct pakfire_packagelist* list, struct pakfire_package* pkg); @@ -40,9 +39,6 @@ int pakfire_packagelist_push(struct pakfire_packagelist* list, struct pakfire_pa #include -int pakfire_packagelist_create_from_queue(struct pakfire_packagelist** list, - struct pakfire* pakfire, Queue* q) __attribute__ ((deprecated)); - typedef int (*pakfire_packagelist_walk_callback) (struct pakfire* pakfire, struct pakfire_package* pkg, void* p); diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index 12a42b32a..15f1c2388 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -194,9 +194,9 @@ global: pakfire_package_unref; # packagelist - pakfire_packagelist_count; pakfire_packagelist_create; pakfire_packagelist_get; + pakfire_packagelist_length; pakfire_packagelist_push; pakfire_packagelist_ref; pakfire_packagelist_sort; diff --git a/src/libpakfire/packagelist.c b/src/libpakfire/packagelist.c index 712a7f767..1578da9e7 100644 --- a/src/libpakfire/packagelist.c +++ b/src/libpakfire/packagelist.c @@ -19,35 +19,49 @@ #############################################################################*/ #include +#include -#include -#include -#include +#include #include #include #include #include #include -#include -#define BLOCK_SIZE 31 +struct pakfire_packagelist_element { + TAILQ_ENTRY(pakfire_packagelist_element) nodes; + + struct pakfire_package* pkg; +}; struct pakfire_packagelist { struct pakfire* pakfire; int nrefs; - struct pakfire_package** elements; - size_t count; + TAILQ_HEAD(entries, pakfire_packagelist_element) packages; }; -static void pakfire_packagelist_free(struct pakfire_packagelist* list) { - if (list->elements) { - for (unsigned int i = 0; i < list->count; i++) - pakfire_package_unref(list->elements[i]); - free(list->elements); +static void pakfire_packagelist_clear(struct pakfire_packagelist* list) { + struct pakfire_packagelist_element* element = NULL; + + while (!TAILQ_EMPTY(&list->packages)) { + // Fetch the first element + element = TAILQ_FIRST(&list->packages); + + // Remove it from the list + TAILQ_REMOVE(&list->packages, element, nodes); + + // Dereference the file + pakfire_package_unref(element->pkg); + + // Free it all + free(element); } +} +static void pakfire_packagelist_free(struct pakfire_packagelist* list) { + pakfire_packagelist_clear(list); pakfire_unref(list->pakfire); free(list); } @@ -58,36 +72,19 @@ PAKFIRE_EXPORT int pakfire_packagelist_create( if (!l) return 1; + // Store a reference to Pakfire l->pakfire = pakfire_ref(pakfire); + + // Initialize the reference counter l->nrefs = 1; + // Initialise packages + TAILQ_INIT(&l->packages); + *list = l; return 0; } -int pakfire_packagelist_create_from_queue(struct pakfire_packagelist** list, struct pakfire* pakfire, Queue* q) { - int r; - - // Create a new package list - r = pakfire_packagelist_create(list, pakfire); - if (r) - goto ERROR; - - r = pakfire_packagelist_import_solvables(*list, q); - if (r) - goto ERROR; - - return 0; - -ERROR: - if (*list) { - pakfire_packagelist_free(*list); - *list = NULL; - } - - return r; -} - PAKFIRE_EXPORT struct pakfire_packagelist* pakfire_packagelist_ref(struct pakfire_packagelist* list) { list->nrefs++; @@ -102,41 +99,72 @@ PAKFIRE_EXPORT struct pakfire_packagelist* pakfire_packagelist_unref(struct pakf return NULL; } -PAKFIRE_EXPORT size_t pakfire_packagelist_count(struct pakfire_packagelist* list) { - return list->count; -} +PAKFIRE_EXPORT size_t pakfire_packagelist_length(struct pakfire_packagelist* list) { + struct pakfire_packagelist_element* element = NULL; + size_t size = 0; -static int _packagelist_cmp(const void* pkg1, const void* pkg2) { - return pakfire_package_cmp( - *(struct pakfire_package**)pkg1, - *(struct pakfire_package**)pkg2 - ); -} + TAILQ_FOREACH(element, &list->packages, nodes) + size++; -PAKFIRE_EXPORT void pakfire_packagelist_sort(struct pakfire_packagelist* list) { - qsort(list->elements, list->count, sizeof(*list->elements), _packagelist_cmp); + return size; } PAKFIRE_EXPORT struct pakfire_package* pakfire_packagelist_get(struct pakfire_packagelist* list, unsigned int index) { - if (index < list->count) - return pakfire_package_ref(list->elements[index]); + struct pakfire_packagelist_element* element = NULL; - return NULL; + // Fetch the first element + element = TAILQ_FIRST(&list->packages); + + while (element && index--) + element = TAILQ_NEXT(element, nodes); + + return pakfire_package_ref(element->pkg); } PAKFIRE_EXPORT int pakfire_packagelist_push(struct pakfire_packagelist* list, struct pakfire_package* pkg) { - list->elements = solv_extend(list->elements, list->count, 1, sizeof(pkg), BLOCK_SIZE); - list->elements[list->count++] = pakfire_package_ref(pkg); + struct pakfire_packagelist_element* element = NULL; + struct pakfire_packagelist_element* e = NULL; + + // Allocate a new element + element = calloc(1, sizeof *element); + if (!element) { + ERROR(list->pakfire, "Could not allocate a new packagelist element: %m\n"); + return 1; + } + + // Reference the package + element->pkg = pakfire_package_ref(pkg); + + // Fetch the last element + e = TAILQ_LAST(&list->packages, entries); + + // Skip all elements that are "greater than" the element we want to add + while (e) { + if (pakfire_package_cmp(e->pkg, pkg) <= 0) + break; + + e = TAILQ_PREV(e, entries, nodes); + } + + // If we found an element on the list, we will append after it, + // otherwise we add right at the start. + if (e) + TAILQ_INSERT_AFTER(&list->packages, e, element, nodes); + else + TAILQ_INSERT_HEAD(&list->packages, element, nodes); return 0; } int pakfire_packagelist_walk(struct pakfire_packagelist* list, - pakfire_packagelist_walk_callback callback, void* p) { + pakfire_packagelist_walk_callback callback, void* data) { + struct pakfire_packagelist_element* element = NULL; int r = 0; - for (unsigned int i = 0; i < list->count; i++) { - r = callback(list->pakfire, list->elements[i], p); + // Call the callback once for every element on the list + TAILQ_FOREACH(element, &list->packages, nodes) { + // Call the callback + r = callback(list->pakfire, element->pkg, data); if (r) break; } @@ -154,8 +182,10 @@ int pakfire_packagelist_import_solvables(struct pakfire_packagelist* list, Queue if (r) return r; - pakfire_packagelist_push(list, pkg); + r = pakfire_packagelist_push(list, pkg); pakfire_package_unref(pkg); + if (r) + return r; } return 0; diff --git a/src/libpakfire/repo.c b/src/libpakfire/repo.c index 9c522ffe4..7789f0f4c 100644 --- a/src/libpakfire/repo.c +++ b/src/libpakfire/repo.c @@ -1631,8 +1631,5 @@ int pakfire_repo_to_packagelist(struct pakfire_repo* repo, return r; } - // Sort the list - pakfire_packagelist_sort(list); - return 0; }