libsaria: Perform filtering
I use an in-place set intersection to find a set of songs that match the search terms.
This commit is contained in:
parent
048313c681
commit
824f589ff2
|
@ -1,12 +1,15 @@
|
|||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
#include <libsaria/format.h>
|
||||
#include "library.h"
|
||||
|
||||
static map<string, set<ino_t> > substr_index;
|
||||
static set<ino_t> results;
|
||||
static bool filtered;
|
||||
|
||||
static void add_to_index(ino_t &inode, string &key)
|
||||
{
|
||||
|
@ -82,6 +85,59 @@ static void reindex_path(list<TrackTag> *tag_list)
|
|||
task->queue();
|
||||
}
|
||||
|
||||
/*
|
||||
* Thanks to: http://stackoverflow.com/questions/1773526/in-place-c-set-intersection
|
||||
* for the set intersection algorithm!
|
||||
*/
|
||||
static void inplace_intersect(set<ino_t> *inodes)
|
||||
{
|
||||
set<ino_t>::iterator it1 = results.begin();
|
||||
set<ino_t>::iterator it2 = inodes->begin();
|
||||
|
||||
while ( (it1 != results.end()) && (it2 != inodes->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 void do_filter(list<string> &terms)
|
||||
{
|
||||
list<string>::iterator it;
|
||||
map<string, set<ino_t> >::iterator index_iter;
|
||||
|
||||
for (it = terms.begin(); it != terms.end(); it++) {
|
||||
index_iter = substr_index.find(*it);
|
||||
/*
|
||||
* Key not found means we don't need to filter anymore
|
||||
* just clear the results set and return
|
||||
*/
|
||||
if (index_iter == substr_index.end()) {
|
||||
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 = index_iter->second;
|
||||
else
|
||||
inplace_intersect(&index_iter->second);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace libsaria
|
||||
{
|
||||
|
||||
|
@ -97,11 +153,16 @@ namespace libsaria
|
|||
void library::filter(string &text)
|
||||
{
|
||||
list<string> key_list;
|
||||
list<string>::iterator it;
|
||||
|
||||
format_text(text, key_list);
|
||||
for (it = key_list.begin(); it != key_list.end(); it++)
|
||||
println(*it);
|
||||
results.clear();
|
||||
|
||||
if (key_list.size() == 0)
|
||||
filtered = false;
|
||||
else {
|
||||
do_filter(key_list);
|
||||
filtered = true;
|
||||
}
|
||||
}
|
||||
|
||||
}; /* Namespace: libsaria */
|
||||
|
|
Loading…
Reference in New Issue