libsaria: Use vectors to store the track list

For each library path, I replace the linked list with a vector allowing
me to easily index into the list to find tracks.

Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
This commit is contained in:
Bryan Schumaker 2012-11-22 14:01:25 -05:00 committed by Anna Schumaker
parent 592a924881
commit 36e9995bb9
7 changed files with 67 additions and 94 deletions

View File

@ -7,6 +7,7 @@
#include <playlist.h>
#include <string>
#include <vector>
using namespace std;
namespace libsaria
@ -18,9 +19,8 @@ namespace libsaria
struct Path {
bool visible;
unsigned int id;
unsigned int next_track;
string path;
List<Track> tracks;
vector<Track> tracks;
};
void init();

View File

@ -99,10 +99,10 @@ namespace libsaria
void set_banned(bool);
bool operator<(Track &);
const string &operator[](track_sprop_t);
const unsigned int &operator[](track_uiprop_t);
const int &operator[](track_iprop_t);
const bool &operator[](track_bprop_t);
string &operator[](track_sprop_t);
unsigned int &operator[](track_uiprop_t);
int &operator[](track_iprop_t);
bool &operator[](track_bprop_t);
};
Track *current_track();

View File

@ -15,6 +15,7 @@
#include <sstream>
using namespace std;
#define LIBRARY_CURRENT_VERSION 2 /* 11/22/2012 */
static string libdir = "library";
static string id_to_filename(unsigned int id)
@ -24,23 +25,19 @@ static string id_to_filename(unsigned int id)
return s.str();
}
static void save_track(libsaria::Track &track, void *data)
{
track.save((ofstream *)data);
}
static void do_save_path(ofstream &stream, void *data)
{
libsaria::library::Path *path = (libsaria::library::Path *)data;
list<libsaria::Track>::iterator it;
println("Saving library path: %d", path->id);
stream << 2 << "\n"; /* Save file version: 2 */
stream << LIBRARY_CURRENT_VERSION << "\n";
stream << path->path << "\n";
stream << path->id << " " << path->visible << " ";
stream << path->next_track << " " << path->tracks.size() << "\n";
stream << path->tracks.size() << "\n";
path->tracks.for_each_item(save_track, &stream);
for (unsigned int i = 0; i < path->tracks.size(); i++)
path->tracks[i].save(&stream);
}
void libsaria::library::save_path(libsaria::library::Path *path)
@ -56,8 +53,6 @@ void read_path(ifstream &stream)
unsigned int size;
unsigned int version;
libsaria::Track *track;
list<libsaria::Track *> tracks, banned;
libsaria::ListItem<libsaria::Track> *item;
struct libsaria::library::Path path, *path_ptr;
getline(stream, tmp);
@ -72,29 +67,25 @@ void read_path(ifstream &stream)
s.clear();
s.str(tmp);
s >> path.id;
s >> path.visible;
s >> path.next_track;
s >> path.id >> path.visible;
if (version <= 3) {
unsigned int next_track;
s >> next_track;
}
s >> size;
path_ptr = push_path(path);
for (unsigned int i = 0; i < size; i++) {
item = path_ptr->tracks.push_back(libsaria::Track(stream, path_ptr, version));
track = &item->get_value();
if ((*track)[TRACK_BANNED])
banned.push_back(track);
else
tracks.push_back(track);
path_ptr->tracks.push_back(libsaria::Track(stream, path_ptr, version));
track = &path_ptr->tracks.back();
if ((*track)[TRACK_ID] != i)
(*track)[TRACK_ID] = i;
}
if (version != 2)
libsaria::library::save_path(path_ptr);
libsaria::library::save_path(path_ptr);
libsaria::notify(PATH_UPDATED, path_ptr);
if (path.visible) {
lib_playlist.push_back(tracks);
libsaria::ban::get_banned_plist()->push_back(banned);
}
if (path.visible)
libsaria::library::show_path(path_ptr);
}
unsigned int schedule_load()

View File

@ -29,26 +29,7 @@ libsaria::library::Path *push_path(libsaria::library::Path &path)
return ptr;
}
struct sort_data {
list<libsaria::Track *> tracks;
list<libsaria::Track *> banned;
};
/*
* TODO: Add tracks directly to a playlist without going through
* these intermediate lists. (Possibly) use insertion sort
* for inserting?
*/
static void sort_tracks(libsaria::Track &track, void *data)
{
struct sort_data *sort = (struct sort_data *)data;
if (track[TRACK_BANNED])
sort->banned.push_back(&track);
else
sort->tracks.push_back(&track);
}
static void hide_track(libsaria::Track &track, void *data)
static void hide_track(libsaria::Track &track)
{
if (track[TRACK_BANNED])
libsaria::ban::get_banned_plist()->remove_track(&track);
@ -56,17 +37,6 @@ static void hide_track(libsaria::Track &track, void *data)
lib_playlist.remove_track(&track);
}
static void delete_track(libsaria::Track &track, void *data)
{
hide_track(track, NULL);
libsaria::deck::track_removed(&track);
}
static bool check_trackid(libsaria::Track &track, void *data)
{
return track[TRACK_ID] == *(unsigned int *)data;
}
void pop_path(libsaria::library::Path *path)
{
for (unsigned int i = 0; i < path_list.size(); i++) {
@ -96,7 +66,6 @@ namespace libsaria
path.visible = true;
path.id = next_id++;
path.next_track = 0;
path.path = dir;
path_ptr = push_path(path);
@ -109,7 +78,10 @@ namespace libsaria
list<Path>::iterator p_it;
remove_file(path);
path->tracks.for_each_item(delete_track, NULL);
for (unsigned int i = 0; i < path->tracks.size(); i++) {
hide_track(path->tracks[i]);
libsaria::deck::track_removed(&path->tracks[i]);
}
pop_path(path);
}
@ -127,7 +99,10 @@ namespace libsaria
void library::hide_path(Path *path)
{
path->tracks.for_each_item(hide_track, NULL);
for (unsigned int i = 0; i < path->tracks.size(); i++) {
hide_track(path->tracks[i]);
libsaria::deck::track_removed(&path->tracks[i]);
}
path->visible = false;
save_path(path);
notify(PATH_UPDATED, path);
@ -135,11 +110,18 @@ namespace libsaria
void library::show_path(Path *path)
{
struct sort_data sort;
list<Track *> ban, lib;
Track *track;
path->tracks.for_each_item(sort_tracks, &sort);
lib_playlist.push_back(sort.tracks);
ban::get_banned_plist()->push_back(sort.banned);
for (unsigned int i = 0; i < path->tracks.size(); i++) {
track = &path->tracks[i];
if ((*track)[TRACK_BANNED])
ban.push_back(track);
else
lib.push_back(track);
}
lib_playlist.push_back(lib);
ban::get_banned_plist()->push_back(ban);
path->visible = true;
save_path(path);
@ -148,15 +130,11 @@ namespace libsaria
Track *library::lookup(unsigned int libid, unsigned int trackid)
{
ListItem<Track> *track;
if (libid >= path_list.size())
return NULL;
track = path_list[libid].tracks.find_item(check_trackid, &trackid);
if (track == NULL)
if (trackid >= path_list[libid].tracks.size())
return NULL;
return &track->get_value();
return &path_list[libid].tracks[trackid];
}
void library::set_random(bool random)

View File

@ -37,16 +37,17 @@ ValidateTask::~ValidateTask()
void ValidateTask::run_task()
{
libsaria::Track *track;
libsaria::ListItem<libsaria::Track> *it;
unsigned int i = 0;
for (it = path->tracks.first(); it != path->tracks.end(); it = it->next()) {
track = &it->get_value();
while (i < path->tracks.size()) {
track = &path->tracks[i];
if (!libsaria::exists((*track)[TRACK_FILEPATH])) {
println("Reaping: " + (*track)[TRACK_FILEPATH]);
lib_playlist.remove_track(&it->get_value());
it = path->tracks.erase(it);
}
};
lib_playlist.remove_track(track);
path->tracks.erase(path->tracks.begin() + i);
} else
i++;
}
libsaria::notify(PATH_UPDATED, path);
save_path(path);
@ -88,15 +89,18 @@ ScanTask::~ScanTask()
{
}
static bool check_file(libsaria::Track &track, void *data)
static bool find_file(libsaria::library::Path *path, string &file)
{
return track[TRACK_FILEPATH] == *(string *)data;
for (unsigned int i = 0; i < path->tracks.size(); i++) {
if (path->tracks[i][TRACK_FILEPATH] == file)
return true;
}
return false;
}
void ScanTask::run_task()
{
list<string>::iterator it;
libsaria::ListItem<libsaria::Track> *li;
for (it = file_list.begin(); it != file_list.end(); it++) {
/*
@ -105,12 +109,12 @@ void ScanTask::run_task()
* the tree to check if the path exists. It'll be much faster
* than having to walk the same list over and over...
*/
if (path->tracks.find_item(check_file, &(*it)))
if (find_file(path, *it))
continue;
try {
li = path->tracks.push_back(libsaria::Track(*it, path));
lib_playlist.push_back(&li->get_value());
path->tracks.push_back(libsaria::Track(*it, path));
lib_playlist.push_back(&path->tracks.back());
} catch (string message) {
println(message);
}

View File

@ -44,7 +44,7 @@ namespace libsaria
return track < cmp_track.track;
}
const string &Track::operator[](track_sprop_t property)
string &Track::operator[](track_sprop_t property)
{
switch (property) {
case TRACK_FILEPATH:
@ -64,7 +64,7 @@ namespace libsaria
}
}
const unsigned int &Track::operator[](track_uiprop_t property)
unsigned int &Track::operator[](track_uiprop_t property)
{
switch (property) {
case TRACK_ID:
@ -86,7 +86,7 @@ namespace libsaria
}
}
const int &Track::operator[](track_iprop_t property)
int &Track::operator[](track_iprop_t property)
{
switch (property) {
case TRACK_LENGTH:
@ -100,7 +100,7 @@ namespace libsaria
}
}
const bool &Track::operator[](track_bprop_t property)
bool &Track::operator[](track_bprop_t property)
{
switch (property) {
default: /* TRACK_BANNED */

View File

@ -100,7 +100,7 @@ namespace libsaria
read_tags();
id = lib_path->next_track++;
id = lib_path->tracks.size();
artist_lc = lowercase(artist);
album_lc = lowercase(album);
make_lenstr(length, lenstr);