Compact tries even more
This commit is contained in:
parent
cefdc8fdd9
commit
9605c34e66
10
gen/trie.ts
10
gen/trie.ts
|
@ -139,14 +139,18 @@ export class TrieBuilder {
|
||||||
|
|
||||||
// Generate the code for a node's variable name and value, and return the name.
|
// Generate the code for a node's variable name and value, and return the name.
|
||||||
private generateNode (node: Node): string {
|
private generateNode (node: Node): string {
|
||||||
// Only generate elements up to the last non-undefined child to cut down on size of array.
|
// Only generate defined children to cut down on size of array, which would otherwise
|
||||||
|
// bog down compile time and binary size for large trees with lots of nodes.
|
||||||
|
// If array is empty, just use zero.
|
||||||
|
const firstIdx = node.children.length && node.children.findIndex(v => v);
|
||||||
const children = Array.from(
|
const children = Array.from(
|
||||||
{length: node.children.length},
|
{length: node.children.length - firstIdx},
|
||||||
(_, i) => node.children[i] ? `Some(${this.generateNode(node.children[i])})` : 'None',
|
(_, i) => node.children[i + firstIdx] ? `Some(${this.generateNode(node.children[i + firstIdx])})` : 'None',
|
||||||
).join(', ');
|
).join(', ');
|
||||||
|
|
||||||
const value = node.value === undefined ? 'None' : `Some(${node.value})`;
|
const value = node.value === undefined ? 'None' : `Some(${node.value})`;
|
||||||
const varValue = `&crate::pattern::TrieNode {
|
const varValue = `&crate::pattern::TrieNode {
|
||||||
|
offset: ${firstIdx},
|
||||||
value: ${value},
|
value: ${value},
|
||||||
children: &[${children}],
|
children: &[${children}],
|
||||||
}`;
|
}`;
|
||||||
|
|
|
@ -33,6 +33,10 @@ impl SinglePattern {
|
||||||
|
|
||||||
// Can't use pub const fn constructor due to Copy trait, so allow directly creating struct publicly for now.
|
// Can't use pub const fn constructor due to Copy trait, so allow directly creating struct publicly for now.
|
||||||
pub struct TrieNode<V: 'static + Copy> {
|
pub struct TrieNode<V: 'static + Copy> {
|
||||||
|
// Using a children array of size 256 would probably be fastest, but waste too much memory and cause slow compiles
|
||||||
|
// and large binaries. Instead, we only store the children between the first and last defined (see `gen/trie.ts`).
|
||||||
|
// When getting a child, use `index + offset`.
|
||||||
|
pub offset: usize,
|
||||||
pub value: Option<V>,
|
pub value: Option<V>,
|
||||||
pub children: &'static [Option<&'static TrieNode<V>>],
|
pub children: &'static [Option<&'static TrieNode<V>>],
|
||||||
}
|
}
|
||||||
|
@ -58,7 +62,7 @@ impl<V: 'static + Copy> TrieNode<V> {
|
||||||
let mut node: &TrieNode<V> = self;
|
let mut node: &TrieNode<V> = self;
|
||||||
let mut next_pos = from;
|
let mut next_pos = from;
|
||||||
while let Some(&c) = text.get(next_pos) {
|
while let Some(&c) = text.get(next_pos) {
|
||||||
match node.children.get(c as usize) {
|
match node.children.get(c as usize + node.offset) {
|
||||||
Some(Some(child)) => node = child,
|
Some(Some(child)) => node = child,
|
||||||
None | Some(None) => return None,
|
None | Some(None) => return None,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue