drive/util/object_size_info/
path_info.rs

1use grovedb::batch::key_info::KeyInfo::KnownKey;
2use grovedb::batch::KeyInfoPath;
3
4use grovedb_storage::worst_case_costs::WorstKeyLength;
5
6use DriveKeyInfo::{Key, KeyRef, KeySize};
7use PathInfo::{PathAsVec, PathFixedSizeArray, PathWithSizes};
8
9use crate::error::drive::DriveError;
10use crate::error::Error;
11use crate::util::object_size_info::drive_key_info::DriveKeyInfo;
12
13/// Info about a path.
14#[derive(Clone, Debug)]
15pub enum PathInfo<'a, const N: usize> {
16    /// An into iter Path
17    PathFixedSizeArray([&'a [u8]; N]),
18
19    /// An into iter Path
20    PathAsVec(Vec<Vec<u8>>),
21
22    /// A path size
23    PathWithSizes(KeyInfoPath),
24}
25
26impl<'a, const N: usize> PathInfo<'a, N> {
27    /// Returns the length of the path as a usize.
28    pub fn len(&self) -> u32 {
29        match self {
30            PathFixedSizeArray(path_iterator) => {
31                (*path_iterator).into_iter().map(|a| a.len() as u32).sum()
32            }
33            PathAsVec(path_iterator) => path_iterator.iter().map(|a| a.len() as u32).sum(),
34            PathWithSizes(path_size) => path_size.iterator().map(|a| a.max_length() as u32).sum(),
35        }
36    }
37
38    /// Returns true if the path is empty.
39    pub fn is_empty(&self) -> bool {
40        match self {
41            PathFixedSizeArray(path_iterator) => (*path_iterator).is_empty(),
42            PathAsVec(path_iterator) => path_iterator.is_empty(),
43            PathWithSizes(path_size) => path_size.is_empty(),
44        }
45    }
46
47    /// Pushes the given key into the path.
48    pub fn push(&mut self, key_info: DriveKeyInfo<'a>) -> Result<(), Error> {
49        match self {
50            PathFixedSizeArray(_) => {
51                return Err(Error::Drive(DriveError::CorruptedCodeExecution(
52                    "can not add a key to a fixed size path iterator",
53                )))
54            }
55            PathAsVec(path_iterator) => match key_info {
56                Key(key) => path_iterator.push(key),
57                KeyRef(key_ref) => path_iterator.push(key_ref.to_vec()),
58                KeySize(..) => {
59                    return Err(Error::Drive(DriveError::CorruptedCodeExecution(
60                        "can not add a key size to path iterator",
61                    )))
62                }
63            },
64            PathWithSizes(key_info_path) => match key_info {
65                Key(key) => key_info_path.push(KnownKey(key)),
66                KeyRef(key_ref) => key_info_path.push(KnownKey(key_ref.to_vec())),
67                KeySize(key_info) => key_info_path.push(key_info),
68            },
69        }
70        Ok(())
71    }
72
73    /// Get the KeyInfoPath for grovedb estimated costs
74    pub(crate) fn convert_to_key_info_path(self) -> KeyInfoPath {
75        match self {
76            PathFixedSizeArray(path) => KeyInfoPath::from_known_path(path),
77            PathAsVec(path) => KeyInfoPath::from_known_owned_path(path),
78            PathWithSizes(key_info_path) => key_info_path,
79        }
80    }
81}