1
Fork 0
mirror of https://github.com/RGBCube/cstree synced 2025-07-28 01:27:44 +00:00

Remove smallvec (#8)

c.f. #6
This commit is contained in:
Stu 2021-01-13 22:05:02 +01:00 committed by GitHub
parent ac4f659470
commit 695d72e8ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 114 additions and 31 deletions

29
Cargo.lock generated
View file

@ -8,9 +8,9 @@ checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
[[package]]
name = "aho-corasick"
version = "0.7.10"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
@ -37,7 +37,6 @@ dependencies = [
"parking_lot",
"serde",
"servo_arc",
"smallvec",
"text-size",
]
@ -109,9 +108,9 @@ dependencies = [
[[package]]
name = "memchr"
version = "2.3.3"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "nodrop"
@ -152,9 +151,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "regex"
version = "1.3.6"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3"
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
dependencies = [
"aho-corasick",
"memchr",
@ -164,9 +163,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.17"
version = "0.6.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
[[package]]
name = "scopeguard"
@ -176,9 +175,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.106"
version = "1.0.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399"
checksum = "9bdd36f49e35b61d49efd8aa7fc068fd295961fd2286d0b2ee9a4c7a14e99cc3"
[[package]]
name = "servo_arc"
@ -202,18 +201,18 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "text-size"
version = "1.0.0"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f03e7efdedc3bc78cb2337f1e2785c39e45f5ef762d9e4ebb137fff7380a6d8a"
checksum = "288cb548dbe72b652243ea797201f3d481a0609a967980fcc5b2315ea811560a"
dependencies = [
"serde",
]
[[package]]
name = "thread_local"
version = "1.0.1"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447"
dependencies = [
"lazy_static",
]

View file

@ -12,7 +12,6 @@ serde = { version = "1.0.89", optional = true, default-features = false }
lasso = "0.4.1"
text-size = "1.0.0"
fxhash= "0.2.1"
smallvec = "1.6.1"
servo_arc = { path = "vendor/servo_arc" }
parking_lot= "0.11.1"

View file

@ -1,7 +1,7 @@
mod builder;
mod element;
mod node;
mod token;
mod element;
mod builder;
pub(crate) use self::element::GreenElementRef;
use self::element::{GreenElement, PackedGreenElement};

View file

@ -2,7 +2,6 @@ use std::{convert::TryFrom, num::NonZeroUsize};
use fxhash::{FxBuildHasher, FxHashMap};
use lasso::{Capacity, Rodeo, Spur};
use smallvec::SmallVec;
use text_size::TextSize;
use crate::{
@ -13,6 +12,12 @@ use crate::{
use super::{node::GreenNodeHead, token::GreenTokenData};
/// If `node.children() <= CHILDREN_CACHE_THRESHOLD`, we will not create
/// a new [`GreenNode`], but instead lookup in the cache if this node is
/// already present. If so we use the one in the cache, otherwise we insert
/// this node into the cache.
const CHILDREN_CACHE_THRESHOLD: usize = 3;
#[derive(Debug)]
pub struct NodeCache {
nodes: FxHashMap<GreenNodeHead, GreenNode>,
@ -39,6 +44,7 @@ impl NodeCache {
I::IntoIter: ExactSizeIterator,
{
let children = children.into_iter();
// Green nodes are fully immutable, so it's ok to deduplicate them.
// This is the same optimization that Roslyn does
// https://github.com/KirillOsenkov/Bliki/wiki/Roslyn-Immutable-Trees
@ -46,16 +52,67 @@ impl NodeCache {
// For example, all `#[inline]` in this file share the same green node!
// For `libsyntax/parse/parser.rs`, measurements show that deduping saves
// 17% of the memory for green nodes!
if children.len() <= 3 {
let children: SmallVec<[_; 3]> = children.collect();
let head = GreenNodeHead::from_child_slice(kind, children.as_ref());
if children.len() <= CHILDREN_CACHE_THRESHOLD {
self.get_cached_node(kind, children)
} else {
GreenNode::new(kind, children)
}
}
/// Creates a [`GreenNode`] by looking inside the cache or inserting
/// a new node into the cache if it's a cache miss.
fn get_cached_node<I>(&mut self, kind: SyntaxKind, children: I) -> GreenNode
where
I: IntoIterator<Item = GreenElement>,
I::IntoIter: ExactSizeIterator,
{
#[derive(Clone)]
struct ChildrenIter {
data: [Option<GreenElement>; CHILDREN_CACHE_THRESHOLD],
idx: usize,
len: usize,
}
impl ChildrenIter {
fn new(data: [Option<GreenElement>; CHILDREN_CACHE_THRESHOLD], count: usize) -> Self {
ChildrenIter {
data,
idx: 0,
len: count,
}
}
}
impl Iterator for ChildrenIter {
type Item = GreenElement;
fn next(&mut self) -> Option<Self::Item> {
let item = self.data.get_mut(self.idx)?;
self.idx += 1;
item.take()
}
}
impl ExactSizeIterator for ChildrenIter {
fn len(&self) -> usize {
self.len - self.idx
}
}
let mut data: [Option<GreenElement>; CHILDREN_CACHE_THRESHOLD] = [None, None, None];
let mut count = 0;
for child in children {
data[count] = Some(child);
count += 1;
}
let children = ChildrenIter::new(data, count);
let head = GreenNodeHead::from_child_iter(kind, children.clone());
self.nodes
.entry(head.clone())
.or_insert_with(|| GreenNode::from_head_and_children(head, children))
.clone()
} else {
GreenNode::new(kind, children)
}
}
fn token(&mut self, kind: SyntaxKind, text: &str) -> GreenToken {

View file

@ -22,7 +22,10 @@ pub(super) struct GreenNodeHead {
impl GreenNodeHead {
#[inline]
pub(super) fn from_child_slice(kind: SyntaxKind, children: &[GreenElement]) -> Self {
pub(super) fn from_child_iter<I>(kind: SyntaxKind, children: I) -> Self
where
I: Iterator<Item = GreenElement>,
{
let mut hasher = FxHasher32::default();
let mut text_len: TextSize = 0.into();
for child in children {

View file

@ -1,10 +1,7 @@
use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer};
use std::fmt;
use crate::{
api::{Language, SyntaxNode, SyntaxToken},
NodeOrToken,
};
use crate::{Language, NodeOrToken, SyntaxNode, SyntaxToken};
struct SerDisplay<T>(T);
impl<T: fmt::Display> Serialize for SerDisplay<T> {

28
vendor/servo_arc/Cargo.lock generated vendored Normal file
View file

@ -0,0 +1,28 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "nodrop"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
[[package]]
name = "serde"
version = "1.0.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bdd36f49e35b61d49efd8aa7fc068fd295961fd2286d0b2ee9a4c7a14e99cc3"
[[package]]
name = "servo_arc"
version = "0.1.1"
dependencies = [
"nodrop",
"serde",
"stable_deref_trait",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"