1use std::alloc::Layout;
2
3use bytes::Bytes;
4
5#[derive(Debug, thiserror::Error)]
6pub enum MemError {
7 #[error("Mem error")]
8 CpuAllocationError,
9}
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12pub enum MemDevice {
13 Cpu,
14 Gpu(u32),
15}
16
17pub trait MemBlock: Send {
18 type Ref<'a>: MemBlock + Clone
19 where
20 Self: 'a;
21
22 fn device(&self) -> MemDevice;
23 fn borrow(&self) -> Self::Ref<'_>;
24 fn map_to_cpu(&self) -> &[u8];
25
26 #[inline]
28 fn len(&self) -> usize {
29 self.map_to_cpu().len()
30 }
31
32 #[inline]
33 fn layout(&self) -> Layout {
34 let mapped = self.map_to_cpu();
35 let len = mapped.len();
36 let ptr = self.map_to_cpu() as *const [u8] as *const u8 as usize;
37
38 unsafe { Layout::from_size_align_unchecked(len, 1 << ptr.trailing_zeros()) }
39 }
40
41 #[inline]
42 fn into_cpu_bytes(self) -> Bytes
43 where
44 Self: Sized,
45 {
46 Bytes::copy_from_slice(self.map_to_cpu())
47 }
48}
49
50impl MemBlock for Bytes {
51 type Ref<'a> = &'a Bytes;
52
53 #[inline]
54 fn borrow(&self) -> Self::Ref<'_> {
55 todo!()
56 }
57
58 #[inline]
59 fn device(&self) -> MemDevice {
60 MemDevice::Cpu
61 }
62
63 #[inline]
64 fn map_to_cpu(&self) -> &[u8] {
65 self
66 }
67
68 #[inline]
69 fn into_cpu_bytes(self) -> Bytes {
70 self
71 }
72}
73
74impl<'a> MemBlock for &'a [u8] {
75 type Ref<'b>
76 = &'b [u8]
77 where
78 Self: 'b;
79
80 #[inline]
81 fn borrow(&self) -> Self::Ref<'_> {
82 self
83 }
84
85 #[inline]
86 fn device(&self) -> MemDevice {
87 MemDevice::Cpu
88 }
89
90 #[inline]
91 fn map_to_cpu(&self) -> &[u8] {
92 self
93 }
94}
95
96impl<'a> MemBlock for &'a Bytes {
97 type Ref<'b>
98 = &'b [u8]
99 where
100 Self: 'b;
101
102 #[inline]
103 fn borrow(&self) -> Self::Ref<'_> {
104 self
105 }
106
107 #[inline]
108 fn device(&self) -> MemDevice {
109 MemDevice::Cpu
110 }
111
112 #[inline]
113 fn map_to_cpu(&self) -> &[u8] {
114 self
115 }
116}
117
118pub trait MemAlloc {
119 type Data: MemBlock;
120 type Error: std::error::Error + Send + Sync + 'static;
121
122 fn device(&self) -> MemDevice;
123 fn alloc(&self, data: &[u8]) -> Result<Self::Data, Self::Error>;
124}
125
126impl<A: MemAlloc> MemAlloc for std::sync::Arc<A> {
127 type Data = A::Data;
128 type Error = A::Error;
129
130 fn device(&self) -> MemDevice {
131 (**self).device()
132 }
133
134 fn alloc(&self, data: &[u8]) -> Result<Self::Data, Self::Error> {
135 (**self).alloc(data)
136 }
137}
138
139#[derive(Debug, Clone)]
140pub struct CpuAllocator;
141impl MemAlloc for CpuAllocator {
142 type Data = Bytes;
143 type Error = MemError;
144
145 fn device(&self) -> MemDevice {
146 MemDevice::Cpu
147 }
148
149 fn alloc(&self, data: &[u8]) -> Result<Self::Data, Self::Error> {
150 Ok(Bytes::copy_from_slice(data))
151 }
152}