summaryrefslogtreecommitdiffstats
path: root/debian/htdig/htdig-3.2.0b6/htsearch/OrQuery.cc
diff options
context:
space:
mode:
Diffstat (limited to 'debian/htdig/htdig-3.2.0b6/htsearch/OrQuery.cc')
-rw-r--r--debian/htdig/htdig-3.2.0b6/htsearch/OrQuery.cc126
1 files changed, 126 insertions, 0 deletions
diff --git a/debian/htdig/htdig-3.2.0b6/htsearch/OrQuery.cc b/debian/htdig/htdig-3.2.0b6/htsearch/OrQuery.cc
new file mode 100644
index 00000000..facbd9b0
--- /dev/null
+++ b/debian/htdig/htdig-3.2.0b6/htsearch/OrQuery.cc
@@ -0,0 +1,126 @@
+//
+// OrQuery.cc
+//
+// OrQuery: an operator query that merges all the results of its operands
+// i.e. does 'or' 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: OrQuery.cc,v 1.4 2004/05/28 13:15:24 lha Exp $
+//
+
+
+#include "OrQuery.h"
+//
+// return a ResultList containing an Or of the results of the operands
+// evaluate all operands to do so
+//
+// l r or
+// ---------------------
+// 0 0 0
+// 0 b b
+// 0 x x
+// a 0 a
+// a b union(a,b)
+// a x a
+// x 0 x
+// x b b
+// x x x
+//
+// i.e. nulls and ignored are left out union
+//
+// Note that all operands are evaluated
+// Ignored operands are not included in the operation
+// the longer input result list is passed separately to Union
+//
+
+ResultList *
+OrQuery::Evaluate()
+{
+ ResultList *result = 0;
+ ResultList *longer = 0;
+ List shorter;
+ int ignores = 0;
+ operands.Start_Get();
+ Query *operand = (Query *) operands.Get_Next();
+ while(operand)
+ {
+ ResultList *next = operand->GetResults();
+ if(next)
+ {
+ if(!next->IsIgnore())
+ {
+ if(!longer || longer->Count() < next->Count())
+ {
+ if(longer)
+ {
+ shorter.Add(longer);
+ }
+ longer = next;
+ }
+ else
+ {
+ shorter.Add(next);
+ }
+ }
+ else
+ {
+ ignores++;
+ }
+ }
+ operand = (Query *) operands.Get_Next();
+ }
+ if(longer)
+ {
+ result = Union(*longer, shorter);
+ shorter.Release();
+ }
+ else if(ignores == operands.Count())
+ {
+ result = new ResultList;
+ result->Ignore();
+ }
+ return result;
+}
+
+//
+// copy unique DocMatches to the resulting list
+// matches with the same docId are merged
+// the longer list is assumed to be the first parameter
+// this is a modest optimisation
+//
+ResultList *
+OrQuery::Union(const ResultList &longer, const List &lists)
+{
+ ResultList *result = new ResultList(longer);
+
+ ListCursor lc;
+ lists.Start_Get(lc);
+ ResultList *current = (ResultList *) lists.Get_Next(lc);
+ while(current)
+ {
+ DictionaryCursor c;
+ current->Start_Get(c);
+ DocMatch *match = (DocMatch *) current->Get_NextElement(c);
+ while(match)
+ {
+ DocMatch *previous = result->find(match->GetId());
+ if(previous)
+ {
+ previous->Merge(*match);
+ }
+ else
+ {
+ DocMatch *copy = new DocMatch(*match);
+ result->add(copy);
+ }
+ match = (DocMatch *) current->Get_NextElement(c);
+ }
+ current = (ResultList *) lists.Get_Next(lc);
+ }
+ return result;
+}