libsaria: Add filtering to the new index
Otherwise it's useless. I search all three indexes and use the union of those results to determine what is visible.
This commit is contained in:
parent
9c749e4ade
commit
83488dfa06
|
@ -10,6 +10,10 @@ namespace libsaria
|
||||||
{
|
{
|
||||||
|
|
||||||
void add_track(libsaria::Track &);
|
void add_track(libsaria::Track &);
|
||||||
|
void filter(string &);
|
||||||
|
bool is_visible(sid_t &);
|
||||||
|
bool is_filtered();
|
||||||
|
unsigned int size();
|
||||||
void print_stats();
|
void print_stats();
|
||||||
|
|
||||||
}; /* Namespace: index */
|
}; /* Namespace: index */
|
||||||
|
|
115
libsaria/index/filter.cpp
Normal file
115
libsaria/index/filter.cpp
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
|
||||||
|
#include <libsaria/index.h>
|
||||||
|
#include <libsaria/format.h>
|
||||||
|
#include <libsaria/callback.h>
|
||||||
|
#include "index.h"
|
||||||
|
|
||||||
|
static set<sid_t> results;
|
||||||
|
static bool filtered = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Thanks to: http://stackoverflow.com/questions/1773526/in-place-c-set-intersection
|
||||||
|
* for the set intersection algorithm!
|
||||||
|
*/
|
||||||
|
static void inplace_intersect(set<sid_t> *ids)
|
||||||
|
{
|
||||||
|
set<sid_t>::iterator it1 = results.begin();
|
||||||
|
set<sid_t>::iterator it2 = ids->begin();
|
||||||
|
|
||||||
|
while ( (it1 != results.end()) && (it2 != ids->end()) ) {
|
||||||
|
if (*it1 < *it2)
|
||||||
|
results.erase(it1++);
|
||||||
|
else if (*it2 < *it1)
|
||||||
|
it2++;
|
||||||
|
else { /* *it1 == *it2 */
|
||||||
|
it1++;
|
||||||
|
it2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove everything in results that wasn't in inodes */
|
||||||
|
results.erase(it1, results.end());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void search_index(string &term,
|
||||||
|
map<string, set<sid_t> > *index,
|
||||||
|
set<ino_t> *found)
|
||||||
|
{
|
||||||
|
map<string, set<sid_t> >::iterator it;
|
||||||
|
it = index->find(term);
|
||||||
|
if (it != index->end())
|
||||||
|
found->insert(it->second.begin(), it->second.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void search_indexes(string &term, set<ino_t> *found)
|
||||||
|
{
|
||||||
|
search_index(term, &artist_index, found);
|
||||||
|
search_index(term, &album_index, found);
|
||||||
|
search_index(term, &title_index, found);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_filter(list<string> *terms)
|
||||||
|
{
|
||||||
|
set<ino_t> found;
|
||||||
|
list<string>::iterator it;
|
||||||
|
|
||||||
|
for (it = terms->begin(); it != terms->end(); it++) {
|
||||||
|
found.clear();
|
||||||
|
search_indexes(*it, &found);
|
||||||
|
/*
|
||||||
|
* Key not found means we don't need to filter anymore
|
||||||
|
* just clear the results set and return.
|
||||||
|
*/
|
||||||
|
if (found.size() == 0) {
|
||||||
|
results.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This is the first result, so the result set is empty.
|
||||||
|
* Taking an intersection will always give us an empty set.
|
||||||
|
*/
|
||||||
|
if (it == terms->begin())
|
||||||
|
results = found;
|
||||||
|
else
|
||||||
|
inplace_intersect(&found);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace libsaria
|
||||||
|
{
|
||||||
|
|
||||||
|
void index::filter(string &search)
|
||||||
|
{
|
||||||
|
list<string> *terms = format_text(search);
|
||||||
|
results.clear();
|
||||||
|
|
||||||
|
if (terms->size() == 0)
|
||||||
|
filtered = false;
|
||||||
|
else {
|
||||||
|
do_filter(terms);
|
||||||
|
filtered = true;
|
||||||
|
}
|
||||||
|
trigger_callback(REFILTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool index::is_visible(sid_t &songid)
|
||||||
|
{
|
||||||
|
set<sid_t>::iterator it;
|
||||||
|
|
||||||
|
if (filtered == false)
|
||||||
|
return true;
|
||||||
|
it = results.find(songid);
|
||||||
|
return it != results.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool index::is_filtered()
|
||||||
|
{
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int index::size()
|
||||||
|
{
|
||||||
|
return results.size();
|
||||||
|
}
|
||||||
|
};
|
|
@ -2,6 +2,7 @@
|
||||||
#include <libsaria/track.h>
|
#include <libsaria/track.h>
|
||||||
#include <libsaria/index.h>
|
#include <libsaria/index.h>
|
||||||
#include <libsaria/format.h>
|
#include <libsaria/format.h>
|
||||||
|
#include "index.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
13
libsaria/index/index.h
Normal file
13
libsaria/index/index.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef LIBSARIA_INDEX_INTERNAL_H
|
||||||
|
#define LIBSARIA_INDEX_INTERNAL_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
extern map<string, set<sid_t> > artist_index;
|
||||||
|
extern map<string, set<sid_t> > album_index;
|
||||||
|
extern map<string, set<sid_t> > title_index;
|
||||||
|
|
||||||
|
#endif /* LIBSARIA_INDEX_INTERNAL_H */
|
|
@ -6,6 +6,7 @@ using namespace std;
|
||||||
|
|
||||||
#include <libsaria/audio.h>
|
#include <libsaria/audio.h>
|
||||||
#include <libsaria/prefs.h>
|
#include <libsaria/prefs.h>
|
||||||
|
#include <libsaria/index.h>
|
||||||
#include <libsaria/print.h>
|
#include <libsaria/print.h>
|
||||||
#include "library.h"
|
#include "library.h"
|
||||||
|
|
||||||
|
@ -91,7 +92,7 @@ static void print_cur_track()
|
||||||
static void random_next()
|
static void random_next()
|
||||||
{
|
{
|
||||||
cur_track = play_list.begin();
|
cur_track = play_list.begin();
|
||||||
if (libsaria::library::is_filtered()) {
|
if (libsaria::index::is_filtered()) {
|
||||||
println("Picking random track from index");
|
println("Picking random track from index");
|
||||||
sid_t inode = libsaria::library::index_rand();
|
sid_t inode = libsaria::library::index_rand();
|
||||||
libsaria::library::play_id(inode);
|
libsaria::library::play_id(inode);
|
||||||
|
@ -112,7 +113,7 @@ static void sequential_next()
|
||||||
if (cur_track == play_list.end())
|
if (cur_track == play_list.end())
|
||||||
cur_track = play_list.begin();
|
cur_track = play_list.begin();
|
||||||
inode = (*cur_track)->get_songid();
|
inode = (*cur_track)->get_songid();
|
||||||
} while (!libsaria::library::is_visible(inode));
|
} while (!libsaria::index::is_visible(inode));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pick_next()
|
static void pick_next()
|
||||||
|
@ -197,8 +198,8 @@ namespace libsaria
|
||||||
|
|
||||||
unsigned int library::size()
|
unsigned int library::size()
|
||||||
{
|
{
|
||||||
if (is_filtered() == true)
|
if (index::is_filtered() == true)
|
||||||
return filter_size();
|
return index::size();
|
||||||
return play_list.size();
|
return play_list.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user