ordered binary search working - but need to be sped up
This commit is contained in:
parent
f1074e4340
commit
b86e5fd3e4
3 changed files with 166 additions and 93 deletions
110
src/vcd/parse.rs
110
src/vcd/parse.rs
|
@ -1,6 +1,6 @@
|
|||
use std::{fs::File};
|
||||
use std::collections::HashMap;
|
||||
use num::BigInt;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -19,27 +19,95 @@ use scopes::*;
|
|||
mod events;
|
||||
use events::*;
|
||||
|
||||
pub fn parse_vcd(file : File) -> Result<VCD, String> {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
fn compare_strs(a: &str, b: &str) -> Ordering {
|
||||
let last_idx = if a.len() > b.len() { a.len() } else { b.len() };
|
||||
// let last_idx += -1;
|
||||
Ordering::Less
|
||||
}
|
||||
|
||||
fn ordered_binary_lookup(map: &Vec<(String, SignalIdx)>, key: &str) -> Result<SignalIdx, String> {
|
||||
let mut upper_idx = map.len() - 1;
|
||||
let mut lower_idx = 0usize;
|
||||
|
||||
while lower_idx <= upper_idx {
|
||||
let mid_idx = lower_idx + ((upper_idx - lower_idx) / 2);
|
||||
let (str_val, signal_idx) = map.get(mid_idx).unwrap();
|
||||
let ordering = key.partial_cmp(str_val.as_str()).unwrap();
|
||||
|
||||
match ordering {
|
||||
Ordering::Less => {
|
||||
upper_idx = mid_idx - 1;
|
||||
}
|
||||
Ordering::Equal => {
|
||||
return Ok(*signal_idx);
|
||||
}
|
||||
Ordering::Greater => {
|
||||
lower_idx = mid_idx + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Err(format!(
|
||||
"Error near {}:{}. Unable to find key: `{key}` in the map.",
|
||||
file!(),
|
||||
line!()
|
||||
));
|
||||
}
|
||||
|
||||
pub fn parse_vcd(file: File) -> Result<VCD, String> {
|
||||
let mut word_gen = WordReader::new(file);
|
||||
|
||||
let header = parse_metadata(&mut word_gen)?;
|
||||
|
||||
// later, we'll need to map parsed ascii symbols to their
|
||||
// later, we'll need to map parsed ascii symbols to their
|
||||
// respective signal indexes
|
||||
let mut signal_map = std::collections::HashMap::new();
|
||||
|
||||
// after we parse metadata, we form the VCD object
|
||||
let mut vcd = VCD{
|
||||
metadata : header,
|
||||
timeline : vec![],
|
||||
timeline_markers : vec![],
|
||||
all_signals : vec![],
|
||||
all_scopes : vec![],
|
||||
scope_roots : vec![],
|
||||
let mut vcd = VCD {
|
||||
metadata: header,
|
||||
timeline: vec![],
|
||||
timeline_markers: vec![],
|
||||
all_signals: vec![],
|
||||
all_scopes: vec![],
|
||||
scope_roots: vec![],
|
||||
};
|
||||
|
||||
parse_scopes(&mut word_gen, &mut vcd, &mut signal_map)?;
|
||||
parse_events(&mut word_gen, &mut vcd, &mut signal_map)?;
|
||||
|
||||
// the signal map should not contain any empty string
|
||||
for (k, v) in &signal_map {
|
||||
if k.len() == 0 {
|
||||
return Err(format!("Critical error near {}:{}. There should be no empty strings in vcd string -> SignalIdx hashmap.", file!(), line!()));
|
||||
}
|
||||
}
|
||||
|
||||
// now that we've parsed all scopes and filled the hashmap
|
||||
// with signals, we convert hashmap to an ordered vector
|
||||
let mut signal_map1: Vec<(String, SignalIdx)> = signal_map
|
||||
.iter()
|
||||
.map(|(string, idx)| (string.clone(), idx.clone()))
|
||||
.collect();
|
||||
signal_map1.sort_by(|a: &(String, SignalIdx), b: &(String, SignalIdx)| {
|
||||
let a = &a.0;
|
||||
let b = &b.0;
|
||||
a.partial_cmp(&b).unwrap()
|
||||
});
|
||||
|
||||
let now = std::time::Instant::now();
|
||||
for (k, v) in &signal_map1 {
|
||||
let signal_idx = ordered_binary_lookup(&signal_map1, k.as_str())?;
|
||||
assert!(*v == signal_idx);
|
||||
}
|
||||
let ordered_binary_search_elapsed = now.elapsed();
|
||||
println!(
|
||||
"ordered_binary_search_elapsed: {:.2?}",
|
||||
ordered_binary_search_elapsed
|
||||
);
|
||||
|
||||
// parse_events(&mut wosrd_gen, &mut vcd, &mut signal_map)?;
|
||||
|
||||
Ok(vcd)
|
||||
}
|
||||
|
@ -55,29 +123,18 @@ mod tests {
|
|||
// two loops
|
||||
// testing dates
|
||||
for file in test::GOOD_DATE_FILES {
|
||||
let metadata = parse_metadata(
|
||||
&mut WordReader::new(
|
||||
File::open(file)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
let metadata = parse_metadata(&mut WordReader::new(File::open(file).unwrap()));
|
||||
assert!(metadata.is_ok());
|
||||
assert!(metadata.unwrap().date.is_some());
|
||||
}
|
||||
|
||||
for file in test::FILES {
|
||||
let metadata = parse_metadata(
|
||||
&mut WordReader::new(
|
||||
File::open(file)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
let metadata = parse_metadata(&mut WordReader::new(File::open(file).unwrap()));
|
||||
assert!(metadata.is_ok());
|
||||
|
||||
let (scalar, _timescale) = metadata.unwrap().timescale;
|
||||
assert!(scalar.is_some());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -94,6 +151,5 @@ mod tests {
|
|||
|
||||
// assert!(vcd.is_ok());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue