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 228 - (show annotations) (download) (as text)
Sun Jul 12 09:01:48 2009 UTC (15 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 9254 byte(s)
Tidy up and fix comments and include files.

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

Properties

Name Value
cvs:description Results data type.