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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 949 - (hide annotations) (download) (as text)
Fri Jan 13 17:13:39 2012 UTC (13 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 6815 byte(s)
Add an infrastructure to allow adding new functions to prune nodes and segments.

1 amb 949 /***************************************
2     Data pruning functions.
3    
4     Part of the Routino routing software.
5     ******************/ /******************
6     This file Copyright 2011-2012 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 <stdlib.h>
24     #include <stdio.h>
25     #include <assert.h>
26    
27     #include "nodesx.h"
28     #include "segmentsx.h"
29     #include "waysx.h"
30     #include "prunex.h"
31    
32     #include "files.h"
33     #include "logging.h"
34    
35    
36     /* Local functions */
37    
38     static void prune_node(NodesX *nodesx,NodeX *nodex);
39     static void prune_segment(NodesX *nodesx,SegmentsX *segmentsx,SegmentX *segmentx);
40     static void modify_segment(SegmentsX *segmentsx,SegmentX *segmentx,index_t newnode1,index_t newnode2);
41    
42     static void unlink_segment_node_refs(SegmentsX *segmentsx,SegmentX *segmentx,index_t node);
43    
44    
45     /*++++++++++++++++++++++++++++++++++++++
46     Initialise the data structures needed for pruning.
47    
48     NodesX *nodesx The set of nodes to use.
49    
50     SegmentsX *segmentsx The set of segments to use.
51    
52     WaysX *waysx The set of ways to use.
53     ++++++++++++++++++++++++++++++++++++++*/
54    
55     void StartPruning(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx)
56     {
57     SegmentX segmentx;
58     index_t index=0,lastnode1=NO_NODE;
59    
60     /* Print the start message */
61    
62     printf_first("Adding Extra Segment Indexes: Segments=0");
63    
64     /* Allocate the array of next segment */
65    
66     segmentsx->next1=(index_t*)calloc(segmentsx->number,sizeof(index_t));
67    
68     assert(segmentsx->next1); /* Check malloc() worked */
69    
70     /* Open the file read-only */
71    
72     segmentsx->fd=ReOpenFile(segmentsx->filename);
73    
74     /* Read the on-disk image */
75    
76     while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
77     {
78     index_t node1=segmentx.node1;
79    
80     if(lastnode1==node1)
81     segmentsx->next1[index]=index+1;
82     else
83     segmentsx->next1[index]=NO_SEGMENT;
84    
85     lastnode1=node1;
86     index++;
87    
88     if(!(index%10000))
89     printf_middle("Added Extra Segment Indexes: Segments=%"Pindex_t,index);
90     }
91    
92     segmentsx->next1[index]=NO_SEGMENT;
93    
94     /* Close the file */
95    
96     segmentsx->fd=CloseFile(segmentsx->fd);
97    
98     /* Print the final message */
99    
100     printf_last("Added Extra Segment Indexes: Segments=%"Pindex_t,segmentsx->number);
101     }
102    
103    
104     /*++++++++++++++++++++++++++++++++++++++
105     Delete the data structures needed for pruning.
106    
107     NodesX *nodesx The set of nodes to use.
108    
109     SegmentsX *segmentsx The set of segments to use.
110    
111     WaysX *waysx The set of ways to use.
112     ++++++++++++++++++++++++++++++++++++++*/
113    
114     void FinishPruning(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx)
115     {
116     free(segmentsx->next1);
117     segmentsx->next1=NULL;
118    
119     SortSegmentList(segmentsx,1);
120    
121     IndexSegments(segmentsx,nodesx);
122     }
123    
124    
125     /*++++++++++++++++++++++++++++++++++++++
126     Prune a node - all segment references to this node must already have gone.
127    
128     NodesX *nodesx The set of nodes to use.
129    
130     NodeX *nodex The node to be pruned.
131     ++++++++++++++++++++++++++++++++++++++*/
132    
133     static void prune_node(NodesX *nodesx,NodeX *nodex)
134     {
135     nodex->flags|=NODE_PRUNED;
136    
137     PutBackNodeX(nodesx,nodex);
138     }
139    
140    
141     /*++++++++++++++++++++++++++++++++++++++
142     Prune a segment.
143    
144     NodesX *nodesx The set of nodes to use.
145    
146     SegmentsX *segmentsx The set of segments to use.
147    
148     SegmentX *segmentx The segment to be pruned.
149     ++++++++++++++++++++++++++++++++++++++*/
150    
151     static void prune_segment(NodesX *nodesx,SegmentsX *segmentsx,SegmentX *segmentx)
152     {
153     unlink_segment_node_refs(segmentsx,segmentx,segmentx->node1);
154     unlink_segment_node_refs(segmentsx,segmentx,segmentx->node2);
155    
156     segmentx->node1=NO_NODE;
157     segmentx->node2=NO_NODE;
158     segmentx->next2=NO_SEGMENT;
159    
160     PutBackSegmentX(segmentsx,segmentx);
161     }
162    
163    
164     /*++++++++++++++++++++++++++++++++++++++
165     Modify a segment's nodes.
166    
167     NodesX *nodesx The set of nodes to use.
168    
169     SegmentX *segmentx The segment to be modified.
170    
171     index_t newnode1 The new value of node1.
172    
173     index_t newnode2 The new value of node2.
174     ++++++++++++++++++++++++++++++++++++++*/
175    
176     static void modify_segment(SegmentsX *segmentsx,SegmentX *segmentx,index_t newnode1,index_t newnode2)
177     {
178     index_t thissegment=IndexSegmentX(segmentsx,segmentx);
179    
180     if(newnode1!=segmentx->node1)
181     {
182     unlink_segment_node_refs(segmentsx,segmentx,segmentx->node1);
183    
184     segmentx->node1=newnode1;
185    
186     segmentsx->next1[thissegment]=segmentsx->firstnode[newnode1];
187     segmentsx->firstnode[newnode1]=thissegment;
188     }
189    
190     if(newnode1!=segmentx->node1)
191     {
192     unlink_segment_node_refs(segmentsx,segmentx,segmentx->node2);
193    
194     segmentx->node2=newnode2;
195    
196     segmentx->next2=segmentsx->firstnode[newnode2];
197     segmentsx->firstnode[newnode2]=thissegment;
198     }
199    
200     PutBackSegmentX(segmentsx,segmentx);
201     }
202    
203    
204     /*++++++++++++++++++++++++++++++++++++++
205     Unlink one node from a segment by modifying the linked list type arrangement of node references.
206    
207     SegmentsX *segmentsx The set of segments to use.
208    
209     SegmentX *segmentx The segment to be pruned.
210    
211     index_t node The node index of the end of the segment being modified here.
212     ++++++++++++++++++++++++++++++++++++++*/
213    
214     static void unlink_segment_node_refs(SegmentsX *segmentsx,SegmentX *segmentx,index_t node)
215     {
216     index_t thissegment=IndexSegmentX(segmentsx,segmentx);
217     index_t segment=segmentsx->firstnode[node];
218    
219     if(segment==thissegment)
220     {
221     if(segmentx->node1==node)
222     segmentsx->firstnode[node]=segmentsx->next1[thissegment];
223     else
224     segmentsx->firstnode[node]=segmentx->next2;
225     }
226     else
227     {
228     index_t nextsegment;
229    
230     do
231     {
232     SegmentX *segx=LookupSegmentX(segmentsx,segment,2);
233    
234     if(segx->node1==node)
235     {
236     nextsegment=segmentsx->next1[segment];
237    
238     if(thissegment==nextsegment)
239     {
240     if(segmentx->node1==node)
241     segmentsx->next1[segment]=segmentsx->next1[thissegment];
242     else
243     segmentsx->next1[segment]=segmentx->next2;
244     }
245     }
246     else
247     {
248     nextsegment=segx->next2;
249    
250     if(thissegment==nextsegment)
251     {
252     if(segmentx->node1==node)
253     segx->next2=segmentsx->next1[thissegment];
254     else
255     segx->next2=segmentx->next2;
256    
257     PutBackSegmentX(segmentsx,segx);
258     }
259     }
260    
261     segment=nextsegment;
262     }
263     while(segment!=thissegment);
264     }
265     }