ocarina/libsaria/index/index.cpp

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());
}
}