@@ -7,8 +7,10 @@ use crate::{
7 Rope, RopeSlice, Tendril,
7 Rope, RopeSlice, Tendril,
10+use ahash::RandomState;
10use arc_swap::{ArcSwap, Guard};
11use arc_swap::{ArcSwap, Guard};
11use bitflags::bitflags;
12use bitflags::bitflags;
13+use hashbrown::raw::RawTable;
12use slotmap::{DefaultKey as LayerId, HopSlotMap};
14use slotmap::{DefaultKey as LayerId, HopSlotMap};
@@ -16,7 +18,8 @@ use std::{
16 cell::RefCell,
18 cell::RefCell,
17 collections::{HashMap, VecDeque},
19 collections::{HashMap, VecDeque},
21+ hash::{Hash, Hasher},
19− mem::replace,
22+ mem::{replace, transmute},
20 path::Path,
23 path::Path,
21 str::FromStr,
24 str::FromStr,
22 sync::Arc,
25 sync::Arc,
@@ -770,30 +773,38 @@ impl Syntax {
770 // Convert the changeset into tree sitter edits.
773 // Convert the changeset into tree sitter edits.
771 let edits = generate_edits(old_source, changeset);
774 let edits = generate_edits(old_source, changeset);
776+ // This table allows inverse indexing of `layers`.
777+ // That is by hashing a `Layer` you can find
778+ // the `LayerId` of an existing equivalent `Layer` in `layers`.
780+ // It is used to determine if a new layer exists for an injection
781+ // or if an existing layer needs to be updated.
782+ let mut layers_table = RawTable::with_capacity(self.layers.len());
783+ let layers_hasher = RandomState::new();
773 // Use the edits to update all layers markers
784 // Use the edits to update all layers markers
774− if !edits.is_empty() {
775− fn point_add(a: Point, b: Point) -> Point {
785+ fn point_add(a: Point, b: Point) -> Point {
776− if b.row > 0 {
786+ if b.row > 0 {
777− Point::new(a.row.saturating_add(b.row), b.column)
787+ Point::new(a.row.saturating_add(b.row), b.column)
778− } else {
788+ } else {
779− Point::new(0, a.column.saturating_add(b.column))
789+ Point::new(0, a.column.saturating_add(b.column))
782− fn point_sub(a: Point, b: Point) -> Point {
792+ fn point_sub(a: Point, b: Point) -> Point {
783− if a.row > b.row {
793+ if a.row > b.row {
784− Point::new(a.row.saturating_sub(b.row), a.column)
794+ Point::new(a.row.saturating_sub(b.row), a.column)
785− } else {
795+ } else {
786− Point::new(0, a.column.saturating_sub(b.column))
796+ Point::new(0, a.column.saturating_sub(b.column))
790− for layer in self.layers.values_mut() {
800+ for (layer_id, layer) in self.layers.iter_mut() {
791− // The root layer always covers the whole range (0..usize::MAX)
801+ // The root layer always covers the whole range (0..usize::MAX)
792− if layer.depth == 0 {
802+ if layer.depth == 0 {
793− layer.flags = LayerUpdateFlags::MODIFIED;
803+ layer.flags = LayerUpdateFlags::MODIFIED;
794− continue;
804+ continue;
807+ if !edits.is_empty() {
797 for range in &mut layer.ranges {
808 for range in &mut layer.ranges {
798 // Roughly based on https://github.com/tree-sitter/tree-sitter/blob/ddeaa0c7f534268b35b4f6cb39b52df082754413/lib/src/subtree.c#L691-L720
809 // Roughly based on https://github.com/tree-sitter/tree-sitter/blob/ddeaa0c7f534268b35b4f6cb39b52df082754413/lib/src/subtree.c#L691-L720
799 for edit in edits.iter().rev() {
810 for edit in edits.iter().rev() {
@@ -858,6 +869,12 @@ impl Syntax {
873+ let hash = layers_hasher.hash_one(layer);
874+ // Safety: insert_no_grow is unsafe because it assumes that the table
875+ // has enough capacity to hold additional elements.
876+ // This is always the case as we reserved enough capacity above.
877+ unsafe { layers_table.insert_no_grow(hash, layer_id) };
863 PARSER.with(|ts_parser| {
880 PARSER.with(|ts_parser| {
@@ -982,27 +999,23 @@ impl Syntax {
982 let depth = layer.depth + 1;
999 let depth = layer.depth + 1;
983 // TODO: can't inline this since matches borrows self.layers
1000 // TODO: can't inline this since matches borrows self.layers
984 for (config, ranges) in injections {
1001 for (config, ranges) in injections {
1002+ let new_layer = LanguageLayer {
1007+ flags: LayerUpdateFlags::empty(),
985− // Find an existing layer
1010+ // Find an identical existing layer
986− let layer = self
1011+ let layer = layers_table
1012+ .get(layers_hasher.hash_one(&new_layer), |&it| {
987− .layers
1013+ self.layers[it] == new_layer
989− .find(|(_, layer)| {
990− layer.depth == depth && // TODO: track parent id instead
991− layer.config.language == config.language && layer.ranges == ranges
993− .map(|(id, _layer)| id);
1015+ .copied();
995 // ...or insert a new one.
1017 // ...or insert a new one.
996− let layer_id = layer.unwrap_or_else(|| {
1018+ let layer_id = layer.unwrap_or_else(|| self.layers.insert(new_layer));
997− self.layers.insert(LanguageLayer {
1002− // set the modified flag to ensure the layer is parsed
1003− flags: LayerUpdateFlags::empty(),
1007 queue.push_back(layer_id);
1020 queue.push_back(layer_id);
@@ -1139,6 +1152,34 @@ pub struct LanguageLayer {
1139 flags: LayerUpdateFlags,
1152 flags: LayerUpdateFlags,
1155+/// This PartialEq implementation only checks if that
1156+/// two layers are theoretically identical (meaning they highlight the same text range with the same language).
1157+/// It does not check whether the layers have the same internal treesitter
1159+impl PartialEq for LanguageLayer {
1160+ fn eq(&self, other: &Self) -> bool {
1161+ self.depth == other.depth
1162+ && self.config.language == other.config.language
1163+ && self.ranges == other.ranges
1167+/// Hash implementation belongs to PartialEq implementation above.
1168+/// See its documentation for details.
1169+impl Hash for LanguageLayer {
1170+ fn hash<H: Hasher>(&self, state: &mut H) {
1171+ self.depth.hash(state);
1172+ // The transmute is necessary here because tree_sitter::Language does not derive Hash at the moment.
1173+ // However it does use #[repr] transparent so the transmute here is safe
1174+ // as `Language` (which `Grammar` is an alias for) is just a newtype wrapper around a (thin) pointer.
1175+ // This is also compatible with the PartialEq implementation of language
1176+ // as that is just a pointer comparison.
1177+ let language: *const () = unsafe { transmute(self.config.language) };
1178+ language.hash(state);
1179+ self.ranges.hash(state);
1142impl LanguageLayer {
1183impl LanguageLayer {
1143 pub fn tree(&self) -> &Tree {
1184 pub fn tree(&self) -> &Tree {
1144 // TODO: no unwrap
1185 // TODO: no unwrap