Skip to main content

rustdb/
value.rs

1use crate::*;
2
3#[derive(Clone, Copy)]
4/// Code for variable length values.
5pub struct Code {
6    /// ByteStorage Id.
7    pub id: u64,
8    /// Fragment type.
9    pub ft: usize,
10}
11
12#[derive(Clone)]
13/// Simple value ( Binary, String, Int, Float, Bool ).
14///
15/// When stored in a database record, binary(n) and string(n) values are allocated (n+1) bytes (8<=n<=249).
16/// If the value is more than n bytes, the first (n-8) bytes are stored inline, and the rest are coded.
17#[non_exhaustive]
18pub enum Value {
19    /// No value.
20    None,
21    /// Binary.
22    RcBinary(Rc<Vec<u8>>),
23    /// Arc Binary.
24    ArcBinary(Arc<Vec<u8>>),
25    /// String.
26    String(Rc<String>),
27    /// Integer.
28    Int(i64),
29    /// Float.
30    Float(f64),
31    /// Bool.
32    Bool(bool),
33    /// For expression.
34    For(Rc<RefCell<run::ForState>>),
35    /// For expression ( sorted case ).
36    ForSort(Rc<RefCell<run::ForSortState>>),
37}
38
39impl Value {
40    /// Get the default Value for a DataType.
41    pub fn default(t: DataType) -> Value {
42        match data_kind(t) {
43            DataKind::Bool => Value::Bool(false),
44            DataKind::Float => Value::Float(0.0),
45            DataKind::String => Value::String(Rc::new(String::new())),
46            DataKind::Binary => Value::RcBinary(Rc::new(Vec::new())),
47            _ => Value::Int(0),
48        }
49    }
50
51    /// Get a Value from byte data.
52    pub fn load(db: &DB, typ: DataType, data: &[u8], off: usize) -> (Value, Code) {
53        let mut code = Code {
54            id: u64::MAX,
55            ft: 0,
56        };
57        let size = data_size(typ);
58        let val = match data_kind(typ) {
59            DataKind::Binary => {
60                let (bytes, u) = get_bytes(db, &data[off..], size);
61                code = u;
62                Value::RcBinary(Rc::new(bytes))
63            }
64            DataKind::String => {
65                let (bytes, u) = get_bytes(db, &data[off..], size);
66                code = u;
67                let str = String::from_utf8(bytes).unwrap();
68                Value::String(Rc::new(str))
69            }
70            DataKind::Bool => Value::Bool(data[off] != 0),
71            DataKind::Float => {
72                let f = if size == 4 {
73                    util::getf32(data, off) as f64
74                } else {
75                    util::getf64(data, off)
76                };
77                Value::Float(f)
78            }
79            _ => Value::Int(util::iget(data, off, size)),
80        };
81        (val, code)
82    }
83
84    /// Save a Value to byte data.
85    pub fn save(&self, typ: DataType, data: &mut [u8], off: usize, code: Code) {
86        let size = data_size(typ);
87        match self {
88            Value::Bool(x) => {
89                data[off] = if *x { 1 } else { 0 };
90            }
91            Value::Int(x) => util::iset(data, off, *x, size),
92            Value::Float(x) => {
93                if size == 8 {
94                    let bytes = (*x).to_le_bytes();
95                    data[off..off + 8].copy_from_slice(&bytes);
96                } else {
97                    debug_assert!(size == 4);
98                    let val = *x as f32;
99                    let bytes = val.to_le_bytes();
100                    data[off..off + 4].copy_from_slice(&bytes);
101                }
102            }
103            Value::String(s) => {
104                save_bytes(s.as_bytes(), &mut data[off..], code, size);
105            }
106            Value::RcBinary(b) => {
107                save_bytes(b, &mut data[off..], code, size);
108            }
109            Value::ArcBinary(b) => {
110                save_bytes(b, &mut data[off..], code, size);
111            }
112            _ => {}
113        }
114    }
115
116    /// Convert a Value to a String.
117    pub fn str(&self) -> Rc<String> {
118        match self {
119            Value::String(s) => s.clone(),
120            Value::Int(x) => Rc::new(x.to_string()),
121            Value::Bool(x) => Rc::new(x.to_string()),
122            Value::Float(x) => Rc::new(x.to_string()),
123            Value::RcBinary(x) => Rc::new(util::to_hex(x)),
124            Value::ArcBinary(x) => Rc::new(util::to_hex(x)),
125            _ => panic!("str not implemented"),
126        }
127    }
128
129    /// Get integer value.
130    pub fn int(&self) -> i64 {
131        match self {
132            Value::Int(x) => *x,
133            _ => panic!(),
134        }
135    }
136
137    /// Get float value.
138    pub fn float(&self) -> f64 {
139        match self {
140            Value::Float(x) => *x,
141            _ => panic!(),
142        }
143    }
144
145    /// Append to a String.
146    pub fn append(&mut self, val: &Value) {
147        if let Value::String(s) = self {
148            let val = val.str();
149            if let Some(ms) = Rc::get_mut(s) {
150                ms.push_str(&val);
151            } else {
152                let mut ns = String::with_capacity(s.len() + val.len());
153                ns.push_str(s);
154                ns.push_str(&val);
155                *self = Value::String(Rc::new(ns));
156            }
157        } else {
158            panic!()
159        }
160    }
161
162    /// Inc an integer or float.
163    pub fn inc(&mut self, val: &Value) {
164        match self {
165            Value::Int(x) => *x += val.int(),
166            Value::Float(x) => *x += val.float(),
167            _ => panic!(),
168        }
169    }
170
171    /// Dec an integer or float.
172    pub fn dec(&mut self, val: &Value) {
173        match self {
174            Value::Int(x) => *x -= val.int(),
175            Value::Float(x) => *x -= val.float(),
176            _ => panic!(),
177        }
178    }
179
180    /// Convert a Value to a Binary.
181    pub fn bin(&self) -> Rc<Vec<u8>> {
182        match self {
183            Value::ArcBinary(x) => Rc::new(x.to_vec()),
184            Value::RcBinary(x) => x.clone(),
185            Value::String(s) => Rc::new(s.as_bytes().to_vec()),
186            Value::Float(x) => Rc::new(x.to_le_bytes().to_vec()),
187            Value::Int(x) => Rc::new(x.to_le_bytes().to_vec()),
188            _ => panic!("bin not implemented"),
189        }
190    }
191
192    /// Borrow address of Binary value.
193    pub fn bina(&self) -> &[u8] {
194        match self {
195            Value::RcBinary(data) => data,
196            Value::ArcBinary(data) => data,
197            _ => panic!(),
198        }
199    }
200}
201
202/// Value comparison.
203impl std::cmp::Ord for Value {
204    fn cmp(&self, other: &Self) -> Ordering {
205        match self {
206            Value::String(s1) => {
207                if let Value::String(s2) = other {
208                    return s1.cmp(s2);
209                }
210            }
211            Value::Int(x1) => {
212                if let Value::Int(x2) = other {
213                    return x1.cmp(x2);
214                }
215            }
216            Value::Float(x1) => {
217                if let Value::Float(x2) = other {
218                    return x1.partial_cmp(x2).unwrap();
219                }
220            }
221            Value::RcBinary(b1) => {
222                if let Value::RcBinary(b2) = other {
223                    return b1.cmp(b2);
224                }
225            }
226            _ => {}
227        }
228        panic!()
229    }
230}
231
232impl PartialOrd for Value {
233    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
234        Some(self.cmp(other))
235    }
236}
237
238impl PartialEq for Value {
239    fn eq(&self, other: &Self) -> bool {
240        if let Some(eq) = self.partial_cmp(other) {
241            eq == Ordering::Equal
242        } else {
243            false
244        }
245    }
246}
247
248impl Eq for Value {}
249
250/// Decode bytes. Result is bytes and code ( or u64::MAX if no code ).
251pub fn get_bytes(db: &DB, data: &[u8], size: usize) -> (Vec<u8>, Code) {
252    let n = data[0] as usize;
253    if n < size {
254        let mut bytes = vec![0_u8; n];
255        bytes[0..n].copy_from_slice(&data[1..=n]);
256        (
257            bytes,
258            Code {
259                id: u64::MAX,
260                ft: 0,
261            },
262        )
263    } else {
264        let id = util::getu64(data, size - 8);
265        let ft = 255 - n;
266        let code = Code { id, ft };
267        let mut bytes = db.decode(code, size - 9);
268        bytes[0..size - 9].copy_from_slice(&data[1..size - 8]);
269        (bytes, code)
270    }
271}
272
273/// Save bytes.
274pub fn save_bytes(bytes: &[u8], data: &mut [u8], code: Code, size: usize) {
275    let n = bytes.len();
276    if n < size {
277        data[0] = n as u8;
278        data[1..=n].copy_from_slice(&bytes[0..n]);
279    } else {
280        // Store first (size-9) bytes and code.
281        data[0] = 255 - code.ft as u8;
282        data[1..size - 8].copy_from_slice(&bytes[0..size - 9]);
283        util::setu64(&mut data[size - 8..], code.id);
284    }
285}