2
* Copyright (C) 2010-2013 Canonical Ltd
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License version 3 as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Authored by Michal Hruby <michal.hruby@canonical.com>
22
private static Dee.ICUTermFilter icu_filter;
24
public Dee.Index prepare_index (Dee.Model model,
26
owned Dee.ModelReaderFunc reader_func,
27
out Dee.Analyzer out_analyzer)
29
// reuse the icu_filter
30
if (icu_filter == null)
32
icu_filter = new Dee.ICUTermFilter.ascii_folder ();
35
var sort_filter = Dee.Filter.new_collator (sort_column);
36
var filter_model = new Dee.FilterModel (model, sort_filter);
38
var analyzer = new Dee.TextAnalyzer ();
39
analyzer.add_term_filter ((terms_in, terms_out) =>
41
for (uint i = 0; i < terms_in.num_terms (); i++)
43
unowned string term = terms_in.get_term (i);
44
var folded = icu_filter.apply (term);
45
terms_out.add_term (term);
46
if (folded != term) terms_out.add_term (folded);
49
out_analyzer = analyzer;
51
var reader = Dee.ModelReader.new ((owned) reader_func);
52
return new Dee.TreeIndex (filter_model, analyzer, reader);
55
public SList<Dee.ModelIter> search_index (Dee.Index index,
56
Dee.Analyzer analyzer,
59
if (query.strip ().length == 0)
61
var model = index.get_model ();
62
var iter = model.get_first_iter ();
63
var end_iter = model.get_last_iter ();
65
var result = new SList<Dee.ModelIter> ();
66
while (iter != end_iter)
68
result.prepend (iter);
69
iter = model.next (iter);
75
var term_list = Object.new (typeof (Dee.TermList)) as Dee.TermList;
76
analyzer.tokenize (query, term_list);
77
var matches = new Sequence<Dee.ModelIter> ();
79
uint num_terms = term_list.num_terms ();
80
for (uint i = 0; i < num_terms; i++)
82
var rs = index.lookup (term_list.get_term (i),
83
i < num_terms - 1 ? Dee.TermMatchFlag.EXACT : Dee.TermMatchFlag.PREFIX);
85
bool first_pass = i == 0;
86
CompareDataFunc<Dee.ModelIter> cmp_func = (a, b) =>
88
return a == b ? 0 : ((void*) a > (void*) b ? 1 : -1);
90
// intersect the results (cause we want to AND the terms)
91
var remaining = new Sequence<Dee.ModelIter> ();
92
foreach (var item in rs)
95
matches.insert_sorted (item, cmp_func);
96
else if (matches.lookup (item, cmp_func) != null)
97
remaining.insert_sorted (item, cmp_func);
99
if (!first_pass) matches = (owned) remaining;
100
// final result set empty already?
101
if (matches.get_begin_iter () == matches.get_end_iter ()) break;
104
var result = new SList<Dee.ModelIter> ();
105
var iter = matches.get_begin_iter ();
106
var end_iter = matches.get_end_iter ();
107
while (iter != end_iter)
109
result.prepend (iter.get ());