schala/schala-lang/src/symbol_table/symbol_trie.rs

71 lines
1.8 KiB
Rust
Raw Normal View History

use std::{
collections::hash_map::DefaultHasher,
hash::{Hash, Hasher},
};
2019-10-17 03:15:39 -07:00
use radix_trie::{Trie, TrieCommon, TrieKey};
2021-11-02 01:20:30 -07:00
use super::{DefId, Fqsn, ScopeSegment};
2019-10-17 03:15:39 -07:00
2019-10-18 09:54:56 -07:00
#[derive(Debug)]
pub struct SymbolTrie(Trie<Fqsn, DefId>);
2019-10-17 03:15:39 -07:00
2021-10-19 21:14:15 -07:00
impl TrieKey for Fqsn {
2021-10-21 14:46:42 -07:00
fn encode_bytes(&self) -> Vec<u8> {
let mut hasher = DefaultHasher::new();
let mut output = vec![];
for segment in self.scopes.iter() {
2021-11-02 01:20:30 -07:00
let ScopeSegment::Name(s) = segment;
2021-10-21 14:46:42 -07:00
s.as_bytes().hash(&mut hasher);
output.extend_from_slice(&hasher.finish().to_be_bytes());
}
output
2019-10-17 03:15:39 -07:00
}
}
impl SymbolTrie {
2021-10-21 14:46:42 -07:00
pub fn new() -> SymbolTrie {
SymbolTrie(Trie::new())
}
pub fn insert(&mut self, fqsn: &Fqsn, def_id: DefId) {
self.0.insert(fqsn.clone(), def_id);
}
pub fn lookup(&self, fqsn: &Fqsn) -> Option<DefId> {
self.0.get(fqsn).cloned()
2021-10-21 14:46:42 -07:00
}
pub fn get_children(&self, fqsn: &Fqsn) -> Vec<Fqsn> {
let subtrie = match self.0.subtrie(fqsn) {
Some(s) => s,
None => return vec![],
};
let output: Vec<Fqsn> = subtrie.keys().filter(|cur_key| **cur_key != *fqsn).cloned().collect();
2021-10-21 14:46:42 -07:00
output
}
2019-10-17 03:15:39 -07:00
}
2021-10-19 13:48:00 -07:00
#[cfg(test)]
mod test {
2021-10-21 14:46:42 -07:00
use super::*;
use crate::symbol_table::Fqsn;
2021-10-19 13:48:00 -07:00
2021-10-21 14:46:42 -07:00
fn make_fqsn(strs: &[&str]) -> Fqsn {
Fqsn::from_strs(strs)
}
2021-10-19 13:48:00 -07:00
2021-10-21 14:46:42 -07:00
#[test]
fn test_trie_insertion() {
let id = DefId::default();
2021-10-21 14:46:42 -07:00
let mut trie = SymbolTrie::new();
2019-10-17 03:15:39 -07:00
trie.insert(&make_fqsn(&["unrelated", "thing"]), id);
trie.insert(&make_fqsn(&["outer", "inner"]), id);
trie.insert(&make_fqsn(&["outer", "inner", "still_inner"]), id);
2019-10-17 03:15:39 -07:00
2021-10-21 14:46:42 -07:00
let children = trie.get_children(&make_fqsn(&["outer", "inner"]));
assert_eq!(children.len(), 1);
}
2019-10-17 03:15:39 -07:00
}