Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/memory_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,15 @@ impl<M: Memory> MemoryManager<M> {
memory_manager: self.inner.clone(),
}
}

/// Returns the underlying memory.
///
/// # Returns
/// - The underlying memory, if there is exactly one strong reference to the memory manager. Please see [`Rc::try_unwrap`](https://doc.rust-lang.org/std/rc/struct.Rc.html#method.try_unwrap) for more details.
/// - None otherwise.
pub fn into_memory(self) -> Option<M> {
Rc::into_inner(self.inner).map(|inner| inner.into_inner().into_memory())
}
}

#[repr(C, packed)]
Expand Down Expand Up @@ -419,6 +428,11 @@ impl<M: Memory> MemoryManagerInner<M> {
// Ceiling division.
(num_pages + self.bucket_size_in_pages as u64 - 1) / self.bucket_size_in_pages as u64
}

// Returns the underlying memory.
pub fn into_memory(self) -> M {
self.memory
}
}

struct Segment {
Expand Down
18 changes: 18 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::*;
use crate::memory_manager::{MemoryId, MemoryManager};
use std::cell::RefCell;
use std::rc::Rc;

Expand Down Expand Up @@ -48,3 +49,20 @@ fn vec_exposes_init_err() {
#[allow(unused_imports)]
use crate::vec::InitError;
}

#[test]
fn should_be_able_to_recover_memory_from_memory_manager() {
let raw_memory = DefaultMemoryImpl::default();
let memory_manager = MemoryManager::init(raw_memory);
let recovered_memory = memory_manager.into_memory();
assert!(recovered_memory.is_some());
}

#[test]
fn should_fail_to_recover_memory_from_memory_manager_if_memory_is_in_use() {
let raw_memory = DefaultMemoryImpl::default();
let memory_manager = MemoryManager::init(raw_memory);
let _a_virtual_memory = memory_manager.get(MemoryId::new(0));
let recovered_memory = memory_manager.into_memory();
assert!(recovered_memory.is_none());
}