summaryrefslogtreecommitdiffstats
path: root/debian/htdig/htdig-3.2.0b6/htsearch/AndQuery.cc
diff options
context:
space:
mode:
Diffstat (limited to 'debian/htdig/htdig-3.2.0b6/htsearch/AndQuery.cc')
-rw-r--r--debian/htdig/htdig-3.2.0b6/htsearch/AndQuery.cc150
1 files changed, 150 insertions, 0 deletions
diff --git a/debian/htdig/htdig-3.2.0b6/htsearch/AndQuery.cc b/debian/htdig/htdig-3.2.0b6/htsearch/AndQuery.cc
new file mode 100644
index 00000000..a1a608e5
--- /dev/null
+++ b/debian/htdig/htdig-3.2.0b6/htsearch/AndQuery.cc
@@ -0,0 +1,150 @@
+//
+// AndQuery.cc
+//
+// AndQuery: an operator query that does 'and' combination
+//
+// Part of the ht://Dig package <http://www.htdig.org/>
+// Copyright (c) 1995-2004 The ht://Dig Group
+// For copyright details, see the file COPYING in your distribution
+// or the GNU Library General Public License (LGPL) version 2 or later
+// <http://www.gnu.org/copyleft/lgpl.html>
+//
+// $Id: AndQuery.cc,v 1.4 2004/05/28 13:15:24 lha Exp $
+//
+
+
+#include "AndQuery.h"
+//
+// l r and
+// ----------------------
+// 0 0 0
+// 0 b 0
+// 0 x 0
+// a 0 0
+// a b intersect(a,b)
+// a x a
+// x 0 0
+// x b b
+// x x x
+//
+// i.e. some 0 => 0
+// ignores can be left out of intersection
+// the shorter of the result lists is put apart for intersection
+// this optimises the intersection process
+//
+
+ResultList *
+AndQuery::Evaluate()
+{
+ ResultList *result = 0;
+ ResultList *shorter = 0;
+
+ operands.Start_Get();
+ Query *operand = (Query *) operands.Get_Next();
+ while(operand && !shorter)
+ {
+ result = operand->GetResults();
+ if(!result)
+ {
+ break;
+ }
+ if(!result->IsIgnore())
+ {
+ shorter = result;
+ }
+ operand = (Query *) operands.Get_Next();
+ }
+ if(shorter)
+ {
+ List longer;
+ while(operand && result)
+ {
+ result = operand->GetResults();
+ if(result && !result->IsIgnore())
+ {
+ if(result->Count() < shorter->Count())
+ {
+ longer.Add(shorter);
+ shorter = result;
+ }
+ else
+ {
+ longer.Add(result);
+ }
+ }
+ operand = (Query *) operands.Get_Next();
+ }
+ if(longer.Count())
+ {
+ result = Intersection(*shorter, longer);
+ longer.Release();
+ }
+ else
+ {
+ result = new ResultList(*shorter);
+ }
+ }
+ return result;
+}
+
+//
+// return a result list containing only the matches common to
+// all input parameters.
+//
+// l is iterated, matches from l are searched in all elements of rs
+//
+//
+// foreach match in shorter
+// confirm the match in each lists
+// if confirmed
+// copy all matches in result
+//
+// the shorter of the input lists is assumed to be in the first parameter
+// this is a modest optimisation in order to minimise iteration
+//
+
+ResultList *
+AndQuery::Intersection(const ResultList &shorter, const List &lists)
+{
+ ResultList *result = 0;
+ DictionaryCursor c;
+ shorter.Start_Get(c);
+ DocMatch *match = (DocMatch *)shorter.Get_NextElement(c);
+ while(match)
+ {
+ List confirms;
+
+ ListCursor lc;
+ lists.Start_Get(lc);
+ ResultList *list = (ResultList *)lists.Get_Next(lc);
+ while(list)
+ {
+ DocMatch *confirm = list->find(match->GetId());
+ if(confirm)
+ {
+ confirms.Add(confirm);
+ }
+ list = (ResultList *)lists.Get_Next(lc);
+ }
+ if(confirms.Count() == lists.Count())
+ {
+ if(!result)
+ {
+ result = new ResultList;
+ }
+ DocMatch *copy = new DocMatch(*match);
+ confirms.Start_Get();
+ DocMatch *confirm = (DocMatch *)confirms.Get_Next();
+ while(confirm)
+ {
+ copy->Merge(*confirm);
+ confirm = (DocMatch *)confirms.Get_Next();
+ }
+ result->add(copy);
+ }
+ confirms.Release();
+ match = (DocMatch *)shorter.Get_NextElement(c);
+ }
+ return result;
+}
+