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 1289 -
(show annotations)
(download)
(as text)
Wed May 1 18:09:20 2013 UTC (11 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 6213 byte(s)
Wed May 1 18:09:20 2013 UTC (11 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 6213 byte(s)
Try to speed up the priority queue by allocating less memory and storing the score in the queue rather than in the result.
1 | /*************************************** |
2 | Result data type functions. |
3 | |
4 | Part of the Routino routing software. |
5 | ******************/ /****************** |
6 | This file Copyright 2008-2013 Andrew M. Bishop |
7 | |
8 | This program is free software: you can redistribute it and/or modify |
9 | it under the terms of the GNU Affero General Public License as published by |
10 | the Free Software Foundation, either version 3 of the License, or |
11 | (at your option) any later version. |
12 | |
13 | This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU Affero General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU Affero General Public License |
19 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | ***************************************/ |
21 | |
22 | |
23 | #include <string.h> |
24 | #include <stdlib.h> |
25 | |
26 | #include "results.h" |
27 | |
28 | #include "logging.h" |
29 | |
30 | |
31 | #define HASH_NODE_SEGMENT(node,segment) ((node)^(segment<<4)) |
32 | |
33 | |
34 | /*++++++++++++++++++++++++++++++++++++++ |
35 | Allocate a new results list. |
36 | |
37 | Results *NewResultsList Returns the results list. |
38 | |
39 | uint8_t log2bins The base 2 logarithm of the initial number of bins in the results array. |
40 | ++++++++++++++++++++++++++++++++++++++*/ |
41 | |
42 | Results *NewResultsList(uint8_t log2bins) |
43 | { |
44 | Results *results; |
45 | |
46 | results=(Results*)malloc(sizeof(Results)); |
47 | |
48 | results->nbins=1<<log2bins; |
49 | results->mask=results->nbins-1; |
50 | results->ncollisions=log2bins-4; |
51 | |
52 | results->number=0; |
53 | |
54 | results->count=(uint8_t*)calloc(results->nbins,sizeof(uint8_t)); |
55 | results->point=(Result**)calloc(results->nbins,sizeof(Result*)); |
56 | |
57 | results->ndata1=0; |
58 | results->ndata2=results->nbins>>2; |
59 | |
60 | results->data=NULL; |
61 | |
62 | results->start_node=NO_NODE; |
63 | results->prev_segment=NO_SEGMENT; |
64 | |
65 | results->finish_node=NO_NODE; |
66 | results->last_segment=NO_SEGMENT; |
67 | |
68 | return(results); |
69 | } |
70 | |
71 | |
72 | /*++++++++++++++++++++++++++++++++++++++ |
73 | Free a results list. |
74 | |
75 | Results *results The results list to be destroyed. |
76 | ++++++++++++++++++++++++++++++++++++++*/ |
77 | |
78 | void FreeResultsList(Results *results) |
79 | { |
80 | int i; |
81 | |
82 | for(i=0;i<results->ndata1;i++) |
83 | free(results->data[i]); |
84 | |
85 | free(results->data); |
86 | |
87 | free(results->point); |
88 | |
89 | free(results->count); |
90 | |
91 | free(results); |
92 | } |
93 | |
94 | |
95 | /*++++++++++++++++++++++++++++++++++++++ |
96 | Insert a new result into the results data structure in the right order. |
97 | |
98 | Result *InsertResult Returns the result that has been inserted. |
99 | |
100 | Results *results The results structure to insert into. |
101 | |
102 | index_t node The node that is to be inserted into the results. |
103 | |
104 | index_t segment The segment that is to be inserted into the results. |
105 | ++++++++++++++++++++++++++++++++++++++*/ |
106 | |
107 | Result *InsertResult(Results *results,index_t node,index_t segment) |
108 | { |
109 | Result *result; |
110 | int bin=HASH_NODE_SEGMENT(node,segment)&results->mask; |
111 | |
112 | /* Check if we have hit the limit on the number of collisions per bin */ |
113 | |
114 | if(results->count[bin]==results->ncollisions) |
115 | { |
116 | int i; |
117 | |
118 | results->nbins<<=1; |
119 | results->mask=results->nbins-1; |
120 | results->ncollisions++; |
121 | |
122 | results->count=(uint8_t*)realloc((void*)results->count,results->nbins*sizeof(uint8_t)); |
123 | results->point=(Result**)realloc((void*)results->point,results->nbins*sizeof(Result*)); |
124 | |
125 | for(i=0;i<results->nbins/2;i++) |
126 | { |
127 | Result *r=results->point[i]; |
128 | Result **bin1,**bin2; |
129 | |
130 | results->count[i] =0; |
131 | results->count[i+results->nbins/2]=0; |
132 | |
133 | bin1=&results->point[i]; |
134 | bin2=&results->point[i+results->nbins/2]; |
135 | |
136 | *bin1=NULL; |
137 | *bin2=NULL; |
138 | |
139 | while(r) |
140 | { |
141 | Result *rh=r->hashnext; |
142 | int newbin=HASH_NODE_SEGMENT(r->node,r->segment)&results->mask; |
143 | |
144 | r->hashnext=NULL; |
145 | |
146 | if(newbin==i) |
147 | { *bin1=r; bin1=&r->hashnext; } |
148 | else |
149 | { *bin2=r; bin2=&r->hashnext; } |
150 | |
151 | results->count[newbin]++; |
152 | |
153 | r=rh; |
154 | } |
155 | } |
156 | |
157 | bin=HASH_NODE_SEGMENT(node,segment)&results->mask; |
158 | } |
159 | |
160 | /* Check if we need more data space allocated */ |
161 | |
162 | if((results->number%results->ndata2)==0) |
163 | { |
164 | results->ndata1++; |
165 | |
166 | results->data=(Result**)realloc((void*)results->data,results->ndata1*sizeof(Result*)); |
167 | results->data[results->ndata1-1]=(Result*)malloc(results->ndata2*sizeof(Result)); |
168 | } |
169 | |
170 | /* Insert the new entry */ |
171 | |
172 | result=&results->data[results->ndata1-1][results->number%results->ndata2]; |
173 | |
174 | result->hashnext=results->point[bin]; |
175 | |
176 | results->point[bin]=result; |
177 | |
178 | results->count[bin]++; |
179 | |
180 | results->number++; |
181 | |
182 | /* Initialise the result */ |
183 | |
184 | result->node=node; |
185 | result->segment=segment; |
186 | |
187 | result->prev=NULL; |
188 | result->next=NULL; |
189 | |
190 | result->score=0; |
191 | |
192 | result->queued=NOT_QUEUED; |
193 | |
194 | return(result); |
195 | } |
196 | |
197 | |
198 | /*++++++++++++++++++++++++++++++++++++++ |
199 | Find a result; search by node and segment. |
200 | |
201 | Result *FindResult Returns the result that has been found. |
202 | |
203 | Results *results The results structure to search. |
204 | |
205 | index_t node The node that is to be found. |
206 | |
207 | index_t segment The segment that was used to reach this node. |
208 | ++++++++++++++++++++++++++++++++++++++*/ |
209 | |
210 | Result *FindResult(Results *results,index_t node,index_t segment) |
211 | { |
212 | Result *r; |
213 | int bin=HASH_NODE_SEGMENT(node,segment)&results->mask; |
214 | |
215 | r=results->point[bin]; |
216 | |
217 | while(r) |
218 | { |
219 | if(r->segment==segment && r->node==node) |
220 | break; |
221 | |
222 | r=r->hashnext; |
223 | } |
224 | |
225 | return(r); |
226 | } |
227 | |
228 | |
229 | /*++++++++++++++++++++++++++++++++++++++ |
230 | Find the first result from a set of results. |
231 | |
232 | Result *FirstResult Returns the first result. |
233 | |
234 | Results *results The set of results. |
235 | ++++++++++++++++++++++++++++++++++++++*/ |
236 | |
237 | Result *FirstResult(Results *results) |
238 | { |
239 | return(&results->data[0][0]); |
240 | } |
241 | |
242 | |
243 | /*++++++++++++++++++++++++++++++++++++++ |
244 | Find the next result from a set of results. |
245 | |
246 | Result *NextResult Returns the next result. |
247 | |
248 | Results *results The set of results. |
249 | |
250 | Result *result The previous result. |
251 | ++++++++++++++++++++++++++++++++++++++*/ |
252 | |
253 | Result *NextResult(Results *results,Result *result) |
254 | { |
255 | int i,j=0; |
256 | |
257 | for(i=0;i<results->ndata1;i++) |
258 | { |
259 | j=result-results->data[i]; |
260 | |
261 | if(j>=0 && j<results->ndata2) |
262 | break; |
263 | } |
264 | |
265 | if(++j>=results->ndata2) |
266 | {i++;j=0;} |
267 | |
268 | if((i*results->ndata2+j)>=results->number) |
269 | return(NULL); |
270 | |
271 | return(&results->data[i][j]); |
272 | } |
Properties
Name | Value |
---|---|
cvs:description | Results data type. |