libsaria: Move filter code

From index.cpp to filter.cpp.  I also added in an "is_visible()"
function for testing visibility of tracks.

Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
This commit is contained in:
Bryan Schumaker 2012-04-06 07:56:24 -04:00
parent 7820b28534
commit 235ac70033
5 changed files with 59 additions and 171 deletions

View File

@ -28,6 +28,7 @@ namespace libsaria
void add_track(Track *);
void remove_track(Track *);
void do_filter(string &);
bool is_visible(Track *);
};
/* namespace index

View File

@ -69,6 +69,7 @@ namespace libsaria
void prepare_for_removal();
void reset_iterator();
void set_filter_text(string &);
bool is_visible(libsaria::Track *);
virtual Track *next() = 0;
string &get_name();

View File

@ -1,125 +1,85 @@
// Copyright (c) 2011 Bryan Schumaker.
#include <libsaria/index.h>
#include <libsaria/format.h>
#include "index.h"
//set<sid_t> results;
set<string> *cur_terms;
//static bool filtered = false;
#include <libsaria/track.h>
#include <libsaria/index.h>
/*
* 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)
static void inplace_intersect(set<libsaria::Track *> *results,
set<libsaria::Track *> *tracks)
{
set<sid_t>::iterator it1 = results.begin();
set<sid_t>::iterator it2 = ids->begin();
set<libsaria::Track *>::iterator it1 = results->begin();
set<libsaria::Track *>::iterator it2 = tracks->begin();
while ( (it1 != results.end()) && (it2 != ids->end()) ) {
while ( (it1 != results->end()) && (it2 != tracks->end()) ) {
if (*it1 < *it2)
results.erase(it1++);
results->erase(it1++);
else if (*it2 < *it1)
it2++;
else { *//* *it1 == *it2 */
/* it1++;
else { /* *it1 == *it2 */
it1++;
it2++;
}
}*/
}
/* Remove everything in results that wasn't in inodes */
/*results.erase(it1, results.end());
results->erase(it1, results->end());
}
static inline void search_index(const string &term,
map<string, set<sid_t> > *index,
set<ino_t> *found)
static void search_index(map<string, set<libsaria::Track *> > *index,
const string &term, set<libsaria::Track *> *res)
{
map<string, set<sid_t> >::iterator it;
map<string, set<libsaria::Track *> >::iterator it;
it = index->find(term);
if (it != index->end())
found->insert(it->second.begin(), it->second.end());
}
static inline void search_indexes(const 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(set<string> *terms)
{
set<ino_t> found;
set<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);
}
}
static void run_filter()
{
results.clear();
if (cur_terms == NULL || cur_terms->size() == 0)
filtered = false;
else {
do_filter(cur_terms);
filtered = true;
}
trigger_callback(REFILTER);
res->insert(it->second.begin(), it->second.end());
}
namespace libsaria
{
void index::filter(string &search)
void Index::do_filter(string &text)
{
cur_terms = format_text(search);
run_filter();
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);
}
}
void index::refresh()
bool Index::is_visible(Track *track)
{
run_filter();
}
bool index::is_visible(sid_t &songid)
{
set<sid_t>::iterator it;
if (filtered == false)
if (!terms || terms->size() == 0)
return true;
it = results.find(songid);
return it != results.end();
return results.find(track) != results.end();
}
bool index::is_filtered()
{
return filtered;
}
unsigned int index::size()
{
return results.size();
}
};*/
}; /* Namespace: libsaria */

View File

@ -77,40 +77,6 @@ static void index_tag(libsaria::Track *track, const string &tag,
index_word(track, *it, index);
}
/*
* 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
{
@ -134,54 +100,9 @@ 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);
}
}
void Index::print_stats()
{
println("Index cache hits: %u size: %u", hits, substr_cache.size());
}
/*
sid_t index::rand_id()
{
set<sid_t>::iterator it = results.begin();
unsigned int index = rand() % results.size();
println("results.size()? %d", results.size());
for (unsigned int i = 0; i < index; i++)
it++;
return *it;
}*/
}

View File

@ -48,6 +48,11 @@ namespace libsaria
RENDER( refilter() );
}
bool Playlist::is_visible(libsaria::Track *track)
{
return index.is_visible(track);
}
string &Playlist::get_name()
{
return name;