mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
style: Move lru_cache to its own crate.
One less crate pointlessly in components/.
This commit is contained in:
parent
d117694ecc
commit
47b02658ec
7 changed files with 14 additions and 263 deletions
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -1672,13 +1672,6 @@ name = "log"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lru_cache"
|
|
||||||
version = "0.0.1"
|
|
||||||
dependencies = [
|
|
||||||
"arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lzw"
|
name = "lzw"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
|
@ -3180,7 +3173,6 @@ dependencies = [
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lru_cache 0.0.1",
|
|
||||||
"malloc_size_of 0.0.1",
|
"malloc_size_of 0.0.1",
|
||||||
"malloc_size_of_derive 0.0.1",
|
"malloc_size_of_derive 0.0.1",
|
||||||
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -3206,6 +3198,7 @@ dependencies = [
|
||||||
"style_traits 0.0.1",
|
"style_traits 0.0.1",
|
||||||
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"uluru 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -3457,6 +3450,14 @@ name = "typeable"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uluru"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicase"
|
name = "unicase"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
@ -4079,6 +4080,7 @@ dependencies = [
|
||||||
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
|
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
|
||||||
"checksum truetype 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec30350633d6dac9dc1a625786b6cbe9150664be941aac2c35ad7199eab877"
|
"checksum truetype 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec30350633d6dac9dc1a625786b6cbe9150664be941aac2c35ad7199eab877"
|
||||||
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
|
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
|
||||||
|
"checksum uluru 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd28fce445fd48f4e2c10ab0d3d8f6a646b11fd2b05228fa94fc83cf69ad6e98"
|
||||||
"checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764"
|
"checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764"
|
||||||
"checksum unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e01da42520092d0cd2d6ac3ae69eb21a22ad43ff195676b86f8c37f487d6b80"
|
"checksum unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e01da42520092d0cd2d6ac3ae69eb21a22ad43ff195676b86f8c37f487d6b80"
|
||||||
"checksum unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a6a2c4e3710edd365cd7e78383153ed739fa31af19f9172f72d3575060f5a43a"
|
"checksum unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a6a2c4e3710edd365cd7e78383153ed739fa31af19f9172f72d3575060f5a43a"
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "lru_cache"
|
|
||||||
version = "0.0.1"
|
|
||||||
authors = ["The Servo Project Developers"]
|
|
||||||
license = "MPL-2.0"
|
|
||||||
publish = false # We should publish this at some point
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
name = "lru_cache"
|
|
||||||
path = "lib.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
arrayvec = "0.3.20"
|
|
|
@ -1,238 +0,0 @@
|
||||||
/* 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/. */
|
|
||||||
|
|
||||||
//! A simple LRU cache.
|
|
||||||
|
|
||||||
extern crate arrayvec;
|
|
||||||
|
|
||||||
use arrayvec::{Array, ArrayVec};
|
|
||||||
|
|
||||||
/// A LRU cache using a statically-sized array for storage.
|
|
||||||
///
|
|
||||||
/// The most-recently-used entry is at index `head`. The entries form a linked list, linked to each
|
|
||||||
/// other by indices within the `entries` array. After an entry is added to the array, its index
|
|
||||||
/// never changes, so these links are never invalidated.
|
|
||||||
pub struct LRUCache<T, A: Array<Item=Entry<T>>> {
|
|
||||||
entries: ArrayVec<A>,
|
|
||||||
/// Index of the first entry. If the cache is empty, ignore this field.
|
|
||||||
head: u16,
|
|
||||||
/// Index of the last entry. If the cache is empty, ignore this field.
|
|
||||||
tail: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An opaque token used as an index into an LRUCache.
|
|
||||||
pub struct CacheIndex(u16);
|
|
||||||
|
|
||||||
/// An entry in an LRUCache.
|
|
||||||
pub struct Entry<T> {
|
|
||||||
val: T,
|
|
||||||
/// Index of the previous entry. If this entry is the head, ignore this field.
|
|
||||||
prev: u16,
|
|
||||||
/// Index of the next entry. If this entry is the tail, ignore this field.
|
|
||||||
next: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, A: Array<Item=Entry<T>>> Default for LRUCache<T, A> {
|
|
||||||
fn default() -> Self {
|
|
||||||
let cache = LRUCache {
|
|
||||||
entries: ArrayVec::new(),
|
|
||||||
head: 0,
|
|
||||||
tail: 0,
|
|
||||||
};
|
|
||||||
assert!(cache.entries.capacity() < u16::max_value() as usize, "Capacity overflow");
|
|
||||||
cache
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, A: Array<Item=Entry<T>>> LRUCache<T, A> {
|
|
||||||
/// Returns the number of elements in the cache.
|
|
||||||
pub fn num_entries(&self) -> usize {
|
|
||||||
self.entries.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Touch a given entry, putting it first in the list.
|
|
||||||
pub fn touch(&mut self, idx: CacheIndex) {
|
|
||||||
if idx.0 != self.head {
|
|
||||||
self.remove(idx.0);
|
|
||||||
self.push_front(idx.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the front entry in the list (most recently used).
|
|
||||||
pub fn front(&self) -> Option<&T> {
|
|
||||||
self.entries.get(self.head as usize).map(|e| &e.val)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a mutable reference to the front entry in the list (most recently used).
|
|
||||||
pub fn front_mut(&mut self) -> Option<&mut T> {
|
|
||||||
self.entries.get_mut(self.head as usize).map(|e| &mut e.val)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterate over the contents of this cache, from more to less recently
|
|
||||||
/// used.
|
|
||||||
pub fn iter(&self) -> LRUCacheIterator<T, A> {
|
|
||||||
LRUCacheIterator {
|
|
||||||
pos: self.head,
|
|
||||||
done: self.entries.len() == 0,
|
|
||||||
cache: self,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterate mutably over the contents of this cache.
|
|
||||||
pub fn iter_mut(&mut self) -> LRUCacheMutIterator<T, A> {
|
|
||||||
LRUCacheMutIterator {
|
|
||||||
pos: self.head,
|
|
||||||
done: self.entries.len() == 0,
|
|
||||||
cache: self,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Performs a lookup on the cache with the given test routine. Touches
|
|
||||||
/// the result on a hit.
|
|
||||||
pub fn lookup<F, R>(&mut self, mut test_one: F) -> Option<R>
|
|
||||||
where
|
|
||||||
F: FnMut(&mut T) -> Option<R>
|
|
||||||
{
|
|
||||||
let mut result = None;
|
|
||||||
for (i, candidate) in self.iter_mut() {
|
|
||||||
if let Some(r) = test_one(candidate) {
|
|
||||||
result = Some((i, r));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match result {
|
|
||||||
None => None,
|
|
||||||
Some((i, r)) => {
|
|
||||||
self.touch(i);
|
|
||||||
let front = self.front_mut().unwrap();
|
|
||||||
debug_assert!(test_one(front).is_some());
|
|
||||||
Some(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Insert a given key in the cache.
|
|
||||||
pub fn insert(&mut self, val: T) {
|
|
||||||
let entry = Entry { val, prev: 0, next: 0 };
|
|
||||||
|
|
||||||
// If the cache is full, replace the oldest entry. Otherwise, add an entry.
|
|
||||||
let new_head = if self.entries.len() == self.entries.capacity() {
|
|
||||||
let i = self.pop_back();
|
|
||||||
self.entries[i as usize] = entry;
|
|
||||||
i
|
|
||||||
} else {
|
|
||||||
self.entries.push(entry);
|
|
||||||
self.entries.len() as u16 - 1
|
|
||||||
};
|
|
||||||
|
|
||||||
self.push_front(new_head);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove an from the linked list.
|
|
||||||
///
|
|
||||||
/// Note: This only unlinks the entry from the list; it does not remove it from the array.
|
|
||||||
fn remove(&mut self, i: u16) {
|
|
||||||
let prev = self.entries[i as usize].prev;
|
|
||||||
let next = self.entries[i as usize].next;
|
|
||||||
|
|
||||||
if i == self.head {
|
|
||||||
self.head = next;
|
|
||||||
} else {
|
|
||||||
self.entries[prev as usize].next = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if i == self.tail {
|
|
||||||
self.tail = prev;
|
|
||||||
} else {
|
|
||||||
self.entries[next as usize].prev = prev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Insert a new entry at the head of the list.
|
|
||||||
fn push_front(&mut self, i: u16) {
|
|
||||||
if self.entries.len() == 1 {
|
|
||||||
self.tail = i;
|
|
||||||
} else {
|
|
||||||
self.entries[i as usize].next = self.head;
|
|
||||||
self.entries[self.head as usize].prev = i;
|
|
||||||
}
|
|
||||||
self.head = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove the last entry from the linked list. Returns the index of the removed entry.
|
|
||||||
///
|
|
||||||
/// Note: This only unlinks the entry from the list; it does not remove it from the array.
|
|
||||||
fn pop_back(&mut self) -> u16 {
|
|
||||||
let old_tail = self.tail;
|
|
||||||
let new_tail = self.entries[old_tail as usize].prev;
|
|
||||||
self.tail = new_tail;
|
|
||||||
old_tail
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Evict all elements from the cache.
|
|
||||||
pub fn evict_all(&mut self) {
|
|
||||||
self.entries.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Immutable iterator over values in an LRUCache, from most-recently-used to least-recently-used.
|
|
||||||
pub struct LRUCacheIterator<'a, T: 'a, A: 'a + Array<Item=Entry<T>>> {
|
|
||||||
cache: &'a LRUCache<T, A>,
|
|
||||||
pos: u16,
|
|
||||||
done: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T, A> Iterator for LRUCacheIterator<'a, T, A>
|
|
||||||
where T: 'a,
|
|
||||||
A: 'a + Array<Item=Entry<T>>
|
|
||||||
{
|
|
||||||
type Item = (CacheIndex, &'a T);
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
if self.done { return None }
|
|
||||||
|
|
||||||
let entry = &self.cache.entries[self.pos as usize];
|
|
||||||
|
|
||||||
let index = CacheIndex(self.pos);
|
|
||||||
if self.pos == self.cache.tail {
|
|
||||||
self.done = true;
|
|
||||||
}
|
|
||||||
self.pos = entry.next;
|
|
||||||
|
|
||||||
Some((index, &entry.val))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Mutable iterator over values in an LRUCache, from most-recently-used to least-recently-used.
|
|
||||||
pub struct LRUCacheMutIterator<'a, T: 'a, A: 'a + Array<Item=Entry<T>>> {
|
|
||||||
cache: &'a mut LRUCache<T, A>,
|
|
||||||
pos: u16,
|
|
||||||
done: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T, A> Iterator for LRUCacheMutIterator<'a, T, A>
|
|
||||||
where T: 'a,
|
|
||||||
A: 'a + Array<Item=Entry<T>>
|
|
||||||
{
|
|
||||||
type Item = (CacheIndex, &'a mut T);
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
if self.done { return None }
|
|
||||||
|
|
||||||
// Use a raw pointer because the compiler doesn't know that subsequent calls can't alias.
|
|
||||||
let entry = unsafe {
|
|
||||||
&mut *(&mut self.cache.entries[self.pos as usize] as *mut Entry<T>)
|
|
||||||
};
|
|
||||||
|
|
||||||
let index = CacheIndex(self.pos);
|
|
||||||
if self.pos == self.cache.tail {
|
|
||||||
self.done = true;
|
|
||||||
}
|
|
||||||
self.pos = entry.next;
|
|
||||||
|
|
||||||
Some((index, &mut entry.val))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -45,7 +45,6 @@ html5ever = {version = "0.21", optional = true}
|
||||||
itertools = "0.5"
|
itertools = "0.5"
|
||||||
itoa = "0.3"
|
itoa = "0.3"
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
lru_cache = { path = "../lru_cache" }
|
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
malloc_size_of = { path = "../malloc_size_of" }
|
malloc_size_of = { path = "../malloc_size_of" }
|
||||||
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
|
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
|
||||||
|
@ -70,6 +69,7 @@ style_derive = {path = "../style_derive"}
|
||||||
style_traits = {path = "../style_traits"}
|
style_traits = {path = "../style_traits"}
|
||||||
servo_url = {path = "../url", optional = true}
|
servo_url = {path = "../url", optional = true}
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
|
uluru = "0.1"
|
||||||
unicode-bidi = "0.3"
|
unicode-bidi = "0.3"
|
||||||
unicode-segmentation = "1.0"
|
unicode-segmentation = "1.0"
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ use euclid::ScaleFactor;
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
use font_metrics::FontMetricsProvider;
|
use font_metrics::FontMetricsProvider;
|
||||||
use lru_cache::{Entry, LRUCache};
|
|
||||||
#[cfg(feature = "gecko")] use gecko_bindings::structs;
|
#[cfg(feature = "gecko")] use gecko_bindings::structs;
|
||||||
use parallel::{STACK_SAFETY_MARGIN_KB, STYLE_THREAD_STACK_SIZE_KB};
|
use parallel::{STACK_SAFETY_MARGIN_KB, STYLE_THREAD_STACK_SIZE_KB};
|
||||||
#[cfg(feature = "servo")] use parking_lot::RwLock;
|
#[cfg(feature = "servo")] use parking_lot::RwLock;
|
||||||
|
@ -42,6 +41,7 @@ use time;
|
||||||
use timer::Timer;
|
use timer::Timer;
|
||||||
use traversal::DomTraversal;
|
use traversal::DomTraversal;
|
||||||
use traversal_flags::TraversalFlags;
|
use traversal_flags::TraversalFlags;
|
||||||
|
use uluru::{Entry, LRUCache};
|
||||||
|
|
||||||
pub use selectors::matching::QuirksMode;
|
pub use selectors::matching::QuirksMode;
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,6 @@ extern crate itoa;
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate lru_cache;
|
|
||||||
#[macro_use] extern crate malloc_size_of;
|
#[macro_use] extern crate malloc_size_of;
|
||||||
#[macro_use] extern crate malloc_size_of_derive;
|
#[macro_use] extern crate malloc_size_of_derive;
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
|
@ -86,6 +85,7 @@ extern crate style_derive;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate style_traits;
|
extern crate style_traits;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
|
extern crate uluru;
|
||||||
extern crate unicode_bidi;
|
extern crate unicode_bidi;
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
extern crate unicode_segmentation;
|
extern crate unicode_segmentation;
|
||||||
|
|
|
@ -70,7 +70,6 @@ use atomic_refcell::{AtomicRefCell, AtomicRefMut};
|
||||||
use bloom::StyleBloom;
|
use bloom::StyleBloom;
|
||||||
use context::{SelectorFlagsMap, SharedStyleContext, StyleContext};
|
use context::{SelectorFlagsMap, SharedStyleContext, StyleContext};
|
||||||
use dom::{TElement, SendElement};
|
use dom::{TElement, SendElement};
|
||||||
use lru_cache::{LRUCache, Entry};
|
|
||||||
use matching::MatchMethods;
|
use matching::MatchMethods;
|
||||||
use owning_ref::OwningHandle;
|
use owning_ref::OwningHandle;
|
||||||
use properties::ComputedValues;
|
use properties::ComputedValues;
|
||||||
|
@ -85,6 +84,7 @@ use std::mem;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use style_resolver::{PrimaryStyle, ResolvedElementStyles};
|
use style_resolver::{PrimaryStyle, ResolvedElementStyles};
|
||||||
use stylist::Stylist;
|
use stylist::Stylist;
|
||||||
|
use uluru::{LRUCache, Entry};
|
||||||
|
|
||||||
mod checks;
|
mod checks;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue