From 393b88af6e104d3a027e2b0d3d21f4dc8df69489 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Mon, 11 Mar 2019 17:20:50 +0100 Subject: [PATCH] [meta] Implement UniqueTable in the Rust crate; ... and also rename the previously-named UniqueTable to UniqueSeqTable, which is the name used in the Python code. --- cranelift/codegen/meta/src/gen_settings.rs | 4 +- cranelift/codegen/meta/src/unique_table.rs | 43 +++++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/cranelift/codegen/meta/src/gen_settings.rs b/cranelift/codegen/meta/src/gen_settings.rs index 20fc6d1fc3..a797544534 100644 --- a/cranelift/codegen/meta/src/gen_settings.rs +++ b/cranelift/codegen/meta/src/gen_settings.rs @@ -7,7 +7,7 @@ use crate::constant_hash::{generate_table, simple_hash}; use crate::error; use crate::shared; use crate::srcgen::{Formatter, Match}; -use crate::unique_table::UniqueTable; +use crate::unique_table::UniqueSeqTable; use std::collections::HashMap; enum ParentGroup { @@ -238,7 +238,7 @@ impl<'a> SettingOrPreset<'a> { /// Emits DESCRIPTORS, ENUMERATORS, HASH_TABLE and PRESETS. fn gen_descriptors(group: &SettingGroup, fmt: &mut Formatter) { - let mut enum_table: UniqueTable<&'static str> = UniqueTable::new(); + let mut enum_table = UniqueSeqTable::new(); let mut descriptor_index_map: HashMap = HashMap::new(); diff --git a/cranelift/codegen/meta/src/unique_table.rs b/cranelift/codegen/meta/src/unique_table.rs index 8e325cdeed..d4f4fa00cf 100644 --- a/cranelift/codegen/meta/src/unique_table.rs +++ b/cranelift/codegen/meta/src/unique_table.rs @@ -1,15 +1,54 @@ +use std::collections::HashMap; +use std::hash::Hash; use std::slice; +/// Collect items into the `table` list, removing duplicates. +pub struct UniqueTable<'entries, T: Eq + Hash> { + table: Vec<&'entries T>, + map: HashMap<&'entries T, usize>, +} + +impl<'entries, T: Eq + Hash> UniqueTable<'entries, T> { + pub fn new() -> Self { + Self { + table: Vec::new(), + map: HashMap::new(), + } + } + + pub fn add(&mut self, entry: &'entries T) -> usize { + match self.map.get(&entry) { + None => { + let i = self.table.len(); + self.table.push(entry); + self.map.insert(entry, i); + i + } + Some(&i) => i, + } + } + + pub fn len(&self) -> usize { + self.table.len() + } + pub fn iter(&self) -> slice::Iter<&'entries T> { + self.table.iter() + } +} + /// A table of sequences which tries to avoid common subsequences. -pub struct UniqueTable { +pub struct UniqueSeqTable { table: Vec, } -impl UniqueTable { +impl UniqueSeqTable { pub fn new() -> Self { Self { table: Vec::new() } } pub fn add(&mut self, values: &Vec) -> usize { + if values.len() == 0 { + return 0; + } if let Some(offset) = find_subsequence(values, &self.table) { offset } else {