blob: 1d5228539c5a8fe771356e6f70c4ae374641a06b [file] [log] [blame]
// 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::{
filesystem::{ApplyContext, JournalingObject},
object_store::{
allocator::{Allocator, AllocatorInfo, Reservation, ReservationOwner},
transaction::{AssocObj, Mutation, Transaction},
},
serialized_types::{Version, LATEST_VERSION},
},
anyhow::Error,
async_trait::async_trait,
std::{
any::Any,
collections::BTreeMap,
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
}
fn info(&self) -> AllocatorInfo {
Default::default()
}
async fn allocate(
&self,
_transaction: &mut Transaction<'_>,
_store_object_id: u64,
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)
}
async fn deallocate(
&self,
_transaction: &mut Transaction<'_>,
_object_id: u64,
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<'_>,
_store_object_id: u64,
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(())
}
async fn mark_for_deletion(&self, _transaction: &mut Transaction<'_>, _owner_object_id: u64) {
unimplemented!();
}
fn as_journaling_object(self: Arc<Self>) -> Arc<dyn JournalingObject> {
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> {
Some(Reservation::new(self, amount))
}
fn reserve_at_most(self: Arc<Self>, amount: u64) -> Reservation {
Reservation::new(self, amount)
}
fn get_allocated_bytes(&self) -> u64 {
let inner = self.0.lock().unwrap();
(inner.alloc_bytes - inner.dealloc_bytes) as u64
}
fn get_owner_allocated_bytes(&self) -> BTreeMap<u64, i64> {
unimplemented!();
}
fn get_used_bytes(&self) -> u64 {
self.get_allocated_bytes()
}
}
impl ReservationOwner for FakeAllocator {
fn release_reservation(&self, _amount: u64) {}
}
#[async_trait]
impl JournalingObject for FakeAllocator {
async fn apply_mutation(
&self,
_mutation: Mutation,
_context: &ApplyContext<'_, '_>,
_associated_object: AssocObj<'_>,
) {
}
fn drop_mutation(&self, _mutation: Mutation, _transaction: &Transaction<'_>) {}
async fn flush(&self) -> Result<Version, Error> {
return Ok(LATEST_VERSION);
}
}