Browse Source

Add DenseNode::raw_tags

Johannes Hofmann 7 years ago
parent
commit
c99af47fb4
4 changed files with 133 additions and 2 deletions
  1. BIN
      src/.blob.rs.swo
  2. BIN
      src/.block.rs.swo
  3. 39
    2
      src/dense.rs
  4. 94
    0
      src/hungry_count.rs

BIN
src/.blob.rs.swo View File


BIN
src/.block.rs.swo View File


+ 39
- 2
src/dense.rs View File

@@ -53,13 +53,23 @@ impl<'a> DenseNode<'a> {
53 53
         self.timestamp * i64::from(self.block.get_date_granularity())
54 54
     }
55 55
 
56
-    /// Returns an iterator over the tags of this way (See [OSM wiki](http://wiki.openstreetmap.org/wiki/Tags)).
56
+    /// Returns an iterator over the tags of this node (See [OSM wiki](http://wiki.openstreetmap.org/wiki/Tags)).
57 57
     pub fn tags(&self) -> DenseTagIter<'a> {
58 58
         DenseTagIter {
59 59
             block: self.block,
60 60
             keys_vals_indices: self.keys_vals_indices.iter(),
61 61
         }
62 62
     }
63
+
64
+    /// Returns an iterator over the tags of this node
65
+    /// (See [OSM wiki](http://wiki.openstreetmap.org/wiki/Tags)).
66
+    /// A tag is represented as a pair of indices (key and value) to the stringtable of the current
67
+    /// `PrimitiveBlock`.
68
+    pub fn raw_tags(&self) -> DenseRawTagIter<'a> {
69
+        DenseRawTagIter {
70
+            keys_vals_indices: self.keys_vals_indices.iter(),
71
+        }
72
+    }
63 73
 }
64 74
 
65 75
 /// An iterator over dense nodes. It decodes the delta encoded values.
@@ -228,8 +238,35 @@ impl<'a> Iterator for DenseTagIter<'a> {
228 238
     }
229 239
 
230 240
     fn size_hint(&self) -> (usize, Option<usize>) {
231
-        self.keys_vals_indices.size_hint()
241
+        let len = self.keys_vals_indices.len() / 2;
242
+        (len, Some(len))
232 243
     }
233 244
 }
234 245
 
235 246
 impl<'a> ExactSizeIterator for DenseTagIter<'a> {}
247
+
248
+/// An iterator over the tags of a node. It returns a pair of indices (key and value) to the
249
+/// stringtable of the current `PrimitiveBlock`.
250
+#[derive(Clone, Debug)]
251
+pub struct DenseRawTagIter<'a> {
252
+    keys_vals_indices: std::slice::Iter<'a, i32>,
253
+}
254
+
255
+//TODO return Result
256
+impl<'a> Iterator for DenseRawTagIter<'a> {
257
+    type Item = (i32, i32);
258
+
259
+    fn next(&mut self) -> Option<Self::Item> {
260
+        match (self.keys_vals_indices.next(), self.keys_vals_indices.next()) {
261
+            (Some(&key_index), Some(&val_index)) => Some((key_index, val_index)),
262
+            _ => None,
263
+        }
264
+    }
265
+
266
+    fn size_hint(&self) -> (usize, Option<usize>) {
267
+        let len = self.keys_vals_indices.len() / 2;
268
+        (len, Some(len))
269
+    }
270
+}
271
+
272
+impl<'a> ExactSizeIterator for DenseRawTagIter<'a> {}

+ 94
- 0
src/hungry_count.rs View File

@@ -0,0 +1,94 @@
1
+extern crate osmpbf;
2
+extern crate crossbeam;
3
+
4
+use osmpbf::*;
5
+use std::fs::File;
6
+use std::sync::mpsc::sync_channel;
7
+
8
+
9
+enum WorkerMessage<'a> {
10
+    PleaseStop,
11
+    DoBlob(MmapBlob<'a>),
12
+}
13
+
14
+fn stats(file: &File) {
15
+    let mmap = Mmap::from_file(file).unwrap();
16
+
17
+    crossbeam::scope(|scope| {
18
+        let mut iter = MmapBlobIter::new(&mmap);
19
+
20
+        let num_threads = 4_usize;
21
+        let mut chans = Vec::with_capacity(num_threads);
22
+
23
+        let (result_tx, result_rx) = sync_channel::<(usize, usize)>(0);
24
+
25
+        for thread_id in 0..num_threads {
26
+            let result_tx = result_tx.clone();
27
+
28
+            let (request_tx, request_rx) = sync_channel::<WorkerMessage>(0);
29
+            chans.push(request_tx);
30
+
31
+            scope.spawn(move || {
32
+                loop {
33
+                    match request_rx.recv().unwrap() {
34
+                        WorkerMessage::PleaseStop => return,
35
+                        WorkerMessage::DoBlob(mmap_blob) => {
36
+                            let count = if let BlobDecode::OsmData(block) = mmap_blob.decode() {
37
+                                block.groups()
38
+                                     .flat_map(|g| g.dense_nodes())
39
+                                     .count()
40
+                            } else {
41
+                                0
42
+                            };
43
+                            match result_tx.send((thread_id, count)) {
44
+                                Ok(_) => {},
45
+                                Err(_) => {
46
+                                    println!("Thread id {}, Err", thread_id);
47
+                                    return;
48
+                                },
49
+                            };
50
+                        },
51
+                    };
52
+                }
53
+            });
54
+        }
55
+
56
+        //TODO fix dead lock when number of blobs is less than number of threads
57
+        for (thread_id, mmap_blob) in iter.by_ref().take(num_threads).enumerate() {
58
+            chans[thread_id].send(WorkerMessage::DoBlob(mmap_blob)).unwrap();
59
+        }
60
+
61
+        let mut stopped = 0;
62
+        let mut nodes = 0;
63
+        loop {
64
+            let (thread_id, count) = result_rx.recv().unwrap();
65
+            nodes += count;
66
+
67
+            if let Some(mmap_blob) = iter.next() {
68
+                match chans[thread_id].send(WorkerMessage::DoBlob(mmap_blob)) {
69
+                    Ok(_) => {},
70
+                    Err(_) => {println!("Err");},
71
+                };
72
+            } else {
73
+                match chans[thread_id].send(WorkerMessage::PleaseStop) {
74
+                    Ok(_) => {},
75
+                    Err(_) => {
76
+                    }
77
+                };
78
+                stopped += 1;
79
+                if stopped == num_threads {
80
+                    break;
81
+                }
82
+            }
83
+        }
84
+
85
+        println!("Number of nodes: {}", nodes);
86
+    });
87
+}
88
+
89
+fn main() {
90
+    let path = std::env::args_os().nth(1).unwrap();
91
+    let f = std::fs::File::open(path).unwrap();
92
+
93
+    stats(&f);
94
+}