Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/src/results.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 213 - (show annotations) (download) (as text)
Thu Jul 2 16:33:31 2009 UTC (15 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 9109 byte(s)
Removed unused header files, change assert statements, tidy some code.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/results.c,v 1.15 2009-07-02 16:33:31 amb Exp $
3
4 Result data type functions.
5
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2008,2009 Andrew M. Bishop
9
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU Affero General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Affero General Public License for more details.
19
20 You should have received a copy of the GNU Affero General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 ***************************************/
23
24
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include "results.h"
29
30
31 #define RESULTS_INCREMENT 16
32 #define QUEUE_INCREMENT 10240
33
34
35 /*+ A queue of results. +*/
36 typedef struct _Queue
37 {
38 uint32_t alloced; /*+ The amount of space allocated for results in the array. +*/
39 uint32_t number; /*+ The number of occupied results in the array. +*/
40 Result **xqueue; /*+ An array of pointers to parts of the results structure. +*/
41 }
42 Queue;
43
44 /*+ The queue of nodes. +*/
45 static Queue queue={0,0,NULL};
46
47
48 /*++++++++++++++++++++++++++++++++++++++
49 Allocate a new results list.
50
51 Results *NewResultsList Returns the results list.
52
53 int nbins The number of bins in the results array.
54 ++++++++++++++++++++++++++++++++++++++*/
55
56 Results *NewResultsList(int nbins)
57 {
58 Results *results;
59 int i;
60
61 results=(Results*)malloc(sizeof(Results));
62
63 results->nbins=1;
64 results->mask=~0;
65
66 while(nbins>>=1)
67 {
68 results->mask<<=1;
69 results->nbins<<=1;
70 }
71
72 results->mask=~results->mask;
73
74 results->alloced=RESULTS_INCREMENT;
75 results->number=0;
76
77 results->count=(uint32_t*)malloc(results->nbins*sizeof(uint32_t));
78 results->point=(Result***)malloc(results->nbins*sizeof(Result**));
79
80 for(i=0;i<results->nbins;i++)
81 {
82 results->count[i]=0;
83
84 results->point[i]=(Result**)malloc(results->alloced*sizeof(Result*));
85 }
86
87 results->data=(Result**)malloc(1*sizeof(Result*));
88 results->data[0]=(Result*)malloc(results->nbins*RESULTS_INCREMENT*sizeof(Result));
89
90 results->start=NO_NODE;
91 results->finish=NO_NODE;
92
93 return(results);
94 }
95
96
97 /*++++++++++++++++++++++++++++++++++++++
98 Allocate a new results list.
99
100 Results *results The results list to be destroyed.
101 ++++++++++++++++++++++++++++++++++++++*/
102
103 void FreeResultsList(Results *results)
104 {
105 int c=(results->number-1)/(results->nbins*RESULTS_INCREMENT);
106 int i;
107
108 for(i=c;i>=0;i--)
109 free(results->data[i]);
110
111 free(results->data);
112
113 for(i=0;i<results->nbins;i++)
114 free(results->point[i]);
115
116 free(results->point);
117
118 free(results->count);
119
120 free(results);
121 }
122
123
124 /*++++++++++++++++++++++++++++++++++++++
125 Insert a new result into the results data structure in the right order.
126
127 Result *insert_result Returns the result that has been inserted.
128
129 Results *results The results structure to insert into.
130
131 index_t node The node that is to be inserted into the results.
132 ++++++++++++++++++++++++++++++++++++++*/
133
134 Result *InsertResult(Results *results,index_t node)
135 {
136 int bin=node&results->mask;
137 int i;
138
139 /* Check that the arrays have enough space. */
140
141 if(results->count[bin]==results->alloced)
142 {
143 results->alloced+=RESULTS_INCREMENT;
144
145 for(i=0;i<results->nbins;i++)
146 results->point[i]=(Result**)realloc((void*)results->point[i],results->alloced*sizeof(Result*));
147 }
148
149 if(results->number && (results->number%RESULTS_INCREMENT)==0 && (results->number%(RESULTS_INCREMENT*results->nbins))==0)
150 {
151 int c=results->number/(results->nbins*RESULTS_INCREMENT);
152
153 results->data=(Result**)realloc((void*)results->data,(c+1)*sizeof(Result*));
154 results->data[c]=(Result*)malloc(results->nbins*RESULTS_INCREMENT*sizeof(Result));
155 }
156
157 /* Insert the new entry */
158
159 results->point[bin][results->count[bin]]=&results->data[results->number/(results->nbins*RESULTS_INCREMENT)][results->number%(results->nbins*RESULTS_INCREMENT)];
160
161 results->number++;
162
163 results->count[bin]++;
164
165 results->point[bin][results->count[bin]-1]->node=node;
166
167 return(results->point[bin][results->count[bin]-1]);
168 }
169
170
171 /*++++++++++++++++++++++++++++++++++++++
172 Zero the values in a result structure.
173
174 Result *result The result to modify.
175 ++++++++++++++++++++++++++++++++++++++*/
176
177 void ZeroResult(Result *result)
178 {
179 result->prev=NO_NODE;
180 result->next=NO_NODE;
181
182 result->score=0;
183 result->sortby=0;
184
185 result->segment=NULL;
186 }
187
188
189 /*++++++++++++++++++++++++++++++++++++++
190 Find a result; search by node.
191
192 Result *insert_result Returns the result that has been found.
193
194 Results *results The results structure to search.
195
196 index_t node The node that is to be found.
197 ++++++++++++++++++++++++++++++++++++++*/
198
199 Result *FindResult(Results *results,index_t node)
200 {
201 int bin=node&results->mask;
202 int i;
203
204 for(i=results->count[bin]-1;i>=0;i--)
205 if(results->point[bin][i]->node==node)
206 return(results->point[bin][i]);
207
208 return(NULL);
209 }
210
211
212 /*++++++++++++++++++++++++++++++++++++++
213 Find a result from a set of results.
214
215 Result *FirstResult Returns the first results from a set of results.
216
217 Results *results The set of results.
218 ++++++++++++++++++++++++++++++++++++++*/
219
220 Result *FirstResult(Results *results)
221 {
222 return(&results->data[0][0]);
223 }
224
225
226 /*++++++++++++++++++++++++++++++++++++++
227 Find a result from a set of results.
228
229 Result *NextResult Returns the next result from a set of results.
230
231 Results *results The set of results.
232
233 Result *result The previous result.
234 ++++++++++++++++++++++++++++++++++++++*/
235
236 Result *NextResult(Results *results,Result *result)
237 {
238 int c=(results->number-1)/(results->nbins*RESULTS_INCREMENT);
239 int i,j=0;
240
241 for(i=0;i<=c;i++)
242 {
243 j=(result-results->data[i]);
244
245 if(j>=0 && j<(results->nbins*RESULTS_INCREMENT))
246 break;
247 }
248
249 if(++j>=(results->nbins*RESULTS_INCREMENT))
250 {i++;j=0;}
251
252 if((i*(results->nbins*RESULTS_INCREMENT)+j)>=results->number)
253 return(NULL);
254
255 return(&results->data[i][j]);
256 }
257
258
259 /*++++++++++++++++++++++++++++++++++++++
260 Insert an item into the queue in the right order.
261
262 Result *result The result to insert into the queue.
263 ++++++++++++++++++++++++++++++++++++++*/
264
265 void insert_in_queue(Result *result)
266 {
267 int start=0;
268 int end=queue.number-1;
269 int mid;
270 int insert=-1;
271
272 /* Check that the array is allocated. */
273
274 if(!queue.xqueue)
275 {
276 queue.alloced=QUEUE_INCREMENT;
277 queue.number=0;
278 queue.xqueue=(Result**)malloc(queue.alloced*sizeof(Result*));
279 }
280
281 /* Check that the arrays have enough space. */
282
283 if(queue.number==queue.alloced)
284 {
285 queue.alloced+=QUEUE_INCREMENT;
286 queue.xqueue=(Result**)realloc((void*)queue.xqueue,queue.alloced*sizeof(Result*));
287 }
288
289 /* Binary search - search key may not match, new insertion point required
290 *
291 * # <- start | Check mid and move start or end if it doesn't match
292 * # |
293 * # | Since there may not be an exact match we must set end=mid
294 * # <- mid | or start=mid because we know that mid doesn't match.
295 * # |
296 * # | Eventually end=start+1 and the insertion point is before
297 * # <- end | end (since it cannot be before the initial start or end).
298 */
299
300 if(queue.number==0) /* There is nothing in the queue */
301 insert=0;
302 else if(result->sortby>queue.xqueue[start]->sortby) /* Check key is not before start */
303 insert=start;
304 else if(result->sortby<queue.xqueue[end]->sortby) /* Check key is not after end */
305 insert=end+1;
306 else if(queue.number==2) /* Must be between them */
307 insert=1;
308 else
309 {
310 do
311 {
312 mid=(start+end)/2; /* Choose mid point */
313
314 if(queue.xqueue[mid]->sortby>result->sortby) /* Mid point is too low */
315 start=mid;
316 else if(queue.xqueue[mid]->sortby<result->sortby) /* Mid point is too high */
317 end=mid;
318 else /* Mid point is correct */
319 {
320 if(queue.xqueue[mid]==result)
321 return;
322
323 insert=mid;
324 break;
325 }
326 }
327 while((end-start)>1);
328
329 if(insert==-1)
330 insert=end;
331 }
332
333 /* Shuffle the array up */
334
335 if(insert!=queue.number)
336 memmove(&queue.xqueue[insert+1],&queue.xqueue[insert],(queue.number-insert)*sizeof(Result*));
337
338 /* Insert the new entry */
339
340 queue.xqueue[insert]=result;
341
342 queue.number++;
343 }
344
345
346 /*++++++++++++++++++++++++++++++++++++++
347 Pop an item from the end of the queue.
348
349 Result *pop_from_queue Returns the top item.
350
351 Results *results The set of results that the queue is processing.
352 ++++++++++++++++++++++++++++++++++++++*/
353
354 Result *pop_from_queue()
355 {
356 if(queue.number)
357 return(queue.xqueue[--queue.number]);
358 else
359 return(NULL);
360 }

Properties

Name Value
cvs:description Results data type.