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

speed up green node building by removing copies

This commit is contained in:
Domenic Quirl 2021-06-23 13:42:49 +02:00
parent 987774d2a5
commit b3390aeea6
3 changed files with 48 additions and 54 deletions

View file

@ -2,14 +2,20 @@
edition = "2018" edition = "2018"
name = "cstree" name = "cstree"
version = "0.4.0" version = "0.4.0"
authors = ["Domenic Quirl <DomenicQuirl@pm.me>", "Aleksey Kladov <aleksey.kladov@gmail.com>"] authors = [
"Domenic Quirl <DomenicQuirl@pm.me>",
"Aleksey Kladov <aleksey.kladov@gmail.com>",
]
description = "Library for generic lossless syntax trees" description = "Library for generic lossless syntax trees"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
repository = "https://github.com/domenicquirl/cstree" repository = "https://github.com/domenicquirl/cstree"
readme = "README.md" readme = "README.md"
[profile.release]
debug = true
[dependencies] [dependencies]
lasso = "0.5" lasso = { version="0.5", features=["inline-more"] }
text-size = "1.0.0" text-size = "1.0.0"
fxhash = "0.2.1" fxhash = "0.2.1"
parking_lot = "0.11.1" parking_lot = "0.11.1"

View file

@ -1,6 +1,9 @@
use std::convert::TryFrom; use std::{
convert::TryFrom,
hash::{Hash, Hasher},
};
use fxhash::FxHashMap; use fxhash::{FxHashMap, FxHasher32};
use text_size::TextSize; use text_size::TextSize;
use crate::{ use crate::{
@ -132,11 +135,11 @@ where
} }
impl ChildrenIter { impl ChildrenIter {
fn new(data: [Option<GreenElement>; CHILDREN_CACHE_THRESHOLD], count: usize) -> Self { fn new() -> Self {
ChildrenIter { ChildrenIter {
data, data: [None, None, None],
idx: 0, idx: 0,
len: count, len: 0,
} }
} }
} }
@ -157,19 +160,24 @@ where
} }
} }
let mut data: [Option<GreenElement>; CHILDREN_CACHE_THRESHOLD] = [None, None, None]; let mut new_children = ChildrenIter::new();
let mut count = 0; let mut hasher = FxHasher32::default();
let mut text_len: TextSize = 0.into();
for child in children { for (i, child) in children.into_iter().enumerate() {
data[count] = Some(child); text_len += child.text_len();
count += 1; child.hash(&mut hasher);
new_children.data[i] = Some(child);
new_children.len += 1;
} }
let children = ChildrenIter::new(data, count);
let head = GreenNodeHead::from_child_iter(kind, children.clone()); let head = GreenNodeHead {
kind,
text_len,
child_hash: hasher.finish() as u32,
};
self.nodes self.nodes
.entry(head.clone()) .entry(head)
.or_insert_with(|| GreenNode::from_head_and_children(head, children)) .or_insert_with_key(|head| GreenNode::from_head_and_children(head.clone(), new_children))
.clone() .clone()
} }

View file

@ -15,29 +15,9 @@ use triomphe::{Arc, HeaderWithLength, ThinArc};
#[repr(align(2))] //to use 1 bit for pointer tagging. NB: this is an at-least annotation #[repr(align(2))] //to use 1 bit for pointer tagging. NB: this is an at-least annotation
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub(super) struct GreenNodeHead { pub(super) struct GreenNodeHead {
kind: SyntaxKind, pub(super) kind: SyntaxKind,
text_len: TextSize, pub(super) text_len: TextSize,
child_hash: u32, pub(super) child_hash: u32,
}
impl GreenNodeHead {
#[inline]
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 {
text_len += child.text_len();
child.hash(&mut hasher);
}
Self {
kind,
text_len,
child_hash: hasher.finish() as u32,
}
}
} }
/// Internal node in the immutable "green" tree. /// Internal node in the immutable "green" tree.