87e926 | 2001-06-22 | Martin Nilsson | |
|
5d3ab5 | 2001-07-05 | Martin Nilsson | |
|
87e926 | 2001-06-22 | Martin Nilsson | |
|
5d3ab5 | 2001-07-05 | Martin Nilsson | | static function(string,int:string) blobfeeder(Search.Database.Base db, array words)
|
11aeec | 2001-05-25 | Johan Schön | | {
|
9be796 | 2001-07-04 | Martin Nilsson | | mapping state = mkmapping(words,allocate(sizeof(words)));
|
5d3ab5 | 2001-07-05 | Martin Nilsson | | return lambda( string word, int foo )
|
11aeec | 2001-05-25 | Johan Schön | | {
return db->get_blob(word, state[word]++);
};
}
|
dd6aa6 | 2001-06-01 | David Norlin | | static array(string) uniq_preserve_order(array(string) a) {
array(string) result = ({});
foreach (a, string s)
if (search(result, s) < 0)
result += ({ s });
return result;
}
|
965c0b | 2001-05-29 | Johan Schön | |
|
eac31a | 2001-05-31 | Johan Schön | | Search.ResultSet do_query_or(Search.Database.Base db,
|
965c0b | 2001-05-29 | Johan Schön | | array(string) words,
Search.RankingProfile ranking)
{
|
5d3ab5 | 2001-07-05 | Martin Nilsson | | Search.ResultSet result =
_WhiteFish.do_query_or(words,
ranking->field_ranking,
ranking->proximity_ranking,
ranking->cutoff,
blobfeeder(db, words));
werror("do_query_or(%{ %O %}) => %d hits\n", words, result->size());
return result;
|
965c0b | 2001-05-29 | Johan Schön | | }
|
eac31a | 2001-05-31 | Johan Schön | | Search.ResultSet do_query_and(Search.Database.Base db,
|
965c0b | 2001-05-29 | Johan Schön | | array(string) words,
Search.RankingProfile ranking)
{
|
5d3ab5 | 2001-07-05 | Martin Nilsson | | Search.ResultSet result =
_WhiteFish.do_query_and(words,
ranking->field_ranking,
ranking->proximity_ranking,
ranking->cutoff,
blobfeeder(db, words));
werror("do_query_and(%{ %O %}) => %d hits\n", words, result->size());
return result;
|
965c0b | 2001-05-29 | Johan Schön | | }
|
eac31a | 2001-05-31 | Johan Schön | | Search.ResultSet do_query_phrase(Search.Database.Base db,
|
195e68 | 2001-06-12 | David Norlin | | array(string) words,
Search.RankingProfile ranking)
|
965c0b | 2001-05-29 | Johan Schön | | {
|
5d3ab5 | 2001-07-05 | Martin Nilsson | | Search.ResultSet result =
_WhiteFish.do_query_phrase(words,
ranking->field_ranking,
blobfeeder(db, words));
werror("do_query_phrase(%{ %O %}) => %d hits\n", words, result->size());
return result;
|
965c0b | 2001-05-29 | Johan Schön | | }
|
788675 | 2001-05-31 | David Norlin | |
|
195e68 | 2001-06-12 | David Norlin | |
array(Search.ResultSet|array(string)) execute(Search.Database.Base db,
Search.Grammar.AbstractParser parser,
string query,
Search.RankingProfile defaultRanking)
|
788675 | 2001-05-31 | David Norlin | | {
Search.Grammar.ParseNode q = parser->parse(query);
|
6e0e90 | 2001-06-14 | David Norlin | |
|
788675 | 2001-05-31 | David Norlin | | q = Search.Grammar.optimize(q);
|
808758 | 2001-06-11 | David Norlin | |
|
195e68 | 2001-06-12 | David Norlin | | if (!q)
return ({ Search.ResultSet(), ({}) });
|
808758 | 2001-06-11 | David Norlin | |
|
788675 | 2001-05-31 | David Norlin | | string error = Search.Grammar.validate(q);
if (error)
throw (error);
|
3771f1 | 2001-05-31 | David Norlin | |
|
788675 | 2001-05-31 | David Norlin | | return class {
static Search.RankingProfile defaultRanking;
static Search.Database.Base db;
|
3771f1 | 2001-05-31 | David Norlin | |
|
788675 | 2001-05-31 | David Norlin | |
static Search.RankingProfile specialRanking;
static void create(Search.Database.Base _db, Search.RankingProfile _defaultRanking) {
db = _db;
defaultRanking = _defaultRanking;
specialRanking = defaultRanking->copy();
}
static constant ParseNode = Search.Grammar.ParseNode;
|
195e68 | 2001-06-12 | David Norlin | | static array(array(string)|string) words = ({ });
|
788675 | 2001-05-31 | David Norlin | | static array(Search.ResultSet) stack = ({ });
static void push(Search.ResultSet r) {
|
6e0e90 | 2001-06-14 | David Norlin | |
|
788675 | 2001-05-31 | David Norlin | | stack = ({ r }) + stack;
}
static Search.ResultSet pop() {
|
6e0e90 | 2001-06-14 | David Norlin | |
|
788675 | 2001-05-31 | David Norlin | | if (!sizeof(stack))
error("Very bad!");
Search.ResultSet r = stack[0];
stack = stack[1 .. ];
return r;
}
|
195e68 | 2001-06-12 | David Norlin | | array(Search.ResultSet|array(string)) execute(ParseNode q) {
|
788675 | 2001-05-31 | David Norlin | | exec(q);
if (sizeof(stack) != 1)
throw ("Stack should have exactly one item!");
|
195e68 | 2001-06-12 | David Norlin | | return ({ pop(), words });
|
788675 | 2001-05-31 | David Norlin | | }
void exec(ParseNode q) {
|
6e0e90 | 2001-06-14 | David Norlin | |
|
788675 | 2001-05-31 | David Norlin | | switch (q->op) {
case "and":
{
int first = 1;
foreach (q->children, ParseNode child)
if (child->op != "date") {
exec(child);
if (!first) {
Search.ResultSet r2 = pop();
Search.ResultSet r1 = pop();
push(r1 & r2);
}
else
first = 0;
}
}
break;
case "or":
int first = 1;
foreach (q->children, ParseNode child) {
exec(child);
if (!first) {
Search.ResultSet r2 = pop();
Search.ResultSet r1 = pop();
push(r1 | r2);
}
else
first = 0;
}
break;
case "date":
break;
case "text":
{
Search.RankingProfile ranking = defaultRanking;
if (q->field != "any") {
ranking = specialRanking;
int fieldID = db->get_field_id(q->field, 1);
if (!fieldID && q->field != "body") {
push(Search.ResultSet());
break;
}
ranking->field_ranking = allocate(66);
ranking->field_ranking[fieldID] = defaultRanking->field_ranking[fieldID];
}
int hasPlus = sizeof(q->plusWords) || sizeof(q->plusPhrases);
int hasOrdinary = sizeof(q->words) || sizeof(q->phrases);
int hasMinus = sizeof(q->minusWords) || sizeof(q->minusPhrases);
if (hasPlus) {
int first = 1;
if (sizeof(q->plusWords)) {
|
195e68 | 2001-06-12 | David Norlin | | words += q->plusWords;
|
788675 | 2001-05-31 | David Norlin | | push(do_query_and(db, q->plusWords, ranking));
first = 0;
}
foreach (q->plusPhrases, array(string) ph) {
|
195e68 | 2001-06-12 | David Norlin | | words += ph;
|
788675 | 2001-05-31 | David Norlin | | push(do_query_phrase(db, ph, ranking));
if (!first) {
Search.ResultSet r2 = pop();
Search.ResultSet r1 = pop();
push(r1 & r2);
}
first = 0;
}
}
if (hasOrdinary) {
int first = 1;
if (sizeof(q->words)) {
|
195e68 | 2001-06-12 | David Norlin | | words += q->words;
|
60ae23 | 2001-06-01 | David Norlin | | push(do_query_or(db, q->words, ranking));
|
788675 | 2001-05-31 | David Norlin | | first = 0;
}
foreach (q->phrases, array(string) ph) {
|
195e68 | 2001-06-12 | David Norlin | | words += ph;
|
788675 | 2001-05-31 | David Norlin | | push(do_query_phrase(db, ph, ranking));
if (!first) {
Search.ResultSet r2 = pop();
Search.ResultSet r1 = pop();
push(r1 | r2);
}
first = 0;
}
}
if (hasPlus && hasOrdinary) {
Search.ResultSet r2 = pop();
Search.ResultSet r1 = pop();
|
dd6aa6 | 2001-06-01 | David Norlin | |
push(r1->add_ranking(r2));
|
788675 | 2001-05-31 | David Norlin | | }
if ((hasPlus || hasOrdinary) && hasMinus) {
int first = 1;
if (sizeof(q->minusWords)) {
push(do_query_or(db, q->minusWords, ranking));
first = 0;
}
foreach (q->minusPhrases, array(string) ph) {
push(do_query_phrase(db, ph, ranking));
if (!first) {
Search.ResultSet r2 = pop();
Search.ResultSet r1 = pop();
push(r1 | r2);
}
first = 0;
}
Search.ResultSet r2 = pop();
Search.ResultSet r1 = pop();
push(r1 - r2);
}
}
break;
default:
error("Unknown type of ParseNode!");
}
}
|
3771f1 | 2001-05-31 | David Norlin | |
|
788675 | 2001-05-31 | David Norlin | | } (db, defaultRanking)->execute(q);
|
3771f1 | 2001-05-31 | David Norlin | | }
|