| // Copyright 2021 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use { |
| crate::object_store::{ |
| allocator::{Allocator, Reservation}, |
| filesystem::Mutations, |
| journal::checksum_list::ChecksumList, |
| transaction::{AssocObj, Mutation, Transaction}, |
| }, |
| anyhow::Error, |
| async_trait::async_trait, |
| std::{ |
| any::Any, |
| ops::Range, |
| sync::{Arc, Mutex}, |
| }, |
| }; |
| |
| const ALLOCATOR_OBJECT_ID: u64 = 2; |
| |
| #[derive(Debug)] |
| struct Inner { |
| next_offset: u64, |
| alloc_bytes: usize, |
| dealloc_bytes: usize, |
| } |
| |
| pub struct FakeAllocator(Mutex<Inner>); |
| |
| impl FakeAllocator { |
| pub fn new() -> Self { |
| FakeAllocator(Mutex::new(Inner { next_offset: 0, alloc_bytes: 0, dealloc_bytes: 0 })) |
| } |
| } |
| |
| #[async_trait] |
| impl Allocator for FakeAllocator { |
| fn object_id(&self) -> u64 { |
| ALLOCATOR_OBJECT_ID |
| } |
| |
| async fn allocate( |
| &self, |
| _transaction: &mut Transaction<'_>, |
| len: u64, |
| ) -> Result<Range<u64>, Error> { |
| let mut inner = self.0.lock().unwrap(); |
| let result = inner.next_offset..inner.next_offset + len; |
| inner.next_offset = result.end; |
| inner.alloc_bytes += len as usize; |
| Ok(result) |
| } |
| |
| fn add_ref(&self, _transaction: &mut Transaction<'_>, _device_range: Range<u64>) { |
| unreachable!(); |
| } |
| |
| async fn deallocate( |
| &self, |
| _transaction: &mut Transaction<'_>, |
| device_range: Range<u64>, |
| ) -> Result<u64, Error> { |
| let mut inner = self.0.lock().unwrap(); |
| assert!(device_range.end <= inner.next_offset); |
| let len = device_range.end - device_range.start; |
| inner.dealloc_bytes += len as usize; |
| assert!(inner.dealloc_bytes <= inner.alloc_bytes); |
| Ok(len) |
| } |
| |
| async fn mark_allocated( |
| &self, |
| _transaction: &mut Transaction<'_>, |
| device_range: Range<u64>, |
| ) -> Result<(), Error> { |
| let mut inner = self.0.lock().unwrap(); |
| inner.next_offset = std::cmp::max(device_range.end, inner.next_offset); |
| Ok(()) |
| } |
| |
| fn as_mutations(self: Arc<Self>) -> Arc<dyn Mutations> { |
| self |
| } |
| |
| fn as_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> { |
| self |
| } |
| |
| async fn did_flush_device(&self, _flush_log_offset: u64) {} |
| |
| fn reserve(self: Arc<Self>, _amount: u64) -> Option<Reservation> { |
| panic!("Not supported"); |
| } |
| |
| fn reserve_at_most(self: Arc<Self>, _amount: u64) -> Reservation { |
| panic!("Not supported"); |
| } |
| |
| fn release_reservation(&self, _reservation: &mut Reservation) {} |
| |
| fn get_allocated_bytes(&self) -> u64 { |
| let inner = self.0.lock().unwrap(); |
| (inner.alloc_bytes - inner.dealloc_bytes) as u64 |
| } |
| |
| async fn validate_mutation( |
| &self, |
| _journal_offset: u64, |
| _mutation: &Mutation, |
| _checksum_list: &mut ChecksumList, |
| ) -> Result<bool, Error> { |
| Ok(true) |
| } |
| } |
| |
| #[async_trait] |
| impl Mutations for FakeAllocator { |
| async fn apply_mutation( |
| &self, |
| _mutation: Mutation, |
| _transaction: Option<&Transaction<'_>>, |
| _log_offset: u64, |
| _associated_object: AssocObj<'_>, |
| ) { |
| } |
| |
| fn drop_mutation(&self, _mutation: Mutation, _transaction: &Transaction<'_>) {} |
| |
| async fn flush(&self) -> Result<(), Error> { |
| Ok(()) |
| } |
| } |