Skip to content

Commit de3117f

Browse files
authored
Add serde feature to buffers and expose it externally (#4709)
This is useful for persisting buffers easily, or sending them over the network. Crates like `foyer` require it for their persistent feature. Signed-off-by: Adam Gutglick <[email protected]>
1 parent b132237 commit de3117f

File tree

6 files changed

+113
-1
lines changed

6 files changed

+113
-1
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vortex-buffer/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ all-features = true
2020
arrow = ["dep:arrow-buffer"]
2121
memmap2 = ["dep:memmap2"]
2222
warn-copy = ["dep:log"]
23+
serde = ["dep:serde"]
2324

2425
[dependencies]
2526
arrow-buffer = { workspace = true, optional = true }
@@ -28,6 +29,7 @@ itertools = { workspace = true }
2829
log = { workspace = true, optional = true }
2930
memmap2 = { workspace = true, optional = true }
3031
num-traits = { workspace = true }
32+
serde = { workspace = true, optional = true }
3133
simdutf8 = { workspace = true }
3234
vortex-error = { workspace = true }
3335

vortex-buffer/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ mod debug;
6363
mod macros;
6464
#[cfg(feature = "memmap2")]
6565
mod memmap2;
66+
#[cfg(feature = "serde")]
67+
mod serde;
6668
mod string;
6769
mod trusted_len;
6870

vortex-buffer/src/serde.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3+
4+
use std::marker::PhantomData;
5+
6+
use serde::de::Visitor;
7+
use serde::{Deserialize, Deserializer, Serialize, Serializer};
8+
9+
use crate::{Alignment, Buffer, BufferMut, ByteBuffer};
10+
11+
impl<T> Serialize for Buffer<T>
12+
where
13+
T: Serialize,
14+
{
15+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
16+
where
17+
S: Serializer,
18+
{
19+
serializer.serialize_bytes(self.inner().as_ref())
20+
}
21+
}
22+
23+
struct BufferVisitor<T> {
24+
_marker: PhantomData<T>,
25+
}
26+
27+
impl<T> Default for BufferVisitor<T> {
28+
fn default() -> Self {
29+
Self {
30+
_marker: PhantomData,
31+
}
32+
}
33+
}
34+
35+
impl<'de, T> Visitor<'de> for BufferVisitor<T>
36+
where
37+
T: Deserialize<'de>,
38+
{
39+
type Value = Buffer<T>;
40+
41+
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
42+
write!(formatter, "byte buffer")
43+
}
44+
45+
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
46+
where
47+
E: serde::de::Error,
48+
{
49+
let bytes = ByteBuffer::copy_from_aligned(v, Alignment::of::<T>());
50+
Ok(Buffer::from_byte_buffer(bytes))
51+
}
52+
53+
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
54+
where
55+
E: serde::de::Error,
56+
{
57+
let bytes = ByteBuffer::copy_from_aligned(v, Alignment::of::<T>());
58+
Ok(Buffer::from_byte_buffer(bytes))
59+
}
60+
61+
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
62+
where
63+
E: serde::de::Error,
64+
{
65+
let bytes = ByteBuffer::copy_from_aligned(v, Alignment::of::<T>());
66+
Ok(Buffer::from_byte_buffer(bytes))
67+
}
68+
69+
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
70+
where
71+
A: serde::de::SeqAccess<'de>,
72+
{
73+
let mut buffer = seq
74+
.size_hint()
75+
.map(|hint| BufferMut::<T>::with_capacity(hint))
76+
.unwrap_or_default();
77+
78+
while let Some(e) = seq.next_element()? {
79+
buffer.push(e);
80+
}
81+
82+
Ok(buffer.freeze())
83+
}
84+
}
85+
86+
impl<'de, T> Deserialize<'de> for Buffer<T>
87+
where
88+
T: Deserialize<'de>,
89+
{
90+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
91+
where
92+
D: Deserializer<'de>,
93+
{
94+
deserializer.deserialize_byte_buf(BufferVisitor::<T>::default())
95+
}
96+
}

vortex-expr/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,10 @@ arbitrary = [
5050
"vortex-scalar/arbitrary",
5151
"vortex-dtype/arbitrary",
5252
]
53-
serde = ["dep:serde", "vortex-dtype/serde", "vortex-error/serde"]
53+
serde = [
54+
"dep:serde",
55+
"vortex-dtype/serde",
56+
"vortex-error/serde",
57+
"vortex-buffer/serde",
58+
]
5459
test-harness = []

vortex/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ python = ["vortex-error/python"]
7171
tokio = ["vortex-file/tokio", "vortex-scan/tokio"]
7272
zstd = ["dep:vortex-zstd", "vortex-file/zstd", "vortex-layout/zstd"]
7373
pretty = ["vortex-array/table-display"]
74+
serde = [
75+
"vortex-expr/serde",
76+
"vortex-dtype/serde",
77+
"vortex-buffer/serde",
78+
"vortex-error/serde",
79+
]
7480

7581
[[bench]]
7682
name = "single_encoding_throughput"

0 commit comments

Comments
 (0)