wasmer_journal/concrete/
aligned_cow_vec.rs

1use std::{
2    borrow::{Borrow, BorrowMut, Cow},
3    fmt::{self, Pointer},
4    ops::{Deref, DerefMut},
5};
6
7use rkyv::{
8    rancor::Fallible,
9    ser::{Allocator, WriterExt},
10    vec::{ArchivedVec, VecResolver},
11    Archive, Archived,
12};
13
14/// An aligned COW vector of bytes which avoids copying data
15/// when its constructed. The vector is aligned on the 16-byte
16/// boundary
17#[derive(Clone)]
18pub struct AlignedCowVec<'a, T>
19where
20    [T]: ToOwned,
21{
22    inner: Cow<'a, [T]>,
23}
24
25impl<'a, T> AlignedCowVec<'a, T>
26where
27    T: 'a,
28    [T]: ToOwned,
29{
30    /// The alignment of the vector
31    pub const ALIGNMENT: usize = 16;
32
33    pub fn into_inner(self) -> Cow<'a, [T]> {
34        self.inner
35    }
36
37    #[inline]
38    pub fn as_slice(&self) -> &[T] {
39        self.inner.as_ref()
40    }
41
42    pub fn len(&self) -> usize {
43        self.inner.len()
44    }
45
46    pub fn is_empty(&self) -> bool {
47        self.inner.is_empty()
48    }
49
50    pub fn len_with_padding(&self) -> usize {
51        let mut ret = self.inner.len() * std::mem::size_of::<T>();
52        let padding = ret % Self::ALIGNMENT;
53        if padding != 0 {
54            ret += Self::ALIGNMENT - padding;
55        }
56        ret
57    }
58}
59
60impl<'a, T> Default for AlignedCowVec<'a, T>
61where
62    T: 'a + Clone,
63    [T]: ToOwned,
64{
65    fn default() -> Self {
66        Self {
67            inner: Vec::new().into(),
68        }
69    }
70}
71
72impl<'a, T> fmt::Debug for AlignedCowVec<'a, T>
73where
74    T: 'a,
75    [T]: ToOwned,
76{
77    #[inline]
78    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79        self.as_slice().fmt(f)
80    }
81}
82
83impl<'a, T> From<Vec<T>> for AlignedCowVec<'a, T>
84where
85    T: 'a + Clone,
86    [T]: ToOwned,
87{
88    fn from(value: Vec<T>) -> Self {
89        Self {
90            inner: value.into(),
91        }
92    }
93}
94
95#[allow(clippy::from_over_into)]
96impl<'a> Into<Vec<u8>> for AlignedCowVec<'a, u8> {
97    fn into(self) -> Vec<u8> {
98        self.inner.into_owned()
99    }
100}
101
102impl<'a, T> From<Cow<'a, [T]>> for AlignedCowVec<'a, T>
103where
104    T: 'a,
105    [T]: ToOwned,
106{
107    fn from(value: Cow<'a, [T]>) -> Self {
108        Self { inner: value }
109    }
110}
111
112#[allow(clippy::from_over_into)]
113impl<'a, T> Into<Cow<'a, [T]>> for AlignedCowVec<'a, T>
114where
115    T: 'a,
116    [T]: ToOwned,
117{
118    fn into(self) -> Cow<'a, [T]> {
119        self.inner
120    }
121}
122
123impl<'a, T> Deref for AlignedCowVec<'a, T>
124where
125    T: 'a,
126    [T]: ToOwned,
127{
128    type Target = [T];
129
130    fn deref(&self) -> &Self::Target {
131        self.inner.deref()
132    }
133}
134
135impl<'a, T> DerefMut for AlignedCowVec<'a, T>
136where
137    T: 'a,
138    [T]: ToOwned,
139    <[T] as ToOwned>::Owned: BorrowMut<[T]>,
140{
141    fn deref_mut(&mut self) -> &mut Self::Target {
142        self.inner.to_mut().borrow_mut()
143    }
144}
145
146impl<'a, T> AsMut<[T]> for AlignedCowVec<'a, T>
147where
148    T: 'a,
149    [T]: ToOwned,
150    <[T] as ToOwned>::Owned: BorrowMut<[T]>,
151{
152    #[inline]
153    fn as_mut(&mut self) -> &mut [T] {
154        self.inner.to_mut().borrow_mut()
155    }
156}
157
158impl<'a, T> AsRef<[T]> for AlignedCowVec<'a, T>
159where
160    T: 'a,
161    [T]: ToOwned,
162{
163    #[inline]
164    fn as_ref(&self) -> &[T] {
165        self.inner.as_ref()
166    }
167}
168
169impl<'a, T> Borrow<[T]> for AlignedCowVec<'a, T>
170where
171    T: 'a,
172    [T]: ToOwned,
173{
174    #[inline]
175    fn borrow(&self) -> &[T] {
176        self.inner.borrow()
177    }
178}
179
180impl<'a, T> BorrowMut<[T]> for AlignedCowVec<'a, T>
181where
182    T: 'a,
183    [T]: ToOwned,
184    <[T] as ToOwned>::Owned: BorrowMut<[T]>,
185{
186    #[inline]
187    fn borrow_mut(&mut self) -> &mut [T] {
188        self.inner.to_mut().borrow_mut()
189    }
190}
191
192impl<'a, T> Archive for AlignedCowVec<'a, T>
193where
194    T: 'a,
195    [T]: ToOwned,
196{
197    type Archived = ArchivedVec<T>;
198    type Resolver = VecResolver;
199
200    #[inline]
201    fn resolve(&self, resolver: Self::Resolver, out: rkyv::Place<Self::Archived>) {
202        ArchivedVec::resolve_from_len(self.len(), resolver, out);
203    }
204}
205
206impl<'a, S> rkyv::Serialize<S> for AlignedCowVec<'a, u8>
207where
208    S: Fallible + WriterExt<S::Error> + Allocator + ?Sized,
209    S::Error: rkyv::rancor::Source,
210{
211    #[inline]
212    fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
213        serializer.align(Self::ALIGNMENT)?;
214        ArchivedVec::<Archived<u8>>::serialize_from_slice(self.as_slice(), serializer)
215    }
216}