2007-01-19 09:28:44 +00:00
|
|
|
/*
|
2007-03-29 00:40:49 -04:00
|
|
|
* alpm_list.h
|
2007-11-16 20:18:45 -06:00
|
|
|
*
|
2022-01-02 13:34:52 +10:00
|
|
|
* Copyright (c) 2006-2022 Pacman Development Team <pacman-dev@lists.archlinux.org>
|
2009-07-01 02:08:33 -05:00
|
|
|
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
2007-11-16 20:18:45 -06:00
|
|
|
*
|
2007-01-19 09:28:44 +00:00
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2007-12-10 22:55:22 -06:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2007-01-19 09:28:44 +00:00
|
|
|
*/
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
|
2016-09-03 22:14:49 -05:00
|
|
|
#ifndef ALPM_LIST_H
|
|
|
|
#define ALPM_LIST_H
|
2007-01-19 09:28:44 +00:00
|
|
|
|
2008-02-15 20:57:30 -06:00
|
|
|
#include <stdlib.h> /* size_t */
|
|
|
|
|
2013-06-03 14:15:31 +10:00
|
|
|
/* Note: alpm_list.{c,h} are intended to be standalone files. Do not include
|
|
|
|
* any other libalpm headers.
|
|
|
|
*/
|
|
|
|
|
2007-03-29 00:40:49 -04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
2020-12-29 11:54:56 +10:00
|
|
|
* @ingroup libalpm
|
2021-01-09 09:19:03 +10:00
|
|
|
* @addtogroup libalpm_list libalpm_list(3)
|
2020-12-07 22:19:47 +00:00
|
|
|
* @brief Functions to manipulate alpm_list_t lists.
|
|
|
|
*
|
|
|
|
* These functions are designed to create, destroy, and modify lists of
|
|
|
|
* type alpm_list_t. This is an internal list type used by libalpm that is
|
|
|
|
* publicly exposed for use by frontends if desired.
|
2007-03-29 00:40:49 -04:00
|
|
|
*
|
|
|
|
* It is exposed so front ends can use it to prevent the need to reimplement
|
|
|
|
* lists of their own; however, it is not required that the front end uses
|
|
|
|
* it.
|
2020-12-07 22:19:47 +00:00
|
|
|
* @{
|
2007-03-29 00:40:49 -04:00
|
|
|
*/
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/** A doubly linked list */
|
2021-05-03 11:58:22 +01:00
|
|
|
typedef struct _alpm_list_t {
|
2007-03-29 00:40:49 -04:00
|
|
|
/** data held by the list node */
|
2007-01-19 09:28:44 +00:00
|
|
|
void *data;
|
2007-03-29 00:40:49 -04:00
|
|
|
/** pointer to the previous node */
|
2021-05-03 11:58:22 +01:00
|
|
|
struct _alpm_list_t *prev;
|
2007-03-29 00:40:49 -04:00
|
|
|
/** pointer to the next node */
|
2021-05-03 11:58:22 +01:00
|
|
|
struct _alpm_list_t *next;
|
2007-10-14 17:29:32 -05:00
|
|
|
} alpm_list_t;
|
2007-01-19 09:28:44 +00:00
|
|
|
|
2020-12-07 22:19:47 +00:00
|
|
|
/** Frees a list and its contents */
|
2007-04-28 03:54:25 -04:00
|
|
|
#define FREELIST(p) do { alpm_list_free_inner(p, free); alpm_list_free(p); p = NULL; } while(0)
|
2007-01-19 09:28:44 +00:00
|
|
|
|
2020-12-07 22:19:47 +00:00
|
|
|
/** item deallocation callback.
|
2021-02-03 16:57:33 -05:00
|
|
|
* @param item the item to free
|
2020-12-07 22:19:47 +00:00
|
|
|
*/
|
|
|
|
typedef void (*alpm_list_fn_free)(void * item);
|
|
|
|
|
|
|
|
/** item comparison callback */
|
|
|
|
typedef int (*alpm_list_fn_cmp)(const void *, const void *);
|
2007-01-19 09:28:44 +00:00
|
|
|
|
|
|
|
/* allocation */
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/** Free a list, but not the contained data.
|
|
|
|
*
|
|
|
|
* @param list the list to free
|
|
|
|
*/
|
2007-01-24 08:51:50 +00:00
|
|
|
void alpm_list_free(alpm_list_t *list);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/** Free the internal data of a list structure but not the list itself.
|
|
|
|
*
|
|
|
|
* @param list the list to free
|
|
|
|
* @param fn a free function for the internal data
|
|
|
|
*/
|
2007-01-24 08:51:50 +00:00
|
|
|
void alpm_list_free_inner(alpm_list_t *list, alpm_list_fn_free fn);
|
2007-01-19 09:28:44 +00:00
|
|
|
|
|
|
|
/* item mutators */
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/** Add a new item to the end of the list.
|
|
|
|
*
|
|
|
|
* @param list the list to add to
|
|
|
|
* @param data the new item to be added to the list
|
|
|
|
*
|
|
|
|
* @return the resultant list
|
|
|
|
*/
|
2007-01-19 09:28:44 +00:00
|
|
|
alpm_list_t *alpm_list_add(alpm_list_t *list, void *data);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Add a new item to the end of the list.
|
|
|
|
*
|
|
|
|
* @param list the list to add to
|
|
|
|
* @param data the new item to be added to the list
|
|
|
|
*
|
|
|
|
* @return the newly added item
|
|
|
|
*/
|
2016-01-11 09:29:22 -05:00
|
|
|
alpm_list_t *alpm_list_append(alpm_list_t **list, void *data);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Duplicate and append a string to a list.
|
|
|
|
*
|
|
|
|
* @param list the list to append to
|
|
|
|
* @param data the string to duplicate and append
|
|
|
|
*
|
|
|
|
* @return the newly added item
|
|
|
|
*/
|
2017-02-18 17:09:49 -05:00
|
|
|
alpm_list_t *alpm_list_append_strdup(alpm_list_t **list, const char *data);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Add items to a list in sorted order.
|
|
|
|
*
|
|
|
|
* @param list the list to add to
|
|
|
|
* @param data the new item to be added to the list
|
|
|
|
* @param fn the comparison function to use to determine order
|
|
|
|
*
|
|
|
|
* @return the resultant list
|
|
|
|
*/
|
2007-01-19 09:28:44 +00:00
|
|
|
alpm_list_t *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_list_fn_cmp fn);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Join two lists.
|
|
|
|
* The two lists must be independent. Do not free the original lists after
|
|
|
|
* calling this function, as this is not a copy operation. The list pointers
|
|
|
|
* passed in should be considered invalid after calling this function.
|
|
|
|
*
|
|
|
|
* @param first the first list
|
|
|
|
* @param second the second list
|
|
|
|
*
|
|
|
|
* @return the resultant joined list
|
|
|
|
*/
|
2007-11-20 09:11:40 +01:00
|
|
|
alpm_list_t *alpm_list_join(alpm_list_t *first, alpm_list_t *second);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Merge the two sorted sublists into one sorted list.
|
|
|
|
*
|
|
|
|
* @param left the first list
|
|
|
|
* @param right the second list
|
|
|
|
* @param fn comparison function for determining merge order
|
|
|
|
*
|
|
|
|
* @return the resultant list
|
|
|
|
*/
|
2007-02-13 08:15:38 +00:00
|
|
|
alpm_list_t *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, alpm_list_fn_cmp fn);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Sort a list of size `n` using mergesort algorithm.
|
|
|
|
*
|
|
|
|
* @param list the list to sort
|
|
|
|
* @param n the size of the list
|
|
|
|
* @param fn the comparison function for determining order
|
|
|
|
*
|
|
|
|
* @return the resultant list
|
|
|
|
*/
|
2010-12-08 15:13:36 +10:00
|
|
|
alpm_list_t *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn_cmp fn);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Remove an item from the list.
|
|
|
|
* item is not freed; this is the responsibility of the caller.
|
|
|
|
*
|
|
|
|
* @param haystack the list to remove the item from
|
|
|
|
* @param item the item to remove from the list
|
|
|
|
*
|
|
|
|
* @return the resultant list
|
|
|
|
*/
|
2011-02-02 20:46:28 -06:00
|
|
|
alpm_list_t *alpm_list_remove_item(alpm_list_t *haystack, alpm_list_t *item);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Remove an item from the list.
|
|
|
|
*
|
|
|
|
* @param haystack the list to remove the item from
|
|
|
|
* @param needle the data member of the item we're removing
|
|
|
|
* @param fn the comparison function for searching
|
|
|
|
* @param data output parameter containing data of the removed item
|
|
|
|
*
|
|
|
|
* @return the resultant list
|
|
|
|
*/
|
2007-03-03 08:13:59 +00:00
|
|
|
alpm_list_t *alpm_list_remove(alpm_list_t *haystack, const void *needle, alpm_list_fn_cmp fn, void **data);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Remove a string from a list.
|
|
|
|
*
|
|
|
|
* @param haystack the list to remove the item from
|
|
|
|
* @param needle the data member of the item we're removing
|
|
|
|
* @param data output parameter containing data of the removed item
|
|
|
|
*
|
|
|
|
* @return the resultant list
|
|
|
|
*/
|
Cleanup usages of alpm_list_find and alpm_list_remove.
* remove obsolete and unused *_cmp helper functions like deppkg_cmp and
_alpm_grp_cmp
* new alpm_list_remove_str function, used 6 times in handle.c
* remove _alpm_prov_cmp / _alpm_db_whatprovides and replace them by
a more general alpm_find_pkg_satisfiers with a cleaner implementation.
before: alpm_db_whatprovides(db, targ)
after: alpm_find_pkg_satisfiers(alpm_db_getpkgcache(db), targ)
* remove satisfycmp and replace alpm_list_find + satisfycmp usage by
_alpm_find_dep_satisfiers.
before : alpm_list_find(_alpm_db_get_pkgcache(db), dep, satisfycmp)
after : _alpm_find_dep_satisfiers(_alpm_db_get_pkgcache(db), dep)
* remove _alpm_pkgname_pkg_cmp, which was used with alpm_list_remove, and
use _alpm_pkg_find + alpm_list_remove with _alpm_pkg_cmp instead.
This commit actually get rids of all complicated and asymmetric _cmp
functions. I first thought these functions were worth it, be caused it
allowed us to reuse list_find and list_remove. But this was at the detriment
of the clarity and also the ease of use of these functions, dangerous
because of their asymmetricity.
Signed-off-by: Chantry Xavier <shiningxc@gmail.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
2008-05-10 18:47:42 +02:00
|
|
|
alpm_list_t *alpm_list_remove_str(alpm_list_t *haystack, const char *needle, char **data);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Create a new list without any duplicates.
|
|
|
|
*
|
|
|
|
* This does NOT copy data members.
|
|
|
|
*
|
|
|
|
* @param list the list to copy
|
|
|
|
*
|
|
|
|
* @return a new list containing non-duplicate items
|
|
|
|
*/
|
2007-06-05 17:34:33 -04:00
|
|
|
alpm_list_t *alpm_list_remove_dupes(const alpm_list_t *list);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Copy a string list, including data.
|
|
|
|
*
|
|
|
|
* @param list the list to copy
|
|
|
|
*
|
|
|
|
* @return a copy of the original list
|
|
|
|
*/
|
2007-06-05 17:34:33 -04:00
|
|
|
alpm_list_t *alpm_list_strdup(const alpm_list_t *list);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Copy a list, without copying data.
|
|
|
|
*
|
|
|
|
* @param list the list to copy
|
|
|
|
*
|
|
|
|
* @return a copy of the original list
|
|
|
|
*/
|
2007-10-19 13:17:51 -04:00
|
|
|
alpm_list_t *alpm_list_copy(const alpm_list_t *list);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Copy a list and copy the data.
|
|
|
|
* Note that the data elements to be copied should not contain pointers
|
|
|
|
* and should also be of constant size.
|
|
|
|
*
|
|
|
|
* @param list the list to copy
|
|
|
|
* @param size the size of each data element
|
|
|
|
*
|
|
|
|
* @return a copy of the original list, data copied as well
|
|
|
|
*/
|
2007-11-14 22:51:16 -06:00
|
|
|
alpm_list_t *alpm_list_copy_data(const alpm_list_t *list, size_t size);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Create a new list in reverse order.
|
|
|
|
*
|
|
|
|
* @param list the list to copy
|
|
|
|
*
|
|
|
|
* @return a new list in reverse order
|
|
|
|
*/
|
2007-01-19 09:28:44 +00:00
|
|
|
alpm_list_t *alpm_list_reverse(alpm_list_t *list);
|
|
|
|
|
|
|
|
/* item accessors */
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Return nth element from list (starting from 0).
|
|
|
|
*
|
|
|
|
* @param list the list
|
|
|
|
* @param n the index of the item to find (n < alpm_list_count(list) IS needed)
|
|
|
|
*
|
|
|
|
* @return an alpm_list_t node for index `n`
|
|
|
|
*/
|
2010-12-08 15:13:36 +10:00
|
|
|
alpm_list_t *alpm_list_nth(const alpm_list_t *list, size_t n);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get the next element of a list.
|
|
|
|
*
|
|
|
|
* @param list the list node
|
|
|
|
*
|
|
|
|
* @return the next element, or NULL when no more elements exist
|
|
|
|
*/
|
2007-06-05 17:34:33 -04:00
|
|
|
alpm_list_t *alpm_list_next(const alpm_list_t *list);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get the previous element of a list.
|
|
|
|
*
|
|
|
|
* @param list the list head
|
|
|
|
*
|
|
|
|
* @return the previous element, or NULL when no previous element exist
|
|
|
|
*/
|
2011-07-04 11:17:12 +10:00
|
|
|
alpm_list_t *alpm_list_previous(const alpm_list_t *list);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get the last item in the list.
|
|
|
|
*
|
|
|
|
* @param list the list
|
|
|
|
*
|
|
|
|
* @return the last element in the list
|
|
|
|
*/
|
2007-06-05 17:34:33 -04:00
|
|
|
alpm_list_t *alpm_list_last(const alpm_list_t *list);
|
2007-01-19 09:28:44 +00:00
|
|
|
|
|
|
|
/* misc */
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get the number of items in a list.
|
|
|
|
*
|
|
|
|
* @param list the list
|
|
|
|
*
|
|
|
|
* @return the number of list items
|
|
|
|
*/
|
2010-12-08 15:13:36 +10:00
|
|
|
size_t alpm_list_count(const alpm_list_t *list);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Find an item in a list.
|
|
|
|
*
|
|
|
|
* @param needle the item to search
|
|
|
|
* @param haystack the list
|
|
|
|
* @param fn the comparison function for searching (!= NULL)
|
|
|
|
*
|
|
|
|
* @return `needle` if found, NULL otherwise
|
|
|
|
*/
|
2007-12-02 23:48:12 +01:00
|
|
|
void *alpm_list_find(const alpm_list_t *haystack, const void *needle, alpm_list_fn_cmp fn);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Find an item in a list.
|
|
|
|
*
|
|
|
|
* Search for the item whose data matches that of the `needle`.
|
|
|
|
*
|
|
|
|
* @param needle the data to search for (== comparison)
|
|
|
|
* @param haystack the list
|
|
|
|
*
|
|
|
|
* @return `needle` if found, NULL otherwise
|
|
|
|
*/
|
2007-12-02 23:48:12 +01:00
|
|
|
void *alpm_list_find_ptr(const alpm_list_t *haystack, const void *needle);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Find a string in a list.
|
|
|
|
*
|
|
|
|
* @param needle the string to search for
|
|
|
|
* @param haystack the list
|
|
|
|
*
|
|
|
|
* @return `needle` if found, NULL otherwise
|
|
|
|
*/
|
2007-12-02 23:48:12 +01:00
|
|
|
char *alpm_list_find_str(const alpm_list_t *haystack, const char *needle);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Find the differences between list `left` and list `right`
|
|
|
|
*
|
|
|
|
* The two lists must be sorted. Items only in list `left` are added to the
|
|
|
|
* `onlyleft` list. Items only in list `right` are added to the `onlyright`
|
|
|
|
* list.
|
|
|
|
*
|
|
|
|
* @param left the first list
|
|
|
|
* @param right the second list
|
|
|
|
* @param fn the comparison function
|
|
|
|
* @param onlyleft pointer to the first result list
|
|
|
|
* @param onlyright pointer to the second result list
|
|
|
|
*
|
|
|
|
*/
|
2010-03-24 15:22:23 +10:00
|
|
|
void alpm_list_diff_sorted(const alpm_list_t *left, const alpm_list_t *right,
|
2009-10-11 02:38:33 +02:00
|
|
|
alpm_list_fn_cmp fn, alpm_list_t **onlyleft, alpm_list_t **onlyright);
|
2020-12-07 22:19:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Find the items in list `lhs` that are not present in list `rhs`.
|
|
|
|
*
|
|
|
|
* @param lhs the first list
|
|
|
|
* @param rhs the second list
|
|
|
|
* @param fn the comparison function
|
|
|
|
*
|
|
|
|
* @return a list containing all items in `lhs` not present in `rhs`
|
|
|
|
*/
|
|
|
|
|
|
|
|
alpm_list_t *alpm_list_diff(const alpm_list_t *lhs, const alpm_list_t *rhs, alpm_list_fn_cmp fn);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Copy a list and data into a standard C array of fixed length.
|
|
|
|
* Note that the data elements are shallow copied so any contained pointers
|
|
|
|
* will point to the original data.
|
|
|
|
*
|
|
|
|
* @param list the list to copy
|
|
|
|
* @param n the size of the list
|
|
|
|
* @param size the size of each data element
|
|
|
|
*
|
|
|
|
* @return an array version of the original list, data copied as well
|
|
|
|
*/
|
Convert package filelists to an array instead of linked list
This accomplishes quite a few things with one rather invasive change.
1. Iteration is much more performant, due to a reduction in pointer
chasing and linear item access.
2. Data structures are smaller- we no longer have the overhead of the
linked list as the file struts are now laid out consecutively in
memory.
3. Memory allocation has been massively reworked. Before, we would
allocate three different pieces of memory per file item- the list
struct, the file struct, and the copied filename. What this resulted
in was massive fragmentation of memory when loading filelists since
the memory allocator had to leave holes all over the place. The new
situation here now removes the need for any list item allocation;
allocates the file structs in contiguous memory (and reallocs as
necessary), leaving only the strings as individually allocated. Tests
using valgrind (massif) show some pretty significant memory
reductions on the worst case `pacman -Ql > /dev/null` (366387 files
on my machine):
Before:
Peak heap: 54,416,024 B
Useful heap: 36,840,692 B
Extra heap: 17,575,332 B
After:
Peak heap: 38,004,352 B
Useful heap: 28,101,347 B
Extra heap: 9,903,005 B
Several small helper methods have been introduced, including a list to
array conversion helper as well as a filelist merge sort that works
directly on arrays.
Signed-off-by: Dan McGee <dan@archlinux.org>
2011-07-19 04:47:29 -05:00
|
|
|
void *alpm_list_to_array(const alpm_list_t *list, size_t n, size_t size);
|
2007-01-19 09:28:44 +00:00
|
|
|
|
2020-12-07 22:19:47 +00:00
|
|
|
/* End of alpm_list */
|
|
|
|
/** @} */
|
|
|
|
|
2007-03-29 00:40:49 -04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
2016-09-03 22:14:49 -05:00
|
|
|
#endif /* ALPM_LIST_H */
|