mirror of
https://github.com/lexmount/moli.git
synced 2026-10-05 00:00:55 +00:00
perf(dom): compact named index strings
This commit is contained in:
Generated
+1
@@ -2482,6 +2482,7 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
"selectors",
|
||||
"serde_json",
|
||||
"servo_arc",
|
||||
"thin-vec",
|
||||
"url",
|
||||
]
|
||||
|
||||
@@ -94,6 +94,7 @@ cookie = { git = "https://github.com/ldm0/cookie-rs", branch = "priority" }
|
||||
v8 = { path = "vendor/v8-152.2.0" }
|
||||
deno_v8 = { path = "vendor/deno_v8-0.3.0" }
|
||||
selectors = { git = "https://github.com/ldm0/stylo", rev = "671d13d31b3b00e7b1e0088ba2b36a4e35c0858c" }
|
||||
servo_arc = { git = "https://github.com/ldm0/stylo", rev = "671d13d31b3b00e7b1e0088ba2b36a4e35c0858c" }
|
||||
stylo = { git = "https://github.com/ldm0/stylo", rev = "671d13d31b3b00e7b1e0088ba2b36a4e35c0858c" }
|
||||
stylo_atoms = { git = "https://github.com/ldm0/stylo", rev = "671d13d31b3b00e7b1e0088ba2b36a4e35c0858c" }
|
||||
stylo_dom = { git = "https://github.com/ldm0/stylo", rev = "671d13d31b3b00e7b1e0088ba2b36a4e35c0858c" }
|
||||
|
||||
@@ -12,6 +12,7 @@ moli-html-input-temporal = { path = "../moli-html-input-temporal" }
|
||||
percent-encoding = "2.3"
|
||||
selectors = "0.40"
|
||||
serde_json = "1.0.145"
|
||||
servo_arc = "0.4.3"
|
||||
thin-vec = "0.2.14"
|
||||
url = "2.5.7"
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ use self::query_index::ElementQueryIndex;
|
||||
use self::types::{
|
||||
CachedConnectedShadowRoots, CachedLiveCollection, LiveCollectionCacheKey,
|
||||
LiveCollectionCacheKind, MutationScope, NamedElementIndex, ShadowRootState,
|
||||
ShadowSlotNameIndex,
|
||||
ShadowSlotNameIndex, ThinArcStr,
|
||||
};
|
||||
pub use self::types::{ConnectedShadowRootSnapshot, DomHandle, DomHost};
|
||||
pub use self::types::{HostElementSnapshot, ShadowRootBindingSnapshot, ShadowRootInit};
|
||||
|
||||
@@ -320,13 +320,12 @@ impl DomHost {
|
||||
}
|
||||
}
|
||||
if let Some(current_value) = current_value {
|
||||
let current_value = std::sync::Arc::<str>::from(current_value);
|
||||
index
|
||||
let entry = index
|
||||
.handles_by_value
|
||||
.entry(current_value.clone())
|
||||
.or_default()
|
||||
.insert(handle);
|
||||
index.value_by_handle.insert(handle, current_value);
|
||||
.entry(ThinArcStr::from(current_value));
|
||||
let canonical_value = entry.key().clone();
|
||||
entry.or_default().insert(handle);
|
||||
index.value_by_handle.insert(handle, canonical_value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -993,14 +993,14 @@ mod tests {
|
||||
#[test]
|
||||
fn named_candidate_index_shares_values_between_directions() {
|
||||
let mut host = test_host();
|
||||
let element = host.create_element("div");
|
||||
assert!(host.set_attribute(element, "id", "shared-identifier"));
|
||||
assert!(host.append_child(host.document_handle(), element));
|
||||
let first = host.create_element("div");
|
||||
let second = host.create_element("span");
|
||||
for element in [first, second] {
|
||||
assert!(host.set_attribute(element, "id", "shared-identifier"));
|
||||
assert!(host.append_child(host.document_handle(), element));
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
host.element_handle_by_id("shared-identifier"),
|
||||
Some(element)
|
||||
);
|
||||
assert_eq!(host.element_handle_by_id("shared-identifier"), Some(first));
|
||||
|
||||
let index = host.id_index.borrow();
|
||||
let index = index.as_ref().expect("materialized ID index");
|
||||
@@ -1009,11 +1009,17 @@ mod tests {
|
||||
.keys()
|
||||
.find(|value| value.as_ref() == "shared-identifier")
|
||||
.expect("forward index key");
|
||||
let reverse = index
|
||||
.value_by_handle
|
||||
.get(&element)
|
||||
.expect("reverse index value");
|
||||
assert!(std::sync::Arc::ptr_eq(forward, reverse));
|
||||
for element in [first, second] {
|
||||
let reverse = index
|
||||
.value_by_handle
|
||||
.get(&element)
|
||||
.expect("reverse index value");
|
||||
assert!(forward.ptr_eq(reverse));
|
||||
}
|
||||
assert_eq!(
|
||||
std::mem::size_of::<ThinArcStr>(),
|
||||
std::mem::size_of::<usize>()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
use super::*;
|
||||
use std::sync::Arc;
|
||||
use servo_arc::ThinArc;
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
fmt,
|
||||
hash::{Hash, Hasher},
|
||||
};
|
||||
|
||||
pub type DomHandle = NativeNodeId;
|
||||
|
||||
@@ -10,8 +15,63 @@ pub struct HostElementSnapshot {
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub(super) struct NamedElementIndex {
|
||||
pub(super) handles_by_value: HashMap<Arc<str>, IndexSet<DomHandle>>,
|
||||
pub(super) value_by_handle: HashMap<DomHandle, Arc<str>>,
|
||||
pub(super) handles_by_value: HashMap<ThinArcStr, IndexSet<DomHandle>>,
|
||||
pub(super) value_by_handle: HashMap<DomHandle, ThinArcStr>,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone)]
|
||||
pub(super) struct ThinArcStr(ThinArc<(), u8>);
|
||||
|
||||
impl ThinArcStr {
|
||||
fn as_str(&self) -> &str {
|
||||
// SAFETY: Construction only accepts UTF-8 `str` bytes, and the shared
|
||||
// backing slice cannot be mutated.
|
||||
unsafe { std::str::from_utf8_unchecked(self.0.slice()) }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(super) fn ptr_eq(&self, other: &Self) -> bool {
|
||||
servo_arc::Arc::ptr_eq(&self.0, &other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for ThinArcStr {
|
||||
fn from(value: &str) -> Self {
|
||||
Self(ThinArc::from_header_and_iter((), value.bytes()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<str> for ThinArcStr {
|
||||
fn borrow(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for ThinArcStr {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for ThinArcStr {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.as_str() == other.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for ThinArcStr {}
|
||||
|
||||
impl Hash for ThinArcStr {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.as_str().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ThinArcStr {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.as_str().fmt(formatter)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
|
||||
Reference in New Issue
Block a user