Allocate a new aligned buffer. `min_capacity` is rounded up to the next multiple of `alignment`. `alignment` must be a power of two.
(min_capacity: usize, alignment: usize)
| 49 | /// `min_capacity` is rounded up to the next multiple of `alignment`. |
| 50 | /// `alignment` must be a power of two. |
| 51 | pub fn new(min_capacity: usize, alignment: usize) -> Result<Self> { |
| 52 | assert!( |
| 53 | alignment.is_power_of_two(), |
| 54 | "alignment must be power of two" |
| 55 | ); |
| 56 | assert!(alignment > 0, "alignment must be > 0"); |
| 57 | |
| 58 | // Round capacity up to alignment boundary. |
| 59 | let capacity = round_up(min_capacity.max(alignment), alignment); |
| 60 | |
| 61 | let layout = std::alloc::Layout::from_size_align(capacity, alignment).map_err(|_| { |
| 62 | WalError::AlignmentViolation { |
| 63 | context: "buffer allocation", |
| 64 | required: alignment, |
| 65 | actual: min_capacity, |
| 66 | } |
| 67 | })?; |
| 68 | |
| 69 | // SAFETY: Layout has non-zero size (capacity >= alignment > 0). |
| 70 | let ptr = unsafe { std::alloc::alloc_zeroed(layout) }; |
| 71 | if ptr.is_null() { |
| 72 | std::alloc::handle_alloc_error(layout); |
| 73 | } |
| 74 | |
| 75 | Ok(Self { |
| 76 | ptr, |
| 77 | capacity, |
| 78 | len: 0, |
| 79 | alignment, |
| 80 | layout, |
| 81 | }) |
| 82 | } |
| 83 | |
| 84 | /// Allocate with the default 4 KiB alignment. |
| 85 | pub fn with_default_alignment(min_capacity: usize) -> Result<Self> { |