Skip to content

Commit ff6a57a

Browse files
committed
u
Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
1 parent bea37ad commit ff6a57a

4 files changed

Lines changed: 37 additions & 101 deletions

File tree

Cargo.lock

Lines changed: 26 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ itertools = "0.14.0"
163163
jetscii = "0.5.3"
164164
jiff = "0.2.0"
165165
kanal = "0.1.1"
166+
lasso = { version = "0.7", features = ["multi-threaded"] }
166167
lending-iterator = "0.1.7"
167168
libfuzzer-sys = "0.4"
168169
libloading = "0.8"
@@ -227,7 +228,6 @@ similar = "2.7.0"
227228
sketches-ddsketch = "0.4.0"
228229
smol = "2.0.2"
229230
static_assertions = "1.1"
230-
string-interner = "0.19.0"
231231
strum = "0.28"
232232
syn = { version = "2.0.117", features = ["full"] }
233233
sysinfo = "0.38.0"

vortex-session/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,9 @@ all-features = true
2020
workspace = true
2121

2222
[dependencies]
23-
arc-swap = { workspace = true }
2423
arcref = { workspace = true }
2524
dashmap = { workspace = true }
25+
lasso = { workspace = true }
2626
parking_lot = { workspace = true }
27-
string-interner = { workspace = true }
2827
vortex-error = { workspace = true }
2928
vortex-utils = { workspace = true, features = ["dashmap"] }

vortex-session/src/registry.rs

Lines changed: 9 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -14,101 +14,39 @@ use std::sync::Arc;
1414
use std::sync::LazyLock;
1515
use std::sync::OnceLock;
1616

17-
use arc_swap::ArcSwap;
18-
use parking_lot::Mutex;
17+
use lasso::Spur;
18+
use lasso::ThreadedRodeo;
1919
use parking_lot::RwLock;
20-
use string_interner::DefaultBackend;
21-
use string_interner::DefaultSymbol;
22-
use string_interner::StringInterner;
2320
use vortex_error::VortexExpect;
2421
use vortex_utils::aliases::dash_map::DashMap;
2522

2623
/// Global string interner for [`Id`] values.
27-
static INTERNER: LazyLock<Interner> = LazyLock::new(Interner::default);
28-
29-
struct Interner {
30-
state: ArcSwap<StringInterner<DefaultBackend>>,
31-
write_lock: Mutex<()>,
32-
}
33-
34-
impl Default for Interner {
35-
fn default() -> Self {
36-
Self {
37-
state: ArcSwap::from_pointee(StringInterner::with_capacity(200)),
38-
write_lock: Mutex::new(()),
39-
}
40-
}
41-
}
42-
43-
impl Interner {
44-
fn intern_static(&self, s: &'static str) -> DefaultSymbol {
45-
if let Some(symbol) = self.state.load().get(s) {
46-
return symbol;
47-
}
48-
49-
// Ensure if we need to add this we have the write lock and check again if its was
50-
// added just now.
51-
let _guard = self.write_lock.lock();
52-
let state = self.state.load_full();
53-
if let Some(symbol) = state.get(s) {
54-
return symbol;
55-
}
56-
57-
let mut next = (*state).clone();
58-
let symbol = next.get_or_intern_static(s);
59-
self.state.store(Arc::new(next));
60-
symbol
61-
}
62-
63-
fn intern(&self, s: &str) -> DefaultSymbol {
64-
if let Some(symbol) = self.state.load().get(s) {
65-
return symbol;
66-
}
67-
68-
// Ensure if we need to add this we have the write lock and check again if its was
69-
// added just now.
70-
let _guard = self.write_lock.lock();
71-
let state = self.state.load_full();
72-
if let Some(symbol) = state.get(s) {
73-
return symbol;
74-
}
75-
76-
let mut next = (*state).clone();
77-
let symbol = next.get_or_intern(s);
78-
self.state.store(Arc::new(next));
79-
symbol
80-
}
81-
}
24+
static INTERNER: LazyLock<ThreadedRodeo> = LazyLock::new(ThreadedRodeo::new);
8225

8326
/// A lightweight, copyable identifier backed by a global string interner.
8427
///
8528
/// Used for array encoding IDs, scalar function IDs, layout IDs, and similar
8629
/// globally-unique string identifiers throughout Vortex. Equality and hashing
8730
/// are O(1) symbol comparisons.
8831
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
89-
pub struct Id(DefaultSymbol);
32+
pub struct Id(Spur);
9033

9134
impl Id {
9235
/// Intern a string and return its `Id`.
9336
pub fn new(s: &str) -> Self {
94-
Self(INTERNER.intern(s))
37+
Self(INTERNER.get_or_intern(s))
9538
}
9639

9740
/// Intern a string and return its `Id`.
9841
pub fn new_static(s: &'static str) -> Self {
99-
Self(INTERNER.intern_static(s))
42+
Self(INTERNER.get_or_intern_static(s))
10043
}
10144

10245
/// Returns the interned string.
10346
pub fn as_str(&self) -> &str {
104-
// SAFETY: The interner is append-only (symbols are never removed), so the resolved
105-
// string reference is valid for the lifetime of this borrow.
106-
let interner = INTERNER.state.load();
107-
let s = interner
108-
.resolve(self.0)
109-
.vortex_expect("Id symbol not found in interner");
110-
// SAFETY: The interner is append-only and lives for 'static, so the &str is valid
111-
// for the program's lifetime. We just can't express that through the RwLock borrow.
47+
let s = INTERNER.resolve(&self.0);
48+
// SAFETY: INTERNER is 'static and its arena is append-only, so resolved string
49+
// pointers are stable for the lifetime of the program.
11250
unsafe { &*(s as *const str) }
11351
}
11452
}

0 commit comments

Comments
 (0)