Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /trunk/src/results.c
Parent Directory
|
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)
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. |