mirror of
https://github.com/RGBCube/cstree
synced 2025-07-27 17:17:45 +00:00
parent
ac4f659470
commit
695d72e8ee
7 changed files with 114 additions and 31 deletions
29
Cargo.lock
generated
29
Cargo.lock
generated
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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,18 +52,69 @@ 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());
|
||||
self.nodes
|
||||
.entry(head.clone())
|
||||
.or_insert_with(|| GreenNode::from_head_and_children(head, children))
|
||||
.clone()
|
||||
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()
|
||||
}
|
||||
|
||||
fn token(&mut self, kind: SyntaxKind, text: &str) -> GreenToken {
|
||||
let text_len = TextSize::try_from(text.len()).unwrap();
|
||||
let text = self.interner.get_or_intern(text);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
28
vendor/servo_arc/Cargo.lock
generated
vendored
Normal 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"
|
Loading…
Add table
Add a link
Reference in a new issue