Commit aa9ffcd0 authored by Max Kellermann's avatar Max Kellermann

queue: merged songs, songMod, positionToId into struct queue_item

Move everything which belongs together into one common struct. This simplifies the implementation of several queue operations.
parent f78cddb4
...@@ -58,7 +58,7 @@ queue_increment_version(struct queue *queue) ...@@ -58,7 +58,7 @@ queue_increment_version(struct queue *queue)
if (queue->version >= max) { if (queue->version >= max) {
for (unsigned i = 0; i < queue->length; i++) for (unsigned i = 0; i < queue->length; i++)
queue->songMod[i] = 0; queue->items[i].version = 0;
queue->version = 1; queue->version = 1;
} }
...@@ -72,7 +72,7 @@ queue_modify(struct queue *queue, unsigned order) ...@@ -72,7 +72,7 @@ queue_modify(struct queue *queue, unsigned order)
assert(order < queue->length); assert(order < queue->length);
position = queue->order[order]; position = queue->order[order];
queue->songMod[position] = queue->version; queue->items[position].version = queue->version;
queue_increment_version(queue); queue_increment_version(queue);
} }
...@@ -81,7 +81,7 @@ void ...@@ -81,7 +81,7 @@ void
queue_modify_all(struct queue *queue) queue_modify_all(struct queue *queue)
{ {
for (unsigned i = 0; i < queue->length; i++) for (unsigned i = 0; i < queue->length; i++)
queue->songMod[i] = queue->version; queue->items[i].version = queue->version;
queue_increment_version(queue); queue_increment_version(queue);
} }
...@@ -93,12 +93,14 @@ queue_append(struct queue *queue, struct song *song) ...@@ -93,12 +93,14 @@ queue_append(struct queue *queue, struct song *song)
assert(!queue_is_full(queue)); assert(!queue_is_full(queue));
queue->songs[queue->length] = song; queue->items[queue->length] = (struct queue_item){
queue->songMod[queue->length] = queue->version; .song = song,
.id = id,
.version = queue->version,
};
queue->order[queue->length] = queue->length; queue->order[queue->length] = queue->length;
queue->positionToId[queue->length] = id; queue->idToPosition[id] = queue->length;
queue->idToPosition[queue->positionToId[queue->length]] =
queue->length;
++queue->length; ++queue->length;
...@@ -108,43 +110,34 @@ queue_append(struct queue *queue, struct song *song) ...@@ -108,43 +110,34 @@ queue_append(struct queue *queue, struct song *song)
void void
queue_swap(struct queue *queue, unsigned position1, unsigned position2) queue_swap(struct queue *queue, unsigned position1, unsigned position2)
{ {
struct song *sTemp; struct queue_item tmp;
unsigned iTemp; unsigned id1 = queue->items[position1].id;
unsigned id2 = queue->items[position2].id;
sTemp = queue->songs[position1];
queue->songs[position1] = queue->songs[position2];
queue->songs[position2] = sTemp;
queue->songMod[position1] = queue->version; tmp = queue->items[position1];
queue->songMod[position2] = queue->version; queue->items[position1] = queue->items[position2];
queue->items[position2] = tmp;
queue->idToPosition[queue->positionToId[position1]] = position2; queue->items[position1].version = queue->version;
queue->idToPosition[queue->positionToId[position2]] = position1; queue->items[position2].version = queue->version;
iTemp = queue->positionToId[position1]; queue->idToPosition[id1] = position2;
queue->positionToId[position1] = queue->positionToId[position2]; queue->idToPosition[id2] = position1;
queue->positionToId[position2] = iTemp;
} }
static void static void
queue_move_song_to(struct queue *queue, unsigned from, unsigned to) queue_move_song_to(struct queue *queue, unsigned from, unsigned to)
{ {
unsigned from_id = queue->positionToId[from]; unsigned from_id = queue->items[from].id;
queue->items[to] = queue->items[from];
queue->idToPosition[from_id] = to; queue->idToPosition[from_id] = to;
queue->positionToId[to] = from_id;
queue->songs[to] = queue->songs[from];
queue->songMod[to] = queue->version;
} }
void void
queue_move(struct queue *queue, unsigned from, unsigned to) queue_move(struct queue *queue, unsigned from, unsigned to)
{ {
struct song *song; struct queue_item item = queue->items[from];
unsigned id;
song = queue_get(queue, from);
id = queue_position_to_id(queue, from);
/* move songs to one less in from->to */ /* move songs to one less in from->to */
...@@ -158,10 +151,9 @@ queue_move(struct queue *queue, unsigned from, unsigned to) ...@@ -158,10 +151,9 @@ queue_move(struct queue *queue, unsigned from, unsigned to)
/* put song at _to_ */ /* put song at _to_ */
queue->idToPosition[id] = to; queue->idToPosition[item.id] = to;
queue->positionToId[to] = id; queue->items[to] = item;
queue->songs[to] = song; queue->items[to].version = queue->version;
queue->songMod[to] = queue->version;
} }
void void
...@@ -206,10 +198,12 @@ void ...@@ -206,10 +198,12 @@ void
queue_clear(struct queue *queue) queue_clear(struct queue *queue)
{ {
for (unsigned i = 0; i < queue->length; i++) { for (unsigned i = 0; i < queue->length; i++) {
if (!song_in_database(queue->songs[i])) struct queue_item *item = &queue->items[i];
song_free(queue->songs[i]);
if (!song_in_database(item->song))
song_free(item->song);
queue->idToPosition[queue->positionToId[i]] = -1; queue->idToPosition[item->id] = -1;
} }
queue->length = 0; queue->length = 0;
...@@ -224,15 +218,11 @@ queue_init(struct queue *queue, unsigned max_length) ...@@ -224,15 +218,11 @@ queue_init(struct queue *queue, unsigned max_length)
queue->repeat = false; queue->repeat = false;
queue->random = false; queue->random = false;
queue->songs = g_malloc(sizeof(queue->songs[0]) * max_length); queue->items = g_new(struct queue_item, max_length);
queue->songMod = g_malloc(sizeof(queue->songMod[0]) *
max_length);
queue->order = g_malloc(sizeof(queue->order[0]) * queue->order = g_malloc(sizeof(queue->order[0]) *
max_length); max_length);
queue->idToPosition = g_malloc(sizeof(queue->idToPosition[0]) * queue->idToPosition = g_malloc(sizeof(queue->idToPosition[0]) *
max_length * QUEUE_HASH_MULT); max_length * QUEUE_HASH_MULT);
queue->positionToId = g_malloc(sizeof(queue->positionToId[0]) *
max_length);
for (unsigned i = 0; i < max_length * QUEUE_HASH_MULT; ++i) for (unsigned i = 0; i < max_length * QUEUE_HASH_MULT; ++i)
queue->idToPosition[i] = -1; queue->idToPosition[i] = -1;
...@@ -245,11 +235,9 @@ queue_finish(struct queue *queue) ...@@ -245,11 +235,9 @@ queue_finish(struct queue *queue)
{ {
queue_clear(queue); queue_clear(queue);
g_free(queue->songs); g_free(queue->items);
g_free(queue->songMod);
g_free(queue->order); g_free(queue->order);
g_free(queue->idToPosition); g_free(queue->idToPosition);
g_free(queue->positionToId);
g_rand_free(queue->rand); g_rand_free(queue->rand);
} }
......
...@@ -34,6 +34,20 @@ enum { ...@@ -34,6 +34,20 @@ enum {
}; };
/** /**
* One element of the queue: basically a song plus some queue specific
* information attached.
*/
struct queue_item {
struct song *song;
/** the unique id of this item in the queue */
unsigned id;
/** when was this item last changed? */
uint32_t version;
};
/**
* A queue of songs. This is the backend of the playlist: it contains * A queue of songs. This is the backend of the playlist: it contains
* an ordered list of songs. * an ordered list of songs.
* *
...@@ -54,17 +68,11 @@ struct queue { ...@@ -54,17 +68,11 @@ struct queue {
uint32_t version; uint32_t version;
/** all songs in "position" order */ /** all songs in "position" order */
struct song **songs; struct queue_item *items;
/** holds version a song was modified on */
uint32_t *songMod;
/** map order numbers to positions */ /** map order numbers to positions */
unsigned *order; unsigned *order;
/** map positions to song ids */
unsigned *positionToId;
/** map song ids to posiitons */ /** map song ids to posiitons */
int *idToPosition; int *idToPosition;
...@@ -142,7 +150,7 @@ queue_position_to_id(const struct queue *queue, unsigned position) ...@@ -142,7 +150,7 @@ queue_position_to_id(const struct queue *queue, unsigned position)
{ {
assert(position < queue->length); assert(position < queue->length);
return queue->positionToId[position]; return queue->items[position].id;
} }
static inline unsigned static inline unsigned
...@@ -174,7 +182,7 @@ queue_get(const struct queue *queue, unsigned position) ...@@ -174,7 +182,7 @@ queue_get(const struct queue *queue, unsigned position)
{ {
assert(position < queue->length); assert(position < queue->length);
return queue->songs[position]; return queue->items[position].song;
} }
/** /**
...@@ -197,8 +205,8 @@ queue_song_newer(const struct queue *queue, unsigned position, ...@@ -197,8 +205,8 @@ queue_song_newer(const struct queue *queue, unsigned position,
assert(position < queue->length); assert(position < queue->length);
return version > queue->version || return version > queue->version ||
queue->songMod[position] >= version || queue->items[position].version >= version ||
queue->songMod[position] == 0; queue->items[position].version == 0;
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment