Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/prunex.c
Parent Directory
|
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)
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 | } |