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 214 - (show annotations) (download) (as text)
Thu Jul 2 17:49:16 2009 UTC (15 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 9128 byte(s)
Fix some gcc pedantic warnings.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/results.c,v 1.16 2009-07-02 17:49:16 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
32 #define RESULTS_INCREMENT 16
33 #define QUEUE_INCREMENT 10240
34
35
36 /*+ A queue of results. +*/
37 typedef struct _Queue
38 {
39 uint32_t alloced; /*+ The amount of space allocated for results in the array. +*/
40 uint32_t number; /*+ The number of occupied results in the array. +*/
41 Result **xqueue; /*+ An array of pointers to parts of the results structure. +*/
42 }
43 Queue;
44
45 /*+ The queue of nodes. +*/
46 static Queue queue={0,0,NULL};
47
48
49 /*++++++++++++++++++++++++++++++++++++++
50 Allocate a new results list.
51
52 Results *NewResultsList Returns the results list.
53
54 int nbins The number of bins in the results array.
55 ++++++++++++++++++++++++++++++++++++++*/
56
57 Results *NewResultsList(int nbins)
58 {
59 Results *results;
60 uint32_t i;
61
62 results=(Results*)malloc(sizeof(Results));
63
64 results->nbins=1;
65 results->mask=~0;
66
67 while(nbins>>=1)
68 {
69 results->mask<<=1;
70 results->nbins<<=1;
71 }
72
73 results->mask=~results->mask;
74
75 results->alloced=RESULTS_INCREMENT;
76 results->number=0;
77
78 results->count=(uint32_t*)malloc(results->nbins*sizeof(uint32_t));
79 results->point=(Result***)malloc(results->nbins*sizeof(Result**));
80
81 for(i=0;i<results->nbins;i++)
82 {
83 results->count[i]=0;
84
85 results->point[i]=(Result**)malloc(results->alloced*sizeof(Result*));
86 }
87
88 results->data=(Result**)malloc(1*sizeof(Result*));
89 results->data[0]=(Result*)malloc(results->nbins*RESULTS_INCREMENT*sizeof(Result));
90
91 results->start=NO_NODE;
92 results->finish=NO_NODE;
93
94 return(results);
95 }
96
97
98 /*++++++++++++++++++++++++++++++++++++++
99 Allocate a new results list.
100
101 Results *results The results list to be destroyed.
102 ++++++++++++++++++++++++++++++++++++++*/
103
104 void FreeResultsList(Results *results)
105 {
106 int i,c=(results->number-1)/(results->nbins*RESULTS_INCREMENT);
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 uint32_t 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 i,j=0,c=(results->number-1)/(results->nbins*RESULTS_INCREMENT);
239
240 for(i=0;i<=c;i++)
241 {
242 j=result-results->data[i];
243
244 if(j>=0 && j<(results->nbins*RESULTS_INCREMENT))
245 break;
246 }
247
248 if(++j>=(results->nbins*RESULTS_INCREMENT))
249 {i++;j=0;}
250
251 if((i*(results->nbins*RESULTS_INCREMENT)+j)>=results->number)
252 return(NULL);
253
254 return(&results->data[i][j]);
255 }
256
257
258 /*++++++++++++++++++++++++++++++++++++++
259 Insert an item into the queue in the right order.
260
261 Result *result The result to insert into the queue.
262 ++++++++++++++++++++++++++++++++++++++*/
263
264 void insert_in_queue(Result *result)
265 {
266 int start=0;
267 int end=queue.number-1;
268 int mid;
269 int insert=-1;
270
271 /* Check that the array is allocated. */
272
273 if(!queue.xqueue)
274 {
275 queue.alloced=QUEUE_INCREMENT;
276 queue.number=0;
277 queue.xqueue=(Result**)malloc(queue.alloced*sizeof(Result*));
278 }
279
280 /* Check that the arrays have enough space. */
281
282 if(queue.number==queue.alloced)
283 {
284 queue.alloced+=QUEUE_INCREMENT;
285 queue.xqueue=(Result**)realloc((void*)queue.xqueue,queue.alloced*sizeof(Result*));
286 }
287
288 /* Binary search - search key may not match, new insertion point required
289 *
290 * # <- start | Check mid and move start or end if it doesn't match
291 * # |
292 * # | Since there may not be an exact match we must set end=mid
293 * # <- mid | or start=mid because we know that mid doesn't match.
294 * # |
295 * # | Eventually end=start+1 and the insertion point is before
296 * # <- end | end (since it cannot be before the initial start or end).
297 */
298
299 if(queue.number==0) /* There is nothing in the queue */
300 insert=0;
301 else if(result->sortby>queue.xqueue[start]->sortby) /* Check key is not before start */
302 insert=start;
303 else if(result->sortby<queue.xqueue[end]->sortby) /* Check key is not after end */
304 insert=end+1;
305 else if(queue.number==2) /* Must be between them */
306 insert=1;
307 else
308 {
309 do
310 {
311 mid=(start+end)/2; /* Choose mid point */
312
313 if(queue.xqueue[mid]->sortby>result->sortby) /* Mid point is too low */
314 start=mid;
315 else if(queue.xqueue[mid]->sortby<result->sortby) /* Mid point is too high */
316 end=mid;
317 else /* Mid point is correct */
318 {
319 if(queue.xqueue[mid]==result)
320 return;
321
322 insert=mid;
323 break;
324 }
325 }
326 while((end-start)>1);
327
328 if(insert==-1)
329 insert=end;
330 }
331
332 /* Shuffle the array up */
333
334 if(insert!=queue.number)
335 memmove(&queue.xqueue[insert+1],&queue.xqueue[insert],(queue.number-insert)*sizeof(Result*));
336
337 /* Insert the new entry */
338
339 queue.xqueue[insert]=result;
340
341 queue.number++;
342 }
343
344
345 /*++++++++++++++++++++++++++++++++++++++
346 Pop an item from the end of the queue.
347
348 Result *pop_from_queue Returns the top item.
349
350 Results *results The set of results that the queue is processing.
351 ++++++++++++++++++++++++++++++++++++++*/
352
353 Result *pop_from_queue()
354 {
355 if(queue.number)
356 return(queue.xqueue[--queue.number]);
357 else
358 return(NULL);
359 }

Properties

Name Value
cvs:description Results data type.