Set block size programatically
This commit is contained in:
Vendored
-204
@@ -9,23 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
//! A HashMap wrapper that holds key-value pairs in insertion order.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```
|
||||
//! use linked_hash_map::LinkedHashMap;
|
||||
//!
|
||||
//! let mut map = LinkedHashMap::new();
|
||||
//! map.insert(2, 20);
|
||||
//! map.insert(1, 10);
|
||||
//! map.insert(3, 30);
|
||||
//! assert_eq!(map[&1], 10);
|
||||
//! assert_eq!(map[&2], 20);
|
||||
//! assert_eq!(map[&3], 30);
|
||||
//!
|
||||
//! let items: Vec<(i32, i32)> = map.iter().map(|t| (*t.0, *t.1)).collect();
|
||||
//! assert_eq!(items, [(2, 20), (1, 10), (3, 30)]);
|
||||
//! ```
|
||||
|
||||
#![forbid(missing_docs)]
|
||||
#![cfg_attr(feature = "nightly", feature(hashmap_public_hasher))]
|
||||
@@ -167,18 +150,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> {
|
||||
|
||||
/// Inserts a key-value pair into the map. If the key already existed, the old value is
|
||||
/// returned.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
/// let mut map = LinkedHashMap::new();
|
||||
///
|
||||
/// map.insert(1, "a");
|
||||
/// map.insert(2, "b");
|
||||
/// assert_eq!(map[&1], "a");
|
||||
/// assert_eq!(map[&2], "b");
|
||||
/// ```
|
||||
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
|
||||
if self.head.is_null() {
|
||||
// allocate the guard node if not present
|
||||
@@ -231,39 +202,11 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> {
|
||||
}
|
||||
|
||||
/// Returns the value corresponding to the key in the map.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
/// let mut map = LinkedHashMap::new();
|
||||
///
|
||||
/// map.insert(1, "a");
|
||||
/// map.insert(2, "b");
|
||||
/// map.insert(2, "c");
|
||||
/// map.insert(3, "d");
|
||||
///
|
||||
/// assert_eq!(map.get(&1), Some(&"a"));
|
||||
/// assert_eq!(map.get(&2), Some(&"c"));
|
||||
/// ```
|
||||
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V> where K: Borrow<Q>, Q: Eq + Hash {
|
||||
self.map.get(Qey::from_ref(k)).map(|e| &e.value)
|
||||
}
|
||||
|
||||
/// Returns the mutable reference corresponding to the key in the map.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
/// let mut map = LinkedHashMap::new();
|
||||
///
|
||||
/// map.insert(1, "a");
|
||||
/// map.insert(2, "b");
|
||||
///
|
||||
/// *map.get_mut(&1).unwrap() = "c";
|
||||
/// assert_eq!(map.get(&1), Some(&"c"));
|
||||
/// ```
|
||||
pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V> where K: Borrow<Q>, Q: Eq + Hash {
|
||||
self.map.get_mut(Qey::from_ref(k)).map(|e| &mut e.value)
|
||||
}
|
||||
@@ -272,21 +215,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> {
|
||||
///
|
||||
/// If value is found, it is moved to the end of the list.
|
||||
/// This operation can be used in implemenation of LRU cache.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
/// let mut map = LinkedHashMap::new();
|
||||
///
|
||||
/// map.insert(1, "a");
|
||||
/// map.insert(2, "b");
|
||||
/// map.insert(3, "d");
|
||||
///
|
||||
/// assert_eq!(map.get_refresh(&2), Some(&mut "b"));
|
||||
///
|
||||
/// assert_eq!((&2, &"b"), map.iter().rev().next().unwrap());
|
||||
/// ```
|
||||
pub fn get_refresh<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V> where K: Borrow<Q>, Q: Eq + Hash {
|
||||
let (value, node_ptr_opt) = match self.map.get_mut(Qey::from_ref(k)) {
|
||||
None => (None, None),
|
||||
@@ -303,20 +231,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> {
|
||||
}
|
||||
|
||||
/// Removes and returns the value corresponding to the key from the map.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
/// let mut map = LinkedHashMap::new();
|
||||
///
|
||||
/// map.insert(2, "a");
|
||||
///
|
||||
/// assert_eq!(map.remove(&1), None);
|
||||
/// assert_eq!(map.remove(&2), Some("a"));
|
||||
/// assert_eq!(map.remove(&2), None);
|
||||
/// assert_eq!(map.len(), 0);
|
||||
/// ```
|
||||
pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V> where K: Borrow<Q>, Q: Eq + Hash {
|
||||
let removed = self.map.remove(Qey::from_ref(k));
|
||||
removed.map(|mut node| {
|
||||
@@ -335,14 +249,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> {
|
||||
}
|
||||
|
||||
/// Returns the maximum number of key-value pairs the map can hold without reallocating.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
/// let mut map: LinkedHashMap<i32, &str> = LinkedHashMap::new();
|
||||
/// let capacity = map.capacity();
|
||||
/// ```
|
||||
pub fn capacity(&self) -> usize {
|
||||
self.map.capacity()
|
||||
}
|
||||
@@ -350,18 +256,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> {
|
||||
/// Removes the first entry.
|
||||
///
|
||||
/// Can be used in implementation of LRU cache.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
/// let mut map = LinkedHashMap::new();
|
||||
/// map.insert(1, 10);
|
||||
/// map.insert(2, 20);
|
||||
/// map.pop_front();
|
||||
/// assert_eq!(map.get(&1), None);
|
||||
/// assert_eq!(map.get(&2), Some(&20));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn pop_front(&mut self) -> Option<(K, V)> {
|
||||
if self.len() > 0 {
|
||||
@@ -375,16 +269,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> {
|
||||
}
|
||||
|
||||
/// Gets the first entry.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
/// let mut map = LinkedHashMap::new();
|
||||
/// map.insert(1, 10);
|
||||
/// map.insert(2, 20);
|
||||
/// assert_eq!(map.front(), Some((&1, &10)));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn front(&self) -> Option<(&K, &V)> {
|
||||
if self.len() > 0 {
|
||||
@@ -396,18 +280,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> {
|
||||
}
|
||||
|
||||
/// Removes the last entry.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
/// let mut map = LinkedHashMap::new();
|
||||
/// map.insert(1, 10);
|
||||
/// map.insert(2, 20);
|
||||
/// map.pop_back();
|
||||
/// assert_eq!(map.get(&1), Some(&10));
|
||||
/// assert_eq!(map.get(&2), None);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn pop_back(&mut self) -> Option<(K, V)> {
|
||||
if self.len() > 0 {
|
||||
@@ -421,16 +293,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> {
|
||||
}
|
||||
|
||||
/// Gets the last entry.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
/// let mut map = LinkedHashMap::new();
|
||||
/// map.insert(1, 10);
|
||||
/// map.insert(2, 20);
|
||||
/// assert_eq!(map.back(), Some((&2, &20)));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn back(&mut self) -> Option<(&K, &V)> {
|
||||
if self.len() > 0 {
|
||||
@@ -461,22 +323,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> {
|
||||
|
||||
/// Returns a double-ended iterator visiting all key-value pairs in order of insertion.
|
||||
/// Iterator element type is `(&'a K, &'a V)`
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
///
|
||||
/// let mut map = LinkedHashMap::new();
|
||||
/// map.insert("a", 10);
|
||||
/// map.insert("c", 30);
|
||||
/// map.insert("b", 20);
|
||||
///
|
||||
/// let mut iter = map.iter();
|
||||
/// assert_eq!((&"a", &10), iter.next().unwrap());
|
||||
/// assert_eq!((&"c", &30), iter.next().unwrap());
|
||||
/// assert_eq!((&"b", &20), iter.next().unwrap());
|
||||
/// assert_eq!(None, iter.next());
|
||||
/// ```
|
||||
pub fn iter(&self) -> Iter<K, V> {
|
||||
let head = if ! self.head.is_null() {
|
||||
unsafe { (*self.head).prev }
|
||||
@@ -493,24 +339,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> {
|
||||
|
||||
/// Returns a double-ended iterator visiting all key-value pairs in order of insertion.
|
||||
/// Iterator element type is `(&'a K, &'a mut V)`
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
///
|
||||
/// let mut map = LinkedHashMap::new();
|
||||
/// map.insert("a", 10);
|
||||
/// map.insert("c", 30);
|
||||
/// map.insert("b", 20);
|
||||
///
|
||||
/// {
|
||||
/// let mut iter = map.iter_mut();
|
||||
/// let mut entry = iter.next().unwrap();
|
||||
/// assert_eq!(&"a", entry.0);
|
||||
/// *entry.1 = 17;
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(&17, map.get(&"a").unwrap());
|
||||
/// ```
|
||||
pub fn iter_mut(&mut self) -> IterMut<K, V> {
|
||||
let head = if ! self.head.is_null() {
|
||||
unsafe { (*self.head).prev }
|
||||
@@ -526,22 +354,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> {
|
||||
}
|
||||
|
||||
/// Returns a double-ended iterator visiting all key in order of insertion.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
///
|
||||
/// let mut map = LinkedHashMap::new();
|
||||
/// map.insert('a', 10);
|
||||
/// map.insert('c', 30);
|
||||
/// map.insert('b', 20);
|
||||
///
|
||||
/// let mut keys = map.keys();
|
||||
/// assert_eq!(&'a', keys.next().unwrap());
|
||||
/// assert_eq!(&'c', keys.next().unwrap());
|
||||
/// assert_eq!(&'b', keys.next().unwrap());
|
||||
/// assert_eq!(None, keys.next());
|
||||
/// ```
|
||||
pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
|
||||
fn first<A, B>((a, _): (A, B)) -> A { a }
|
||||
let first: fn((&'a K, &'a V)) -> &'a K = first; // coerce to fn ptr
|
||||
@@ -550,22 +362,6 @@ impl<K: Hash + Eq, V, S: BuildHasher> LinkedHashMap<K, V, S> {
|
||||
}
|
||||
|
||||
/// Returns a double-ended iterator visiting all values in order of insertion.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use linked_hash_map::LinkedHashMap;
|
||||
///
|
||||
/// let mut map = LinkedHashMap::new();
|
||||
/// map.insert('a', 10);
|
||||
/// map.insert('c', 30);
|
||||
/// map.insert('b', 20);
|
||||
///
|
||||
/// let mut values = map.values();
|
||||
/// assert_eq!(&10, values.next().unwrap());
|
||||
/// assert_eq!(&30, values.next().unwrap());
|
||||
/// assert_eq!(&20, values.next().unwrap());
|
||||
/// assert_eq!(None, values.next());
|
||||
/// ```
|
||||
pub fn values<'a>(&'a self) -> Values<'a, K, V> {
|
||||
fn second<A, B>((_, b): (A, B)) -> B { b }
|
||||
let second: fn((&'a K, &'a V)) -> &'a V = second; // coerce to fn ptr
|
||||
|
||||
Vendored
-164
@@ -12,30 +12,6 @@
|
||||
//! capacity of the cache is exceeded, the least-recently-used
|
||||
//! (where "used" means a look-up or putting the pair into the cache)
|
||||
//! pair is automatically removed.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```
|
||||
//! use lru_cache::LruCache;
|
||||
//!
|
||||
//! let mut cache = LruCache::new(2);
|
||||
//!
|
||||
//! cache.insert(1, 10);
|
||||
//! cache.insert(2, 20);
|
||||
//! cache.insert(3, 30);
|
||||
//! assert!(cache.get_mut(&1).is_none());
|
||||
//! assert_eq!(*cache.get_mut(&2).unwrap(), 20);
|
||||
//! assert_eq!(*cache.get_mut(&3).unwrap(), 30);
|
||||
//!
|
||||
//! cache.insert(2, 22);
|
||||
//! assert_eq!(*cache.get_mut(&2).unwrap(), 22);
|
||||
//!
|
||||
//! cache.insert(6, 60);
|
||||
//! assert!(cache.get_mut(&3).is_none());
|
||||
//!
|
||||
//! cache.set_capacity(1);
|
||||
//! assert!(cache.get_mut(&2).is_none());
|
||||
//! ```
|
||||
|
||||
use std::collections::hash_map::RandomState;
|
||||
use std::fmt;
|
||||
@@ -54,13 +30,6 @@ pub struct LruCache<K, V, S = RandomState> where K: Eq + Hash, S: BuildHasher {
|
||||
|
||||
impl<K: Hash + Eq, V> LruCache<K, V> {
|
||||
/// Creates an empty cache that can hold at most `capacity` items.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use lru_cache::LruCache;
|
||||
/// let mut cache: LruCache<i32, &str> = LruCache::new(10);
|
||||
/// ```
|
||||
pub fn new(capacity: usize) -> LruCache<K, V> {
|
||||
LruCache {
|
||||
map: LinkedHashMap::new(),
|
||||
@@ -76,17 +45,6 @@ impl<K, V, S> LruCache<K, V, S> where K: Eq + Hash, S: BuildHasher {
|
||||
}
|
||||
|
||||
/// Checks if the map contains the given key.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use lru_cache::LruCache;
|
||||
///
|
||||
/// let mut cache = LruCache::new(1);
|
||||
///
|
||||
/// cache.insert(1, "a");
|
||||
/// assert_eq!(cache.contains_key(&1), true);
|
||||
/// ```
|
||||
pub fn contains_key<Q: ?Sized>(&mut self, key: &Q) -> bool
|
||||
where K: Borrow<Q>,
|
||||
Q: Hash + Eq
|
||||
@@ -96,19 +54,6 @@ impl<K, V, S> LruCache<K, V, S> where K: Eq + Hash, S: BuildHasher {
|
||||
|
||||
/// Inserts a key-value pair into the cache. If the key already existed, the old value is
|
||||
/// returned.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use lru_cache::LruCache;
|
||||
///
|
||||
/// let mut cache = LruCache::new(2);
|
||||
///
|
||||
/// cache.insert(1, "a");
|
||||
/// cache.insert(2, "b");
|
||||
/// assert_eq!(cache.get_mut(&1), Some(&mut "a"));
|
||||
/// assert_eq!(cache.get_mut(&2), Some(&mut "b"));
|
||||
/// ```
|
||||
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
|
||||
let old_val = self.map.insert(k, v);
|
||||
if self.len() > self.capacity() {
|
||||
@@ -119,22 +64,6 @@ impl<K, V, S> LruCache<K, V, S> where K: Eq + Hash, S: BuildHasher {
|
||||
|
||||
/// Returns a mutable reference to the value corresponding to the given key in the cache, if
|
||||
/// any.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use lru_cache::LruCache;
|
||||
///
|
||||
/// let mut cache = LruCache::new(2);
|
||||
///
|
||||
/// cache.insert(1, "a");
|
||||
/// cache.insert(2, "b");
|
||||
/// cache.insert(2, "c");
|
||||
/// cache.insert(3, "d");
|
||||
///
|
||||
/// assert_eq!(cache.get_mut(&1), None);
|
||||
/// assert_eq!(cache.get_mut(&2), Some(&mut "c"));
|
||||
/// ```
|
||||
pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
|
||||
where K: Borrow<Q>,
|
||||
Q: Hash + Eq
|
||||
@@ -143,21 +72,6 @@ impl<K, V, S> LruCache<K, V, S> where K: Eq + Hash, S: BuildHasher {
|
||||
}
|
||||
|
||||
/// Removes the given key from the cache and returns its corresponding value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use lru_cache::LruCache;
|
||||
///
|
||||
/// let mut cache = LruCache::new(2);
|
||||
///
|
||||
/// cache.insert(2, "a");
|
||||
///
|
||||
/// assert_eq!(cache.remove(&1), None);
|
||||
/// assert_eq!(cache.remove(&2), Some("a"));
|
||||
/// assert_eq!(cache.remove(&2), None);
|
||||
/// assert_eq!(cache.len(), 0);
|
||||
/// ```
|
||||
pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
|
||||
where K: Borrow<Q>,
|
||||
Q: Hash + Eq
|
||||
@@ -166,50 +80,12 @@ impl<K, V, S> LruCache<K, V, S> where K: Eq + Hash, S: BuildHasher {
|
||||
}
|
||||
|
||||
/// Returns the maximum number of key-value pairs the cache can hold.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use lru_cache::LruCache;
|
||||
/// let mut cache: LruCache<i32, &str> = LruCache::new(2);
|
||||
/// assert_eq!(cache.capacity(), 2);
|
||||
/// ```
|
||||
pub fn capacity(&self) -> usize {
|
||||
self.max_size
|
||||
}
|
||||
|
||||
/// Sets the number of key-value pairs the cache can hold. Removes
|
||||
/// least-recently-used key-value pairs if necessary.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use lru_cache::LruCache;
|
||||
///
|
||||
/// let mut cache = LruCache::new(2);
|
||||
///
|
||||
/// cache.insert(1, "a");
|
||||
/// cache.insert(2, "b");
|
||||
/// cache.insert(3, "c");
|
||||
///
|
||||
/// assert_eq!(cache.get_mut(&1), None);
|
||||
/// assert_eq!(cache.get_mut(&2), Some(&mut "b"));
|
||||
/// assert_eq!(cache.get_mut(&3), Some(&mut "c"));
|
||||
///
|
||||
/// cache.set_capacity(3);
|
||||
/// cache.insert(1, "a");
|
||||
/// cache.insert(2, "b");
|
||||
///
|
||||
/// assert_eq!(cache.get_mut(&1), Some(&mut "a"));
|
||||
/// assert_eq!(cache.get_mut(&2), Some(&mut "b"));
|
||||
/// assert_eq!(cache.get_mut(&3), Some(&mut "c"));
|
||||
///
|
||||
/// cache.set_capacity(1);
|
||||
///
|
||||
/// assert_eq!(cache.get_mut(&1), None);
|
||||
/// assert_eq!(cache.get_mut(&2), None);
|
||||
/// assert_eq!(cache.get_mut(&3), Some(&mut "c"));
|
||||
/// ```
|
||||
pub fn set_capacity(&mut self, capacity: usize) {
|
||||
for _ in capacity..self.len() {
|
||||
self.remove_lru();
|
||||
@@ -234,52 +110,12 @@ impl<K, V, S> LruCache<K, V, S> where K: Eq + Hash, S: BuildHasher {
|
||||
/// Returns an iterator over the cache's key-value pairs in least- to most-recently-used order.
|
||||
///
|
||||
/// Accessing the cache through the iterator does _not_ affect the cache's LRU state.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use lru_cache::LruCache;
|
||||
///
|
||||
/// let mut cache = LruCache::new(2);
|
||||
///
|
||||
/// cache.insert(1, 10);
|
||||
/// cache.insert(2, 20);
|
||||
/// cache.insert(3, 30);
|
||||
///
|
||||
/// let kvs: Vec<_> = cache.iter().collect();
|
||||
/// assert_eq!(kvs, [(&2, &20), (&3, &30)]);
|
||||
/// ```
|
||||
pub fn iter(&self) -> Iter<K, V> { Iter(self.map.iter()) }
|
||||
|
||||
/// Returns an iterator over the cache's key-value pairs in least- to most-recently-used order,
|
||||
/// with mutable references to the values.
|
||||
///
|
||||
/// Accessing the cache through the iterator does _not_ affect the cache's LRU state.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use lru_cache::LruCache;
|
||||
///
|
||||
/// let mut cache = LruCache::new(2);
|
||||
///
|
||||
/// cache.insert(1, 10);
|
||||
/// cache.insert(2, 20);
|
||||
/// cache.insert(3, 30);
|
||||
///
|
||||
/// let mut n = 2;
|
||||
///
|
||||
/// for (k, v) in cache.iter_mut() {
|
||||
/// assert_eq!(*k, n);
|
||||
/// assert_eq!(*v, n * 10);
|
||||
/// *v *= 10;
|
||||
/// n += 1;
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(n, 4);
|
||||
/// assert_eq!(cache.get_mut(&2), Some(&mut 200));
|
||||
/// assert_eq!(cache.get_mut(&3), Some(&mut 300));
|
||||
/// ```
|
||||
pub fn iter_mut(&mut self) -> IterMut<K, V> { IterMut(self.map.iter_mut()) }
|
||||
}
|
||||
|
||||
|
||||
Vendored
+14
-13
@@ -1,6 +1,7 @@
|
||||
use std::{cmp, ptr};
|
||||
use syscall::error::Result;
|
||||
|
||||
use BLOCK_SIZE;
|
||||
use disk::Disk;
|
||||
|
||||
use self::lru_cache::LruCache;
|
||||
@@ -16,14 +17,14 @@ fn copy_memory(src: &[u8], dest: &mut [u8]) -> usize {
|
||||
|
||||
pub struct DiskCache<T> {
|
||||
inner: T,
|
||||
cache: LruCache<u64, [u8; 512]>,
|
||||
cache: LruCache<u64, [u8; BLOCK_SIZE as usize]>,
|
||||
}
|
||||
|
||||
impl<T: Disk> DiskCache<T> {
|
||||
pub fn new(inner: T) -> Self {
|
||||
DiskCache {
|
||||
inner: inner,
|
||||
cache: LruCache::new(65536) // 32 MB cache
|
||||
cache: LruCache::new((256 * 1024 * 1024 / BLOCK_SIZE) as usize) // 256 MB cache
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,11 +35,11 @@ impl<T: Disk> Disk for DiskCache<T> {
|
||||
|
||||
let mut read = 0;
|
||||
let mut failed = false;
|
||||
for i in 0..(buffer.len() + 511)/512 {
|
||||
for i in 0..(buffer.len() + BLOCK_SIZE as usize - 1)/(BLOCK_SIZE as usize) {
|
||||
let block_i = block + i as u64;
|
||||
|
||||
let buffer_i = i * 512;
|
||||
let buffer_j = cmp::min(buffer_i + 512, buffer.len());
|
||||
let buffer_i = i * BLOCK_SIZE as usize;
|
||||
let buffer_j = cmp::min(buffer_i + BLOCK_SIZE as usize, buffer.len());
|
||||
let buffer_slice = &mut buffer[buffer_i .. buffer_j];
|
||||
|
||||
if let Some(cache_buf) = self.cache.get_mut(&block_i) {
|
||||
@@ -53,14 +54,14 @@ impl<T: Disk> Disk for DiskCache<T> {
|
||||
self.inner.read_at(block, buffer)?;
|
||||
|
||||
read = 0;
|
||||
for i in 0..(buffer.len() + 511)/512 {
|
||||
for i in 0..(buffer.len() + BLOCK_SIZE as usize - 1)/(BLOCK_SIZE as usize) {
|
||||
let block_i = block + i as u64;
|
||||
|
||||
let buffer_i = i * 512;
|
||||
let buffer_j = cmp::min(buffer_i + 512, buffer.len());
|
||||
let buffer_i = i * BLOCK_SIZE as usize;
|
||||
let buffer_j = cmp::min(buffer_i + BLOCK_SIZE as usize, buffer.len());
|
||||
let buffer_slice = &buffer[buffer_i .. buffer_j];
|
||||
|
||||
let mut cache_buf = [0; 512];
|
||||
let mut cache_buf = [0; BLOCK_SIZE as usize];
|
||||
read += copy_memory(buffer_slice, &mut cache_buf);
|
||||
self.cache.insert(block_i, cache_buf);
|
||||
}
|
||||
@@ -75,14 +76,14 @@ impl<T: Disk> Disk for DiskCache<T> {
|
||||
self.inner.write_at(block, buffer)?;
|
||||
|
||||
let mut written = 0;
|
||||
for i in 0..(buffer.len() + 511)/512 {
|
||||
for i in 0..(buffer.len() + BLOCK_SIZE as usize - 1)/(BLOCK_SIZE as usize) {
|
||||
let block_i = block + i as u64;
|
||||
|
||||
let buffer_i = i * 512;
|
||||
let buffer_j = cmp::min(buffer_i + 512, buffer.len());
|
||||
let buffer_i = i * BLOCK_SIZE as usize;
|
||||
let buffer_j = cmp::min(buffer_i + BLOCK_SIZE as usize, buffer.len());
|
||||
let buffer_slice = &buffer[buffer_i .. buffer_j];
|
||||
|
||||
let mut cache_buf = [0; 512];
|
||||
let mut cache_buf = [0; BLOCK_SIZE as usize];
|
||||
written += copy_memory(buffer_slice, &mut cache_buf);
|
||||
self.cache.insert(block_i, cache_buf);
|
||||
}
|
||||
|
||||
+3
-2
@@ -2,6 +2,7 @@ use std::fs::{File, OpenOptions};
|
||||
use std::io::{Read, Write, Seek, SeekFrom};
|
||||
use syscall::error::{Error, Result, EIO};
|
||||
|
||||
use BLOCK_SIZE;
|
||||
use disk::Disk;
|
||||
|
||||
macro_rules! try_disk {
|
||||
@@ -37,13 +38,13 @@ impl DiskFile {
|
||||
|
||||
impl Disk for DiskFile {
|
||||
fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
|
||||
try_disk!(self.file.seek(SeekFrom::Start(block * 512)));
|
||||
try_disk!(self.file.seek(SeekFrom::Start(block * BLOCK_SIZE)));
|
||||
let count = try_disk!(self.file.read(buffer));
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
fn write_at(&mut self, block: u64, buffer: &[u8]) -> Result<usize> {
|
||||
try_disk!(self.file.seek(SeekFrom::Start(block * 512)));
|
||||
try_disk!(self.file.seek(SeekFrom::Start(block * BLOCK_SIZE)));
|
||||
let count = try_disk!(self.file.write(buffer));
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
+5
-4
@@ -1,13 +1,14 @@
|
||||
use std::{fmt, mem, ops, slice};
|
||||
|
||||
use super::Extent;
|
||||
use BLOCK_SIZE;
|
||||
use Extent;
|
||||
|
||||
/// An extra node
|
||||
#[repr(packed)]
|
||||
pub struct ExNode {
|
||||
pub prev: u64,
|
||||
pub next: u64,
|
||||
pub extents: [Extent; 31],
|
||||
pub extents: [Extent; (BLOCK_SIZE as usize - 16)/16],
|
||||
}
|
||||
|
||||
impl ExNode {
|
||||
@@ -15,7 +16,7 @@ impl ExNode {
|
||||
ExNode {
|
||||
prev: 0,
|
||||
next: 0,
|
||||
extents: [Extent::default(); 31],
|
||||
extents: [Extent::default(); (BLOCK_SIZE as usize - 16)/16],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,5 +55,5 @@ impl ops::DerefMut for ExNode {
|
||||
|
||||
#[test]
|
||||
fn ex_node_size_test() {
|
||||
assert_eq!(mem::size_of::<ExNode>(), 512);
|
||||
assert_eq!(mem::size_of::<ExNode>(), BLOCK_SIZE as usize);
|
||||
}
|
||||
|
||||
+5
-3
@@ -1,5 +1,7 @@
|
||||
use std::cmp::min;
|
||||
|
||||
use BLOCK_SIZE;
|
||||
|
||||
pub struct BlockIter {
|
||||
block: u64,
|
||||
length: u64,
|
||||
@@ -7,10 +9,10 @@ pub struct BlockIter {
|
||||
}
|
||||
|
||||
impl Iterator<> for BlockIter {
|
||||
type Item = (u64, usize);
|
||||
type Item = (u64, u64);
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.i < (self.length + 511)/512 {
|
||||
let ret = Some((self.block + self.i, min(512, self.length - self.i * 512) as usize));
|
||||
if self.i < (self.length + BLOCK_SIZE - 1)/BLOCK_SIZE {
|
||||
let ret = Some((self.block + self.i, min(BLOCK_SIZE, self.length - self.i * BLOCK_SIZE)));
|
||||
self.i += 1;
|
||||
ret
|
||||
} else {
|
||||
|
||||
+41
-41
@@ -2,7 +2,7 @@ use std::cmp::min;
|
||||
|
||||
use syscall::error::{Result, Error, EEXIST, EISDIR, ENOENT, ENOSPC, ENOTDIR, ENOTEMPTY};
|
||||
|
||||
use super::{Disk, ExNode, Extent, Header, Node};
|
||||
use {BLOCK_SIZE, Disk, ExNode, Extent, Header, Node};
|
||||
|
||||
/// A file system
|
||||
pub struct FileSystem<D: Disk> {
|
||||
@@ -45,11 +45,11 @@ impl<D: Disk> FileSystem<D> {
|
||||
/// Reserved data will be zero padded up to the nearest block
|
||||
pub fn create_reserved(mut disk: D, reserved: &[u8], ctime: u64, ctime_nsec: u32) -> Result<Self> {
|
||||
let size = disk.size()?;
|
||||
let block_offset = (reserved.len() as u64 + 511)/512;
|
||||
let block_offset = (reserved.len() as u64 + BLOCK_SIZE - 1)/BLOCK_SIZE;
|
||||
|
||||
if size >= (block_offset + 4) * 512 {
|
||||
if size >= (block_offset + 4) * BLOCK_SIZE {
|
||||
let mut free = (2, Node::new(Node::MODE_FILE, "free", 0, ctime, ctime_nsec));
|
||||
free.1.extents[0] = Extent::new(4, size - (block_offset + 4) * 512);
|
||||
free.1.extents[0] = Extent::new(4, size - (block_offset + 4) * BLOCK_SIZE);
|
||||
disk.write_at(block_offset + free.0, &free.1)?;
|
||||
|
||||
let root = (1, Node::new(Node::MODE_DIR | 0o755, "root", 0, ctime, ctime_nsec));
|
||||
@@ -59,11 +59,11 @@ impl<D: Disk> FileSystem<D> {
|
||||
disk.write_at(block_offset + header.0, &header.1)?;
|
||||
|
||||
for block in 0..block_offset as usize {
|
||||
let mut data = [0; 512];
|
||||
let mut data = [0; BLOCK_SIZE as usize];
|
||||
|
||||
let mut i = 0;
|
||||
while i < data.len() && block * 512 + i < reserved.len() {
|
||||
data[i] = reserved[block * 512 + i];
|
||||
while i < data.len() && block * BLOCK_SIZE as usize + i < reserved.len() {
|
||||
data[i] = reserved[block * BLOCK_SIZE as usize + i];
|
||||
i += 1;
|
||||
}
|
||||
|
||||
@@ -94,9 +94,9 @@ impl<D: Disk> FileSystem<D> {
|
||||
let mut free = self.node(free_block)?;
|
||||
let mut block_option = None;
|
||||
for extent in free.1.extents.iter_mut() {
|
||||
if extent.length/512 >= length {
|
||||
if extent.length/BLOCK_SIZE >= length {
|
||||
block_option = Some(extent.block);
|
||||
extent.length -= length * 512;
|
||||
extent.length -= length * BLOCK_SIZE;
|
||||
extent.block += length;
|
||||
break;
|
||||
}
|
||||
@@ -134,7 +134,7 @@ impl<D: Disk> FileSystem<D> {
|
||||
let parent = self.node(parent_block)?;
|
||||
for extent in parent.1.extents.iter() {
|
||||
for (block, size) in extent.blocks() {
|
||||
if size >= 512 {
|
||||
if size >= BLOCK_SIZE {
|
||||
children.push(self.node(block)?);
|
||||
}
|
||||
}
|
||||
@@ -151,7 +151,7 @@ impl<D: Disk> FileSystem<D> {
|
||||
let parent = self.node(parent_block)?;
|
||||
for extent in parent.1.extents.iter() {
|
||||
for (block, size) in extent.blocks() {
|
||||
if size >= 512 {
|
||||
if size >= BLOCK_SIZE {
|
||||
let child = self.node(block)?;
|
||||
|
||||
let mut matches = false;
|
||||
@@ -185,13 +185,13 @@ impl<D: Disk> FileSystem<D> {
|
||||
extent.block = block;
|
||||
extent.length = length;
|
||||
break;
|
||||
} else if length % 512 == 0 && extent.block == block + length/512 {
|
||||
} else if length % BLOCK_SIZE == 0 && extent.block == block + length/BLOCK_SIZE {
|
||||
//At beginning
|
||||
inserted = true;
|
||||
extent.block = block;
|
||||
extent.length += length;
|
||||
break;
|
||||
} else if extent.length % 512 == 0 && extent.block + extent.length/512 == block {
|
||||
} else if extent.length % BLOCK_SIZE == 0 && extent.block + extent.length/BLOCK_SIZE == block {
|
||||
//At end
|
||||
inserted = true;
|
||||
extent.length += length;
|
||||
@@ -225,7 +225,7 @@ impl<D: Disk> FileSystem<D> {
|
||||
let node = (self.allocate(1)?, Node::new(mode, name, parent_block, ctime, ctime_nsec));
|
||||
self.write_at(node.0, &node.1)?;
|
||||
|
||||
self.insert_blocks(node.0, 512, parent_block)?;
|
||||
self.insert_blocks(node.0, BLOCK_SIZE, parent_block)?;
|
||||
|
||||
Ok(node)
|
||||
}
|
||||
@@ -240,12 +240,12 @@ impl<D: Disk> FileSystem<D> {
|
||||
let mut replace_option = None;
|
||||
let mut parent = self.node(parent_block)?;
|
||||
for extent in parent.1.extents.iter_mut() {
|
||||
if block >= extent.block && block + length <= extent.block + extent.length/512 {
|
||||
if block >= extent.block && block + length <= extent.block + extent.length/BLOCK_SIZE {
|
||||
//Inside
|
||||
removed = true;
|
||||
|
||||
let left = Extent::new(extent.block, (block - extent.block) * 512);
|
||||
let right = Extent::new(block + length, ((extent.block + extent.length/512) - (block + length)) * 512);
|
||||
let left = Extent::new(extent.block, (block - extent.block) * BLOCK_SIZE);
|
||||
let right = Extent::new(block + length, ((extent.block + extent.length/BLOCK_SIZE) - (block + length)) * BLOCK_SIZE);
|
||||
|
||||
if left.length > 0 {
|
||||
*extent = left;
|
||||
@@ -270,7 +270,7 @@ impl<D: Disk> FileSystem<D> {
|
||||
self.insert_blocks(replace.block, replace.length, parent_block)?;
|
||||
}
|
||||
|
||||
self.deallocate(block, 512)?;
|
||||
self.deallocate(block, BLOCK_SIZE)?;
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -316,7 +316,7 @@ impl<D: Disk> FileSystem<D> {
|
||||
break;
|
||||
} else {
|
||||
changed = true;
|
||||
let allocated = ((extent.length + 511)/512) * 512;
|
||||
let allocated = ((extent.length + BLOCK_SIZE - 1)/BLOCK_SIZE) * BLOCK_SIZE;
|
||||
if allocated >= length {
|
||||
extent.length = length;
|
||||
length = 0;
|
||||
@@ -336,7 +336,7 @@ impl<D: Disk> FileSystem<D> {
|
||||
if node.1.next > 0 {
|
||||
self.node_ensure_len(node.1.next, length)
|
||||
} else {
|
||||
let new_block = self.allocate((length + 511)/512)?;
|
||||
let new_block = self.allocate((length + BLOCK_SIZE - 1)/BLOCK_SIZE)?;
|
||||
self.insert_blocks(new_block, length, block)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -356,10 +356,10 @@ impl<D: Disk> FileSystem<D> {
|
||||
let mut node = self.node(block)?;
|
||||
for extent in node.1.extents.iter_mut() {
|
||||
if extent.length > length {
|
||||
let start = (length + 511)/512;
|
||||
let end = (extent.length + 511)/512;
|
||||
let start = (length + BLOCK_SIZE - 1)/BLOCK_SIZE;
|
||||
let end = (extent.length + BLOCK_SIZE - 1)/BLOCK_SIZE;
|
||||
if end > start {
|
||||
self.deallocate(extent.block + start, (end - start) * 512)?;
|
||||
self.deallocate(extent.block + start, (end - start) * BLOCK_SIZE)?;
|
||||
}
|
||||
extent.length = length;
|
||||
changed = true;
|
||||
@@ -393,9 +393,9 @@ impl<D: Disk> FileSystem<D> {
|
||||
if push_extent.block == 0 {
|
||||
push_extent.block = block;
|
||||
}
|
||||
if len >= size {
|
||||
push_extent.length += size as u64;
|
||||
len -= size;
|
||||
if len as u64 >= size {
|
||||
push_extent.length += size;
|
||||
len -= size as usize;
|
||||
} else if len > 0 {
|
||||
push_extent.length += len as u64;
|
||||
len = 0;
|
||||
@@ -423,8 +423,8 @@ impl<D: Disk> FileSystem<D> {
|
||||
}
|
||||
|
||||
pub fn read_node(&mut self, block: u64, offset: u64, buf: &mut [u8]) -> Result<usize> {
|
||||
let block_offset = offset / 512;
|
||||
let mut byte_offset = (offset % 512) as usize;
|
||||
let block_offset = offset / BLOCK_SIZE;
|
||||
let mut byte_offset = (offset % BLOCK_SIZE) as usize;
|
||||
|
||||
let mut extents = Vec::new();
|
||||
self.node_extents(block, block_offset, byte_offset + buf.len(), &mut extents)?;
|
||||
@@ -435,7 +435,7 @@ impl<D: Disk> FileSystem<D> {
|
||||
let mut length = extent.length;
|
||||
|
||||
if byte_offset > 0 && length > 0 {
|
||||
let mut sector = [0; 512];
|
||||
let mut sector = [0; BLOCK_SIZE as usize];
|
||||
self.read_at(block, &mut sector)?;
|
||||
|
||||
let sector_size = min(sector.len() as u64, length) as usize;
|
||||
@@ -450,18 +450,18 @@ impl<D: Disk> FileSystem<D> {
|
||||
byte_offset = 0;
|
||||
}
|
||||
|
||||
let length_aligned = ((min(length, (buf.len() - i) as u64)/512) * 512) as usize;
|
||||
let length_aligned = ((min(length, (buf.len() - i) as u64)/BLOCK_SIZE) * BLOCK_SIZE) as usize;
|
||||
|
||||
if length_aligned > 0 {
|
||||
let extent_buf = &mut buf[i..i + length_aligned];
|
||||
self.read_at(block, extent_buf)?;
|
||||
i += length_aligned;
|
||||
block += (length_aligned as u64)/512;
|
||||
block += (length_aligned as u64)/BLOCK_SIZE;
|
||||
length -= length_aligned as u64;
|
||||
}
|
||||
|
||||
if length > 0 {
|
||||
let mut sector = [0; 512];
|
||||
let mut sector = [0; BLOCK_SIZE as usize];
|
||||
self.read_at(block, &mut sector)?;
|
||||
|
||||
let sector_size = min(sector.len() as u64, length) as usize;
|
||||
@@ -475,17 +475,17 @@ impl<D: Disk> FileSystem<D> {
|
||||
}
|
||||
|
||||
assert_eq!(length, 0);
|
||||
assert_eq!(block, extent.block + (extent.length + 511)/512);
|
||||
assert_eq!(block, extent.block + (extent.length + BLOCK_SIZE - 1)/BLOCK_SIZE);
|
||||
}
|
||||
|
||||
Ok(i)
|
||||
}
|
||||
|
||||
pub fn write_node(&mut self, block: u64, offset: u64, buf: &[u8], mtime: u64, mtime_nsec: u32) -> Result<usize> {
|
||||
let block_offset = offset / 512;
|
||||
let mut byte_offset = (offset % 512) as usize;
|
||||
let block_offset = offset / BLOCK_SIZE;
|
||||
let mut byte_offset = (offset % BLOCK_SIZE) as usize;
|
||||
|
||||
self.node_ensure_len(block, block_offset as u64 * 512 + (byte_offset + buf.len()) as u64)?;
|
||||
self.node_ensure_len(block, block_offset as u64 * BLOCK_SIZE + (byte_offset + buf.len()) as u64)?;
|
||||
|
||||
let mut extents = Vec::new();
|
||||
self.node_extents(block, block_offset, byte_offset + buf.len(), &mut extents)?;
|
||||
@@ -496,7 +496,7 @@ impl<D: Disk> FileSystem<D> {
|
||||
let mut length = extent.length;
|
||||
|
||||
if byte_offset > 0 && length > 0 {
|
||||
let mut sector = [0; 512];
|
||||
let mut sector = [0; BLOCK_SIZE as usize];
|
||||
self.read_at(block, &mut sector)?;
|
||||
|
||||
let sector_size = min(sector.len() as u64, length) as usize;
|
||||
@@ -513,18 +513,18 @@ impl<D: Disk> FileSystem<D> {
|
||||
byte_offset = 0;
|
||||
}
|
||||
|
||||
let length_aligned = ((min(length, (buf.len() - i) as u64)/512) * 512) as usize;
|
||||
let length_aligned = ((min(length, (buf.len() - i) as u64)/BLOCK_SIZE) * BLOCK_SIZE) as usize;
|
||||
|
||||
if length_aligned > 0 {
|
||||
let extent_buf = &buf[i..i + length_aligned];
|
||||
self.write_at(block, extent_buf)?;
|
||||
i += length_aligned;
|
||||
block += (length_aligned as u64)/512;
|
||||
block += (length_aligned as u64)/BLOCK_SIZE;
|
||||
length -= length_aligned as u64;
|
||||
}
|
||||
|
||||
if length > 0 {
|
||||
let mut sector = [0; 512];
|
||||
let mut sector = [0; BLOCK_SIZE as usize];
|
||||
self.read_at(block, &mut sector)?;
|
||||
|
||||
let sector_size = min(sector.len() as u64, length) as usize;
|
||||
@@ -540,7 +540,7 @@ impl<D: Disk> FileSystem<D> {
|
||||
}
|
||||
|
||||
assert_eq!(length, 0);
|
||||
assert_eq!(block, extent.block + (extent.length + 511)/512);
|
||||
assert_eq!(block, extent.block + (extent.length + BLOCK_SIZE - 1)/BLOCK_SIZE);
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
|
||||
+7
-5
@@ -3,6 +3,8 @@ use std::ops::{Deref, DerefMut};
|
||||
|
||||
use uuid::Uuid;
|
||||
|
||||
use BLOCK_SIZE;
|
||||
|
||||
/// The header of the filesystem
|
||||
#[repr(packed)]
|
||||
pub struct Header {
|
||||
@@ -12,14 +14,14 @@ pub struct Header {
|
||||
pub version: u64,
|
||||
/// Disk ID, a 128-bit unique identifier
|
||||
pub uuid: [u8; 16],
|
||||
/// Disk size, in 512-byte sectors
|
||||
/// Disk size, in number of BLOCK_SIZE sectors
|
||||
pub size: u64,
|
||||
/// Block of root node
|
||||
pub root: u64,
|
||||
/// Block of free space node
|
||||
pub free: u64,
|
||||
/// Padding
|
||||
pub padding: [u8; 456]
|
||||
pub padding: [u8; BLOCK_SIZE as usize - 56]
|
||||
}
|
||||
|
||||
impl Header {
|
||||
@@ -34,7 +36,7 @@ impl Header {
|
||||
size: 0,
|
||||
root: 0,
|
||||
free: 0,
|
||||
padding: [0; 456]
|
||||
padding: [0; BLOCK_SIZE as usize - 56]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +49,7 @@ impl Header {
|
||||
size: size,
|
||||
root: root,
|
||||
free: free,
|
||||
padding: [0; 456]
|
||||
padding: [0; BLOCK_SIZE as usize - 56]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,5 +90,5 @@ impl DerefMut for Header {
|
||||
|
||||
#[test]
|
||||
fn header_size_test() {
|
||||
assert_eq!(mem::size_of::<Header>(), 512);
|
||||
assert_eq!(mem::size_of::<Header>(), BLOCK_SIZE as usize);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
extern crate syscall;
|
||||
extern crate uuid;
|
||||
|
||||
pub const BLOCK_SIZE: u64 = 512;
|
||||
|
||||
pub use self::disk::{Disk, DiskCache, DiskFile};
|
||||
pub use self::ex_node::ExNode;
|
||||
pub use self::extent::Extent;
|
||||
|
||||
+3
-2
@@ -7,6 +7,7 @@ use std::os::unix::ffi::OsStrExt;
|
||||
use std::path::Path;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use BLOCK_SIZE;
|
||||
use disk::Disk;
|
||||
use filesystem;
|
||||
use node::Node;
|
||||
@@ -36,7 +37,7 @@ fn node_attr(node: &(u64, Node)) -> FileAttr {
|
||||
FileAttr {
|
||||
ino: node.0,
|
||||
size: node.1.extents[0].length,
|
||||
blocks: (node.1.extents[0].length + 511)/512,
|
||||
blocks: (node.1.extents[0].length + BLOCK_SIZE - 1)/BLOCK_SIZE,
|
||||
atime: NULL_TIME,
|
||||
mtime: Timespec {
|
||||
sec: node.1.mtime as i64,
|
||||
@@ -297,7 +298,7 @@ impl<D: Disk> Filesystem for Fuse<D> {
|
||||
let free = self.fs.header.1.free;
|
||||
match self.fs.node_len(free) {
|
||||
Ok(free_size) => {
|
||||
let bsize = 512;
|
||||
let bsize = BLOCK_SIZE;
|
||||
let blocks = self.fs.header.1.size/bsize;
|
||||
let bfree = free_size/bsize;
|
||||
reply.statfs(blocks, bfree, bfree, 0, 0, bsize as u32, 256, 0);
|
||||
|
||||
@@ -9,6 +9,7 @@ use syscall::error::{Error, Result, EACCES, EEXIST, EISDIR, ENOTDIR, EPERM, ENOE
|
||||
use syscall::flag::{O_APPEND, O_CREAT, O_DIRECTORY, O_STAT, O_EXCL, O_TRUNC, O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR, MODE_PERM, O_SYMLINK, O_NOFOLLOW};
|
||||
use syscall::scheme::Scheme;
|
||||
|
||||
use BLOCK_SIZE;
|
||||
use disk::Disk;
|
||||
use filesystem::FileSystem;
|
||||
use node::Node;
|
||||
@@ -518,7 +519,7 @@ impl<D: Disk> Scheme for FileScheme<D> {
|
||||
let free = fs.header.1.free;
|
||||
let free_size = fs.node_len(free)?;
|
||||
|
||||
stat.f_bsize = 512;
|
||||
stat.f_bsize = BLOCK_SIZE as u32;
|
||||
stat.f_blocks = fs.header.1.size/(stat.f_bsize as u64);
|
||||
stat.f_bfree = free_size/(stat.f_bsize as u64);
|
||||
stat.f_bavail = stat.f_bfree;
|
||||
|
||||
+5
-4
@@ -1,5 +1,6 @@
|
||||
use std::{fmt, mem, ops, slice, str};
|
||||
|
||||
use BLOCK_SIZE;
|
||||
use super::Extent;
|
||||
|
||||
/// A file/folder node
|
||||
@@ -15,7 +16,7 @@ pub struct Node {
|
||||
pub name: [u8; 222],
|
||||
pub parent: u64,
|
||||
pub next: u64,
|
||||
pub extents: [Extent; 15],
|
||||
pub extents: [Extent; (BLOCK_SIZE as usize - 272)/16],
|
||||
}
|
||||
|
||||
impl Node {
|
||||
@@ -41,7 +42,7 @@ impl Node {
|
||||
name: [0; 222],
|
||||
parent: 0,
|
||||
next: 0,
|
||||
extents: [Extent::default(); 15],
|
||||
extents: [Extent::default(); (BLOCK_SIZE as usize - 272)/16],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +63,7 @@ impl Node {
|
||||
name: bytes,
|
||||
parent: parent,
|
||||
next: 0,
|
||||
extents: [Extent::default(); 15],
|
||||
extents: [Extent::default(); (BLOCK_SIZE as usize - 272)/16],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,5 +148,5 @@ impl ops::DerefMut for Node {
|
||||
|
||||
#[test]
|
||||
fn node_size_test() {
|
||||
assert_eq!(mem::size_of::<Node>(), 512);
|
||||
assert_eq!(mem::size_of::<Node>(), BLOCK_SIZE as usize);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user