ocarina/libsaria/index/filter.cpp

86 lines
2.0 KiB
C++

// Copyright (c) 2011 Bryan Schumaker.
#include <format.h>
#include <track.h>
#include <index.h>
/*
* Thanks to: http://stackoverflow.com/questions/1773526/in-place-c-set-intersection
* for the set intersection algorithm!
*/
static void inplace_intersect(set<libsaria::Track *> *results,
set<libsaria::Track *> *tracks)
{
set<libsaria::Track *>::iterator it1 = results->begin();
set<libsaria::Track *>::iterator it2 = tracks->begin();
while ( (it1 != results->end()) && (it2 != tracks->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 search_index(map<string, set<libsaria::Track *> > *index,
const string &term, set<libsaria::Track *> *res)
{
map<string, set<libsaria::Track *> >::iterator it;
it = index->find(term);
if (it != index->end())
res->insert(it->second.begin(), it->second.end());
}
namespace libsaria
{
void Index::do_filter(string &text)
{
set<string>::iterator it;
set<Track *> found;
results.clear();
terms = format_text(text);
if (terms == NULL || terms->size() == 0)
return;
for (it = terms->begin(); it != terms->end(); it++) {
found.clear();
search_index(&artist, *it, &found);
search_index(&album, *it, &found);
search_index(&title, *it, &found);
/*
* Key not found means we don't need to filtered
* 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(&results, &found);
}
}
bool Index::is_visible(Track *track)
{
if (!terms || terms->size() == 0)
return true;
return results.find(track) != results.end();
}
}; /* Namespace: libsaria */