Added documentation / HeapAllocable

This commit is contained in:
Paul Masurel
2016-09-22 14:32:44 +09:00
parent 994f223e35
commit ca331e7fe5
12 changed files with 177 additions and 78 deletions

View File

@@ -1,5 +1,5 @@
use std::mem;
use super::heap::Heap;
use super::heap::{Heap, HeapAllocable};
#[inline]
@@ -53,8 +53,8 @@ impl ExpUnrolledLinkedList {
}
impl From<u32> for ExpUnrolledLinkedList {
fn from(addr: u32) -> ExpUnrolledLinkedList {
impl HeapAllocable for ExpUnrolledLinkedList {
fn with_addr(addr: u32) -> ExpUnrolledLinkedList {
let last_addr = addr + mem::size_of::<u32>() as u32 * 2u32;
ExpUnrolledLinkedList {
len: 0u32,
@@ -67,22 +67,6 @@ impl From<u32> for ExpUnrolledLinkedList {
}
}
impl Default for ExpUnrolledLinkedList {
fn default() -> ExpUnrolledLinkedList {
ExpUnrolledLinkedList {
len: 0u32,
end: 0u32,
val0: 0u32,
val1: 0u32,
val2: 0u32,
next: 0u32,
}
}
}
pub struct ExpUnrolledLinkedListIterator<'a> {
heap: &'a Heap,
addr: u32,

View File

@@ -1,6 +1,9 @@
use std::iter;
use std::marker::PhantomData;
use super::heap::{Heap, BytesRef};
use super::heap::{Heap, HeapAllocable, BytesRef};
/// dbj2 hash function
fn djb2(key: &[u8]) -> u64 {
@@ -54,7 +57,7 @@ pub enum Entry {
/// the computation of the hash of the key twice,
/// or copying the key as long as there is no insert.
///
pub struct HashMap<'a, V> where V: From<u32> {
pub struct HashMap<'a, V> where V: HeapAllocable {
table: Box<[KeyValue]>,
heap: &'a Heap,
_phantom: PhantomData<V>,
@@ -62,7 +65,7 @@ pub struct HashMap<'a, V> where V: From<u32> {
occupied: Vec<usize>,
}
impl<'a, V> HashMap<'a, V> where V: From<u32> {
impl<'a, V> HashMap<'a, V> where V: HeapAllocable {
pub fn new(num_bucket_power_of_2: usize, heap: &'a Heap) -> HashMap<'a, V> {
let table_size = 1 << num_bucket_power_of_2;
@@ -157,7 +160,7 @@ impl<'a, V> HashMap<'a, V> where V: From<u32> {
mod tests {
use super::*;
use super::super::heap::Heap;
use super::super::heap::{Heap, HeapAllocable};
use super::djb2;
use test::Bencher;
use std::hash::SipHasher;
@@ -168,8 +171,8 @@ mod tests {
_addr: u32,
}
impl From<u32> for TestValue {
fn from(addr: u32) -> TestValue {
impl HeapAllocable for TestValue {
fn with_addr(addr: u32) -> TestValue {
TestValue {
val: 0u32,
_addr: addr,

View File

@@ -3,19 +3,26 @@ use std::mem;
use std::ptr;
use std::iter;
/// `BytesRef` refers to a slice in tantivy's custom `Heap`.
#[derive(Copy, Clone)]
pub struct BytesRef {
pub start: u32,
pub stop: u32,
}
/// Object that can be allocated in tantivy's custom `Heap`.
pub trait HeapAllocable {
fn with_addr(addr: u32) -> Self;
}
/// Tantivy's custom `Heap`.
pub struct Heap {
inner: UnsafeCell<InnerHeap>,
}
impl Heap {
/// Creates a new heap with a given capacity
pub fn with_capacity(num_bytes: usize) -> Heap {
Heap {
inner: UnsafeCell::new(
@@ -27,46 +34,62 @@ impl Heap {
fn inner(&self,) -> &mut InnerHeap {
unsafe { &mut *self.inner.get() }
}
/// Clears the heap. All the underlying data is lost.
///
/// This heap does not support deallocation.
/// This method is the only way to free memory.
pub fn clear(&self) {
self.inner().clear();
}
/// Return the heap capacity.
pub fn capacity(&self,) -> u32 {
self.inner().capacity()
}
/// Return the amount of memory that has been allocated so far.
pub fn len(&self,) -> u32 {
self.inner().len()
}
/// Return amount of free space, in bytes.
pub fn num_free_bytes(&self,) -> u32 {
self.inner().num_free_bytes()
}
/// Allocate a given amount of space and returns an address
/// in the Heap.
pub fn allocate_space(&self, num_bytes: usize) -> u32 {
self.inner().allocate_space(num_bytes)
}
pub fn allocate_object<V: From<u32>>(&self,) -> (u32, &mut V) {
/// Allocate an object in the heap
pub fn allocate_object<V: HeapAllocable>(&self,) -> (u32, &mut V) {
let addr = self.inner().allocate_space(mem::size_of::<V>());
let v: V = V::from(addr);
let v: V = V::with_addr(addr);
self.inner().set(addr, &v);
(addr, self.inner().get_mut_ref(addr))
}
/// Stores a `&[u8]` in the heap and returns the destination BytesRef.
pub fn allocate_and_set(&self, data: &[u8]) -> BytesRef {
self.inner().allocate_and_set(data)
}
/// Fetches the `&[u8]` stored on the slice defined by the `BytesRef`
/// given as argumetn
pub fn get_slice(&self, bytes_ref: BytesRef) -> &[u8] {
self.inner().get_slice(bytes_ref.start, bytes_ref.stop)
}
/// Stores an item's data in the heap, at the given `address`.
pub fn set<Item>(&self, addr: u32, val: &Item) {
self.inner().set(addr, val);
}
/// Returns a mutable reference for an object at a given Item.
pub fn get_mut_ref<Item>(&self, addr: u32) -> &mut Item {
self.inner().get_mut_ref(addr)
}
@@ -183,7 +206,7 @@ impl InnerHeap {
}
}
pub fn set<Item>(&mut self, addr: u32, val: &Item) {
fn set<Item>(&mut self, addr: u32, val: &Item) {
if addr >= self.buffer_len {
self.next_heap.as_mut().unwrap().set(addr - self.buffer_len, val);
}

View File

@@ -2,7 +2,7 @@ mod hashmap;
mod heap;
mod expull;
pub use self::heap::Heap;
pub use self::heap::{Heap, HeapAllocable};
pub use self::expull::ExpUnrolledLinkedList;
pub use self::hashmap::{HashMap, Entry};