storage_device/
buffer.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::buffer_allocator::BufferAllocator;
6use std::ops::{Bound, Range, RangeBounds};
7use std::slice::SliceIndex;
8
9pub use crate::buffer_allocator::BufferFuture;
10
11pub(super) fn round_down<T>(value: T, granularity: T) -> T
12where
13    T: num::Num + Copy,
14{
15    value - value % granularity
16}
17
18pub(super) fn round_up<T>(value: T, granularity: T) -> T
19where
20    T: num::Num + Copy,
21{
22    round_down(value + granularity - T::one(), granularity)
23}
24
25// Returns a range within a range.
26// For example, subrange(100..200, 20..30) = 120..130.
27fn subrange<R: RangeBounds<usize>>(source: &Range<usize>, bounds: &R) -> Range<usize> {
28    let subrange = (match bounds.start_bound() {
29        Bound::Included(&s) => source.start + s,
30        Bound::Excluded(&s) => source.start + s + 1,
31        Bound::Unbounded => source.start,
32    })..(match bounds.end_bound() {
33        Bound::Included(&e) => source.start + e + 1,
34        Bound::Excluded(&e) => source.start + e,
35        Bound::Unbounded => source.end,
36    });
37    assert!(subrange.end <= source.end);
38    subrange
39}
40
41fn split_range(range: &Range<usize>, mid: usize) -> (Range<usize>, Range<usize>) {
42    let l = range.end - range.start;
43    let base = range.start;
44    (base..base + mid, base + mid..base + l)
45}
46/// Buffer is a read-write buffer that can be used for I/O with the block device. They are created
47/// by a BufferAllocator, and automatically deallocate themselves when they go out of scope.
48///
49/// Most usage will be on the unowned BufferRef and MutableBufferRef types, since these types are
50/// used for Device::read and Device::write.
51///
52/// Buffers are always block-aligned (both in offset and length), but unaligned slices can be made
53/// with the reference types. That said, the Device trait requires aligned BufferRef and
54/// MutableBufferRef objects, so alignment must be restored by the time a device read/write is
55/// requested.
56///
57/// For example, when writing an unaligned amount of data to the device, generally two Buffers
58/// would need to be involved; the input Buffer could be used to write everything up to the last
59/// block, and a second single-block alignment Buffer would be used to read-modify-update the last
60/// block.
61#[derive(Debug)]
62pub struct Buffer<'a>(MutableBufferRef<'a>);
63
64// Alias for the traits which need to be satisfied for |subslice| and friends.
65// This trait is automatically satisfied for most typical uses (a..b, a.., ..b, ..).
66pub trait SliceRange: Clone + RangeBounds<usize> + SliceIndex<[u8], Output = [u8]> {}
67impl<T> SliceRange for T where T: Clone + RangeBounds<usize> + SliceIndex<[u8], Output = [u8]> {}
68
69impl<'a> Buffer<'a> {
70    pub(super) fn new(
71        slice: &'a mut [u8],
72        range: Range<usize>,
73        allocator: &'a BufferAllocator,
74    ) -> Self {
75        Self(MutableBufferRef { slice, range, allocator })
76    }
77
78    /// Takes a read-only reference to this buffer.
79    pub fn as_ref(&self) -> BufferRef<'_> {
80        self.subslice(..)
81    }
82
83    /// Takes a read-only reference to this buffer over |range| (which must be within the size of
84    /// the buffer).
85    pub fn subslice<R: SliceRange>(&self, range: R) -> BufferRef<'_> {
86        self.0.subslice(range)
87    }
88
89    /// Takes a read-write reference to this buffer.
90    pub fn as_mut(&mut self) -> MutableBufferRef<'_> {
91        self.subslice_mut(..)
92    }
93
94    /// Takes a read-write reference to this buffer over |range| (which must be within the size of
95    /// the buffer).
96    pub fn subslice_mut<R: SliceRange>(&mut self, range: R) -> MutableBufferRef<'_> {
97        self.0.reborrow().subslice_mut(range)
98    }
99
100    /// Returns the buffer's capacity.
101    pub fn len(&self) -> usize {
102        self.0.len()
103    }
104
105    /// Returns a slice of the buffer's contents.
106    pub fn as_slice(&self) -> &[u8] {
107        self.0.as_slice()
108    }
109
110    /// Returns a mutable slice of the buffer's contents.
111    pub fn as_mut_slice(&mut self) -> &mut [u8] {
112        self.0.as_mut_slice()
113    }
114
115    /// Returns the range in the underlying BufferSource that this buffer covers.
116    pub fn range(&self) -> Range<usize> {
117        self.0.range()
118    }
119
120    /// Returns a reference to the allocator.
121    pub fn allocator(&self) -> &BufferAllocator {
122        self.0.allocator
123    }
124}
125
126impl<'a> Drop for Buffer<'a> {
127    fn drop(&mut self) {
128        self.0.allocator.free_buffer(self.range());
129    }
130}
131
132/// BufferRef is an unowned, read-only view over a Buffer.
133#[derive(Clone, Copy, Debug)]
134pub struct BufferRef<'a> {
135    slice: &'a [u8],
136    start: usize, // Not range so that we get Copy.
137    end: usize,
138    allocator: &'a BufferAllocator,
139}
140
141impl<'a> BufferRef<'a> {
142    /// Returns the buffer's capacity.
143    pub fn len(&self) -> usize {
144        self.end - self.start
145    }
146
147    pub fn is_empty(&self) -> bool {
148        self.end == self.start
149    }
150
151    /// Returns a slice of the buffer's contents.
152    pub fn as_slice(&self) -> &[u8] {
153        self.slice
154    }
155
156    /// Slices and consumes this reference. See Buffer::subslice.
157    pub fn subslice<R: SliceRange>(&self, range: R) -> BufferRef<'_> {
158        let slice = &self.slice[range.clone()];
159        let range = subrange(&self.range(), &range);
160        BufferRef { slice, start: range.start, end: range.end, allocator: self.allocator }
161    }
162
163    /// Splits at |mid| (included in the right child), yielding two BufferRefs.
164    pub fn split_at(&self, mid: usize) -> (BufferRef<'_>, BufferRef<'_>) {
165        let slices = self.slice.split_at(mid);
166        let ranges = split_range(&self.range(), mid);
167        (
168            BufferRef {
169                slice: slices.0,
170                start: ranges.0.start,
171                end: ranges.0.end,
172                allocator: self.allocator,
173            },
174            BufferRef {
175                slice: slices.1,
176                start: ranges.1.start,
177                end: ranges.1.end,
178                allocator: self.allocator,
179            },
180        )
181    }
182
183    /// Returns the range in the underlying BufferSource that this BufferRef covers.
184    pub fn range(&self) -> Range<usize> {
185        self.start..self.end
186    }
187}
188
189/// MutableBufferRef is an unowned, read-write view of a Buffer.
190#[derive(Debug)]
191pub struct MutableBufferRef<'a> {
192    slice: &'a mut [u8],
193    range: Range<usize>,
194    allocator: &'a BufferAllocator,
195}
196
197impl<'a> MutableBufferRef<'a> {
198    /// Returns the buffer's capacity.
199    pub fn len(&self) -> usize {
200        self.range.end - self.range.start
201    }
202
203    pub fn is_empty(&self) -> bool {
204        self.range.end == self.range.start
205    }
206
207    pub fn as_ref(&self) -> BufferRef<'_> {
208        self.subslice(..)
209    }
210
211    pub fn into_ref(self) -> BufferRef<'a> {
212        BufferRef {
213            slice: self.slice,
214            start: self.range.start,
215            end: self.range.end,
216            allocator: self.allocator,
217        }
218    }
219
220    /// Returns a slice of the buffer's contents.
221    pub fn as_slice(&self) -> &[u8] {
222        self.slice
223    }
224
225    /// Returns a mutable slice of the buffer's contents.
226    pub fn as_mut_slice(&mut self) -> &mut [u8] {
227        self.slice
228    }
229
230    /// Reborrows this reference with a lesser lifetime. This mirrors the usual borrowing semantics
231    /// (i.e. the borrow ends when the new reference goes out of scope), and exists so that a
232    /// MutableBufferRef can be subsliced without consuming it.
233    ///
234    /// For example:
235    ///    let mut buf: MutableBufferRef<'_> = ...;
236    ///    {
237    ///        let sub = buf.reborrow().subslice_mut(a..b);
238    ///    }
239    pub fn reborrow(&mut self) -> MutableBufferRef<'_> {
240        MutableBufferRef { slice: self.slice, range: self.range.clone(), allocator: self.allocator }
241    }
242
243    /// Slices this reference. See Buffer::subslice.
244    pub fn subslice<R: SliceRange>(&self, range: R) -> BufferRef<'_> {
245        let slice = &self.slice[range.clone()];
246        let range = subrange(&self.range, &range);
247        BufferRef { slice, start: range.start, end: range.end, allocator: self.allocator }
248    }
249
250    /// Slices and consumes this reference. See Buffer::subslice_mut.
251    pub fn subslice_mut<R: SliceRange>(mut self, range: R) -> MutableBufferRef<'a> {
252        self.slice = &mut self.slice[range.clone()];
253        self.range = subrange(&self.range, &range);
254        self
255    }
256
257    /// Splits at |mid| (included in the right child), yielding two BufferRefs.
258    pub fn split_at(&self, mid: usize) -> (BufferRef<'_>, BufferRef<'_>) {
259        let slices = self.slice.split_at(mid);
260        let ranges = split_range(&self.range, mid);
261        (
262            BufferRef {
263                slice: slices.0,
264                start: ranges.0.start,
265                end: ranges.0.end,
266                allocator: self.allocator,
267            },
268            BufferRef {
269                slice: slices.1,
270                start: ranges.1.start,
271                end: ranges.1.end,
272                allocator: self.allocator,
273            },
274        )
275    }
276
277    /// Consumes the reference and splits it at |mid| (included in the right child), yielding two
278    /// MutableBufferRefs.
279    pub fn split_at_mut(self, mid: usize) -> (MutableBufferRef<'a>, MutableBufferRef<'a>) {
280        let slices = self.slice.split_at_mut(mid);
281        let ranges = split_range(&self.range, mid);
282        (
283            MutableBufferRef { slice: slices.0, range: ranges.0, allocator: self.allocator },
284            MutableBufferRef { slice: slices.1, range: ranges.1, allocator: self.allocator },
285        )
286    }
287
288    /// Returns the range in the underlying BufferSource that this MutableBufferRef covers.
289    pub fn range(&self) -> Range<usize> {
290        self.range.clone()
291    }
292}