mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Create custom error type
This commit is contained in:
parent
65fe459835
commit
6f5085e4af
4 changed files with 51 additions and 28 deletions
23
src/fake.rs
23
src/fake.rs
|
@ -13,6 +13,9 @@ pub use std::collections::hash_map::{Entry, RandomState};
|
|||
|
||||
pub struct HashMap<K, V, S = RandomState>(StdMap<K, V, S>);
|
||||
|
||||
|
||||
use FailedAllocationError;
|
||||
|
||||
impl<K, V, S> Deref for HashMap<K, V, S> {
|
||||
type Target = StdMap<K, V, S>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
|
@ -39,7 +42,7 @@ impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_with_capacity(capacity: usize) -> Result<HashMap<K, V, RandomState>, ()> {
|
||||
pub fn try_with_capacity(capacity: usize) -> Result<HashMap<K, V, RandomState>, FailedAllocationError> {
|
||||
Ok(HashMap(StdMap::with_capacity(capacity)))
|
||||
}
|
||||
}
|
||||
|
@ -50,12 +53,12 @@ impl<K, V, S> HashMap<K, V, S>
|
|||
S: BuildHasher
|
||||
{
|
||||
#[inline]
|
||||
pub fn try_with_hasher(hash_builder: S) -> Result<HashMap<K, V, S>, ()> {
|
||||
pub fn try_with_hasher(hash_builder: S) -> Result<HashMap<K, V, S>, FailedAllocationError> {
|
||||
Ok(HashMap(StdMap::with_hasher(hash_builder)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Result<HashMap<K, V, S>, ()> {
|
||||
pub fn try_with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Result<HashMap<K, V, S>, FailedAllocationError> {
|
||||
Ok(HashMap(StdMap::with_capacity_and_hasher(capacity, hash_builder)))
|
||||
}
|
||||
|
||||
|
@ -65,20 +68,20 @@ impl<K, V, S> HashMap<K, V, S>
|
|||
|
||||
|
||||
#[inline]
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), ()> {
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError> {
|
||||
Ok(self.reserve(additional))
|
||||
}
|
||||
|
||||
pub fn try_shrink_to_fit(&mut self) -> Result<(), ()> {
|
||||
pub fn try_shrink_to_fit(&mut self) -> Result<(), FailedAllocationError> {
|
||||
Ok(self.shrink_to_fit())
|
||||
}
|
||||
|
||||
pub fn try_entry(&mut self, key: K) -> Result<Entry<K, V>, ()> {
|
||||
pub fn try_entry(&mut self, key: K) -> Result<Entry<K, V>, FailedAllocationError> {
|
||||
Ok(self.entry(key))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_insert(&mut self, k: K, v: V) -> Result<Option<V>, ()> {
|
||||
pub fn try_insert(&mut self, k: K, v: V) -> Result<Option<V>, FailedAllocationError> {
|
||||
Ok(self.insert(k, v))
|
||||
}
|
||||
}
|
||||
|
@ -130,17 +133,17 @@ impl<T, S> HashSet<T, S>
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), ()> {
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError> {
|
||||
Ok(self.reserve(additional))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_shrink_to_fit(&mut self) -> Result<(), ()> {
|
||||
pub fn try_shrink_to_fit(&mut self) -> Result<(), FailedAllocationError> {
|
||||
Ok(self.shrink_to_fit())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_insert(&mut self, value: T) -> Result<bool, ()> {
|
||||
pub fn try_insert(&mut self, value: T) -> Result<bool, FailedAllocationError> {
|
||||
Ok(self.insert(value))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ use ops::{Deref, Index};
|
|||
use super::table::{self, Bucket, EmptyBucket, FullBucket, FullBucketMut, RawTable, SafeHash};
|
||||
use super::table::BucketState::{Empty, Full};
|
||||
|
||||
use FailedAllocationError;
|
||||
|
||||
const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two
|
||||
|
||||
static OOM_STR: &str = "out of memory whilst allocating hashmap";
|
||||
|
@ -614,7 +616,7 @@ impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_with_capacity(capacity: usize) -> Result<HashMap<K, V, RandomState>, ()> {
|
||||
pub fn try_with_capacity(capacity: usize) -> Result<HashMap<K, V, RandomState>, FailedAllocationError> {
|
||||
HashMap::try_with_capacity_and_hasher(capacity, Default::default())
|
||||
}
|
||||
}
|
||||
|
@ -644,7 +646,7 @@ impl<K, V, S> HashMap<K, V, S>
|
|||
/// map.insert(1, 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn try_with_hasher(hash_builder: S) -> Result<HashMap<K, V, S>, ()> {
|
||||
pub fn try_with_hasher(hash_builder: S) -> Result<HashMap<K, V, S>, FailedAllocationError> {
|
||||
Ok(HashMap {
|
||||
hash_builder,
|
||||
resize_policy: DefaultResizePolicy::new(),
|
||||
|
@ -679,7 +681,7 @@ impl<K, V, S> HashMap<K, V, S>
|
|||
/// map.insert(1, 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn try_with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Result<HashMap<K, V, S>, ()> {
|
||||
pub fn try_with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Result<HashMap<K, V, S>, FailedAllocationError> {
|
||||
let resize_policy = DefaultResizePolicy::new();
|
||||
let raw_cap = resize_policy.raw_capacity(capacity);
|
||||
Ok(HashMap {
|
||||
|
@ -746,7 +748,7 @@ impl<K, V, S> HashMap<K, V, S>
|
|||
|
||||
|
||||
#[inline]
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), ()> {
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError> {
|
||||
let remaining = self.capacity() - self.len(); // this can't overflow
|
||||
if remaining < additional {
|
||||
let min_cap = self.len().checked_add(additional).expect("reserve overflow");
|
||||
|
@ -763,7 +765,7 @@ impl<K, V, S> HashMap<K, V, S>
|
|||
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
fn try_resize(&mut self, new_raw_cap: usize) -> Result<(), ()> {
|
||||
fn try_resize(&mut self, new_raw_cap: usize) -> Result<(), FailedAllocationError> {
|
||||
assert!(self.table.size() <= new_raw_cap);
|
||||
assert!(new_raw_cap.is_power_of_two() || new_raw_cap == 0);
|
||||
|
||||
|
@ -829,7 +831,7 @@ impl<K, V, S> HashMap<K, V, S>
|
|||
self.try_shrink_to_fit().expect(OOM_STR);
|
||||
}
|
||||
|
||||
pub fn try_shrink_to_fit(&mut self) -> Result<(), ()> {
|
||||
pub fn try_shrink_to_fit(&mut self) -> Result<(), FailedAllocationError> {
|
||||
let new_raw_cap = self.resize_policy.raw_capacity(self.len());
|
||||
if self.raw_capacity() != new_raw_cap {
|
||||
let old_table = replace(&mut self.table, RawTable::new(new_raw_cap)?);
|
||||
|
@ -1002,7 +1004,7 @@ impl<K, V, S> HashMap<K, V, S>
|
|||
self.try_entry(key).expect(OOM_STR)
|
||||
}
|
||||
|
||||
pub fn try_entry(&mut self, key: K) -> Result<Entry<K, V>, ()> {
|
||||
pub fn try_entry(&mut self, key: K) -> Result<Entry<K, V>, FailedAllocationError> {
|
||||
// Gotta resize now.
|
||||
self.try_reserve(1)?;
|
||||
let hash = self.make_hash(&key);
|
||||
|
@ -1195,7 +1197,7 @@ impl<K, V, S> HashMap<K, V, S>
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_insert(&mut self, k: K, v: V) -> Result<Option<V>, ()> {
|
||||
pub fn try_insert(&mut self, k: K, v: V) -> Result<Option<V>, FailedAllocationError> {
|
||||
let hash = self.make_hash(&k);
|
||||
self.try_reserve(1)?;
|
||||
Ok(self.insert_hashed_nocheck(hash, k, v))
|
||||
|
|
19
src/lib.rs
19
src/lib.rs
|
@ -8,6 +8,8 @@ pub mod hash_set;
|
|||
|
||||
pub mod fake;
|
||||
|
||||
use std::{error, fmt};
|
||||
|
||||
trait Recover<Q: ?Sized> {
|
||||
type Key;
|
||||
|
||||
|
@ -15,3 +17,20 @@ trait Recover<Q: ?Sized> {
|
|||
fn take(&mut self, key: &Q) -> Option<Self::Key>;
|
||||
fn replace(&mut self, key: Self::Key) -> Option<Self::Key>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FailedAllocationError {
|
||||
reason: &'static str,
|
||||
}
|
||||
|
||||
impl error::Error for FailedAllocationError {
|
||||
fn description(&self) -> &str {
|
||||
self.reason
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FailedAllocationError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.reason.fmt(f)
|
||||
}
|
||||
}
|
||||
|
|
19
src/table.rs
19
src/table.rs
|
@ -19,6 +19,7 @@ use ptr;
|
|||
use shim::{Unique, Shared};
|
||||
|
||||
use self::BucketState::*;
|
||||
use FailedAllocationError;
|
||||
|
||||
/// Integer type used for stored hash values.
|
||||
///
|
||||
|
@ -728,7 +729,7 @@ impl<K, V> RawTable<K, V> {
|
|||
|
||||
/// Does not initialize the buckets. The caller should ensure they,
|
||||
/// at the very least, set every hash to EMPTY_BUCKET.
|
||||
unsafe fn try_new_uninitialized(capacity: usize) -> Result<RawTable<K, V>, ()> {
|
||||
unsafe fn try_new_uninitialized(capacity: usize) -> Result<RawTable<K, V>, FailedAllocationError> {
|
||||
if capacity == 0 {
|
||||
return Ok(RawTable {
|
||||
size: 0,
|
||||
|
@ -757,8 +758,7 @@ impl<K, V> RawTable<K, V> {
|
|||
align_of::<(K, V)>());
|
||||
|
||||
if oflo {
|
||||
// capacity overflow
|
||||
return Err(());
|
||||
return Err(FailedAllocationError { reason: "capacity overflow when allocating RawTable" });
|
||||
}
|
||||
|
||||
// One check for overflow that covers calculation and rounding of size.
|
||||
|
@ -768,12 +768,11 @@ impl<K, V> RawTable<K, V> {
|
|||
|
||||
if let Some(cap_bytes) = cap_bytes {
|
||||
if size < cap_bytes {
|
||||
// capacity overflow
|
||||
return Err(());
|
||||
return Err(FailedAllocationError { reason: "capacity overflow when allocating RawTable" });
|
||||
}
|
||||
} else {
|
||||
// capacity overflow
|
||||
return Err(());
|
||||
|
||||
return Err(FailedAllocationError { reason: "capacity overflow when allocating RawTable" });
|
||||
}
|
||||
|
||||
|
||||
|
@ -782,8 +781,8 @@ impl<K, V> RawTable<K, V> {
|
|||
let buffer = alloc(size, alignment);
|
||||
|
||||
if buffer.is_null() {
|
||||
// OOM
|
||||
return Err(())
|
||||
|
||||
return Err(FailedAllocationError { reason: "out of memory when allocating RawTable" });
|
||||
}
|
||||
|
||||
let hashes = buffer.offset(hash_offset as isize) as *mut HashUint;
|
||||
|
@ -817,7 +816,7 @@ impl<K, V> RawTable<K, V> {
|
|||
|
||||
/// Creates a new raw table from a given capacity. All buckets are
|
||||
/// initially empty.
|
||||
pub fn new(capacity: usize) -> Result<RawTable<K, V>, ()> {
|
||||
pub fn new(capacity: usize) -> Result<RawTable<K, V>, FailedAllocationError> {
|
||||
unsafe {
|
||||
let ret = RawTable::try_new_uninitialized(capacity)?;
|
||||
ptr::write_bytes(ret.hashes.ptr(), 0, capacity);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue