1
use std::collections::HashMap;
2

            
3
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
4

            
5
use super::{serialization::BinarySerialization, PagedWriter};
6
use crate::{error::Error, io::File, vault::AnyVault, ArcBytes, ErrorKind};
7

            
8
/// An entry for a key. Stores a single index value for a single key.
9
270889
#[derive(Debug, Clone)]
10
pub struct KeyEntry<Index> {
11
    /// The key of this entry.
12
    pub key: ArcBytes<'static>,
13
    /// The index value of this entry.
14
    pub index: Index,
15
}
16

            
17
/// An index that serializes a value to the file.
18
pub trait PositionIndex {
19
    /// The position on-disk of the stored value.
20
    fn position(&self) -> u64;
21
}
22

            
23
impl<Index: PositionIndex + BinarySerialization> KeyEntry<Index> {
24
3593224
    pub(crate) fn copy_data_to<Callback>(
25
3593224
        &mut self,
26
3593224
        file: &mut dyn File,
27
3593224
        copied_chunks: &mut HashMap<u64, u64>,
28
3593224
        writer: &mut PagedWriter<'_>,
29
3593224
        vault: Option<&dyn AnyVault>,
30
3593224
        index_callback: &mut Callback,
31
3593224
    ) -> Result<bool, Error>
32
3593224
    where
33
3593224
        Callback: FnMut(
34
3593224
            &ArcBytes<'static>,
35
3593224
            &mut Index,
36
3593224
            &mut dyn File,
37
3593224
            &mut HashMap<u64, u64>,
38
3593224
            &mut PagedWriter<'_>,
39
3593224
            Option<&dyn AnyVault>,
40
3593224
        ) -> Result<bool, Error>,
41
3593224
    {
42
3593224
        index_callback(
43
3593224
            &self.key,
44
3593224
            &mut self.index,
45
3593224
            file,
46
3593224
            copied_chunks,
47
3593224
            writer,
48
3593224
            vault,
49
3593224
        )
50
3593224
    }
51
}
52

            
53
impl<Index: BinarySerialization> BinarySerialization for KeyEntry<Index> {
54
4603980
    fn serialize_to(
55
4603980
        &mut self,
56
4603980
        writer: &mut Vec<u8>,
57
4603980
        paged_writer: &mut PagedWriter<'_>,
58
4603980
    ) -> Result<usize, Error> {
59
4603980
        let mut bytes_written = 0;
60
        // Write the key
61
4603980
        let key_len = u16::try_from(self.key.len()).map_err(|_| ErrorKind::KeyTooLarge)?;
62
4603980
        writer.write_u16::<BigEndian>(key_len)?;
63
4603980
        writer.extend_from_slice(&self.key);
64
4603980
        bytes_written += 2 + key_len as usize;
65
4603980

            
66
4603980
        // Write the value
67
4603980
        bytes_written += self.index.serialize_to(writer, paged_writer)?;
68
4603980
        Ok(bytes_written)
69
4603980
    }
70

            
71
8947597
    fn deserialize_from(
72
8947597
        reader: &mut ArcBytes<'_>,
73
8947597
        current_order: Option<usize>,
74
8947597
    ) -> Result<Self, Error> {
75
8947597
        let key_len = reader.read_u16::<BigEndian>()? as usize;
76
8947597
        if key_len > reader.len() {
77
            return Err(Error::data_integrity(format!(
78
                "key length {} found but only {} bytes remaining",
79
                key_len,
80
                reader.len()
81
            )));
82
8947597
        }
83
8947597
        let key = reader.read_bytes(key_len)?.into_owned();
84

            
85
8947597
        let value = Index::deserialize_from(reader, current_order)?;
86

            
87
8947597
        Ok(Self { key, index: value })
88
8947597
    }
89
}