mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	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 <alpernebiyasak@gmail.com> Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
This commit is contained in:
		
							parent
							
								
									ec668ac44b
								
							
						
					
					
						commit
						97d9c28579
					
				
					 2 changed files with 123 additions and 6 deletions
				
			
		| 
						 | 
					@ -381,6 +381,39 @@ at_end:
 | 
				
			||||||
    return NULL;
 | 
					    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* pa_idxset_steal_first(pa_idxset *s, uint32_t *idx) {
 | 
				
			||||||
    void *data;
 | 
					    void *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -399,6 +432,24 @@ void* pa_idxset_steal_first(pa_idxset *s, uint32_t *idx) {
 | 
				
			||||||
    return data;
 | 
					    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) {
 | 
					void* pa_idxset_first(pa_idxset *s, uint32_t *idx) {
 | 
				
			||||||
    pa_assert(s);
 | 
					    pa_assert(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -414,6 +465,21 @@ void* pa_idxset_first(pa_idxset *s, uint32_t *idx) {
 | 
				
			||||||
    return s->iterate_list_head->data;
 | 
					    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) {
 | 
					void *pa_idxset_next(pa_idxset *s, uint32_t *idx) {
 | 
				
			||||||
    struct idxset_entry *e;
 | 
					    struct idxset_entry *e;
 | 
				
			||||||
    unsigned hash;
 | 
					    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) {
 | 
					unsigned pa_idxset_size(pa_idxset*s) {
 | 
				
			||||||
    pa_assert(s);
 | 
					    pa_assert(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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 */
 | 
					/* 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_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_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_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
 | 
					/* Return the entry following or preceding the entry indexed by *idx.
 | 
				
			||||||
 * call *index contains the index of the returned
 | 
					 * After the call *index contains the index of the returned object.
 | 
				
			||||||
 * object. pa_idxset_first() and pa_idxset_next() may be used to
 | 
					 * pa_idxset_first() and pa_idxset_next() may be used to iterate through
 | 
				
			||||||
 * iterate through the set.*/
 | 
					 * 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_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 */
 | 
					/* Return the current number of entries in the idxset */
 | 
				
			||||||
unsigned pa_idxset_size(pa_idxset*s);
 | 
					unsigned pa_idxset_size(pa_idxset*s);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue