86 lines
2.0 KiB
C++
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 */
|