]> git.ipfire.org Git - pakfire.git/commitdiff
packagelist: Refactor the whole thing
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 28 Feb 2023 17:15:02 +0000 (17:15 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 28 Feb 2023 17:18:04 +0000 (17:18 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/util.c
src/libpakfire/include/pakfire/packagelist.h
src/libpakfire/libpakfire.sym
src/libpakfire/packagelist.c
src/libpakfire/repo.c

index a5d282fa0bc48d5af3639181eeb26e46a6bdb58a..3f2cc0ebbe55a28c0ca7dbd2467d38507bf87479 100644 (file)
@@ -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);
index 12ce3e4351479354ddd36de0deff5c3cbcaad182..015bc489440a02907e0090348ae6db1058f948ca 100644 (file)
@@ -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 <solv/queue.h>
 
-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);
 
index 12a42b32a75922c8115832f65b25eb87c68a273e..15f1c238844b27e524de78f418f66edab84a8dbd 100644 (file)
@@ -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;
index 712a7f7672c9c85e0ec0768310aebb235f8bce01..1578da9e7c7664598df7d271f0cf16af21dd1643 100644 (file)
 #############################################################################*/
 
 #include <stdlib.h>
+#include <sys/queue.h>
 
-#include <solv/pool.h>
-#include <solv/solver.h>
-#include <solv/util.h>
+#include <solv/queue.h>
 
 #include <pakfire/logging.h>
 #include <pakfire/package.h>
 #include <pakfire/packagelist.h>
 #include <pakfire/pakfire.h>
 #include <pakfire/private.h>
-#include <pakfire/util.h>
 
-#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;
index 9c522ffe454fb02652d5306cb097cc99f9929863..7789f0f4cfb729e1c5679d536bc9a71871e99fb4 100644 (file)
@@ -1631,8 +1631,5 @@ int pakfire_repo_to_packagelist(struct pakfire_repo* repo,
                        return r;
        }
 
-       // Sort the list
-       pakfire_packagelist_sort(list);
-
        return 0;
 }