138 lines
3.2 KiB
C++
138 lines
3.2 KiB
C++
// Copyright (c) 2011 Bryan Schumaker.
|
|
#include <format.h>
|
|
#include <track.h>
|
|
#include <index.h>
|
|
#include <print.h>
|
|
|
|
#include <map>
|
|
#include <set>
|
|
#include <string>
|
|
using namespace std;
|
|
|
|
static map<string, set<string> > substr_cache;
|
|
unsigned int hits;
|
|
|
|
static set<string> *gen_substrs(const string &word)
|
|
{
|
|
string key;
|
|
set<string> substrs;
|
|
pair< map<string, set<string> >::iterator, bool > ret;
|
|
|
|
for (unsigned int i = 1; i <= word.size(); i++) {
|
|
key = word.substr(0, i);
|
|
substrs.insert(key);
|
|
}
|
|
|
|
ret = substr_cache.insert( pair<string, set<string> >(word, substrs));
|
|
return &(ret.first->second);
|
|
}
|
|
|
|
static set<string> *find_substrs(const string &word)
|
|
{
|
|
map<string, set<string> >::iterator it;
|
|
it = substr_cache.find(word);
|
|
if (it == substr_cache.end())
|
|
return gen_substrs(word);
|
|
else {
|
|
hits++;
|
|
return &(it->second);
|
|
}
|
|
}
|
|
|
|
static void index_substr(libsaria::Track *track, const string &key,
|
|
map<string, set<libsaria::Track *> > *index)
|
|
{
|
|
map<string, set<libsaria::Track *> >::iterator it = index->find(key);
|
|
|
|
if (it != index->end())
|
|
it->second.insert(track);
|
|
else {
|
|
set<libsaria::Track *> tracks;
|
|
tracks.insert(track);
|
|
index->insert(pair<string, set<libsaria::Track *> >(key, tracks));
|
|
}
|
|
}
|
|
|
|
static void index_word(libsaria::Track *track, const string &word,
|
|
map<string, set<libsaria::Track *> > *index)
|
|
{
|
|
set<string> *substrs = find_substrs(word);
|
|
set<string>::iterator it;
|
|
|
|
for (it = substrs->begin(); it != substrs->end(); it++)
|
|
index_substr(track, *it, index);
|
|
}
|
|
|
|
static void index_tag(libsaria::Track *track, const string &tag,
|
|
map<string, set<libsaria::Track *> > *index)
|
|
{
|
|
set<string> *words;
|
|
set<string>::iterator it;
|
|
|
|
words = libsaria::format_text(tag);
|
|
for (it = words->begin(); it != words->end(); it++)
|
|
index_word(track, *it, index);
|
|
}
|
|
|
|
static void remove_substr(libsaria::Track *track, const string &key,
|
|
map<string, set<libsaria::Track *> > *index)
|
|
{
|
|
map<string, set<libsaria::Track *> >::iterator it = index->find(key);
|
|
if (it != index->end())
|
|
it->second.erase(track);
|
|
}
|
|
|
|
static void remove_word(libsaria::Track *track, const string &word,
|
|
map<string, set<libsaria::Track *> > *index)
|
|
{
|
|
set<string> *substrs = find_substrs(word);
|
|
set<string>::iterator it;
|
|
|
|
for (it = substrs->begin(); it != substrs->end(); it++)
|
|
remove_substr(track, *it, index);
|
|
}
|
|
|
|
static void remove_tag(libsaria::Track *track, const string &tag,
|
|
map<string, set<libsaria::Track *> > *index)
|
|
{
|
|
set<string> *words;
|
|
set<string>::iterator it;
|
|
|
|
words = libsaria::format_text(tag);
|
|
for (it = words->begin(); it != words->end(); it++)
|
|
remove_word(track, *it, index);
|
|
}
|
|
|
|
namespace libsaria
|
|
{
|
|
|
|
Index::Index()
|
|
{
|
|
terms = NULL;
|
|
}
|
|
|
|
Index::~Index()
|
|
{
|
|
}
|
|
|
|
void Index::add_track(Track *track)
|
|
{
|
|
index_tag(track, (*track)[TRACK_ARTIST], &artist);
|
|
index_tag(track, (*track)[TRACK_ALBUM], &album);
|
|
index_tag(track, (*track)[TRACK_TITLE], &title);
|
|
}
|
|
|
|
void Index::remove_track(Track *track)
|
|
{
|
|
remove_tag(track, (*track)[TRACK_ARTIST], &artist);
|
|
remove_tag(track, (*track)[TRACK_ALBUM], &album);
|
|
remove_tag(track, (*track)[TRACK_TITLE], &title);
|
|
}
|
|
|
|
void Index::print_stats()
|
|
{
|
|
println("Index cache hits: %u size: %u", hits, substr_cache.size());
|
|
}
|
|
|
|
}
|