summaryrefslogtreecommitdiffstats
path: root/debian/htdig/htdig-3.2.0b6/htsearch/NotQuery.cc
blob: 11a55c70d9fc9acbb4bffa1a1f091b481a354716 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// 
// NotQuery.cc
//
// NotQuery: 'not' query operator (n-ary not!)
//           i.e. not(a, b, c, d...) == a except (b or c or d or...)
// 
// 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: NotQuery.cc,v 1.4 2004/05/28 13:15:24 lha Exp $
//


#include "NotQuery.h"
//
//	l	r	not
//	-------------------------
//	0	0	0
//	0	b	0
//	0	x	0
//	a	0	a
//	a	b	diff(a,b)
//	a	x	a
//	x	0	x
//	x	b	x
//	x	x	x
// 
// note l is the first operand, r is the rest
// i.e. l = 0 => not = 0
//      l = x => not = x
//      r = 0 => not = l
//      r = x => not = l
//      subtract otherwise
//
ResultList *
NotQuery::Evaluate()
{
	operands.Start_Get();
	Query *operand = (Query *) operands.Get_Next();
	ResultList *result = 0;
	ResultList *positive = operand->GetResults();
	if(positive)
	{
		List negative;
		if(!positive->IsIgnore())
		{
			operand = (Query *) operands.Get_Next();
			while(operand)
			{
				ResultList *next = operand->GetResults();
				if(next && !next->IsIgnore())
				{
					negative.Add(next);
				}
				operand = (Query *) operands.Get_Next();
			}
		}
		if(negative.Count())
		{
			result = Subtract(*positive, negative);
			negative.Release();
		}
		else
		{
			result = new ResultList(*positive);
		}
	}
	return result;
}

//
// make a result list containing all matches in positive
// with docId absent from negatives
//
ResultList *
NotQuery::Subtract(const ResultList &positive, const List &negatives)
{
	ResultList *result = 0;
	DictionaryCursor pc;
	positive.Start_Get(pc);
	DocMatch *match = (DocMatch *)positive.Get_NextElement(pc);
	while(match)
	{
		bool confirm = true;
		ListCursor lc;
		negatives.Start_Get(lc);
		ResultList *negative = (ResultList *)negatives.Get_Next(lc);
		while(confirm && negative)
		{
			if(negative->exists(match->GetId()))
			{
				confirm = false;
			}
			negative = (ResultList *)negatives.Get_Next(lc);
		}
		if(confirm)
		{
			if(!result)
			{
				result = new ResultList;
			}
			result->add(new DocMatch(*match));
		}
		match = (DocMatch *)positive.Get_NextElement(pc);
	}
	return result;
}