Showing 4 of 5 files from the diff.

@@ -288,8 +288,6 @@
Loading
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,14 +2,12 @@
Loading
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,6 +21,7 @@
Loading
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,12 +53,6 @@
Loading
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,7 +65,6 @@
Loading
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,7 +79,6 @@
Loading
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,6 +103,7 @@
Loading
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,5 +1,6 @@
Loading
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,6 +11,123 @@
Loading
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,25 +7,19 @@
Loading
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,14 +37,9 @@
Loading
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,8 +49,14 @@
Loading
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,13 +297,8 @@
Loading
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,10 +309,14 @@
Loading
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
        };
Files Coverage
src 93.11%
tests 98.56%
Project Totals (29 files) 94.11%
Notifications are pending CI completion. Waiting for GitLab's status webhook to queue notifications. Push notifications now.
1
coverage:
2
  status:
3
    project:
4
      default:
5
        target: 80%
6
        threshold: 1.0%
7
    patch: off
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading