terminus_store/layer/
id_map.rs1use super::*;
2use crate::storage::{BitIndexMaps, FileLoad, FileStore, IdMapFiles};
3use std::convert::TryInto;
4use std::io;
5use tdb_succinct::util::sorted_iterator;
6use tdb_succinct::*;
7
8#[derive(Clone)]
9pub struct IdMap {
10 pub id_wtree: Option<WaveletTree>,
11}
12
13impl Default for IdMap {
14 fn default() -> Self {
15 Self::from_parts(None)
16 }
17}
18
19impl IdMap {
20 pub fn from_maps(maps: BitIndexMaps, width: u8) -> Self {
21 let bitindex = BitIndex::from_maps(maps.bits_map, maps.blocks_map, maps.sblocks_map);
22 let id_wtree = WaveletTree::from_parts(bitindex, width);
23
24 Self::from_parts(Some(id_wtree))
25 }
26
27 pub fn from_parts(id_wtree: Option<WaveletTree>) -> Self {
28 IdMap { id_wtree }
29 }
30
31 pub fn outer_to_inner(&self, id: u64) -> u64 {
32 self.id_wtree
33 .as_ref()
34 .and_then(|wtree| {
35 if id > wtree.len() as u64 {
36 None
37 } else {
38 Some(wtree.lookup_one(id - 1).unwrap() + 1)
39 }
40 })
41 .unwrap_or(id)
42 }
43
44 pub fn inner_to_outer(&self, id: u64) -> u64 {
45 self.id_wtree
46 .as_ref()
47 .and_then(|wtree| {
48 if id > wtree.len() as u64 {
49 None
50 } else {
51 let id: usize = id.try_into().unwrap();
52 Some(wtree.decode_one(id - 1) + 1)
53 }
54 })
55 .unwrap_or(id)
56 }
57}
58
59pub async fn memory_construct_idmaps<F: 'static + FileLoad + FileStore>(
60 input: &InternalLayer,
61 idmap_files: IdMapFiles<F>,
62) -> io::Result<()> {
63 let layers = input.immediate_layers();
64
65 construct_idmaps_from_layers(&layers, idmap_files).await
66}
67
68pub async fn memory_construct_idmaps_upto<F: 'static + FileLoad + FileStore>(
69 input: &InternalLayer,
70 upto_layer_id: [u32; 5],
71 idmap_files: IdMapFiles<F>,
72) -> io::Result<()> {
73 let layers = input.immediate_layers_upto(upto_layer_id);
74
75 construct_idmaps_from_layers(&layers, idmap_files).await
76}
77
78pub async fn construct_idmaps_from_structures<F: 'static + FileLoad + FileStore>(
79 node_dicts: Vec<StringDict>,
80 predicate_dicts: Vec<StringDict>,
81 value_dicts: Vec<TypedDict>,
82 node_value_idmaps: &[IdMap],
83 predicate_idmaps: &[IdMap],
84 idmap_files: IdMapFiles<F>,
85) -> io::Result<()> {
86 debug_assert!(node_dicts.len() == predicate_dicts.len());
87 debug_assert!(node_dicts.len() == value_dicts.len());
88 debug_assert!(node_dicts.len() == node_value_idmaps.len());
89 debug_assert!(node_dicts.len() == predicate_idmaps.len());
90 let len = node_dicts.len();
91
92 let mut node_iters = Vec::with_capacity(len);
93 let mut node_offset = 0;
94 let node_entries_len: Vec<_> = node_dicts.iter().map(|d| d.num_entries()).collect();
95 for (ix, dict) in node_dicts.into_iter().enumerate() {
96 let idmap = node_value_idmaps[ix].clone();
97 let num_entries = dict.num_entries();
98 node_iters.push(
99 dict.into_iter()
100 .enumerate()
101 .map(move |(i, e)| (idmap.inner_to_outer(i as u64 + 1) + node_offset as u64, e)),
102 );
103
104 node_offset += num_entries + value_dicts[ix].num_entries();
105 }
106
107 let mut value_iters = Vec::with_capacity(len);
108 let mut value_offset = 0;
109 for (ix, dict) in value_dicts.into_iter().enumerate() {
110 let idmap = node_value_idmaps[ix].clone();
111 let node_count = node_entries_len[ix];
112 let num_entries = dict.num_entries();
113 value_iters.push(dict.into_iter().enumerate().map(move |(i, e)| {
114 (
115 idmap.inner_to_outer(i as u64 + node_count as u64 + 1) + value_offset as u64,
116 e,
117 )
118 }));
119
120 value_offset += node_count + num_entries;
121 }
122
123 let mut predicate_iters = Vec::with_capacity(len);
124 let mut predicate_offset = 0;
125 for (ix, dict) in predicate_dicts.into_iter().enumerate() {
126 let idmap = predicate_idmaps[ix].clone();
127 let num_entries = dict.num_entries();
128 predicate_iters.push(dict.into_iter().enumerate().map(move |(i, e)| {
129 (
130 idmap.inner_to_outer(i as u64 + 1) + predicate_offset as u64,
131 e,
132 )
133 }));
134
135 predicate_offset += num_entries;
136 }
137
138 let entry_comparator = |vals: &[Option<&(u64, SizedDictEntry)>]| {
139 vals.iter()
140 .enumerate()
141 .filter(|(_, x)| x.is_some())
142 .min_by(|(_, x), (_, y)| x.unwrap().1.cmp(&y.unwrap().1))
143 .map(|x| x.0)
144 };
145
146 let typed_entry_comparator = |vals: &[Option<&(u64, TypedDictEntry)>]| {
147 vals.iter()
148 .enumerate()
149 .filter(|(_, x)| x.is_some())
150 .min_by(|(_, x), (_, y)| x.unwrap().1.cmp(&y.unwrap().1))
151 .map(|x| x.0)
152 };
153
154 let sorted_node_iter = sorted_iterator(node_iters, entry_comparator)
155 .map(|(i, s)| (i, TypedDictEntry::new(Datatype::String, s)));
156 let sorted_value_iter = sorted_iterator(value_iters, typed_entry_comparator);
157 let sorted_node_value_iter = sorted_node_iter
158 .chain(sorted_value_iter)
159 .map(|(id, _)| id - 1);
160 let sorted_predicate_iter =
161 sorted_iterator(predicate_iters, entry_comparator).map(|(id, _)| id - 1);
162
163 let node_value_width = util::calculate_width(node_offset as u64);
164 let node_value_build_task = tokio::spawn(build_wavelet_tree_from_iter(
165 node_value_width,
166 sorted_node_value_iter,
167 idmap_files.node_value_idmap_files.bits_file,
168 idmap_files.node_value_idmap_files.blocks_file,
169 idmap_files.node_value_idmap_files.sblocks_file,
170 ));
171 let predicate_width = util::calculate_width(predicate_offset as u64);
172 let predicate_build_task = tokio::spawn(build_wavelet_tree_from_iter(
173 predicate_width,
174 sorted_predicate_iter,
175 idmap_files.predicate_idmap_files.bits_file,
176 idmap_files.predicate_idmap_files.blocks_file,
177 idmap_files.predicate_idmap_files.sblocks_file,
178 ));
179
180 node_value_build_task.await??;
181 predicate_build_task.await?
182}
183
184async fn construct_idmaps_from_layers<F: 'static + FileLoad + FileStore>(
185 layers: &[&InternalLayer],
186 idmap_files: IdMapFiles<F>,
187) -> io::Result<()> {
188 let node_dicts: Vec<_> = layers
189 .iter()
190 .map(|layer| layer.node_dictionary().clone())
191 .collect();
192
193 let predicate_dicts: Vec<_> = layers
194 .iter()
195 .map(|layer| layer.predicate_dictionary().clone())
196 .collect();
197
198 let value_dicts: Vec<_> = layers
199 .iter()
200 .map(|layer| layer.value_dictionary().clone())
201 .collect();
202
203 let node_value_idmaps: Vec<_> = layers
204 .iter()
205 .map(|layer| layer.node_value_id_map().clone())
206 .collect();
207
208 let predicate_idmaps: Vec<_> = layers
209 .iter()
210 .map(|layer| layer.predicate_id_map().clone())
211 .collect();
212
213 construct_idmaps_from_structures(
214 node_dicts,
215 predicate_dicts,
216 value_dicts,
217 &node_value_idmaps,
218 &predicate_idmaps,
219 idmap_files,
220 )
221 .await
222}