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

Last change on this file since 1014 was 439, checked in by sjboddie, 25 years ago

renamed mg-1.3d directory mg

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 5.1 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 439 1999-08-10 21:23:37Z sjboddie $
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 1999/08/10 21:18:01 sjboddie
35 renamed mg-1.3d directory mg
36
37 Revision 1.2 1999/07/01 09:30:48 rjmcnab
38 Changes for better match reporting.
39
40 Revision 1.1 1998/11/17 09:34:47 rjmcnab
41 *** empty log message ***
42
43 * Revision 1.3 1994/10/20 03:56:50 tes
44 * I have rewritten the boolean query optimiser and abstracted out the
45 * components of the boolean query.
46 *
47 * Revision 1.2 1994/09/20 04:41:37 tes
48 * For version 1.1
49 *
50 */
51
52static char *RCSID = "$Id: lists.c 439 1999-08-10 21:23:37Z sjboddie $";
53
54
55
56
57
58/*
59 * Make a DocList large enough to hold num entries
60 */
61DocList *
62MakeDocList (int num)
63{
64 DocList *d;
65 if (!(d = Xmalloc (sizeof (DocList) + sizeof (DocEntry) * (num - 1))))
66 return (NULL);
67 d->num = 0;
68 d->total_retrieved = 0;
69 d->is_approx = 0;
70 return (d);
71}
72
73
74/*
75 * Change the size of a DocList so that it can hold num entries
76 */
77DocList *
78ResizeDocList (DocList * d, int num)
79{
80 if (!(d = Xrealloc (d, sizeof (DocList) + sizeof (DocEntry) * (num - 1))))
81 return (NULL);
82 return (d);
83}
84
85
86/* IntersectLists () */
87/* Returns the intersection of List1 and List2 by deleting from List1 all */
88/* entries not in List2. All of List2 is freed, and the nodes of List1 not */
89/* included in the resultant list are freed. */
90/* On exit the intersection of the lists is returned, or NULL on empty */
91/* intersection. */
92/* Assumes that both lists are ordered on increasing Value. */
93DocList *
94IntersectLists (DocList * List1, DocList * List2)
95{
96 DocEntry *s1, *d1, *s2;
97 if (!List2 || !List1)
98 {
99 if (List1)
100 Xfree (List1);
101 if (List2)
102 Xfree (List2);
103 return (MakeDocList (0));
104 }
105 d1 = s1 = List1->DE;
106 s2 = List2->DE;
107 while (s1 - List1->DE < List1->num && s2 - List2->DE < List2->num)
108 {
109 if (s1->DocNum == s2->DocNum)
110 *d1++ = *s1++;
111 if (s1 - List1->DE < List1->num)
112 while (s2 - List2->DE < List2->num && s2->DocNum < s1->DocNum)
113 s2++;
114 if (s2 - List2->DE < List2->num)
115 while (s1 - List1->DE < List1->num && s1->DocNum < s2->DocNum)
116 s1++;
117 }
118 List1->num = d1 - List1->DE;
119 Xfree (List2);
120 return (List1);
121}
122
123
124/* DiffLists () */
125/* Returns the difference of List1 and List2 by deleting from List1 all */
126/* entries in List2. All of List2 is freed, and the nodes of List1 not */
127/* included in the resultant list are freed. */
128/* On exit the differrence of the lists is returned, or NULL on empty */
129/* intersection. */
130/* Assumes that both lists are ordered on increasing Value. */
131DocList *
132DiffLists (DocList * List1, DocList * List2)
133{
134 DocEntry *s1, *d1, *s2;
135 if (!List1)
136 {
137 if (List2)
138 Xfree (List2);
139 return (MakeDocList (0));
140 }
141 if (!List2)
142 return (List1);
143 d1 = s1 = List1->DE;
144 s2 = List2->DE;
145 while (s1 - List1->DE < List1->num)
146 {
147 if (s2 - List2->DE == List2->num)
148 *d1++ = *s1++;
149 else
150 {
151 if (s1->DocNum == s2->DocNum)
152 {
153 s1++;
154 s2++;
155 }
156 else if (s1->DocNum < s2->DocNum)
157 *d1++ = *s1++;
158 else
159 s2++;
160 }
161 }
162 List1->num = d1 - List1->DE;
163 Xfree (List2);
164 return (List1);
165}
166
167/* MergeLists () */
168/* Finds the union of two lists and returns the head of the new list formed. */
169/* Assumes that both lists are ordered on increasing Value. */
170DocList *
171MergeLists (DocList * List1, DocList * List2)
172{
173 DocList *NewList;
174 DocEntry *d, *s1, *s2;
175 if (!List1)
176 {
177 if (List2)
178 return (List2);
179 else
180 return (MakeDocList (0));
181 }
182 if (!List2)
183 return (List1);
184 if (!(NewList = MakeDocList (List1->num + List2->num)))
185 {
186 Xfree (List1);
187 Xfree (List2);
188 return (NULL);
189 }
190
191 s1 = List1->DE;
192 s2 = List2->DE;
193 d = NewList->DE;
194 while (s1 - List1->DE < List1->num || s2 - List2->DE < List2->num)
195 {
196 if (s1 - List1->DE >= List1->num)
197 *d++ = *s2++;
198 else if (s2 - List2->DE >= List2->num)
199 *d++ = *s1++;
200 else if (s1->DocNum == s2->DocNum)
201 {
202 *d = *s1++;
203 (d++)->Weight += (s2++)->Weight;
204 }
205 else if (s1->DocNum < s2->DocNum)
206 *d++ = *s1++;
207 else
208 *d++ = *s2++;
209 }
210 NewList->num = d - NewList->DE;
211 Xfree (List1);
212 Xfree (List2);
213 return (NewList);
214}
Note: See TracBrowser for help on using the repository browser.