core/index: Replace index_entry iterators with struct set_iter

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2015-10-21 15:57:21 -04:00
parent a8bb7ffccd
commit 45207ebd2e
12 changed files with 100 additions and 110 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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));
}

View File

@ -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,

View File

@ -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.

View File

@ -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.
*

View 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:

View File

@ -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()

View File

@ -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);

View File

@ -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");

View File

@ -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()