1use super::{
5 Any, Buffer, MemoryDescription, Result, StorageError, StorageKind, nixl::NixlDescriptor,
6};
7
8#[derive(Clone)]
11pub struct OffsetBuffer {
12 base: Buffer,
13 offset: usize,
14 size: usize,
15}
16
17impl std::fmt::Debug for OffsetBuffer {
18 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 f.debug_struct("OffsetBuffer")
20 .field("base", &self.base)
21 .field("offset", &self.offset)
22 .field("size", &self.size)
23 .finish()
24 }
25}
26
27impl OffsetBuffer {
28 pub fn new(base: Buffer, offset: usize, size: usize) -> Result<Self> {
32 let end = offset
33 .checked_add(size)
34 .ok_or_else(|| StorageError::Unsupported("offset overflow".into()))?;
35 if end > base.size() {
36 return Err(StorageError::Unsupported(
37 "offset region exceeds base allocation bounds".into(),
38 ));
39 }
40 Ok(Self { base, offset, size })
41 }
42
43 pub fn offset(&self) -> usize {
45 self.offset
46 }
47
48 pub fn base(&self) -> &Buffer {
50 &self.base
51 }
52}
53
54impl MemoryDescription for OffsetBuffer {
55 fn addr(&self) -> usize {
56 self.base.addr() + self.offset
57 }
58
59 fn size(&self) -> usize {
60 self.size
61 }
62
63 fn storage_kind(&self) -> StorageKind {
64 self.base.storage_kind()
65 }
66
67 fn as_any(&self) -> &dyn Any {
68 self
69 }
70
71 fn nixl_descriptor(&self) -> Option<NixlDescriptor> {
72 let mut descriptor = self.base.nixl_descriptor()?;
73 descriptor.addr = self.addr() as u64;
74 descriptor.size = self.size();
75 Some(descriptor)
76 }
77}