Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d376b9d

Browse files
committedApr 2, 2025
Convert OwnedValue to contain a buffer and value_type tag.
Towards closing: tursodatabase#1236
1 parent 7b9c0e9 commit d376b9d

File tree

1 file changed

+216
-5
lines changed

1 file changed

+216
-5
lines changed
 

‎core/types.rs

+216-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const MAX_REAL_SIZE: u8 = 15;
1414

1515
#[derive(Debug, Clone, Copy, PartialEq)]
1616
pub enum OwnedValueType {
17-
Null,
1817
Integer,
1918
Float,
2019
Text,
@@ -82,10 +81,11 @@ impl TextRef {
8281
#[derive(Debug, Clone)]
8382
pub enum OwnedValue {
8483
Null,
85-
Integer(i64),
86-
Float(f64),
87-
Text(Text),
88-
Blob(Vec<u8>),
84+
Value {
85+
buffer: Vec<u8>,
86+
value_type: OwnedValueType,
87+
length: usize,
88+
},
8989
}
9090

9191
#[derive(Debug, Clone, PartialEq)]
@@ -103,7 +103,218 @@ pub enum RefValue {
103103
Blob(RawSlice),
104104
}
105105

106+
const INITIAL_BUFFER_SIZE: usize = 16;
107+
106108
impl OwnedValue {
109+
pub const NULL: OwnedValue = OwnedValue::Null;
110+
111+
pub fn Integer(value: i64) -> Self {
112+
let mut buffer = Vec::with_capacity(INITIAL_BUFFER_SIZE);
113+
buffer.extend_from_slice(&value.to_ne_bytes());
114+
Self::Value {
115+
buffer,
116+
value_type: OwnedValueType::Integer,
117+
length: std::mem::size_of::<i64>(),
118+
}
119+
}
120+
121+
pub fn Float(value: f64) -> Self {
122+
let mut buffer = Vec::with_capacity(INITIAL_BUFFER_SIZE);
123+
buffer.extend_from_slice(&value.to_ne_bytes());
124+
Self::Value {
125+
buffer,
126+
value_type: OwnedValueType::Float,
127+
length: std::mem::size_of::<f64>(),
128+
}
129+
}
130+
131+
pub fn Text(text: Text) -> Self {
132+
let bytes = text.value;
133+
Self::Value {
134+
buffer: bytes,
135+
value_type: OwnedValueType::Text,
136+
length: bytes.len(),
137+
}
138+
}
139+
140+
pub fn Blob(bytes: Vec<u8>) -> Self {
141+
Self::Value {
142+
length: bytes.len(),
143+
value_type: OwnedValueType::Blob,
144+
buffer: bytes,
145+
}
146+
}
147+
148+
pub fn is_null(&self) -> bool {
149+
matches!(self, Self::Null)
150+
}
151+
152+
pub fn is_integer(&self) -> bool {
153+
matches!(
154+
self,
155+
Self::Value {
156+
value_type: OwnedValueType::Integer,
157+
..
158+
}
159+
)
160+
}
161+
162+
pub fn is_float(&self) -> bool {
163+
matches!(
164+
self,
165+
Self::Value {
166+
value_type: OwnedValueType::Float,
167+
..
168+
}
169+
)
170+
}
171+
172+
pub fn is_text(&self) -> bool {
173+
matches!(
174+
self,
175+
Self::Value {
176+
value_type: OwnedValueType::Text,
177+
..
178+
}
179+
)
180+
}
181+
182+
pub fn is_blob(&self) -> bool {
183+
matches!(
184+
self,
185+
Self::Value {
186+
value_type: OwnedValueType::Blob,
187+
..
188+
}
189+
)
190+
}
191+
192+
pub fn as_integer(&self) -> Option<i64> {
193+
match self {
194+
Self::Value {
195+
buffer,
196+
value_type: OwnedValueType::Integer,
197+
..
198+
} => Some(i64::from_ne_bytes(buffer[..8].try_into().unwrap())),
199+
_ => None,
200+
}
201+
}
202+
203+
pub fn as_float(&self) -> Option<f64> {
204+
match self {
205+
Self::Value {
206+
buffer,
207+
value_type: OwnedValueType::Float,
208+
..
209+
} => Some(f64::from_ne_bytes(buffer[..8].try_into().unwrap())),
210+
_ => None,
211+
}
212+
}
213+
214+
pub fn as_text(&self) -> Option<&str> {
215+
match self {
216+
Self::Value {
217+
buffer,
218+
value_type: OwnedValueType::Text,
219+
length,
220+
} => std::str::from_utf8(&buffer[..*length]).ok(),
221+
_ => None,
222+
}
223+
}
224+
225+
pub fn as_blob(&self) -> Option<&[u8]> {
226+
match self {
227+
Self::Value {
228+
buffer,
229+
value_type: OwnedValueType::Blob,
230+
length,
231+
} => Some(&buffer[..*length]),
232+
_ => None,
233+
}
234+
}
235+
236+
// Value type getter
237+
pub fn value_type(&self) -> Option<OwnedValueType> {
238+
match self {
239+
Self::Null => None,
240+
Self::Value { value_type, .. } => Some(*value_type),
241+
}
242+
}
243+
244+
// Mutation methods
245+
pub fn set_integer(&mut self, value: i64) {
246+
let bytes = value.to_ne_bytes();
247+
*self = match self {
248+
Self::Value { buffer, .. } => {
249+
if buffer.len() < 8 {
250+
buffer.resize(8, 0);
251+
}
252+
buffer[..8].copy_from_slice(&bytes);
253+
Self::Value {
254+
buffer: buffer.clone(),
255+
value_type: OwnedValueType::Integer,
256+
length: 8,
257+
}
258+
}
259+
_ => Self::Integer(value),
260+
};
261+
}
262+
263+
pub fn set_float(&mut self, value: f64) {
264+
let bytes = value.to_ne_bytes();
265+
*self = match self {
266+
Self::Value { buffer, .. } => {
267+
if buffer.len() < 8 {
268+
buffer.resize(8, 0);
269+
}
270+
buffer[..8].copy_from_slice(&bytes);
271+
Self::Value {
272+
buffer: buffer.clone(),
273+
value_type: OwnedValueType::Float,
274+
length: 8,
275+
}
276+
}
277+
_ => Self::Float(value),
278+
};
279+
}
280+
281+
pub fn set_text(&mut self, text: &str) {
282+
let bytes = text.as_bytes();
283+
*self = match self {
284+
Self::Value { buffer, .. } => {
285+
if buffer.capacity() < bytes.len() {
286+
buffer.reserve(bytes.len() - buffer.capacity());
287+
}
288+
buffer.clear();
289+
buffer.extend_from_slice(bytes);
290+
Self::Value {
291+
buffer: buffer.clone(),
292+
value_type: OwnedValueType::Text,
293+
length: bytes.len(),
294+
}
295+
}
296+
_ => Self::Text(Text::new(text)),
297+
};
298+
}
299+
300+
pub fn set_blob(&mut self, data: &[u8]) {
301+
*self = match self {
302+
Self::Value { buffer, .. } => {
303+
if buffer.capacity() < data.len() {
304+
buffer.reserve(data.len() - buffer.capacity());
305+
}
306+
buffer.clear();
307+
buffer.extend_from_slice(data);
308+
Self::Value {
309+
buffer: buffer.clone(),
310+
value_type: OwnedValueType::Blob,
311+
length: data.len(),
312+
}
313+
}
314+
_ => Self::Blob(data.to_vec()),
315+
};
316+
}
317+
107318
// A helper function that makes building a text OwnedValue easier.
108319
pub fn build_text(text: &str) -> Self {
109320
Self::Text(Text::new(text))

0 commit comments

Comments
 (0)
Please sign in to comment.