core/queue: Implement a new queue_iter

I plan to remove the containers/queue implementation, so we need a new
iterator for queue access.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2016-04-03 09:29:32 -04:00 committed by Anna Schumaker
parent 6bb08ddbaa
commit 9835235acd
2 changed files with 71 additions and 0 deletions

View File

@ -53,6 +53,12 @@ struct queue_ops {
};
struct queue_iter {
GList *it_iter; /* The current link in the GQueue. */
guint it_pos; /* The current index into the queue. */
};
struct queue {
unsigned int q_flags; /* The queue's set of flags. */
unsigned int q_length; /* The queue's total runtime (in seconds). */
@ -65,6 +71,47 @@ struct queue {
};
/* Called to initialize a queue iterator. */
static inline void queue_iter_init(struct queue *queue, struct queue_iter *it)
{
it->it_iter = g_queue_peek_head_link(&queue->q_tracks._queue);
it->it_pos = g_queue_link_index(&queue->q_tracks._queue, it->it_iter);
}
/* Called to advance a queue iterator by one step. */
static inline void queue_iter_next(struct queue_iter *it)
{
it->it_iter = g_list_next(it->it_iter);
it->it_pos++;
}
/* Called to rewind a queue iterator by one step. */
static inline void queue_iter_prev(struct queue_iter *it)
{
it->it_iter = g_list_previous(it->it_iter);
it->it_pos--;
}
/* Called to set a queue iterator to a specific position. */
static inline void queue_iter_set(struct queue *queue, struct queue_iter *it,
unsigned int pos)
{
it->it_iter = g_queue_peek_nth_link(&queue->q_tracks._queue, pos);
it->it_pos = pos;
}
/* Called to access the value of a queue iterator. */
static inline struct track *queue_iter_val(struct queue_iter *it)
{
return (it->it_iter) ? it->it_iter->data : NULL;
}
#define queue_for_each(queue, it) \
for (queue_iter_init(queue, it); (it)->it_iter; queue_iter_next(it))
/* Called to initialize a queue. */
void queue_init(struct queue *, unsigned int, const struct queue_ops *);

View File

@ -111,6 +111,7 @@ static void __test_deinit_core()
static void test_init()
{
struct queue q;
struct queue_iter it;
__test_init_core();
@ -125,6 +126,11 @@ static void test_init()
test_equal((void *)q.q_ops, NULL);
test_equal((void *)queue_next(&q), (void *)NULL);
queue_iter_init(&q, &it);
g_assert_null(it.it_iter);
g_assert_cmpuint(it.it_pos, ==, (unsigned int)-1);
g_assert_null(queue_iter_val(&it));
queue_deinit(&q);
test_equal(count_deinit, 0);
@ -193,6 +199,7 @@ static void test_stress(unsigned int N)
{
unsigned int ex_length = 0;
unsigned int ex_size = N;
struct queue_iter it;
struct track *track;
unsigned int i;
struct queue q;
@ -214,6 +221,23 @@ static void test_stress(unsigned int N)
test_equal(q.q_length, ex_length);
test_equal(queue_size(&q), ex_size);
/* queue_iter_init() */
if (N > 0) {
queue_iter_init(&q, &it);
g_assert_nonnull(it.it_iter);
g_assert_cmpuint(it.it_pos, ==, 0);
}
/* queue_for_each() */
i = 0;
queue_for_each(&q, &it) {
g_assert_cmpuint(it.it_pos, ==, i);
g_assert(queue_iter_val(&it) == track_get(i % 13));
i++;
}
g_assert_cmpuint(i, ==, N);
g_assert_cmpuint(queue_size(&q), ==, ex_size);
/* queue_remove_all() */
track = track_get(0);
ex_length -= track->tr_length * (N / 13);