Routino SVN Repository Browser

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

ViewVC logotype

Annotation of /trunk/src/results.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 116 - (hide annotations) (download) (as text)
Tue Feb 10 19:49:26 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 8248 byte(s)
Added a new 'sortby' entry to the Result.
Changed node_t to index_t.

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

Properties

Name Value
cvs:description Results data type.