src/address.rs
changed.
src/error.rs
changed.
Other files ignored by Codecov
Cargo.toml
has changed.
288 | 288 | if seg_page.segment_delete_entry(delete.segment, delete.recref.pos)? { |
|
289 | 289 | // Avoid to remove last pages, for avoid concurrent operations with page |
|
290 | 290 | // creation |
|
291 | - | // TODO: this is not enough because allocations can go over the size of a page, |
|
292 | - | // so is needed to track allocations in a different way than deletes |
|
293 | 291 | if seg_page.get_next()? != 0 { |
|
294 | 292 | pages_to_remove.push((delete.segment, page)); |
|
295 | 293 | } |
2 | 2 | use std::{borrow::Cow, error, fmt, io, str, sync}; |
|
3 | 3 | ||
4 | 4 | use crate::id::PersyId; |
|
5 | - | use unsigned_varint::decode::Error as VarintError; |
|
6 | 5 | ||
7 | 6 | /// Enum of possible errors from Persy |
|
8 | 7 | #[derive(Debug)] |
|
9 | 8 | pub enum PersyError { |
|
10 | 9 | Io(io::Error), |
|
11 | 10 | DecodingUtf8(str::Utf8Error), |
|
12 | - | DecodingVarint(VarintError), |
|
13 | 11 | DecodingDataEncoding(data_encoding::DecodeError), |
|
14 | 12 | Custom(Box<dyn error::Error + Send + Sync + 'static>), |
|
15 | 13 | VersionNotLastest, |
23 | 21 | IndexTypeMismatch(Cow<'static, str>), |
|
24 | 22 | IndexDuplicateKey(String, String), |
|
25 | 23 | TransactionTimeout, |
|
24 | + | InvalidId(String), |
|
26 | 25 | ||
27 | 26 | #[doc(hidden)] |
|
28 | 27 | __NonExhausive, |
54 | 53 | } |
|
55 | 54 | } |
|
56 | 55 | ||
57 | - | impl From<VarintError> for PersyError { |
|
58 | - | fn from(err: VarintError) -> PersyError { |
|
59 | - | PersyError::DecodingVarint(err) |
|
60 | - | } |
|
61 | - | } |
|
62 | - | ||
63 | 56 | impl From<Box<dyn error::Error + Send + Sync + 'static>> for PersyError { |
|
64 | 57 | fn from(err: Box<dyn error::Error + Send + Sync + 'static>) -> PersyError { |
|
65 | 58 | PersyError::Custom(err) |
72 | 65 | match self { |
|
73 | 66 | Io(ref e) => Some(e), |
|
74 | 67 | DecodingUtf8(ref e) => Some(e), |
|
75 | - | DecodingVarint(ref e) => Some(e), |
|
76 | 68 | DecodingDataEncoding(ref e) => Some(e), |
|
77 | 69 | Custom(ref e) => Some(e.as_ref()), |
|
78 | 70 | _ => None, |
87 | 79 | Io(m) => write!(f, "IO Error: {}", m), |
|
88 | 80 | DecodingUtf8(e) => write!(f, "String decoding error: {}", e), |
|
89 | 81 | DecodingDataEncoding(e) => write!(f, "Data Encoding Decoding error: {}", e), |
|
90 | - | DecodingVarint(e) => write!(f, "Varint decoding error: {}", e), |
|
91 | 82 | Custom(e) => write!(f, "{}", e), |
|
92 | 83 | VersionNotLastest => write!(f, "The record version is not latest"), |
|
93 | 84 | RecordNotFound(r) => write!(f, "Record not found: {}", r), |
112 | 103 | ||
113 | 104 | IndexDuplicateKey(i, k) => write!(f, "Found duplicate key:{} for index: {}", k, i), |
|
114 | 105 | TransactionTimeout => write!(f, "Timeout acquiring the data locks for the transaction"), |
|
106 | + | InvalidId(id) => write!(f, "The id '{}' has no valid format", id), |
|
115 | 107 | ||
116 | 108 | __NonExhausive => write!(f, "__non-Exhausive"), |
|
117 | 109 | } |
1 | 1 | use crate::PRes; |
|
2 | 2 | use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt}; |
|
3 | + | use integer_encoding::VarInt; |
|
3 | 4 | use std::io::{Cursor, Read, Write}; |
|
4 | 5 | ||
5 | 6 | pub trait InfallibleRead { |
10 | 11 | fn write_all(&mut self, buf: &[u8]); |
|
11 | 12 | } |
|
12 | 13 | ||
14 | + | #[allow(dead_code)] |
|
15 | + | pub(crate) fn write_varint<V: VarInt, W: InfallibleWrite + ?Sized>(w: &mut W, v: V) { |
|
16 | + | let mut buf = [0 as u8; 10]; |
|
17 | + | let b = v.encode_var(&mut buf); |
|
18 | + | w.write_all(&buf[0..b]) |
|
19 | + | } |
|
20 | + | ||
21 | + | // Start of snippet taken from integer-ecoding specialized for InfallibleRead |
|
22 | + | pub const MSB: u8 = 0b1000_0000; |
|
23 | + | ||
24 | + | #[allow(dead_code)] |
|
25 | + | pub(crate) fn read_varint<V: VarInt, R: InfallibleRead + ?Sized>(r: &mut R) -> V { |
|
26 | + | let mut int_buf = [0 as u8; 10]; |
|
27 | + | let mut int_cursor = 0; |
|
28 | + | let mut buf = [0 as u8; 1]; |
|
29 | + | ||
30 | + | while int_cursor == 0 || (int_buf[int_cursor - 1] & MSB != 0) { |
|
31 | + | r.read_exact(&mut buf); |
|
32 | + | if int_cursor >= 10 { |
|
33 | + | panic!("Unterminated varint") |
|
34 | + | } |
|
35 | + | int_buf[int_cursor] = buf[0]; |
|
36 | + | int_cursor = 0; |
|
37 | + | } |
|
38 | + | ||
39 | + | V::decode_var(&int_buf[0..int_cursor]).0 |
|
40 | + | } |
|
41 | + | ||
42 | + | // End of snippet taken from integer-ecoding specialized for InfallibleRead |
|
43 | + | ||
44 | + | pub(crate) trait InfallibleReadVarInt: InfallibleRead { |
|
45 | + | #[inline] |
|
46 | + | fn read_u8_varint(&mut self) -> u8 { |
|
47 | + | read_varint(self) |
|
48 | + | } |
|
49 | + | ||
50 | + | #[inline] |
|
51 | + | fn read_u16_varint(&mut self) -> u16 { |
|
52 | + | read_varint(self) |
|
53 | + | } |
|
54 | + | ||
55 | + | #[inline] |
|
56 | + | fn read_u32_varint(&mut self) -> u32 { |
|
57 | + | read_varint(self) |
|
58 | + | } |
|
59 | + | ||
60 | + | #[inline] |
|
61 | + | fn read_u64_varint(&mut self) -> u64 { |
|
62 | + | read_varint(self) |
|
63 | + | } |
|
64 | + | ||
65 | + | #[inline] |
|
66 | + | fn read_i8_varint(&mut self) -> i8 { |
|
67 | + | read_varint(self) |
|
68 | + | } |
|
69 | + | ||
70 | + | #[inline] |
|
71 | + | fn read_i16_varint(&mut self) -> i16 { |
|
72 | + | read_varint(self) |
|
73 | + | } |
|
74 | + | ||
75 | + | #[inline] |
|
76 | + | fn read_i32_varint(&mut self) -> i32 { |
|
77 | + | read_varint(self) |
|
78 | + | } |
|
79 | + | ||
80 | + | #[inline] |
|
81 | + | fn read_i64_varint(&mut self) -> i64 { |
|
82 | + | read_varint(self) |
|
83 | + | } |
|
84 | + | } |
|
85 | + | impl<R: InfallibleRead + ?Sized> InfallibleReadVarInt for R {} |
|
86 | + | ||
87 | + | pub(crate) trait InfallibleWriteVarInt: InfallibleWrite { |
|
88 | + | #[inline] |
|
89 | + | fn write_varint_u8(&mut self, value: u8) { |
|
90 | + | write_varint(self, value) |
|
91 | + | } |
|
92 | + | ||
93 | + | #[inline] |
|
94 | + | fn write_varint_u16(&mut self, value: u16) { |
|
95 | + | write_varint(self, value) |
|
96 | + | } |
|
97 | + | ||
98 | + | #[inline] |
|
99 | + | fn write_varint_u32(&mut self, value: u32) { |
|
100 | + | write_varint(self, value) |
|
101 | + | } |
|
102 | + | ||
103 | + | #[inline] |
|
104 | + | fn write_varint_u64(&mut self, value: u64) { |
|
105 | + | write_varint(self, value) |
|
106 | + | } |
|
107 | + | ||
108 | + | #[inline] |
|
109 | + | fn write_varint_i8(&mut self, value: i8) { |
|
110 | + | write_varint(self, value) |
|
111 | + | } |
|
112 | + | ||
113 | + | #[inline] |
|
114 | + | fn write_varint_i16(&mut self, value: i16) { |
|
115 | + | write_varint(self, value) |
|
116 | + | } |
|
117 | + | ||
118 | + | #[inline] |
|
119 | + | fn write_varint_i32(&mut self, value: i32) { |
|
120 | + | write_varint(self, value) |
|
121 | + | } |
|
122 | + | ||
123 | + | #[inline] |
|
124 | + | fn write_varint_i64(&mut self, value: i64) { |
|
125 | + | write_varint(self, value) |
|
126 | + | } |
|
127 | + | } |
|
128 | + | ||
129 | + | impl<W: InfallibleWrite + ?Sized> InfallibleWriteVarInt for W {} |
|
130 | + | ||
13 | 131 | pub(crate) trait InfallibleWriteFormat: InfallibleWrite { |
|
14 | 132 | #[inline] |
|
15 | 133 | fn write_u8(&mut self, value: u8) { |
7 | 7 | transaction::{Transaction, TxSegCheck}, |
|
8 | 8 | }; |
|
9 | 9 | use data_encoding::BASE32_DNSSEC; |
|
10 | + | use integer_encoding::{VarInt, VarIntReader}; |
|
10 | 11 | pub use std::fs::OpenOptions; |
|
11 | - | use std::{fmt, io::Write, str}; |
|
12 | - | use unsigned_varint::{ |
|
13 | - | decode::{u32 as u32_vdec, u64 as u64_vdec}, |
|
14 | - | encode::{u32 as u32_venc, u32_buffer, u64 as u64_venc, u64_buffer}, |
|
15 | - | }; |
|
12 | + | use std::{fmt, io::Cursor, str}; |
|
16 | 13 | ||
17 | 14 | fn write_id(f: &mut fmt::Formatter, id: u32) -> fmt::Result { |
|
18 | - | let mut buffer = Vec::new(); |
|
19 | - | buffer |
|
20 | - | .write_all(u32_venc(id, &mut u32_buffer())) |
|
21 | - | .expect("no failure expected only memory allocation"); |
|
15 | + | let mut buffer = id.encode_var_vec(); |
|
22 | 16 | buffer.push(0b0101_0101); |
|
23 | 17 | write!(f, "{}", BASE32_DNSSEC.encode(&buffer)) |
|
24 | 18 | } |
|
25 | 19 | ||
26 | 20 | fn read_id(s: &str) -> PRes<u32> { |
|
27 | 21 | let bytes = BASE32_DNSSEC.decode(s.as_bytes())?; |
|
28 | - | Ok(u32_vdec(&bytes)?.0) |
|
22 | + | VarIntReader::read_varint(&mut Cursor::new(bytes)).map_err(|_| PersyError::InvalidId(String::from(s))) |
|
29 | 23 | } |
|
30 | 24 | ||
31 | 25 | #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)] |
43 | 37 | ||
44 | 38 | impl fmt::Display for RecRef { |
|
45 | 39 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
46 | - | let mut buffer = Vec::new(); |
|
47 | - | buffer |
|
48 | - | .write_all(u64_venc(self.page, &mut u64_buffer())) |
|
49 | - | .expect("no failure expected only memory allocation"); |
|
40 | + | let mut buffer = self.page.encode_var_vec(); |
|
50 | 41 | buffer.push(0b0101_0101); |
|
51 | - | buffer |
|
52 | - | .write_all(u32_venc(self.pos, &mut u32_buffer())) |
|
53 | - | .expect("no failure expected only memory allocation"); |
|
42 | + | buffer.extend_from_slice(&self.pos.encode_var_vec()); |
|
54 | 43 | write!(f, "{}", BASE32_DNSSEC.encode(&buffer)) |
|
55 | 44 | } |
|
56 | 45 | } |
60 | 49 | ||
61 | 50 | fn from_str(s: &str) -> Result<Self, Self::Err> { |
|
62 | 51 | let bytes = BASE32_DNSSEC.decode(s.as_bytes())?; |
|
63 | - | let (page, rest) = u64_vdec(&bytes)?; |
|
64 | - | let (pos, _) = u32_vdec(&rest[1..])?; |
|
52 | + | let mut cursor = Cursor::new(bytes); |
|
53 | + | let page = cursor |
|
54 | + | .read_varint() |
|
55 | + | .map_err(|_| PersyError::InvalidId(String::from(s)))?; |
|
56 | + | cursor.set_position(cursor.position() + 1); |
|
57 | + | let pos = cursor |
|
58 | + | .read_varint() |
|
59 | + | .map_err(|_| PersyError::InvalidId(String::from(s)))?; |
|
65 | 60 | Ok(RecRef::new(page, pos)) |
|
66 | 61 | } |
|
67 | 62 | } |
302 | 297 | ||
303 | 298 | impl fmt::Display for IndexId { |
|
304 | 299 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
305 | - | let mut buffer = Vec::new(); |
|
306 | - | buffer |
|
307 | - | .write_all(u32_venc(self.meta, &mut u32_buffer())) |
|
308 | - | .expect("no failure expected only memory allocation"); |
|
309 | - | buffer |
|
310 | - | .write_all(u32_venc(self.data, &mut u32_buffer())) |
|
311 | - | .expect("no failure expected only memory allocation"); |
|
300 | + | let mut buffer = self.meta.encode_var_vec(); |
|
301 | + | buffer.extend_from_slice(&self.data.encode_var_vec()); |
|
312 | 302 | buffer.push(0b0101_0101); |
|
313 | 303 | write!(f, "{}", BASE32_DNSSEC.encode(&buffer)) |
|
314 | 304 | } |
319 | 309 | ||
320 | 310 | fn from_str(s: &str) -> Result<Self, Self::Err> { |
|
321 | 311 | let bytes = BASE32_DNSSEC.decode(s.as_bytes())?; |
|
322 | - | let (meta, bytes) = u32_vdec(&bytes)?; |
|
323 | - | let data = if bytes.len() > 1 { |
|
324 | - | let (d, _) = u32_vdec(&bytes)?; |
|
325 | - | d |
|
312 | + | let mut cursor = Cursor::new(bytes); |
|
313 | + | let meta = cursor |
|
314 | + | .read_varint() |
|
315 | + | .map_err(|_| PersyError::InvalidId(String::from(s)))?; |
|
316 | + | let data = if cursor.get_ref().len() - cursor.position() as usize > 1 { |
|
317 | + | cursor |
|
318 | + | .read_varint() |
|
319 | + | .map_err(|_| PersyError::InvalidId(String::from(s)))? |
|
326 | 320 | } else { |
|
327 | 321 | 0 |
|
328 | 322 | }; |