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 205 - (hide annotations) (download) (as text)
Thu Jun 25 18:25:46 2009 UTC (15 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 9135 byte(s)
Rename part of the structure.

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

Properties

Name Value
cvs:description Extended ways functions.