77 lines
1.5 KiB
C++
77 lines
1.5 KiB
C++
/**
|
|
* Copyright 2013 (c) Anna Schumaker.
|
|
*/
|
|
|
|
#include <core/filter.h>
|
|
#include <core/index.h>
|
|
|
|
extern "C" {
|
|
#include <core/string.h>
|
|
}
|
|
|
|
#include <algorithm>
|
|
|
|
static Index filter_index;
|
|
|
|
void filter_init() { index_init(&filter_index, "", false); }
|
|
void filter_deinit() { db_deinit(&filter_index); }
|
|
|
|
const std::string filter :: add(const std::string &text, unsigned int index)
|
|
{
|
|
gchar *g_lc = string_lowercase(text.c_str());
|
|
const std::string lc = g_lc;
|
|
size_t begin = 0, end;
|
|
|
|
g_free(g_lc);
|
|
|
|
for (end = 1; end <= lc.size(); end++) {
|
|
index_insert(&filter_index,
|
|
lc.substr(begin, end - begin).c_str(),
|
|
index);
|
|
if (lc[end] == ' ')
|
|
begin = ++end;
|
|
}
|
|
return lc;
|
|
}
|
|
|
|
static void do_set_intersection(index_entry *entry,
|
|
std::set<unsigned int> &res)
|
|
{
|
|
std::set<unsigned int> tmp;
|
|
|
|
set_intersection(entry->begin(), entry->end(), res.begin(), res.end(),
|
|
std::inserter(tmp, tmp.begin()));
|
|
res.swap(tmp);
|
|
}
|
|
|
|
void filter :: search(const std::string &text, std::set<unsigned int> &res)
|
|
{
|
|
gchar *g_lc = string_lowercase(text.c_str());
|
|
const std::string lc = g_lc;
|
|
size_t begin = 0, end;
|
|
index_entry *found;
|
|
|
|
g_free(g_lc);
|
|
res.clear();
|
|
|
|
for (end = 1; end <= lc.size(); end++) {
|
|
end = lc.find(' ', begin);
|
|
if (end == std::string::npos)
|
|
end = lc.size();
|
|
|
|
found = db_get(&filter_index, lc.substr(begin, end- begin).c_str());
|
|
if (!found) {
|
|
res.clear();
|
|
return;
|
|
}
|
|
|
|
if (begin == 0)
|
|
std::copy(found->begin(), found->end(),
|
|
std::inserter(res, res.begin()));
|
|
else
|
|
do_set_intersection(found, res);
|
|
|
|
begin = ++end;
|
|
}
|
|
}
|