core/index: Replace index_entry iterators with struct set_iter
Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
parent
a8bb7ffccd
commit
45207ebd2e
|
@ -34,17 +34,7 @@ const std::string filter :: add(const std::string &text, unsigned int index)
|
|||
return lc;
|
||||
}
|
||||
|
||||
static void do_set_intersection(index_entry *entry,
|
||||
std::set<unsigned int> &res)
|
||||
{
|
||||
std::set<unsigned int> tmp;
|
||||
|
||||
set_intersection(entry->begin(), entry->end(), res.begin(), res.end(),
|
||||
std::inserter(tmp, tmp.begin()));
|
||||
res.swap(tmp);
|
||||
}
|
||||
|
||||
void filter :: search(const std::string &text, std::set<unsigned int> &res)
|
||||
void filter :: search(const std::string &text, struct set *res)
|
||||
{
|
||||
gchar *g_lc = string_lowercase(text.c_str());
|
||||
const std::string lc = g_lc;
|
||||
|
@ -52,7 +42,7 @@ void filter :: search(const std::string &text, std::set<unsigned int> &res)
|
|||
index_entry *found;
|
||||
|
||||
g_free(g_lc);
|
||||
res.clear();
|
||||
set_clear(res);
|
||||
|
||||
for (end = 1; end <= lc.size(); end++) {
|
||||
end = lc.find(' ', begin);
|
||||
|
@ -61,15 +51,14 @@ void filter :: search(const std::string &text, std::set<unsigned int> &res)
|
|||
|
||||
found = db_get(&filter_index, lc.substr(begin, end- begin).c_str());
|
||||
if (!found) {
|
||||
res.clear();
|
||||
set_clear(res);
|
||||
return;
|
||||
}
|
||||
|
||||
if (begin == 0)
|
||||
std::copy(found->begin(), found->end(),
|
||||
std::inserter(res, res.begin()));
|
||||
set_copy(&found->ie_set, res);
|
||||
else
|
||||
do_set_intersection(found, res);
|
||||
set_inline_intersect(&found->ie_set, res);
|
||||
|
||||
begin = ++end;
|
||||
}
|
||||
|
|
|
@ -4,47 +4,41 @@
|
|||
#include <core/index.h>
|
||||
|
||||
|
||||
index_entry :: index_entry() {}
|
||||
index_entry :: index_entry()
|
||||
{
|
||||
ie_set = SET_INIT();
|
||||
}
|
||||
|
||||
index_entry :: index_entry(const std::string &key)
|
||||
: ie_key(key)
|
||||
{}
|
||||
{
|
||||
ie_set = SET_INIT();
|
||||
}
|
||||
|
||||
index_entry :: ~index_entry()
|
||||
{
|
||||
set_deinit(&ie_set);
|
||||
}
|
||||
|
||||
const std::string index_entry :: primary_key() const
|
||||
{
|
||||
return ie_key;
|
||||
}
|
||||
|
||||
typename index_entry::iterator index_entry :: begin()
|
||||
{
|
||||
return ie_set.begin();
|
||||
}
|
||||
|
||||
typename index_entry::iterator index_entry :: end()
|
||||
{
|
||||
return ie_set.end();
|
||||
}
|
||||
|
||||
void index_entry :: write(file &file)
|
||||
{
|
||||
std::set<unsigned int>::iterator it;
|
||||
file_writef(&file, "%s\n%zu ", ie_key.c_str(), ie_set.size());
|
||||
for (it = ie_set.begin(); it != ie_set.end(); it++)
|
||||
file_writef(&file, "%u ", *it);
|
||||
file_writef(&file, "%s\n" , ie_key.c_str());
|
||||
set_write(&file, &ie_set);
|
||||
}
|
||||
|
||||
void index_entry :: read(file &file)
|
||||
{
|
||||
unsigned int num, val;
|
||||
gchar *key = file_readl(&file);
|
||||
|
||||
file_readf(&file, "%u ", &num);
|
||||
ie_key = key;
|
||||
g_free(key);
|
||||
|
||||
for (unsigned int i = 0; i < num; i++) {
|
||||
file_readf(&file, "%u", &val);
|
||||
ie_set.insert(val);
|
||||
}
|
||||
set_read(&file, &ie_set);
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,7 +54,7 @@ index_entry *index_insert(database<index_entry> *index, const gchar *key,
|
|||
{
|
||||
index_entry *it = db_find(index, key);
|
||||
|
||||
it->ie_set.insert(value);
|
||||
set_insert(&it->ie_set, value);
|
||||
db_autosave(index);
|
||||
return it;
|
||||
}
|
||||
|
@ -70,7 +64,7 @@ void index_remove(database<index_entry> *index, const gchar *key,
|
|||
{
|
||||
index_entry *it = db_get(index, key);
|
||||
if (it) {
|
||||
it->ie_set.erase(value);
|
||||
set_remove(&it->ie_set, value);
|
||||
db_autosave(index);
|
||||
}
|
||||
}
|
||||
|
@ -81,5 +75,5 @@ bool index_has(database<index_entry> *index, const gchar *key, unsigned int valu
|
|||
|
||||
if (!it)
|
||||
return false;
|
||||
return it->ie_set.find(value) != it->ie_set.end();
|
||||
return set_has(&it->ie_set, value);
|
||||
}
|
||||
|
|
|
@ -24,11 +24,11 @@ public:
|
|||
|
||||
void fill(index_entry *ent)
|
||||
{
|
||||
std::set<unsigned int>::iterator it;
|
||||
struct set_iter it;
|
||||
|
||||
clear();
|
||||
for (it = ent->begin(); it != ent->end(); it++)
|
||||
add(tags :: get_track(*it));
|
||||
set_for_each(&ent->ie_set, &it)
|
||||
add(tags :: get_track(it.it_val));
|
||||
}
|
||||
|
||||
unsigned int find_average_count()
|
||||
|
@ -85,7 +85,7 @@ static std::string cur_plist;
|
|||
|
||||
void playlist :: init()
|
||||
{
|
||||
std::set<unsigned int>::iterator it;
|
||||
struct set_iter it;
|
||||
|
||||
index_init(&playlist_db, "playlist.db", true);
|
||||
db_load(&playlist_db);
|
||||
|
@ -94,8 +94,8 @@ void playlist :: init()
|
|||
if (!ent)
|
||||
return;
|
||||
|
||||
for (it = ent->begin(); it != ent->end(); it++)
|
||||
library :: get_queue()->del(tags :: get_track(*it));
|
||||
set_for_each(&ent->ie_set, &it)
|
||||
library :: get_queue()->del(tags :: get_track(it.it_val));
|
||||
}
|
||||
|
||||
bool playlist :: has(Track *track, const std::string &name)
|
||||
|
|
|
@ -88,14 +88,14 @@ void update_paths()
|
|||
|
||||
static void remove_banned_tracks()
|
||||
{
|
||||
std::set<unsigned int>::iterator it;
|
||||
index_entry *ent = playlist :: get_tracks("Banned");
|
||||
struct set_iter it;
|
||||
|
||||
if (!ent)
|
||||
return;
|
||||
|
||||
for (it = ent->begin(); it != ent->end(); it++)
|
||||
library :: get_queue()->del(tags :: get_track(*it));
|
||||
set_for_each(&ent->ie_set, &it)
|
||||
library :: get_queue()->del(tags :: get_track(it.it_val));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -8,11 +8,13 @@ QueueWindow :: QueueWindow(BaseObjectType *cobject,
|
|||
const Glib::RefPtr<Gtk::Builder> builder)
|
||||
: Gtk::ScrolledWindow(cobject), _builder(builder), _q_search_empty(true)
|
||||
{
|
||||
_q_search_res = SET_INIT();
|
||||
_builder->get_widget("q_treeview", q_treeview);
|
||||
}
|
||||
|
||||
QueueWindow :: ~QueueWindow()
|
||||
{
|
||||
set_deinit(&_q_search_res);
|
||||
}
|
||||
|
||||
void QueueWindow :: init(Queue *queue)
|
||||
|
@ -32,21 +34,19 @@ void QueueWindow :: filter(std::string &text)
|
|||
{
|
||||
_q_search_empty = (text.find_first_not_of(" \t") == std::string::npos);
|
||||
if (!_q_search_empty)
|
||||
filter :: search(text, _q_search_res);
|
||||
filter :: search(text, &_q_search_res);
|
||||
q_filter->refilter();
|
||||
}
|
||||
|
||||
bool QueueWindow :: filter_ids(const Gtk::TreeIter &iter)
|
||||
{
|
||||
unsigned int id;
|
||||
std::set<unsigned int>::iterator it;
|
||||
|
||||
if (_q_search_empty)
|
||||
return true;
|
||||
|
||||
id = q_model->iter_to_id(iter);
|
||||
it = _q_search_res.find(_queue->operator[](id)->index());
|
||||
return it != _q_search_res.end();
|
||||
return set_has(&_q_search_res, _queue->operator[](id)->index());
|
||||
}
|
||||
|
||||
void QueueWindow :: on_row_activated(const Gtk::TreePath &path,
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
#ifndef OCARINA_CORE_FILTER_H
|
||||
#define OCARINA_CORE_FILTER_H
|
||||
|
||||
#include <set>
|
||||
extern "C" {
|
||||
#include <core/set.h>
|
||||
}
|
||||
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
|
@ -45,7 +48,7 @@ namespace filter {
|
|||
* @param text The text to search for.
|
||||
* @param res The results set to fill in with matching indexes.
|
||||
*/
|
||||
void search(const std::string &, std::set<unsigned int> &);
|
||||
void search(const std::string &, struct set *);
|
||||
|
||||
/**
|
||||
* Converts the input text to lowercase and returns the result.
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
#define OCARINA_CORE_INDEX_H
|
||||
|
||||
#include <core/database.h>
|
||||
extern "C" {
|
||||
#include <core/set.h>
|
||||
}
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
@ -15,13 +17,8 @@
|
|||
* integer identifiers. This lets us use a Database as an inverted index.
|
||||
*/
|
||||
struct index_entry : public DatabaseEntry {
|
||||
std::string ie_key;
|
||||
std::set<unsigned int> ie_set;
|
||||
|
||||
/** Iterator access for our backing std::set */
|
||||
typedef typename std::set<unsigned int>::iterator iterator;
|
||||
/** Const iterator access for our backing std::set */
|
||||
typedef typename std::set<unsigned int>::const_iterator const_iterator;
|
||||
std::string ie_key;
|
||||
struct set ie_set;
|
||||
|
||||
index_entry(); /**< Create an empty IndexEntry. */
|
||||
|
||||
|
@ -31,6 +28,7 @@ struct index_entry : public DatabaseEntry {
|
|||
* @param key The key associated with this IndexEntry.
|
||||
*/
|
||||
index_entry(const std::string &);
|
||||
~index_entry();
|
||||
|
||||
|
||||
/**
|
||||
|
@ -40,17 +38,6 @@ struct index_entry : public DatabaseEntry {
|
|||
*/
|
||||
const std::string primary_key() const;
|
||||
|
||||
/**
|
||||
* @return An iterator pointing to the first item in IndexEntry::_values
|
||||
*/
|
||||
iterator begin();
|
||||
|
||||
/**
|
||||
* @return An iterator pointing past the last item in IndexEntry::_vaues
|
||||
*/
|
||||
iterator end();
|
||||
|
||||
|
||||
/**
|
||||
* Write an IndexEntry to file.
|
||||
*
|
||||
|
|
|
@ -4,16 +4,18 @@
|
|||
#ifndef OCARINA_GUI_QUEUE_WINDOW_H
|
||||
#define OCARINA_GUI_QUEUE_WINDOW_H
|
||||
|
||||
extern "C" {
|
||||
#include <core/set.h>
|
||||
}
|
||||
#include <gui/queue/model.h>
|
||||
#include <gtkmm.h>
|
||||
#include <set>
|
||||
|
||||
class QueueWindow : public Gtk::ScrolledWindow {
|
||||
private:
|
||||
Glib::RefPtr<Gtk::Builder> _builder;
|
||||
Queue *_queue;
|
||||
|
||||
std::set<unsigned int> _q_search_res;
|
||||
struct set _q_search_res;
|
||||
bool _q_search_empty;
|
||||
|
||||
public:
|
||||
|
|
|
@ -47,17 +47,18 @@ static void test_addition()
|
|||
static void do_test_search(const std::string &text, unsigned int len,
|
||||
unsigned int *ids)
|
||||
{
|
||||
int init_values[] = { 1, 2, 3, 4, 5 };
|
||||
std::set<unsigned int> res(init_values, init_values + 5);
|
||||
std::set<unsigned int>::iterator it;
|
||||
struct set res = SET_INIT();
|
||||
unsigned int i = 0;
|
||||
|
||||
filter :: search(text, res);
|
||||
test_equal(res.size(), (size_t)len);
|
||||
for (unsigned int i = 1; i <= 6; i++)
|
||||
set_insert(&res, i);
|
||||
|
||||
it = res.begin();
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
test_loop_equal(*it++, ids[i], i);
|
||||
test_loop_passed();
|
||||
filter :: search(text, &res);
|
||||
test_equal(set_size(&res), (size_t)len);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
test_loop_equal(set_has(&res, ids[i]), true, i);
|
||||
} test_loop_passed();
|
||||
}
|
||||
|
||||
static void test_search()
|
||||
|
|
|
@ -9,12 +9,20 @@
|
|||
static void test_entry()
|
||||
{
|
||||
index_entry *ie = new index_entry("Link");
|
||||
struct set_iter it;
|
||||
unsigned int i;
|
||||
struct file f;
|
||||
|
||||
test_equal(ie->primary_key(), "Link");
|
||||
ie->ie_set.insert(0);
|
||||
ie->ie_set.insert(1);
|
||||
ie->ie_set.insert(2);
|
||||
set_insert(&ie->ie_set, 0);
|
||||
set_insert(&ie->ie_set, 1);
|
||||
set_insert(&ie->ie_set, 2);
|
||||
|
||||
i = 0;
|
||||
set_for_each(&ie->ie_set, &it) {
|
||||
test_loop_equal(it.it_val, i, i);
|
||||
i++;
|
||||
} test_loop_passed();
|
||||
|
||||
file_init(&f, "index_entry", 0);
|
||||
file_open(&f, OPEN_WRITE);
|
||||
|
@ -25,18 +33,24 @@ static void test_entry()
|
|||
|
||||
ie = new index_entry();
|
||||
test_equal(ie->primary_key(), "");
|
||||
test_equal(ie->ie_set.size(), 0);
|
||||
test_equal(set_size(&ie->ie_set), 0);
|
||||
|
||||
file_open(&f, OPEN_READ);
|
||||
ie->read(f);
|
||||
test_equal(ie->primary_key(), "Zelda");
|
||||
test_equal(ie->ie_set.size(), 0);
|
||||
test_equal(set_size(&ie->ie_set), 0);
|
||||
|
||||
ie->read(f);
|
||||
test_equal(ie->primary_key(), "Link");
|
||||
test_equal(ie->ie_set.size(), 3);
|
||||
test_equal(set_size(&ie->ie_set), 3);
|
||||
file_close(&f);
|
||||
|
||||
i = 0;
|
||||
set_for_each(&ie->ie_set, &it) {
|
||||
test_loop_equal(it.it_val, i, i);
|
||||
i++;
|
||||
} test_loop_passed();
|
||||
|
||||
delete ie;
|
||||
}
|
||||
|
||||
|
@ -59,7 +73,7 @@ static void test_stress(unsigned int N)
|
|||
for (i = 0; i < N; i++)
|
||||
ie2 = index_insert(&index, key.c_str(), i);
|
||||
test_loop_equal(ie, ie2, c - 'a');
|
||||
test_loop_equal(ie->ie_set.size(), N, c - 'a');
|
||||
test_loop_equal(set_size(&ie->ie_set), N, c - 'a');
|
||||
test_loop_equal(index.db_size, c - 'a' + 1, c - 'a');
|
||||
} test_loop_passed();
|
||||
test_equal(index.db_size, 26);
|
||||
|
@ -79,7 +93,7 @@ static void test_stress(unsigned int N)
|
|||
index_remove(&index, key.c_str(), i);
|
||||
ie = db_find(&index, key.c_str());
|
||||
test_loop_not_equal(ie, NULL, c - 'a');
|
||||
test_loop_equal(ie->ie_set.size(), 0, c - 'a');
|
||||
test_loop_equal(set_size(&ie->ie_set), 0, c - 'a');
|
||||
} test_loop_passed();
|
||||
index_remove(&index, "ZZ", 42);
|
||||
test_equal(index.db_size, 26);
|
||||
|
|
|
@ -30,10 +30,10 @@ static void test_init()
|
|||
playlist :: init();
|
||||
|
||||
ent = playlist :: get_tracks("Banned");
|
||||
test_equal(ent->ie_set.size(), (size_t)4);
|
||||
test_equal(set_size(&ent->ie_set), (size_t)4);
|
||||
test_equal(library :: get_queue()->size(), (unsigned)20);
|
||||
ent = playlist :: get_tracks("Favorites");
|
||||
test_equal(ent->ie_set.size(), (size_t)8);
|
||||
test_equal(set_size(&ent->ie_set), (size_t)8);
|
||||
ent = playlist :: get_tracks("No Such Playlist");
|
||||
test_equal(ent, IDX_NULL);
|
||||
}
|
||||
|
@ -68,14 +68,14 @@ static void test_add()
|
|||
|
||||
playlist :: add(tags :: get_track(5), "Banned");
|
||||
ent = playlist :: get_tracks("Banned");
|
||||
test_equal(ent->ie_set.size(), (size_t)5);
|
||||
test_equal(set_size(&ent->ie_set), (size_t)5);
|
||||
test_equal(q->size(), (unsigned)8);
|
||||
test_equal(l->size(), (unsigned)19);
|
||||
|
||||
playlist :: add(tags :: get_track(16), "Favorites");
|
||||
playlist :: add(tags :: get_track(5), "Favorites");
|
||||
ent = playlist :: get_tracks("Favorites");
|
||||
test_equal(ent->ie_set.size(), (size_t)9);
|
||||
test_equal(set_size(&ent->ie_set), (size_t)9);
|
||||
test_equal(q->size(), (unsigned)9);
|
||||
|
||||
playlist :: add(tags :: get_track(6), "No Playlist");
|
||||
|
@ -90,13 +90,13 @@ static void test_delete()
|
|||
|
||||
playlist :: del(tags :: get_track(5), "Banned");
|
||||
ent = playlist :: get_tracks("Banned");
|
||||
test_equal(ent->ie_set.size(), (size_t)4);
|
||||
test_equal(set_size(&ent->ie_set), (size_t)4);
|
||||
test_equal(q->size(), (unsigned)9);
|
||||
test_equal(l->size(), (unsigned)20);
|
||||
|
||||
playlist :: del(tags :: get_track(5), "Favorites");
|
||||
ent = playlist :: get_tracks("Favorites");
|
||||
test_equal(ent->ie_set.size(), (size_t)8);
|
||||
test_equal(set_size(&ent->ie_set), (size_t)8);
|
||||
test_equal(q->size(), (unsigned)8);
|
||||
|
||||
playlist :: del(tags :: get_track(6), "No Playlist");
|
||||
|
|
|
@ -73,7 +73,7 @@ static void test_track_tag_constructor()
|
|||
Track a(album, artist, genre, library,
|
||||
"Hyrule Symphony/13 - Legend of Zelda Medley.mp3",
|
||||
"Legend of Zelda Medley", 288, 13);
|
||||
std::set<unsigned int> search;
|
||||
struct set search = SET_INIT();
|
||||
Track b;
|
||||
|
||||
verify_track_tag(&a, 1);
|
||||
|
@ -90,17 +90,17 @@ static void test_track_tag_constructor()
|
|||
verify_track_tag(&b, 2);
|
||||
|
||||
|
||||
filter :: search("Legend of Zelda Medley", search);
|
||||
test_equal(search.size(), (size_t)1);
|
||||
test_equal((*search.begin()), (unsigned)0);
|
||||
filter :: search("Legend of Zelda Medley", &search);
|
||||
test_equal(set_size(&search), (size_t)1);
|
||||
test_equal(set_has(&search, 0), true);
|
||||
|
||||
filter :: search("Koji Kondo", search);
|
||||
test_equal(search.size(), (size_t)1);
|
||||
test_equal((*search.begin()), (unsigned)0);
|
||||
filter :: search("Koji Kondo", &search);
|
||||
test_equal(set_size(&search), (size_t)1);
|
||||
test_equal(set_has(&search, 0), true);
|
||||
|
||||
filter :: search("Hyrule Symphony", search);
|
||||
test_equal(search.size(), (size_t)1);
|
||||
test_equal((*search.begin()), (unsigned)0);
|
||||
filter :: search("Hyrule Symphony", &search);
|
||||
test_equal(set_size(&search), (size_t)1);
|
||||
test_equal(set_has(&search, 0), true);
|
||||
}
|
||||
|
||||
static void test_track_tag_destructor()
|
||||
|
|
Loading…
Reference in New Issue