From f352aaf39351fabbe395189834a9b1d02da9b62f Mon Sep 17 00:00:00 2001 From: buque Date: Mon, 12 Dec 2022 15:08:57 +0800 Subject: [PATCH] idxset: Add reverse iteration functions, set comparison operations adn set contains() function Add complementary functions to the existing idxset iterate(), steal_first(), first(), next() functions that work in the reverse direction: reverse_iterate(), steal_last(), last() and previous(). Add isdisjoint(), issubset(), issuperset() and equals() functions that element-wise compare two idxsets. Add set contains() function, This is functionally equivalent to get_by_data(s, p, NULL) == p, but with a more obvious name and form because some existing code is instead manually iterating through idxsets to check for existence of an item. Signed-off-by: Alper Nebi Yasak Part-of: --- 0001-idxset-Add-set-contains-function.patch | 58 ++++++ ...idxset-Add-set-comparison-operations.patch | 86 ++++++++ ...xset-Add-reverse-iteration-functions.patch | 197 ++++++++++++++++++ pulseaudio.spec | 8 +- 4 files changed, 348 insertions(+), 1 deletion(-) create mode 100644 0001-idxset-Add-set-contains-function.patch create mode 100644 0002-idxset-Add-set-comparison-operations.patch create mode 100644 0003-idxset-Add-reverse-iteration-functions.patch diff --git a/0001-idxset-Add-set-contains-function.patch b/0001-idxset-Add-set-contains-function.patch new file mode 100644 index 0000000..5a8ab42 --- /dev/null +++ b/0001-idxset-Add-set-contains-function.patch @@ -0,0 +1,58 @@ +From fb63e589310fab20e60c46bb40c7b7acab5eeac9 Mon Sep 17 00:00:00 2001 +From: Alper Nebi Yasak +Date: Sat, 26 Jun 2021 12:05:17 +0300 +Subject: [PATCH] idxset: Add set contains() function + +This is functionally equivalent to get_by_data(s, p, NULL) == p, but +with a more obvious name and form because some existing code is instead +manually iterating through idxsets to check for existence of an item. + +Signed-off-by: Alper Nebi Yasak +Part-of: +--- + src/pulsecore/idxset.c | 14 ++++++++++++++ + src/pulsecore/idxset.h | 3 +++ + 2 files changed, 17 insertions(+) + +diff --git a/src/pulsecore/idxset.c b/src/pulsecore/idxset.c +index 5175ca217..91ac6a015 100644 +--- a/src/pulsecore/idxset.c ++++ b/src/pulsecore/idxset.c +@@ -258,6 +258,20 @@ void* pa_idxset_get_by_data(pa_idxset*s, const void *p, uint32_t *idx) { + return e->data; + } + ++bool pa_idxset_contains(pa_idxset *s, const void *p) { ++ unsigned hash; ++ struct idxset_entry *e; ++ ++ pa_assert(s); ++ ++ hash = s->hash_func(p) % NBUCKETS; ++ ++ if (!(e = data_scan(s, hash, p))) ++ return false; ++ ++ return e->data == p; ++} ++ + void* pa_idxset_remove_by_index(pa_idxset*s, uint32_t idx) { + struct idxset_entry *e; + unsigned hash; +diff --git a/src/pulsecore/idxset.h b/src/pulsecore/idxset.h +index 7acb202ff..6797852b7 100644 +--- a/src/pulsecore/idxset.h ++++ b/src/pulsecore/idxset.h +@@ -66,6 +66,9 @@ void* pa_idxset_get_by_index(pa_idxset*s, uint32_t idx); + /* Get the entry by its data. The index is returned in *idx */ + void* pa_idxset_get_by_data(pa_idxset*s, const void *p, uint32_t *idx); + ++/* Return true if item is in idxset */ ++bool pa_idxset_contains(pa_idxset *s, const void *p); ++ + /* Similar to pa_idxset_get_by_index(), but removes the entry from the idxset. */ + void* pa_idxset_remove_by_index(pa_idxset*s, uint32_t idx); + +-- +2.33.0 + diff --git a/0002-idxset-Add-set-comparison-operations.patch b/0002-idxset-Add-set-comparison-operations.patch new file mode 100644 index 0000000..c82220c --- /dev/null +++ b/0002-idxset-Add-set-comparison-operations.patch @@ -0,0 +1,86 @@ +From ec668ac44bc6e666123f22f2696745dcdce98fed Mon Sep 17 00:00:00 2001 +From: Alper Nebi Yasak +Date: Wed, 23 Jun 2021 17:50:50 +0300 +Subject: [PATCH] idxset: Add set comparison operations + +Add isdisjoint(), issubset(), issuperset() and equals() functions that +element-wise compare two idxsets. + +Signed-off-by: Alper Nebi Yasak +Part-of: +--- + src/pulsecore/idxset.c | 34 ++++++++++++++++++++++++++++++++++ + src/pulsecore/idxset.h | 12 ++++++++++++ + 2 files changed, 46 insertions(+) + +diff --git a/src/pulsecore/idxset.c b/src/pulsecore/idxset.c +index 91ac6a015..b5dd9b3e1 100644 +--- a/src/pulsecore/idxset.c ++++ b/src/pulsecore/idxset.c +@@ -470,6 +470,40 @@ bool pa_idxset_isempty(pa_idxset *s) { + return s->n_entries == 0; + } + ++bool pa_idxset_isdisjoint(pa_idxset *s, pa_idxset *t) { ++ struct idxset_entry *i; ++ ++ pa_assert(s); ++ pa_assert(t); ++ ++ for (i = s->iterate_list_head; i; i = i->iterate_next) ++ if (pa_idxset_contains(t, i->data)) ++ return false; ++ ++ return true; ++} ++ ++bool pa_idxset_issubset(pa_idxset *s, pa_idxset *t) { ++ struct idxset_entry *i; ++ ++ pa_assert(s); ++ pa_assert(t); ++ ++ for (i = s->iterate_list_head; i; i = i->iterate_next) ++ if (!pa_idxset_contains(t, i->data)) ++ return false; ++ ++ return true; ++} ++ ++bool pa_idxset_issuperset(pa_idxset *s, pa_idxset *t) { ++ return pa_idxset_issubset(t, s); ++} ++ ++bool pa_idxset_equals(pa_idxset *s, pa_idxset *t) { ++ return pa_idxset_issubset(s, t) && pa_idxset_issuperset(s, t); ++} ++ + pa_idxset *pa_idxset_copy(pa_idxset *s, pa_copy_func_t copy_func) { + pa_idxset *copy; + struct idxset_entry *i; +diff --git a/src/pulsecore/idxset.h b/src/pulsecore/idxset.h +index 6797852b7..ee530bf2b 100644 +--- a/src/pulsecore/idxset.h ++++ b/src/pulsecore/idxset.h +@@ -107,6 +107,18 @@ unsigned pa_idxset_size(pa_idxset*s); + /* Return true of the idxset is empty */ + bool pa_idxset_isempty(pa_idxset *s); + ++/* Return true if s and t have no entries in common */ ++bool pa_idxset_isdisjoint(pa_idxset *s, pa_idxset *t); ++ ++/* Return true if all entries in s are also in t */ ++bool pa_idxset_issubset(pa_idxset *s, pa_idxset *t); ++ ++/* Return true if all entries in t are also in s */ ++bool pa_idxset_issuperset(pa_idxset *s, pa_idxset *t); ++ ++/* Return true if s and t have all entries in common */ ++bool pa_idxset_equals(pa_idxset *s, pa_idxset *t); ++ + /* Duplicate the idxset. This will not copy the actual indexes. If copy_func is + * set, each entry is copied using the provided function, otherwise a shallow + * copy will be made. */ +-- +2.33.0 + diff --git a/0003-idxset-Add-reverse-iteration-functions.patch b/0003-idxset-Add-reverse-iteration-functions.patch new file mode 100644 index 0000000..eafeeca --- /dev/null +++ b/0003-idxset-Add-reverse-iteration-functions.patch @@ -0,0 +1,197 @@ +From 97d9c28579c7c7400969fd93f911e7745fb483ef Mon Sep 17 00:00:00 2001 +From: Alper Nebi Yasak +Date: Wed, 23 Jun 2021 17:58:37 +0300 +Subject: [PATCH] idxset: Add reverse iteration functions + +Add complementary functions to the existing idxset iterate(), +steal_first(), first(), next() functions that work in the reverse +direction: reverse_iterate(), steal_last(), last() and previous(). + +Signed-off-by: Alper Nebi Yasak +Part-of: +--- + src/pulsecore/idxset.c | 110 +++++++++++++++++++++++++++++++++++++++++ + src/pulsecore/idxset.h | 19 ++++--- + 2 files changed, 123 insertions(+), 6 deletions(-) + +diff --git a/src/pulsecore/idxset.c b/src/pulsecore/idxset.c +index b5dd9b3e1..324894d01 100644 +--- a/src/pulsecore/idxset.c ++++ b/src/pulsecore/idxset.c +@@ -381,6 +381,39 @@ at_end: + return NULL; + } + ++void *pa_idxset_reverse_iterate(pa_idxset *s, void **state, uint32_t *idx) { ++ struct idxset_entry *e; ++ ++ pa_assert(s); ++ pa_assert(state); ++ ++ if (*state == (void*) -1) ++ goto at_end; ++ ++ if ((!*state && !s->iterate_list_tail)) ++ goto at_end; ++ ++ e = *state ? *state : s->iterate_list_tail; ++ ++ if (e->iterate_previous) ++ *state = e->iterate_previous; ++ else ++ *state = (void*) -1; ++ ++ if (idx) ++ *idx = e->idx; ++ ++ return e->data; ++ ++at_end: ++ *state = (void *) -1; ++ ++ if (idx) ++ *idx = PA_IDXSET_INVALID; ++ ++ return NULL; ++} ++ + void* pa_idxset_steal_first(pa_idxset *s, uint32_t *idx) { + void *data; + +@@ -399,6 +432,24 @@ void* pa_idxset_steal_first(pa_idxset *s, uint32_t *idx) { + return data; + } + ++void* pa_idxset_steal_last(pa_idxset *s, uint32_t *idx) { ++ void *data; ++ ++ pa_assert(s); ++ ++ if (!s->iterate_list_tail) ++ return NULL; ++ ++ data = s->iterate_list_tail->data; ++ ++ if (idx) ++ *idx = s->iterate_list_tail->idx; ++ ++ remove_entry(s, s->iterate_list_tail); ++ ++ return data; ++} ++ + void* pa_idxset_first(pa_idxset *s, uint32_t *idx) { + pa_assert(s); + +@@ -414,6 +465,21 @@ void* pa_idxset_first(pa_idxset *s, uint32_t *idx) { + return s->iterate_list_head->data; + } + ++void* pa_idxset_last(pa_idxset *s, uint32_t *idx) { ++ pa_assert(s); ++ ++ if (!s->iterate_list_tail) { ++ if (idx) ++ *idx = PA_IDXSET_INVALID; ++ return NULL; ++ } ++ ++ if (idx) ++ *idx = s->iterate_list_tail->idx; ++ ++ return s->iterate_list_tail->data; ++} ++ + void *pa_idxset_next(pa_idxset *s, uint32_t *idx) { + struct idxset_entry *e; + unsigned hash; +@@ -458,6 +524,50 @@ void *pa_idxset_next(pa_idxset *s, uint32_t *idx) { + } + } + ++void *pa_idxset_previous(pa_idxset *s, uint32_t *idx) { ++ struct idxset_entry *e; ++ unsigned hash; ++ ++ pa_assert(s); ++ pa_assert(idx); ++ ++ if (*idx == PA_IDXSET_INVALID) ++ return NULL; ++ ++ hash = *idx % NBUCKETS; ++ ++ if ((e = index_scan(s, hash, *idx))) { ++ ++ e = e->iterate_previous; ++ ++ if (e) { ++ *idx = e->idx; ++ return e->data; ++ } else { ++ *idx = PA_IDXSET_INVALID; ++ return NULL; ++ } ++ ++ } else { ++ ++ /* If the entry passed doesn't exist anymore we try to find ++ * the preceding one. */ ++ ++ for ((*idx)--; *idx < s->current_index; (*idx)--) { ++ ++ hash = *idx % NBUCKETS; ++ ++ if ((e = index_scan(s, hash, *idx))) { ++ *idx = e->idx; ++ return e->data; ++ } ++ } ++ ++ *idx = PA_IDXSET_INVALID; ++ return NULL; ++ } ++} ++ + unsigned pa_idxset_size(pa_idxset*s) { + pa_assert(s); + +diff --git a/src/pulsecore/idxset.h b/src/pulsecore/idxset.h +index ee530bf2b..dbc4187d9 100644 +--- a/src/pulsecore/idxset.h ++++ b/src/pulsecore/idxset.h +@@ -88,18 +88,25 @@ void* pa_idxset_rrobin(pa_idxset *s, uint32_t *idx); + + /* Iterate through the idxset. At first iteration state should be NULL */ + void *pa_idxset_iterate(pa_idxset *s, void **state, uint32_t *idx); ++void *pa_idxset_reverse_iterate(pa_idxset *s, void **state, uint32_t *idx); + +-/* Return the oldest entry in the idxset and remove it. If idx is not NULL fill in its index in *idx */ ++/* Return the oldest or newest entry in the idxset and remove it. ++ * If idx is not NULL fill in its index in *idx */ + void* pa_idxset_steal_first(pa_idxset *s, uint32_t *idx); ++void* pa_idxset_steal_last(pa_idxset *s, uint32_t *idx); + +-/* Return the oldest entry in the idxset. Fill in its index in *idx. */ ++/* Return the oldest or newest entry in the idxset. ++ * Fill in its index in *idx. */ + void* pa_idxset_first(pa_idxset *s, uint32_t *idx); ++void* pa_idxset_last(pa_idxset *s, uint32_t *idx); + +-/* Return the entry following the entry indexed by *idx. After the +- * call *index contains the index of the returned +- * object. pa_idxset_first() and pa_idxset_next() may be used to +- * iterate through the set.*/ ++/* Return the entry following or preceding the entry indexed by *idx. ++ * After the call *index contains the index of the returned object. ++ * pa_idxset_first() and pa_idxset_next() may be used to iterate through ++ * the set. pa_idxset_last() and pa_idxset_previous() may be used to ++ * iterate through the set in reverse. */ + void *pa_idxset_next(pa_idxset *s, uint32_t *idx); ++void *pa_idxset_previous(pa_idxset *s, uint32_t *idx); + + /* Return the current number of entries in the idxset */ + unsigned pa_idxset_size(pa_idxset*s); +-- +2.33.0 + diff --git a/pulseaudio.spec b/pulseaudio.spec index 3a38fca..58d8522 100644 --- a/pulseaudio.spec +++ b/pulseaudio.spec @@ -6,7 +6,7 @@ Name: pulseaudio Summary: Improved Linux Sound Server Version: 16.1 -Release: 6 +Release: 7 License: LGPLv2+ URL: https://www.freedesktop.org/wiki/Software/PulseAudio Source0: https://freedesktop.org/software/pulseaudio/releases/pulseaudio-%{version}.tar.xz @@ -17,6 +17,9 @@ Patch201: pulseaudio-autostart.patch Patch1001: 0001-Fix-the-problem-that-the-description-field-of-pa_als.patch Patch1002: 0001-alsa-mixer-avoid-assertion-at-alsa-lib-mixer-API-whe.patch Patch1003: 0001-alsa-mixer-allow-to-re-attach-the-mixer-control-elem.patch +Patch1004: 0001-idxset-Add-set-contains-function.patch +Patch1005: 0002-idxset-Add-set-comparison-operations.patch +Patch1006: 0003-idxset-Add-reverse-iteration-functions.patch BuildRequires: meson BuildRequires: automake libtool gcc-c++ bash-completion @@ -244,6 +247,9 @@ exit 0 %{_mandir}/man*/* %changelog +* Mon Dec 12 2022 wuxu - 16.1-7 +- idxset: Add reverse iteration functions, set comparison operations adn set contains() function + * Mon Dec 12 2022 wuxu - 16.1-6 - alsa-mixer: allow to re-attach the mixer control element -- Gitee