mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
hashglobe: Add a shim on top of OrderMap.
This commit is contained in:
parent
c88dc51d03
commit
a2c2d34753
6 changed files with 357 additions and 0 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -1139,6 +1139,7 @@ name = "hashglobe"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -1608,6 +1609,7 @@ dependencies = [
|
|||
"euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashglobe 0.1.0",
|
||||
"mozjs 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"selectors 0.19.0",
|
||||
"servo_arc 0.1.0",
|
||||
"smallbitvec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2061,6 +2063,11 @@ dependencies = [
|
|||
"unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordermap"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "osmesa-src"
|
||||
version = "17.3.1-devel"
|
||||
|
@ -3700,6 +3707,7 @@ dependencies = [
|
|||
"checksum openssl 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)" = "419ef26bb651d72b6c5a603bcc4e4856a362460e62352dfffa53de91d2e81181"
|
||||
"checksum openssl-sys 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5483bdc56756041ba6aa37c9cb59cc2219f012a2a1377d97ad35556ac6676ee7"
|
||||
"checksum ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da12c96037889ae0be29dd2bdd260e5a62a7df24e6466d5a15bb8131c1c200a8"
|
||||
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
|
||||
"checksum osmesa-src 17.3.1-devel (git+https://github.com/servo/osmesa-src)" = "<none>"
|
||||
"checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b"
|
||||
"checksum ovr-mobile-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7b5f9389b2015f8340f0566c488f3e96735e2e8fd7b85d571832cd274ac2998"
|
||||
|
|
|
@ -11,6 +11,7 @@ readme = "README.md"
|
|||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
ordermap = "0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.3"
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate ordermap;
|
||||
|
||||
pub mod alloc;
|
||||
pub mod hash_map;
|
||||
pub mod hash_set;
|
||||
|
@ -15,6 +17,7 @@ mod shim;
|
|||
mod table;
|
||||
|
||||
pub mod fake;
|
||||
pub mod order;
|
||||
|
||||
use std::{error, fmt};
|
||||
|
||||
|
|
246
components/hashglobe/src/order.rs
Normal file
246
components/hashglobe/src/order.rs
Normal file
|
@ -0,0 +1,246 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//! This module contains shims around the ordermap crate that add fallible
|
||||
//! methods.
|
||||
//!
|
||||
//! These methods are a lie. They are not actually fallible. This is just to
|
||||
//! make it smooth to switch between hashmap impls the codebase.
|
||||
|
||||
use ordermap::{OrderMap, OrderSet};
|
||||
use std::fmt;
|
||||
use std::hash::{BuildHasher, Hash};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
pub use std::collections::hash_map::RandomState;
|
||||
pub use ordermap::{Entry, Iter as MapIter, IterMut as MapIterMut};
|
||||
pub use ordermap::set::{Iter as SetIter, IntoIter as SetIntoIter};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HashMap<K, V, S = RandomState>(OrderMap<K, V, S>);
|
||||
|
||||
|
||||
use FailedAllocationError;
|
||||
|
||||
impl<K, V, S> Deref for HashMap<K, V, S> {
|
||||
type Target = OrderMap<K, V, S>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> DerefMut for HashMap<K, V, S> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> HashMap<K, V, S>
|
||||
where K: Eq + Hash,
|
||||
S: BuildHasher
|
||||
{
|
||||
#[inline]
|
||||
pub fn try_with_hasher(hash_builder: S) -> Result<HashMap<K, V, S>, FailedAllocationError> {
|
||||
Ok(HashMap(OrderMap::with_hasher(hash_builder)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_with_capacity_and_hasher(capacity: usize,
|
||||
hash_builder: S)
|
||||
-> Result<HashMap<K, V, S>, FailedAllocationError> {
|
||||
Ok(HashMap(OrderMap::with_capacity_and_hasher(capacity, hash_builder)))
|
||||
}
|
||||
|
||||
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S> {
|
||||
HashMap(OrderMap::with_capacity_and_hasher(capacity, hash_builder))
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError> {
|
||||
Ok(self.reserve(additional))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_entry(&mut self, key: K) -> Result<Entry<K, V, S>, FailedAllocationError> {
|
||||
Ok(self.entry(key))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_insert(&mut self, k: K, v: V) -> Result<Option<V>, FailedAllocationError> {
|
||||
Ok(self.insert(k, v))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HashSet<T, S = RandomState>(OrderSet<T, S>);
|
||||
|
||||
|
||||
impl<T, S> Deref for HashSet<T, S> {
|
||||
type Target = OrderSet<T, S>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> DerefMut for HashSet<T, S> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Hash + Eq> HashSet<T, RandomState> {
|
||||
#[inline]
|
||||
pub fn new() -> HashSet<T, RandomState> {
|
||||
HashSet(OrderSet::new())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_capacity(capacity: usize) -> HashSet<T, RandomState> {
|
||||
HashSet(OrderSet::with_capacity(capacity))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<T, S> HashSet<T, S>
|
||||
where T: Eq + Hash,
|
||||
S: BuildHasher
|
||||
{
|
||||
#[inline]
|
||||
pub fn with_hasher(hasher: S) -> HashSet<T, S> {
|
||||
HashSet(OrderSet::with_hasher(hasher))
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet<T, S> {
|
||||
HashSet(OrderSet::with_capacity_and_hasher(capacity, hasher))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError> {
|
||||
Ok(self.reserve(additional))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_insert(&mut self, value: T) -> Result<bool, FailedAllocationError> {
|
||||
Ok(self.insert(value))
|
||||
}
|
||||
}
|
||||
|
||||
// Pass through trait impls
|
||||
// We can't derive these since the bounds are not obvious to the derive macro
|
||||
|
||||
impl<K: Hash + Eq, V, S: BuildHasher + Default> Default for HashMap<K, V, S> {
|
||||
fn default() -> Self {
|
||||
HashMap(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> fmt::Debug for HashMap<K, V, S>
|
||||
where K: Eq + Hash + fmt::Debug,
|
||||
V: fmt::Debug,
|
||||
S: BuildHasher {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> PartialEq for HashMap<K, V, S>
|
||||
where K: Eq + Hash,
|
||||
V: PartialEq,
|
||||
S: BuildHasher
|
||||
{
|
||||
fn eq(&self, other: &HashMap<K, V, S>) -> bool {
|
||||
self.0.eq(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> Eq for HashMap<K, V, S>
|
||||
where K: Eq + Hash,
|
||||
V: Eq,
|
||||
S: BuildHasher
|
||||
{
|
||||
}
|
||||
|
||||
impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S>
|
||||
where K: Eq + Hash,
|
||||
S: BuildHasher
|
||||
{
|
||||
type Item = (&'a K, &'a V);
|
||||
type IntoIter = MapIter<'a, K, V>;
|
||||
|
||||
fn into_iter(self) -> MapIter<'a, K, V> {
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S>
|
||||
where K: Eq + Hash,
|
||||
S: BuildHasher
|
||||
{
|
||||
type Item = (&'a K, &'a mut V);
|
||||
type IntoIter = MapIterMut<'a, K, V>;
|
||||
|
||||
fn into_iter(self) -> MapIterMut<'a, K, V> {
|
||||
self.0.iter_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Eq + Hash, S: BuildHasher + Default> Default for HashSet<T, S> {
|
||||
fn default() -> Self {
|
||||
HashSet(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> fmt::Debug for HashSet<T, S>
|
||||
where T: Eq + Hash + fmt::Debug,
|
||||
S: BuildHasher
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> PartialEq for HashSet<T, S>
|
||||
where T: Eq + Hash,
|
||||
S: BuildHasher
|
||||
{
|
||||
fn eq(&self, other: &HashSet<T, S>) -> bool {
|
||||
self.0.eq(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> Eq for HashSet<T, S>
|
||||
where T: Eq + Hash,
|
||||
S: BuildHasher
|
||||
{
|
||||
}
|
||||
|
||||
impl<'a, T, S> IntoIterator for &'a HashSet<T, S>
|
||||
where T: Eq + Hash,
|
||||
S: BuildHasher
|
||||
{
|
||||
type Item = &'a T;
|
||||
type IntoIter = SetIter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> SetIter<'a, T> {
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> IntoIterator for HashSet<T, S>
|
||||
where T: Eq + Hash,
|
||||
S: BuildHasher
|
||||
{
|
||||
type Item = T;
|
||||
type IntoIter = SetIntoIter<T>;
|
||||
|
||||
|
||||
fn into_iter(self) -> SetIntoIter<T> {
|
||||
self.0.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -17,6 +17,7 @@ cssparser = "0.23.0"
|
|||
euclid = "0.16"
|
||||
hashglobe = { path = "../hashglobe" }
|
||||
mozjs = { version = "0.1.8", features = ["promises"], optional = true }
|
||||
ordermap = "0.3"
|
||||
selectors = { path = "../selectors" }
|
||||
servo_arc = { path = "../servo_arc" }
|
||||
smallbitvec = "1.0.3"
|
||||
|
|
|
@ -49,6 +49,7 @@ extern crate euclid;
|
|||
extern crate hashglobe;
|
||||
#[cfg(feature = "servo")]
|
||||
extern crate mozjs as js;
|
||||
extern crate ordermap;
|
||||
extern crate selectors;
|
||||
extern crate servo_arc;
|
||||
extern crate smallbitvec;
|
||||
|
@ -409,6 +410,33 @@ impl<T, S> MallocShallowSizeOf for hashglobe::hash_set::HashSet<T, S>
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, S> MallocSizeOf for ordermap::OrderSet<T, S>
|
||||
where T: Eq + Hash + MallocSizeOf,
|
||||
S: BuildHasher,
|
||||
{
|
||||
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
let mut n = self.shallow_size_of(ops);
|
||||
for t in self.iter() {
|
||||
n += t.size_of(ops);
|
||||
}
|
||||
n
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> MallocShallowSizeOf for ordermap::OrderSet<T, S>
|
||||
where T: Eq + Hash,
|
||||
S: BuildHasher
|
||||
{
|
||||
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
// See the implementation for std::collections::HashSet for details.
|
||||
if ops.has_malloc_enclosing_size_of() {
|
||||
self.iter().next().map_or(0, |t| unsafe { ops.malloc_enclosing_size_of(t) })
|
||||
} else {
|
||||
self.capacity() * (size_of::<T>() + size_of::<usize>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> MallocSizeOf for hashglobe::hash_set::HashSet<T, S>
|
||||
where T: Eq + Hash + MallocSizeOf,
|
||||
S: BuildHasher,
|
||||
|
@ -442,6 +470,26 @@ impl<T, S> MallocSizeOf for hashglobe::fake::HashSet<T, S>
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, S> MallocShallowSizeOf for hashglobe::order::HashSet<T, S>
|
||||
where T: Eq + Hash,
|
||||
S: BuildHasher,
|
||||
{
|
||||
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
use std::ops::Deref;
|
||||
self.deref().shallow_size_of(ops)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> MallocSizeOf for hashglobe::order::HashSet<T, S>
|
||||
where T: Eq + Hash + MallocSizeOf,
|
||||
S: BuildHasher,
|
||||
{
|
||||
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
use std::ops::Deref;
|
||||
self.deref().size_of(ops)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> MallocShallowSizeOf for std::collections::HashMap<K, V, S>
|
||||
where K: Eq + Hash,
|
||||
S: BuildHasher
|
||||
|
@ -471,6 +519,35 @@ impl<K, V, S> MallocSizeOf for std::collections::HashMap<K, V, S>
|
|||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> MallocShallowSizeOf for ordermap::OrderMap<K, V, S>
|
||||
where K: Eq + Hash,
|
||||
S: BuildHasher
|
||||
{
|
||||
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
// See the implementation for std::collections::HashSet for details.
|
||||
if ops.has_malloc_enclosing_size_of() {
|
||||
self.values().next().map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) })
|
||||
} else {
|
||||
self.capacity() * (size_of::<V>() + size_of::<K>() + size_of::<usize>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> MallocSizeOf for ordermap::OrderMap<K, V, S>
|
||||
where K: Eq + Hash + MallocSizeOf,
|
||||
V: MallocSizeOf,
|
||||
S: BuildHasher,
|
||||
{
|
||||
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
let mut n = self.shallow_size_of(ops);
|
||||
for (k, v) in self.iter() {
|
||||
n += k.size_of(ops);
|
||||
n += v.size_of(ops);
|
||||
}
|
||||
n
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> MallocShallowSizeOf for hashglobe::hash_map::HashMap<K, V, S>
|
||||
where K: Eq + Hash,
|
||||
S: BuildHasher
|
||||
|
@ -521,6 +598,27 @@ impl<K, V, S> MallocSizeOf for hashglobe::fake::HashMap<K, V, S>
|
|||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> MallocShallowSizeOf for hashglobe::order::HashMap<K, V, S>
|
||||
where K: Eq + Hash,
|
||||
S: BuildHasher,
|
||||
{
|
||||
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
use std::ops::Deref;
|
||||
self.deref().shallow_size_of(ops)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> MallocSizeOf for hashglobe::order::HashMap<K, V, S>
|
||||
where K: Eq + Hash + MallocSizeOf,
|
||||
V: MallocSizeOf,
|
||||
S: BuildHasher,
|
||||
{
|
||||
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
use std::ops::Deref;
|
||||
self.deref().size_of(ops)
|
||||
}
|
||||
}
|
||||
|
||||
// PhantomData is always 0.
|
||||
impl<T> MallocSizeOf for std::marker::PhantomData<T> {
|
||||
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue