News for hackers. Stuff that matters.
Re:Writing Pythonic Rust by iudqnolq on Monday May 24, 2021 @06:40PM (#27270531)
That's an interesting case. This won't solve your whole problem, but you should be able to make the key the hash of the string and then have a HashMap<u64, Weak<String>>. I feel like there's a pretty solution where you stick the whole map in a Rc and stick that in every interned string. Then strings can remove/lookup themselves. To make that work you'll want some sort of concurrent hash map.
Re:Writing Pythonic Rust by CraigJPerry on Monday May 24, 2021 @07:10PM (#27270779)
But how would you handle hash collisions if the value is just a Weak<String> rather than some kind of nested container type?

I started thinking along the lines of an arena allocator, that would allow a shorter lifetime than static so you could remove unused references by dropping the arena and moving over still live references to a new arena. I guess arenas the wrong term with that behaviour, maybe generational mark and sweep garbage collector is closer to describing this approach.

It a avoids the double reference though of the Rc<> model.

Re:Writing Pythonic Rust by bombela on Tuesday May 25, 2021 @01:21AM (#27272900)
What about using a HashSet<Rc<str>>. And returning a type that implements Drop. The drop method can remove the string from the cache when the last reference is dropped. Since the cache must be accessed by the interning function and drop, I used interior mutability. By putting the cache behind a Rc<RefCell<>>.

https://play.rust-lang.org/?version=stable&mode=debug&editio...

With the same principle, we can use a static, arc and mutex to use a the cache as a global variable. And implement thread-safe string interning. Here, locking the cache at the wrong time during the drop can lead to a race condition.

https://play.rust-lang.org/?version=stable&mode=debug&editio...

To make the InternedStr behaves a bit more like &str or an immutable String, I implemented Clone, Display, Pointer, conversion from &Interned to &str. Ideally it should probably resemble how String de-references to &str for everything (Deref<Target = str>).

Re:Writing Pythonic Rust by iudqnolq on Monday May 24, 2021 @07:29PM (#27270934)
You'd need to pick a hash that won't have collisions within your expected use.

Edit: this might be interesting to you: https://docs.rs/crossbeam-epoch/0.9.4/crossbeam_epoch/