瀏覽代碼

Accelerate key-value queries

by examining the stringtable for each PrimitiveBlock before iterating
over the contained elements.
Johannes Hofmann 7 年之前
父節點
當前提交
b3149bc777
共有 1 個文件被更改,包括 55 次插入31 次删除
  1. 55
    31
      src/query.rs

+ 55
- 31
src/query.rs 查看文件

@@ -5,7 +5,7 @@ use regex::Regex;
5 5
 
6 6
 pub trait Query {
7 7
     type BI;
8
-    fn create_block_index(&self, &PrimitiveBlock) -> Self::BI;
8
+    fn create_block_index(&self, &PrimitiveBlock) -> Option<Self::BI>;
9 9
     fn node_matches(&self, &Self::BI, node: &Node) -> bool;
10 10
     fn dense_node_matches(&self, &Self::BI, dnode: &DenseNode) -> bool;
11 11
     fn way_matches(&self, &Self::BI, way: &Way) -> bool;
@@ -59,8 +59,8 @@ impl ValuePatternQuery {
59 59
 impl Query for ValuePatternQuery {
60 60
     type BI = ();
61 61
 
62
-    fn create_block_index(&self, _block: &PrimitiveBlock) -> () {
63
-        ()
62
+    fn create_block_index(&self, _block: &PrimitiveBlock) -> Option<()> {
63
+        Some(())
64 64
     }
65 65
 
66 66
     fn node_matches(&self, _: &(), node: &Node) -> bool {
@@ -116,22 +116,46 @@ impl KeyValueQuery {
116 116
 }
117 117
 
118 118
 impl Query for KeyValueQuery {
119
-    type BI = ();
119
+    type BI = (Vec<u32>, Vec<u32>);
120
+
121
+    fn create_block_index(&self, block: &PrimitiveBlock) -> Option<(Vec<u32>, Vec<u32>)> {
122
+        let mut key_indices = vec![];
123
+        let mut value_indices = vec![];
124
+
125
+        let key_bytes = self.key.as_bytes();
126
+        let value_bytes = self.value.as_bytes();
127
+
128
+        for (i, string) in block.raw_stringtable().iter().enumerate() {
129
+            if string.as_slice() == key_bytes {
130
+                key_indices.push(i as u32);
131
+            }
132
+            if string.as_slice() == value_bytes {
133
+                value_indices.push(i as u32);
134
+            }
135
+        }
136
+
137
+        if key_indices.is_empty() || value_indices.is_empty() {
138
+            // No matches possible for this block
139
+            return None;
140
+        }
120 141
 
121
-    fn create_block_index(&self, _block: &PrimitiveBlock) -> () {
122
-        ()
142
+        key_indices.sort();
143
+        value_indices.sort();
144
+
145
+        Some((key_indices, value_indices))
123 146
     }
124 147
 
125
-    fn node_matches(&self, _: &(), node: &Node) -> bool {
126
-        for (key, val) in node.tags() {
127
-            if key == self.key && val == self.value {
148
+    fn node_matches(&self, bi: &Self::BI, node: &Node) -> bool {
149
+        for (key, val) in node.raw_tags() {
150
+            if bi.0.binary_search(&key).is_ok() && bi.1.binary_search(&val).is_ok() {
128 151
                 return true;
129 152
             }
130 153
         }
131 154
         return false;
132 155
     }
133 156
 
134
-    fn dense_node_matches(&self, _: &(), dnode: &DenseNode) -> bool {
157
+    fn dense_node_matches(&self, _bi: &Self::BI, dnode: &DenseNode) -> bool {
158
+        //TODO use raw tags
135 159
         for (key, val) in dnode.tags() {
136 160
             if key == self.key && val == self.value {
137 161
                 return true;
@@ -140,18 +164,18 @@ impl Query for KeyValueQuery {
140 164
         return false;
141 165
     }
142 166
 
143
-    fn way_matches(&self, _: &(), way: &Way) -> bool {
144
-        for (key, val) in way.tags() {
145
-            if key == self.key && val == self.value {
167
+    fn way_matches(&self, bi: &Self::BI, way: &Way) -> bool {
168
+        for (key, val) in way.raw_tags() {
169
+            if bi.0.binary_search(&key).is_ok() && bi.1.binary_search(&val).is_ok() {
146 170
                 return true;
147 171
             }
148 172
         }
149 173
         return false;
150 174
     }
151 175
 
152
-    fn relation_matches(&self, _: &(), relation: &Relation) -> bool {
153
-        for (key, val) in relation.tags() {
154
-            if key == self.key && val == self.value {
176
+    fn relation_matches(&self, bi: &Self::BI, relation: &Relation) -> bool {
177
+        for (key, val) in relation.raw_tags() {
178
+            if bi.0.binary_search(&key).is_ok() && bi.1.binary_search(&val).is_ok() {
155 179
                 return true;
156 180
             }
157 181
         }
@@ -165,25 +189,25 @@ pub fn find_query_matches<Q: Query>(
165 189
     matches: &mut Vec<LatLonDeg>,
166 190
     way_node_ids: &mut Vec<i64>,
167 191
 ) {
168
-    let block_index = query.create_block_index(block);
169
-
170
-    for node in block.groups().flat_map(|g| g.nodes()) {
171
-        if query.node_matches(&block_index, &node) {
172
-            let pos = LatLonDeg::new(node.lat(), node.lon());
173
-            matches.push(pos);
192
+    if let Some(block_index) = query.create_block_index(block) {
193
+        for node in block.groups().flat_map(|g| g.nodes()) {
194
+            if query.node_matches(&block_index, &node) {
195
+                let pos = LatLonDeg::new(node.lat(), node.lon());
196
+                matches.push(pos);
197
+            }
174 198
         }
175
-    }
176 199
 
177
-    for node in block.groups().flat_map(|g| g.dense_nodes()) {
178
-        if query.dense_node_matches(&block_index, &node) {
179
-            let pos = LatLonDeg::new(node.lat(), node.lon());
180
-            matches.push(pos);
200
+        for node in block.groups().flat_map(|g| g.dense_nodes()) {
201
+            if query.dense_node_matches(&block_index, &node) {
202
+                let pos = LatLonDeg::new(node.lat(), node.lon());
203
+                matches.push(pos);
204
+            }
181 205
         }
182
-    }
183 206
 
184
-    for way in block.groups().flat_map(|g| g.ways()) {
185
-        if query.way_matches(&block_index, &way) {
186
-            way_node_ids.push(way.refs_slice()[0]);
207
+        for way in block.groups().flat_map(|g| g.ways()) {
208
+            if query.way_matches(&block_index, &way) {
209
+                way_node_ids.push(way.refs_slice()[0]);
210
+            }
187 211
         }
188 212
     }
189 213
 }