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 45 -
(show 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 | /*************************************** |
2 | $Header: /home/amb/CVS/routino/src/results.c,v 1.2 2009-01-17 17:49:58 amb Exp $ |
3 | |
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 | results->number=0; |
39 | |
40 | #if NBINS_RESULTS |
41 | for(i=0;i<NBINS_RESULTS;i++) |
42 | { |
43 | results->numbin[i]=0; |
44 | |
45 | results->offsets[i]=(uint32_t*)malloc(results->alloced*sizeof(uint32_t)); |
46 | } |
47 | |
48 | results->results=(Result*)malloc(results->alloced*NBINS_RESULTS*sizeof(Result)); |
49 | #else |
50 | results->offsets=(uint32_t*)malloc(results->alloced*sizeof(uint32_t)); |
51 | |
52 | results->data=(Result*)malloc(results->alloced*sizeof(Result)); |
53 | #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 | free(results->offsets[i]); |
74 | #else |
75 | free(results->offsets); |
76 | #endif |
77 | |
78 | free(results->results); |
79 | |
80 | 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 | int end=results->numbin[bin]-1; |
100 | uint32_t *offsetsp=results->offsets[bin]; |
101 | int i; |
102 | #else |
103 | int start=0; |
104 | int end=results->number-1; |
105 | uint32_t *offsetsp=results->offsets; |
106 | #endif |
107 | int mid; |
108 | int insert=-1; |
109 | |
110 | /* Check that the arrays have enough space. */ |
111 | |
112 | #ifdef NBINS_RESULTS |
113 | if(results->numbin[bin]==results->alloced) |
114 | { |
115 | results->alloced+=INCREMENT_RESULTS; |
116 | |
117 | for(i=0;i<NBINS_RESULTS;i++) |
118 | results->offsets[i]=(uint32_t*)realloc((void*)results->offsets[i],results->alloced*sizeof(uint32_t)); |
119 | |
120 | offsetsp=results->offsets[bin]; |
121 | |
122 | results->results=(Result*)realloc((void*)results->results,results->alloced*NBINS_RESULTS*sizeof(Result)); |
123 | } |
124 | #else |
125 | if(results->number==results->alloced) |
126 | { |
127 | results->alloced+=INCREMENT_RESULTS; |
128 | |
129 | 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 | #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 | if(end<start) /* There are no results */ |
149 | insert=start; |
150 | else if(node<results->results[offsetsp[start]].node) /* Check key is not before start */ |
151 | insert=start; |
152 | else if(node>results->results[offsetsp[end]].node) /* Check key is not after end */ |
153 | insert=end+1; |
154 | else |
155 | { |
156 | do |
157 | { |
158 | mid=(start+end)/2; /* Choose mid point */ |
159 | |
160 | if(results->results[offsetsp[mid]].node<node) /* Mid point is too low */ |
161 | start=mid; |
162 | else if(results->results[offsetsp[mid]].node>node) /* Mid point is too high */ |
163 | 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 | #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 | |
182 | /* Insert the new entry */ |
183 | |
184 | offsetsp[insert]=results->number; |
185 | |
186 | results->number++; |
187 | |
188 | #ifdef NBINS_RESULTS |
189 | results->numbin[bin]++; |
190 | #endif |
191 | |
192 | return(&results->results[offsetsp[insert]]); |
193 | } |
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 | int end=results->numbin[bin]-1; |
212 | uint32_t *offsetsp=results->offsets[bin]; |
213 | #else |
214 | int start=0; |
215 | int end=results->number-1; |
216 | uint32_t *offsetsp=results->offsets; |
217 | #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 | if(end<start) /* There are no results */ |
232 | return(NULL); |
233 | else if(node<results->results[offsetsp[start]].node) /* Check key is not before start */ |
234 | return(NULL); |
235 | else if(node>results->results[offsetsp[end]].node) /* Check key is not after end */ |
236 | return(NULL); |
237 | else |
238 | { |
239 | do |
240 | { |
241 | mid=(start+end)/2; /* Choose mid point */ |
242 | |
243 | if(results->results[offsetsp[mid]].node<node) /* Mid point is too low */ |
244 | start=mid+1; |
245 | else if(results->results[offsetsp[mid]].node>node) /* Mid point is too high */ |
246 | end=mid-1; |
247 | else /* Mid point is correct */ |
248 | return(&results->results[offsetsp[mid]]); |
249 | } |
250 | while((end-start)>1); |
251 | |
252 | if(results->results[offsetsp[start]].node==node) /* Start is correct */ |
253 | return(&results->results[offsetsp[start]]); |
254 | |
255 | if(results->results[offsetsp[end]].node==node) /* End is correct */ |
256 | return(&results->results[offsetsp[end]]); |
257 | } |
258 | |
259 | return(NULL); |
260 | } |
Properties
Name | Value |
---|---|
cvs:description | Results data type. |