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/waysx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 214 - (hide 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: 8901 byte(s)
Fix some gcc pedantic warnings.

1 amb 110 /***************************************
2 amb 214 $Header: /home/amb/CVS/routino/src/waysx.c,v 1.10 2009-07-02 17:49:16 amb Exp $
3 amb 110
4     Extended Way data type functions.
5 amb 151
6     Part of the Routino routing software.
7 amb 110 ******************/ /******************
8 amb 151 This file Copyright 2008,2009 Andrew M. Bishop
9 amb 110
10 amb 151 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 amb 110 ***************************************/
23    
24    
25     #include <assert.h>
26     #include <stdlib.h>
27     #include <string.h>
28    
29     #include "functions.h"
30     #include "waysx.h"
31    
32    
33     /* Constants */
34    
35     /*+ The array size increment for ways - expect ~1,000,000 ways. +*/
36     #define INCREMENT_WAYS 256*1024
37    
38    
39     /* Functions */
40    
41 amb 203 static int sort_by_id(WayX **a,WayX **b);
42     static int sort_by_name_and_properties(WayX **a,WayX **b);
43 amb 110
44    
45     /*++++++++++++++++++++++++++++++++++++++
46     Allocate a new way list.
47    
48     WaysX *NewWayList Returns the way list.
49     ++++++++++++++++++++++++++++++++++++++*/
50    
51     WaysX *NewWayList(void)
52     {
53     WaysX *waysx;
54    
55 amb 213 waysx=(WaysX*)calloc(1,sizeof(WaysX));
56 amb 110
57     return(waysx);
58     }
59    
60    
61     /*++++++++++++++++++++++++++++++++++++++
62     Save the way list to a file.
63    
64     WaysX* waysx The set of ways to save.
65    
66     const char *filename The name of the file to save.
67     ++++++++++++++++++++++++++++++++++++++*/
68    
69     void SaveWayList(WaysX* waysx,const char *filename)
70     {
71 amb 214 index_t i;
72 amb 110 int fd;
73     Ways *ways=calloc(1,sizeof(Ways));
74    
75     assert(waysx->sorted); /* Must be sorted */
76 amb 213 assert(waysx->wdata); /* Must have wdata filled in */
77 amb 110
78     /* Fill in a Ways structure with the offset of the real data in the file after
79     the Way structure itself. */
80    
81 amb 203 ways->number=waysx->wnumber;
82 amb 110 ways->data=NULL;
83     ways->ways=(void*)sizeof(Ways);
84 amb 214 ways->names=(void*)(sizeof(Ways)+ways->number*sizeof(Way));
85 amb 110
86     /* Write out the Ways structure and then the real data. */
87    
88     fd=OpenFile(filename);
89    
90     WriteFile(fd,ways,sizeof(Ways));
91    
92 amb 203 for(i=0;i<ways->number;i++)
93 amb 132 {
94 amb 203 WriteFile(fd,&waysx->wdata[i],sizeof(Way));
95 amb 110
96 amb 132 if(!((i+1)%10000))
97     {
98     printf("\rWriting Ways: Ways=%d",i+1);
99     fflush(stdout);
100     }
101     }
102    
103 amb 203 printf("\rWrote Ways: Ways=%d \n",ways->number);
104 amb 132 fflush(stdout);
105    
106 amb 110 WriteFile(fd,waysx->names,waysx->length);
107    
108     CloseFile(fd);
109    
110     /* Free the fake Ways */
111    
112     free(ways);
113     }
114    
115    
116     /*++++++++++++++++++++++++++++++++++++++
117 amb 203 Find a particular way.
118    
119     WayX *FindWayX Returns the extended way with the specified id.
120    
121     WaysX* waysx The set of ways to process.
122    
123     way_t id The way id to look for.
124     ++++++++++++++++++++++++++++++++++++++*/
125    
126     WayX *FindWayX(WaysX* waysx,way_t id)
127     {
128     int start=0;
129     int end=waysx->number-1;
130     int mid;
131    
132     assert(waysx->sorted); /* Must be sorted */
133 amb 213 assert(waysx->idata); /* Must have idata filled in */
134 amb 203
135     /* Binary search - search key exact match only is required.
136     *
137     * # <- start | Check mid and move start or end if it doesn't match
138     * # |
139     * # | Since an exact match is wanted we can set end=mid-1
140     * # <- mid | or start=mid+1 because we know that mid doesn't match.
141     * # |
142     * # | Eventually either end=start or end=start+1 and one of
143     * # <- end | start or end is the wanted one.
144     */
145    
146     if(end<start) /* There are no ways */
147     return(NULL);
148 amb 205 else if(id<waysx->idata[start]->id) /* Check key is not before start */
149 amb 203 return(NULL);
150 amb 205 else if(id>waysx->idata[end]->id) /* Check key is not after end */
151 amb 203 return(NULL);
152     else
153     {
154     do
155     {
156     mid=(start+end)/2; /* Choose mid point */
157    
158 amb 205 if(waysx->idata[mid]->id<id) /* Mid point is too low */
159 amb 203 start=mid+1;
160 amb 205 else if(waysx->idata[mid]->id>id) /* Mid point is too high */
161 amb 203 end=mid-1;
162 amb 205 else /* Mid point is correct */
163     return(waysx->idata[mid]);
164 amb 203 }
165     while((end-start)>1);
166    
167 amb 205 if(waysx->idata[start]->id==id) /* Start is correct */
168     return(waysx->idata[start]);
169 amb 203
170 amb 205 if(waysx->idata[end]->id==id) /* End is correct */
171     return(waysx->idata[end]);
172 amb 203 }
173    
174     return(NULL);
175     }
176    
177    
178     /*++++++++++++++++++++++++++++++++++++++
179 amb 110 Append a way to a way list.
180    
181     Way *AppendWay Returns the newly appended way.
182    
183     WaysX* waysx The set of ways to process.
184    
185 amb 203 way_t id The ID of the way.
186    
187 amb 110 const char *name The name or reference of the way.
188     ++++++++++++++++++++++++++++++++++++++*/
189    
190 amb 203 Way *AppendWay(WaysX* waysx,way_t id,const char *name)
191 amb 110 {
192 amb 213 /* Check that the arrays have enough space. */
193 amb 110
194     if(waysx->number==waysx->alloced)
195     {
196     waysx->alloced+=INCREMENT_WAYS;
197    
198 amb 203 waysx->xdata=(WayX*)realloc((void*)waysx->xdata,waysx->alloced*sizeof(WayX));
199    
200     waysx->wdata=(Way*)realloc((void*)waysx->wdata,waysx->alloced*sizeof(Way));
201 amb 110 }
202    
203     /* Insert the way */
204    
205 amb 203 waysx->xdata[waysx->number].id=id;
206     waysx->xdata[waysx->number].name=strcpy((char*)malloc(strlen(name)+1),name);
207     waysx->xdata[waysx->number].way=&waysx->wdata[waysx->number];
208 amb 110
209 amb 203 memset(&waysx->wdata[waysx->number],0,sizeof(Way));
210 amb 110
211     waysx->number++;
212    
213 amb 203 return(&waysx->wdata[waysx->number-1]);
214 amb 213
215     waysx->sorted=0;
216 amb 110 }
217    
218    
219     /*++++++++++++++++++++++++++++++++++++++
220     Sort the list of ways and fix the names.
221    
222     WaysX* waysx The set of ways to process.
223     ++++++++++++++++++++++++++++++++++++++*/
224    
225     void SortWayList(WaysX* waysx)
226     {
227 amb 203 Way *uniq_ways;
228 amb 214 index_t i,j;
229 amb 110
230 amb 213 assert(waysx->xdata); /* Must have xdata filled in */
231 amb 110
232 amb 132 printf("Sorting Ways"); fflush(stdout);
233    
234 amb 203 /* Sort the ways by id */
235 amb 110
236 amb 205 waysx->idata=malloc(waysx->number*sizeof(WayX*));
237 amb 203
238     for(i=0;i<waysx->number;i++)
239 amb 205 waysx->idata[i]=&waysx->xdata[i];
240 amb 203
241 amb 205 qsort(waysx->idata,waysx->number,sizeof(WayX*),(int (*)(const void*,const void*))sort_by_id);
242 amb 203
243     /* Sort the ways by name and way properties */
244    
245 amb 110 waysx->ndata=malloc(waysx->number*sizeof(WayX*));
246    
247     for(i=0;i<waysx->number;i++)
248 amb 203 waysx->ndata[i]=&waysx->xdata[i];
249 amb 110
250 amb 203 qsort(waysx->ndata,waysx->number,sizeof(WayX*),(int (*)(const void*,const void*))sort_by_name_and_properties);
251 amb 110
252 amb 203 /* Allocate the new data for names */
253 amb 110
254     waysx->names=(char*)malloc(waysx->alloced*sizeof(char));
255    
256 amb 203 /* Allocate the data for unique ways */
257    
258     uniq_ways=(Way*)malloc(waysx->number*sizeof(Way));
259    
260 amb 110 /* Setup the offsets for the names in the way array */
261    
262 amb 203 for(i=0,j=0;i<waysx->number;i++)
263 amb 110 {
264     if(i && !strcmp(waysx->ndata[i]->name,waysx->ndata[i-1]->name)) /* Same name */
265 amb 203 {
266     waysx->ndata[i]->way->name=waysx->ndata[i-1]->way->name;
267    
268     if(!WaysCompare(waysx->ndata[i]->way,waysx->ndata[i-1]->way)) /* Same properties */
269     waysx->ndata[i]->way=waysx->ndata[i-1]->way;
270     else
271     {
272 amb 207 uniq_ways[j]=*waysx->ndata[i]->way;
273 amb 203 waysx->ndata[i]->way=&uniq_ways[j++];
274     }
275     }
276 amb 110 else /* Different name */
277     {
278     if((waysx->length+strlen(waysx->ndata[i]->name)+1)>=waysx->alloced)
279     {
280     waysx->alloced+=INCREMENT_WAYS;
281    
282     waysx->names=(char*)realloc((void*)waysx->names,waysx->alloced*sizeof(char));
283     }
284    
285     strcpy(&waysx->names[waysx->length],waysx->ndata[i]->name);
286    
287 amb 203 waysx->ndata[i]->way->name=waysx->length;
288 amb 110
289     waysx->length+=strlen(waysx->ndata[i]->name)+1;
290 amb 203
291 amb 207 uniq_ways[j]=*waysx->ndata[i]->way;
292 amb 203 waysx->ndata[i]->way=&uniq_ways[j++];
293 amb 110 }
294     }
295 amb 132
296 amb 203 waysx->wnumber=j;
297    
298     free(waysx->wdata);
299    
300     waysx->wdata=uniq_ways;
301    
302 amb 132 printf("\rSorted Ways \n"); fflush(stdout);
303 amb 213
304     waysx->sorted=1;
305 amb 110 }
306    
307    
308     /*++++++++++++++++++++++++++++++++++++++
309 amb 203 Sort the ways into id order.
310 amb 110
311 amb 203 int sort_by_id Returns the comparison of the id fields.
312 amb 110
313     Way **a The first Way.
314    
315     Way **b The second Way.
316     ++++++++++++++++++++++++++++++++++++++*/
317    
318 amb 203 static int sort_by_id(WayX **a,WayX **b)
319 amb 110 {
320 amb 203 way_t a_id=(*a)->id;
321     way_t b_id=(*b)->id;
322    
323     if(a_id<b_id)
324     return(-1);
325     else if(a_id>b_id)
326     return(1);
327     else
328     return(0);
329     }
330    
331    
332     /*++++++++++++++++++++++++++++++++++++++
333     Sort the ways into name and properties order.
334    
335     int sort_by_name_and_properties Returns the comparison of the name and properties fields.
336    
337     Way **a The first Way.
338    
339     Way **b The second Way.
340     ++++++++++++++++++++++++++++++++++++++*/
341    
342     static int sort_by_name_and_properties(WayX **a,WayX **b)
343     {
344 amb 110 char *a_name=(*a)->name;
345     char *b_name=(*b)->name;
346 amb 203 int name_compare;
347 amb 110
348 amb 203 name_compare=strcmp(a_name,b_name);
349    
350     if(name_compare)
351     return(name_compare);
352     else
353     {
354     Way *a_way=(*a)->way;
355     Way *b_way=(*b)->way;
356    
357     return(WaysCompare(a_way,b_way));
358     }
359 amb 110 }

Properties

Name Value
cvs:description Extended ways functions.