source: gsdl/trunk/trunk/mg/src/text/lists.c@ 16583

Last change on this file since 16583 was 16583, checked in by davidb, 16 years ago

Undoing change commited in r16582

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 5.2 KB
Line 
1/**************************************************************************
2 *
3 * lists.c -- List processing functions for boolean queries
4 * Copyright (C) 1994 Neil Sharman, Alistair Moffat and Lachlan Andrew
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * $Id: lists.c 16583 2008-07-29 10:20:36Z davidb $
21 *
22 **************************************************************************/
23
24#include "sysfuncs.h"
25
26#include "memlib.h"
27
28#include "lists.h"
29#include "local_strings.h"
30#include "locallib.h"
31
32/*
33 $Log$
34 Revision 1.1 2003/02/20 21:18:24 mdewsnip
35 Addition of MG package for search and retrieval
36
37 Revision 1.1 1999/08/10 21:18:01 sjboddie
38 renamed mg-1.3d directory mg
39
40 Revision 1.2 1999/07/01 09:30:48 rjmcnab
41 Changes for better match reporting.
42
43 Revision 1.1 1998/11/17 09:34:47 rjmcnab
44 *** empty log message ***
45
46 * Revision 1.3 1994/10/20 03:56:50 tes
47 * I have rewritten the boolean query optimiser and abstracted out the
48 * components of the boolean query.
49 *
50 * Revision 1.2 1994/09/20 04:41:37 tes
51 * For version 1.1
52 *
53 */
54
55static char *RCSID = "$Id: lists.c 16583 2008-07-29 10:20:36Z davidb $";
56
57
58
59
60
61/*
62 * Make a DocList large enough to hold num entries
63 */
64DocList *
65MakeDocList (int num)
66{
67 DocList *d;
68 if (!(d = Xmalloc (sizeof (DocList) + sizeof (DocEntry) * (num - 1))))
69 return (NULL);
70 d->num = 0;
71 d->total_retrieved = 0;
72 d->is_approx = 0;
73 return (d);
74}
75
76
77/*
78 * Change the size of a DocList so that it can hold num entries
79 */
80DocList *
81ResizeDocList (DocList * d, int num)
82{
83 if (!(d = Xrealloc (d, sizeof (DocList) + sizeof (DocEntry) * (num - 1))))
84 return (NULL);
85 return (d);
86}
87
88
89/* IntersectLists () */
90/* Returns the intersection of List1 and List2 by deleting from List1 all */
91/* entries not in List2. All of List2 is freed, and the nodes of List1 not */
92/* included in the resultant list are freed. */
93/* On exit the intersection of the lists is returned, or NULL on empty */
94/* intersection. */
95/* Assumes that both lists are ordered on increasing Value. */
96DocList *
97IntersectLists (DocList * List1, DocList * List2)
98{
99 DocEntry *s1, *d1, *s2;
100 if (!List2 || !List1)
101 {
102 if (List1)
103 Xfree (List1);
104 if (List2)
105 Xfree (List2);
106 return (MakeDocList (0));
107 }
108 d1 = s1 = List1->DE;
109 s2 = List2->DE;
110 while (s1 - List1->DE < List1->num && s2 - List2->DE < List2->num)
111 {
112 if (s1->DocNum == s2->DocNum)
113 *d1++ = *s1++;
114 if (s1 - List1->DE < List1->num)
115 while (s2 - List2->DE < List2->num && s2->DocNum < s1->DocNum)
116 s2++;
117 if (s2 - List2->DE < List2->num)
118 while (s1 - List1->DE < List1->num && s1->DocNum < s2->DocNum)
119 s1++;
120 }
121 List1->num = d1 - List1->DE;
122 Xfree (List2);
123 return (List1);
124}
125
126
127/* DiffLists () */
128/* Returns the difference of List1 and List2 by deleting from List1 all */
129/* entries in List2. All of List2 is freed, and the nodes of List1 not */
130/* included in the resultant list are freed. */
131/* On exit the differrence of the lists is returned, or NULL on empty */
132/* intersection. */
133/* Assumes that both lists are ordered on increasing Value. */
134DocList *
135DiffLists (DocList * List1, DocList * List2)
136{
137 DocEntry *s1, *d1, *s2;
138 if (!List1)
139 {
140 if (List2)
141 Xfree (List2);
142 return (MakeDocList (0));
143 }
144 if (!List2)
145 return (List1);
146 d1 = s1 = List1->DE;
147 s2 = List2->DE;
148 while (s1 - List1->DE < List1->num)
149 {
150 if (s2 - List2->DE == List2->num)
151 *d1++ = *s1++;
152 else
153 {
154 if (s1->DocNum == s2->DocNum)
155 {
156 s1++;
157 s2++;
158 }
159 else if (s1->DocNum < s2->DocNum)
160 *d1++ = *s1++;
161 else
162 s2++;
163 }
164 }
165 List1->num = d1 - List1->DE;
166 Xfree (List2);
167 return (List1);
168}
169
170/* MergeLists () */
171/* Finds the union of two lists and returns the head of the new list formed. */
172/* Assumes that both lists are ordered on increasing Value. */
173DocList *
174MergeLists (DocList * List1, DocList * List2)
175{
176 DocList *NewList;
177 DocEntry *d, *s1, *s2;
178 if (!List1)
179 {
180 if (List2)
181 return (List2);
182 else
183 return (MakeDocList (0));
184 }
185 if (!List2)
186 return (List1);
187 if (!(NewList = MakeDocList (List1->num + List2->num)))
188 {
189 Xfree (List1);
190 Xfree (List2);
191 return (NULL);
192 }
193
194 s1 = List1->DE;
195 s2 = List2->DE;
196 d = NewList->DE;
197 while (s1 - List1->DE < List1->num || s2 - List2->DE < List2->num)
198 {
199 if (s1 - List1->DE >= List1->num)
200 *d++ = *s2++;
201 else if (s2 - List2->DE >= List2->num)
202 *d++ = *s1++;
203 else if (s1->DocNum == s2->DocNum)
204 {
205 *d = *s1++;
206 (d++)->Weight += (s2++)->Weight;
207 }
208 else if (s1->DocNum < s2->DocNum)
209 *d++ = *s1++;
210 else
211 *d++ = *s2++;
212 }
213 NewList->num = d - NewList->DE;
214 Xfree (List1);
215 Xfree (List2);
216 return (NewList);
217}
Note: See TracBrowser for help on using the repository browser.