cl-structures: Give the StringArena a new home.
This commit is contained in:
parent
40ec9b30e4
commit
d4432cda7a
@ -1,54 +1,7 @@
|
|||||||
//! Simple, long-lived string buffer
|
//! Simple arena-like allocation
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
use symbol::Symbol;
|
|
||||||
|
|
||||||
pub mod global_intern;
|
pub mod global_intern;
|
||||||
pub mod intern;
|
pub mod intern;
|
||||||
|
pub mod string_arena;
|
||||||
pub mod symbol;
|
pub mod symbol;
|
||||||
|
|
||||||
/// Compactly stores a set of immutable strings, producing a [Symbol] for each one
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct StringArena<T: Symbol> {
|
|
||||||
ends: Vec<usize>,
|
|
||||||
buf: String,
|
|
||||||
_t: PhantomData<fn(T)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Symbol> StringArena<T> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Default::default()
|
|
||||||
}
|
|
||||||
/// # May panic
|
|
||||||
/// Panics if Symbol::from_usize would panic
|
|
||||||
fn next_key(&self) -> T {
|
|
||||||
Symbol::from_usize(self.ends.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_span(&self, key: T) -> Option<(usize, usize)> {
|
|
||||||
let key = key.into_usize();
|
|
||||||
Some((*self.ends.get(key - 1)?, *self.ends.get(key)?))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(&self, key: T) -> Option<&str> {
|
|
||||||
let (start, end) = self.get_span(key)?;
|
|
||||||
// Safety: start and end offsets were created by push_string
|
|
||||||
Some(unsafe { self.buf.get_unchecked(start..end) })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push_string(&mut self, s: &str) -> T {
|
|
||||||
if self.ends.is_empty() {
|
|
||||||
self.ends.push(self.buf.len())
|
|
||||||
}
|
|
||||||
let key = self.next_key();
|
|
||||||
self.buf.push_str(s);
|
|
||||||
self.ends.push(self.buf.len());
|
|
||||||
key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Symbol> Default for StringArena<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self { ends: Default::default(), buf: Default::default(), _t: PhantomData }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! A string interner with deduplication
|
//! A string interner with deduplication
|
||||||
|
|
||||||
use super::{symbol::Symbol, StringArena};
|
use super::{string_arena::StringArena, symbol::Symbol};
|
||||||
use hashbrown::hash_table::HashTable;
|
use hashbrown::hash_table::HashTable;
|
||||||
use std::hash::{BuildHasher, RandomState};
|
use std::hash::{BuildHasher, RandomState};
|
||||||
|
|
||||||
|
48
compiler/cl-structures/src/arena/string_arena.rs
Normal file
48
compiler/cl-structures/src/arena/string_arena.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//! Compactly stores a set of immutable strings, producing a [Symbol] for each one
|
||||||
|
use super::symbol::Symbol;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
/// Compactly stores a set of immutable strings, producing a [Symbol] for each one
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct StringArena<T: Symbol> {
|
||||||
|
ends: Vec<usize>,
|
||||||
|
buf: String,
|
||||||
|
_t: PhantomData<fn(T)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Symbol> StringArena<T> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
/// # May panic
|
||||||
|
/// Panics if Symbol::from_usize would panic
|
||||||
|
fn next_key(&self) -> T {
|
||||||
|
Symbol::from_usize(self.ends.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_span(&self, key: T) -> Option<(usize, usize)> {
|
||||||
|
let key = key.into_usize();
|
||||||
|
Some((*self.ends.get(key - 1)?, *self.ends.get(key)?))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, key: T) -> Option<&str> {
|
||||||
|
let (start, end) = self.get_span(key)?;
|
||||||
|
// Safety: start and end offsets were created by push_string
|
||||||
|
Some(unsafe { self.buf.get_unchecked(start..end) })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_string(&mut self, s: &str) -> T {
|
||||||
|
if self.ends.is_empty() {
|
||||||
|
self.ends.push(self.buf.len())
|
||||||
|
}
|
||||||
|
let key = self.next_key();
|
||||||
|
self.buf.push_str(s);
|
||||||
|
self.ends.push(self.buf.len());
|
||||||
|
key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Symbol> Default for StringArena<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { ends: Default::default(), buf: Default::default(), _t: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user