Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/results.c
Parent Directory
|
Revision Log
Revision 45 -
(hide annotations)
(download)
(as text)
Sat Jan 17 17:49:58 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 7112 byte(s)
Sat Jan 17 17:49:58 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 7112 byte(s)
Change the contents of the results data structure.
1 | amb | 29 | /*************************************** |
2 | amb | 45 | $Header: /home/amb/CVS/routino/src/results.c,v 1.2 2009-01-17 17:49:58 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 | /*++++++++++++++++++++++++++++++++++++++ | ||
23 | Allocate a new results list. | ||
24 | |||
25 | Results *NewResultsList Returns the results list. | ||
26 | ++++++++++++++++++++++++++++++++++++++*/ | ||
27 | |||
28 | Results *NewResultsList(void) | ||
29 | { | ||
30 | Results *results; | ||
31 | #if NBINS_RESULTS | ||
32 | int i; | ||
33 | #endif | ||
34 | |||
35 | results=(Results*)malloc(sizeof(Results)); | ||
36 | |||
37 | results->alloced=INCREMENT_RESULTS; | ||
38 | amb | 45 | results->number=0; |
39 | amb | 29 | |
40 | #if NBINS_RESULTS | ||
41 | for(i=0;i<NBINS_RESULTS;i++) | ||
42 | { | ||
43 | amb | 45 | results->numbin[i]=0; |
44 | |||
45 | results->offsets[i]=(uint32_t*)malloc(results->alloced*sizeof(uint32_t)); | ||
46 | amb | 29 | } |
47 | amb | 45 | |
48 | results->results=(Result*)malloc(results->alloced*NBINS_RESULTS*sizeof(Result)); | ||
49 | amb | 29 | #else |
50 | amb | 45 | results->offsets=(uint32_t*)malloc(results->alloced*sizeof(uint32_t)); |
51 | |||
52 | results->data=(Result*)malloc(results->alloced*sizeof(Result)); | ||
53 | amb | 29 | #endif |
54 | |||
55 | return(results); | ||
56 | } | ||
57 | |||
58 | |||
59 | /*++++++++++++++++++++++++++++++++++++++ | ||
60 | Allocate a new results list. | ||
61 | |||
62 | Results *results The results list to be destroyed. | ||
63 | ++++++++++++++++++++++++++++++++++++++*/ | ||
64 | |||
65 | void FreeResultsList(Results *results) | ||
66 | { | ||
67 | #if NBINS_RESULTS | ||
68 | int i; | ||
69 | #endif | ||
70 | |||
71 | #if NBINS_RESULTS | ||
72 | for(i=0;i<NBINS_RESULTS;i++) | ||
73 | amb | 45 | free(results->offsets[i]); |
74 | amb | 29 | #else |
75 | amb | 45 | free(results->offsets); |
76 | amb | 29 | #endif |
77 | |||
78 | amb | 45 | free(results->results); |
79 | |||
80 | amb | 29 | free(results); |
81 | } | ||
82 | |||
83 | |||
84 | /*++++++++++++++++++++++++++++++++++++++ | ||
85 | Insert a new result into the results data structure in the right order. | ||
86 | |||
87 | Result *insert_result Returns the result that has been inserted. | ||
88 | |||
89 | Results *results The results structure to insert into. | ||
90 | |||
91 | node_t node The node that is to be inserted into the results. | ||
92 | ++++++++++++++++++++++++++++++++++++++*/ | ||
93 | |||
94 | Result *InsertResult(Results *results,node_t node) | ||
95 | { | ||
96 | #ifdef NBINS_RESULTS | ||
97 | int bin=node%NBINS_RESULTS; | ||
98 | int start=0; | ||
99 | amb | 45 | int end=results->numbin[bin]-1; |
100 | uint32_t *offsetsp=results->offsets[bin]; | ||
101 | amb | 29 | int i; |
102 | #else | ||
103 | int start=0; | ||
104 | int end=results->number-1; | ||
105 | amb | 45 | uint32_t *offsetsp=results->offsets; |
106 | amb | 29 | #endif |
107 | int mid; | ||
108 | int insert=-1; | ||
109 | |||
110 | /* Check that the arrays have enough space. */ | ||
111 | |||
112 | amb | 45 | #ifdef NBINS_RESULTS |
113 | if(results->numbin[bin]==results->alloced) | ||
114 | amb | 29 | { |
115 | results->alloced+=INCREMENT_RESULTS; | ||
116 | |||
117 | for(i=0;i<NBINS_RESULTS;i++) | ||
118 | amb | 45 | results->offsets[i]=(uint32_t*)realloc((void*)results->offsets[i],results->alloced*sizeof(uint32_t)); |
119 | amb | 29 | |
120 | amb | 45 | offsetsp=results->offsets[bin]; |
121 | |||
122 | results->results=(Result*)realloc((void*)results->results,results->alloced*NBINS_RESULTS*sizeof(Result)); | ||
123 | } | ||
124 | amb | 29 | #else |
125 | amb | 45 | if(results->number==results->alloced) |
126 | { | ||
127 | results->alloced+=INCREMENT_RESULTS; | ||
128 | amb | 29 | |
129 | amb | 45 | results->offsets=(uint32_t*)realloc((void*)results->offsets[i],results->alloced*sizeof(uint32_t)); |
130 | |||
131 | offsetsp=results->offsets; | ||
132 | |||
133 | results->results=(Result*)realloc((void*)results->results,results->alloced*sizeof(Result)); | ||
134 | } | ||
135 | amb | 29 | #endif |
136 | |||
137 | /* Binary search - search key may not match, if not then insertion point required | ||
138 | * | ||
139 | * # <- start | Check mid and move start or end if it doesn't match | ||
140 | * # | | ||
141 | * # | Since there may not be an exact match we must set end=mid | ||
142 | * # <- mid | or start=mid because we know that mid doesn't match. | ||
143 | * # | | ||
144 | * # | Eventually end=start+1 and the insertion point is before | ||
145 | * # <- end | end (since it cannot be before the initial start or end). | ||
146 | */ | ||
147 | |||
148 | amb | 45 | if(end<start) /* There are no results */ |
149 | amb | 29 | insert=start; |
150 | amb | 45 | else if(node<results->results[offsetsp[start]].node) /* Check key is not before start */ |
151 | amb | 29 | insert=start; |
152 | amb | 45 | else if(node>results->results[offsetsp[end]].node) /* Check key is not after end */ |
153 | amb | 29 | insert=end+1; |
154 | else | ||
155 | { | ||
156 | do | ||
157 | { | ||
158 | amb | 45 | mid=(start+end)/2; /* Choose mid point */ |
159 | amb | 29 | |
160 | amb | 45 | if(results->results[offsetsp[mid]].node<node) /* Mid point is too low */ |
161 | amb | 29 | start=mid; |
162 | amb | 45 | else if(results->results[offsetsp[mid]].node>node) /* Mid point is too high */ |
163 | amb | 29 | end=mid; |
164 | else | ||
165 | assert(0); | ||
166 | } | ||
167 | while((end-start)>1); | ||
168 | |||
169 | insert=end; | ||
170 | } | ||
171 | |||
172 | /* Shuffle the array up */ | ||
173 | |||
174 | amb | 45 | #ifdef NBINS_RESULTS |
175 | if(insert!=results->numbin[bin]) | ||
176 | memmove(&offsetsp[insert+1],&offsetsp[insert],(results->numbin[bin]-insert)*sizeof(uint32_t)); | ||
177 | #else | ||
178 | if(insert!=results->number) | ||
179 | memmove(&offsetsp[insert+1],&offsetsp[insert],(results->number-insert)*sizeof(uint32_t)); | ||
180 | #endif | ||
181 | amb | 29 | |
182 | /* Insert the new entry */ | ||
183 | |||
184 | amb | 45 | offsetsp[insert]=results->number; |
185 | amb | 29 | |
186 | amb | 45 | results->number++; |
187 | amb | 29 | |
188 | amb | 45 | #ifdef NBINS_RESULTS |
189 | results->numbin[bin]++; | ||
190 | #endif | ||
191 | |||
192 | return(&results->results[offsetsp[insert]]); | ||
193 | amb | 29 | } |
194 | |||
195 | |||
196 | /*++++++++++++++++++++++++++++++++++++++ | ||
197 | Find a result, ordered by node. | ||
198 | |||
199 | Result *insert_result Returns the result that has been found. | ||
200 | |||
201 | Results *results The results structure to search. | ||
202 | |||
203 | node_t node The node that is to be found. | ||
204 | ++++++++++++++++++++++++++++++++++++++*/ | ||
205 | |||
206 | Result *FindResult(Results *results,node_t node) | ||
207 | { | ||
208 | #ifdef NBINS_RESULTS | ||
209 | int bin=node%NBINS_RESULTS; | ||
210 | int start=0; | ||
211 | amb | 45 | int end=results->numbin[bin]-1; |
212 | uint32_t *offsetsp=results->offsets[bin]; | ||
213 | amb | 29 | #else |
214 | int start=0; | ||
215 | int end=results->number-1; | ||
216 | amb | 45 | uint32_t *offsetsp=results->offsets; |
217 | amb | 29 | #endif |
218 | int mid; | ||
219 | |||
220 | /* Binary search - search key exact match only is required. | ||
221 | * | ||
222 | * # <- start | Check mid and move start or end if it doesn't match | ||
223 | * # | | ||
224 | * # | Since an exact match is wanted we can set end=mid-1 | ||
225 | * # <- mid | or start=mid+1 because we know that mid doesn't match. | ||
226 | * # | | ||
227 | * # | Eventually either end=start or end=start+1 and one of | ||
228 | * # <- end | start or end is the wanted one. | ||
229 | */ | ||
230 | |||
231 | amb | 45 | if(end<start) /* There are no results */ |
232 | amb | 29 | return(NULL); |
233 | amb | 45 | else if(node<results->results[offsetsp[start]].node) /* Check key is not before start */ |
234 | amb | 29 | return(NULL); |
235 | amb | 45 | else if(node>results->results[offsetsp[end]].node) /* Check key is not after end */ |
236 | amb | 29 | return(NULL); |
237 | else | ||
238 | { | ||
239 | do | ||
240 | { | ||
241 | amb | 45 | mid=(start+end)/2; /* Choose mid point */ |
242 | amb | 29 | |
243 | amb | 45 | if(results->results[offsetsp[mid]].node<node) /* Mid point is too low */ |
244 | amb | 29 | start=mid+1; |
245 | amb | 45 | else if(results->results[offsetsp[mid]].node>node) /* Mid point is too high */ |
246 | amb | 29 | end=mid-1; |
247 | amb | 45 | else /* Mid point is correct */ |
248 | return(&results->results[offsetsp[mid]]); | ||
249 | amb | 29 | } |
250 | while((end-start)>1); | ||
251 | |||
252 | amb | 45 | if(results->results[offsetsp[start]].node==node) /* Start is correct */ |
253 | return(&results->results[offsetsp[start]]); | ||
254 | amb | 29 | |
255 | amb | 45 | if(results->results[offsetsp[end]].node==node) /* End is correct */ |
256 | return(&results->results[offsetsp[end]]); | ||
257 | amb | 29 | } |
258 | |||
259 | return(NULL); | ||
260 | } |
Properties
Name | Value |
---|---|
cvs:description | Results data type. |