1use super::lut::LookupTable;
8use super::marker_types::Canonical;
9use super::minimum_spanning_tree::minimum_spanning_tree_hamming_space;
10use super::*;
11use lut::ValuesOrRedirect;
12use num_traits::{FromPrimitive, Num, One, PrimInt, Signed, ToPrimitive, Unsigned, Zero};
13use point::*;
14use smallvec::SmallVec;
15use std::collections::HashMap;
16use std::fmt;
17use std::io::{Read, Write};
18use tree::*;
19
20type UInt = u32;
21type SInt = i32;
22
23const MAGIC: &[u8] = "fast-steiner lookup-table\r\n".as_bytes();
25
26pub fn write_lut<W: Write>(writer: &mut W, lut: &LookupTable) -> Result<(), LUTWriteError> {
28 let mut trees: Vec<_> = lut
30 .sub_lut_by_degree
31 .iter()
32 .flat_map(|sub_lut| sub_lut.values.iter())
33 .filter_map(|v| match v {
34 ValuesOrRedirect::Values(v) => Some(v),
35 ValuesOrRedirect::Redirect { .. } => None,
36 })
37 .flat_map(|v| v.iter())
38 .map(|v| &v.potential_optimal_steiner_tree)
39 .collect();
40 trees.sort_unstable();
41
42 println!("Compress {} trees.", trees.len());
44
45 {
46 println!("Convert trees to bit vectors...");
48 let trees_as_bit_vectors: Vec<_> = trees.iter().map(|t| t.to_bitvec()).collect();
49
50 println!("Compute minimum spanning tree of trees (under Hamming distance)...");
51 let mst = minimum_spanning_tree_hamming_space(&trees_as_bit_vectors, true);
52 }
53
54 println!("Write trees...");
55 write_trees(writer, &trees)?;
56
57 Ok(())
58}
59
60fn write_trees<W: Write>(
61 writer: &mut W,
62 trees: &Vec<&Tree<Canonical>>,
63) -> Result<(), LUTWriteError> {
64 write_unsigned_integer(writer, trees.len())?;
66
67 let empty_tree = Tree::empty_canonical();
68 let mut prev_tree = &empty_tree;
69 for current_tree in trees {
70 let (edge_diff_horiz, edge_diff_vert): (Vec<_>, Vec<_>) = prev_tree
71 .symmetric_difference(current_tree)
72 .partition(|e| e.is_horizontal());
73
74 write_unsigned_integer(writer, edge_diff_horiz.len())?;
76 write_unsigned_integer(writer, edge_diff_vert.len())?;
77
78 for e in edge_diff_horiz {
80 write_point_u4(writer, e.start())?;
81 }
82 for e in edge_diff_vert {
84 write_point_u4(writer, e.start())?;
85 }
86
87 prev_tree = current_tree;
88 }
89
90 Ok(())
91}
92
93fn write_point_u4<W: Write>(writer: &mut W, p: Point<HananCoord>) -> Result<(), LUTWriteError> {
95 assert!(
96 p.x < 16 && p.y < 16,
97 "edge coordinate out of range for storage"
98 );
99
100 let nibbles = ((p.x << 4) | (p.y & 0xf)) as u8;
101 writer.write_all(&[nibbles])?;
102 Ok(())
103}
104
105fn read_point<R: Read>(reader: &mut R) -> Result<Point<HananCoord>, LUTReadError> {
106 let nibbles = read_byte(reader)?;
107 let x = nibbles >> 4;
108 let y = nibbles & 0xf;
109 Ok(Point::new(x as HananCoord, y as HananCoord))
110}
111
112fn read_byte<R: Read>(reader: &mut R) -> Result<u8, LUTReadError> {
113 let mut b = [0u8];
114 reader.read_exact(&mut b)?;
115 Ok(b[0])
116}
117
118#[cfg(test)]
121fn bits(bit_string: &str) -> Vec<u8> {
122 bit_string
123 .split_ascii_whitespace()
124 .map(|s| u8::from_str_radix(s, 2).unwrap())
125 .collect()
126}
127
128#[cfg(test)]
131macro_rules! bits {
132 ($x:expr) => {
133 &mut bits($x)[..].as_ref()
134 };
135}
136
137#[derive(Debug)]
139pub enum LUTReadError {
140 IOError(std::io::Error),
142 UnexpectedEndOfFile,
144 FormatError,
146}
147
148impl fmt::Display for LUTReadError {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 use LUTReadError::*;
151 match self {
152 LUTReadError::FormatError => write!(f, "illegal table format"),
153 other => other.fmt(f),
154 }
155 }
156}
157
158#[derive(Debug)]
160pub enum LUTWriteError {
161 IOError(std::io::Error),
163}
164
165impl fmt::Display for LUTWriteError {
166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167 use LUTWriteError::*;
168 match self {
169 IOError(ioerr) => ioerr.fmt(f),
170 }
171 }
172}
173
174impl From<std::io::Error> for LUTReadError {
175 fn from(err: std::io::Error) -> Self {
176 match err.kind() {
177 std::io::ErrorKind::UnexpectedEof => LUTReadError::UnexpectedEndOfFile,
178 _ => LUTReadError::IOError(err),
179 }
180 }
181}
182
183impl From<std::io::Error> for LUTWriteError {
184 fn from(err: std::io::Error) -> Self {
185 match err.kind() {
186 _ => LUTWriteError::IOError(err),
187 }
188 }
189}
190
191fn read_magic<R: Read>(reader: &mut R) -> Result<(), LUTReadError> {
194 let mut buf = [0u8; MAGIC.len()];
196 reader.read_exact(&mut buf)?;
197
198 match buf.as_ref() {
200 MAGIC => Ok(()), _ => {
202 let s = String::from_utf8_lossy(&buf);
203 log::error!(
204 "wrong file format, magic string is wrong: '{:?}', hex = '{:02x?}'",
205 s,
206 buf
207 );
208 Err(LUTReadError::FormatError)
209 } }
211}
212
213fn write_magic<W: Write>(writer: &mut W) -> Result<(), LUTWriteError> {
215 writer.write_all(MAGIC)?;
216 Ok(())
217}
218
219fn read_unsigned_integer<T, R: Read>(reader: &mut R) -> Result<T, LUTReadError>
225where
226 T: PrimInt + Zero + FromPrimitive,
227{
228 let mut bytes = <SmallVec<[u8; 8]>>::new();
230 for b in reader.bytes() {
231 let b = b?;
232 bytes.push(b);
233 if b & 0x80 == 0 {
234 break;
235 }
236 }
237 if bytes.last().map(|b| b & 0x80) != Some(0) {
238 Err(LUTReadError::UnexpectedEndOfFile)
241 } else {
242 Ok(bytes
243 .iter()
244 .rev()
245 .map(|b| b & 0x7f) .fold(T::zero(), |acc, b| T::from_u8(b).unwrap() + (acc << 7)))
247 }
248}
249
250#[test]
251fn test_read_unsigned_integer() {
252 assert_eq!(
254 read_unsigned_integer::<u32, _>(bits!("00000000")).unwrap(),
255 0
256 );
257 assert_eq!(
258 read_unsigned_integer::<i32, _>(bits!("01111111")).unwrap(),
259 127
260 );
261 assert_eq!(
262 read_unsigned_integer::<i32, _>(bits!("10000000 00000001")).unwrap(),
263 128
264 );
265 assert_eq!(
266 read_unsigned_integer::<i32, _>(bits!("11111111 01111111")).unwrap(),
267 16383
268 );
269 assert_eq!(
270 read_unsigned_integer::<i32, _>(bits!("10000000 10000000 00000001")).unwrap(),
271 16384
272 );
273
274 assert!(read_unsigned_integer::<i32, _>(bits!("")).is_err());
276 assert!(read_unsigned_integer::<i32, _>(bits!("10000000")).is_err());
278}
279
280fn write_unsigned_integer<T, W: Write>(writer: &mut W, value: T) -> Result<(), LUTWriteError>
286where
287 T: PrimInt + Unsigned + FromPrimitive + ToPrimitive,
288{
289 let mut value = value;
290
291 let mask = T::from_u8(0x7f).unwrap();
292 let _0x80 = T::from_u8(0x80).unwrap();
293 while value > mask {
294 let lowest = (value & mask).to_u8().unwrap();
295 writer.write_all(&[0x80 | lowest])?; value = value.shr(7);
297 }
298 debug_assert!(value & _0x80 == T::zero());
299 writer.write_all(&[value.to_u8().unwrap()])?;
300 Ok(())
301}
302
303#[test]
304fn test_write_unsigned_integer() {
305 fn test(num: UInt, expected: Vec<u8>) {
308 let mut buf = Vec::new();
309 write_unsigned_integer(&mut buf, num).unwrap();
310 assert_eq!(buf, expected);
311 }
312
313 test(0, vec![0x00]);
314 test(1, vec![0x01]);
315 test(127, vec![0x7f]);
316 test(128, vec![0x80, 0x01]);
317 test(16383, vec![0xff, 0x7f]);
318 test(16384, vec![0x80, 0x80, 0x01]);
319}
320
321fn read_signed_integer<T, R: Read>(reader: &mut R) -> Result<T, LUTReadError>
325where
326 T: PrimInt + Num + Zero + One + Signed + FromPrimitive,
327{
328 let u: T = read_unsigned_integer(reader)?;
329 let sign = u & One::one();
330
331 let magnitude = u.unsigned_shr(1);
332
333 Ok(if sign.is_one() {
334 T::zero() - magnitude
335 } else {
336 magnitude
337 })
338}
339
340#[test]
341fn test_read_signed_integer() {
342 assert_eq!(read_signed_integer::<i32, _>(bits!("00")).unwrap(), 0);
344 assert_eq!(read_signed_integer::<i32, _>(bits!("10")).unwrap(), 1);
345 assert_eq!(read_signed_integer::<i32, _>(bits!("11")).unwrap(), -1);
346 assert_eq!(
347 read_signed_integer::<i32, _>(bits!("01111110")).unwrap(),
348 63
349 );
350 assert_eq!(
351 read_signed_integer::<i32, _>(bits!("10000001 00000001")).unwrap(),
352 -64
353 );
354 assert_eq!(
355 read_signed_integer::<i32, _>(bits!("11111110 01111111")).unwrap(),
356 8191
357 );
358 assert_eq!(
359 read_signed_integer::<i32, _>(bits!("10000001 10000000 00000001")).unwrap(),
360 -8192
361 );
362
363 assert!(read_signed_integer::<i32, _>(bits!("")).is_err());
365 assert!(read_signed_integer::<i32, _>(bits!("10000000")).is_err());
367}
368
369fn write_signed_integer<W: Write>(writer: &mut W, value: SInt) -> Result<(), LUTWriteError> {
373 let (sign, value) = if value < 0 { (1, -value) } else { (0, value) };
375
376 let magnitude = (value << 1) as UInt;
378 let u = magnitude | sign;
379
380 write_unsigned_integer(writer, u)
381}
382
383#[test]
384fn test_write_signed_integer() {
385 fn test(num: SInt, expected: Vec<u8>) {
388 let mut buf = Vec::new();
389 write_signed_integer(&mut buf, num).unwrap();
390 assert_eq!(buf, expected);
391 }
392
393 test(0, vec![0x00]);
394 test(1, vec![0b10]);
395 test(-1, vec![0b11]);
396 test(63, vec![0b01111110]);
397 test(-64, vec![0x81, 0x01]);
398 test(8191, vec![0b11111110, 0b01111111]);
399 test(-8192, vec![0b10000001, 0b10000000, 0b1]);
400}
401
402#[test]
403fn test_write_lut() {
404 let lut = super::gen_lut::gen_full_lut(4);
405
406 let mut buffer = Vec::new();
407
408 let write_result = write_lut(&mut buffer, &lut);
409 assert!(write_result.is_ok());
410 dbg!(buffer.len());
411 assert!(buffer.len() < 100);
412}