feat(byr-fogtix): optimize merge/ff case
This commit is contained in:
parent
c2a0aba3a5
commit
4dedcbe057
|
@ -102,6 +102,7 @@ fn data_ser(din: Vec<u64>, dout: &mut Vec<u8>) {
|
|||
dout.extend(din.into_iter().flat_map(|i| i.to_be_bytes()));
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
fn main() {
|
||||
let args = <Args as clap::Parser>::parse();
|
||||
|
||||
|
@ -252,11 +253,7 @@ fn main() {
|
|||
let mut bit = b.changelist.0.iter().peekable();
|
||||
mprgs.add(pbarA.clone());
|
||||
mprgs.add(pbarB.clone());
|
||||
loop {
|
||||
let (ap, bp) = match (ait.peek(), bit.peek()) {
|
||||
(Some(ap), Some(bp)) => (ap, bp),
|
||||
(_, _) => break,
|
||||
};
|
||||
while let (Some(ap), Some(bp)) = (ait.peek(), bit.peek()) {
|
||||
if ap == bp {
|
||||
let bytecode = changes.get(ap)?;
|
||||
BytecodeWrapper(&bytecode[..]).run(&mut data).map_err(|e| {
|
||||
|
@ -287,17 +284,7 @@ fn main() {
|
|||
.enumerate()
|
||||
.map(|(n, &i)| (X::B(n), i))
|
||||
.collect::<Vec<_>>();
|
||||
// this just relies on the fact that any remaining duplicates between A and B are idempotent
|
||||
// TODO: compute common elements between restA & restB, and handle them specifically (dedup)
|
||||
let appAB = restA
|
||||
.iter()
|
||||
.chain(restB.iter())
|
||||
.copied()
|
||||
.collect::<Vec<_>>();
|
||||
let appBA = restB
|
||||
.into_iter()
|
||||
.chain(restA.into_iter())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let appMX = {
|
||||
let mut mx = Vec::new();
|
||||
// time for cursed merge-sort
|
||||
|
@ -327,41 +314,57 @@ fn main() {
|
|||
pbarB.finish_and_clear();
|
||||
mx
|
||||
};
|
||||
// run them...
|
||||
let (data1, data2) = (data.clone(), data.clone());
|
||||
let (changes1, changes2) = (changes.try_clone()?, changes.try_clone()?);
|
||||
fn run_chain(
|
||||
mut data: Vec<u64>,
|
||||
chain: Vec<(X, [u8; 32])>,
|
||||
changes: byr_core::MassChangesGet,
|
||||
pbar: ProgressBar,
|
||||
) -> IoResult<Vec<u64>> {
|
||||
for (idx, i) in pbar.wrap_iter(chain.into_iter()) {
|
||||
let mut p = fogtix_vm::Process {
|
||||
stack: core::mem::take(&mut data),
|
||||
callstack: Vec::new(),
|
||||
m: &changes.get(&i)?,
|
||||
instrp: 0,
|
||||
};
|
||||
p.run(None).map_err(|e| {
|
||||
std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidInput,
|
||||
format!("{:?}:{:?}", idx, e),
|
||||
)
|
||||
})?;
|
||||
data = p.stack;
|
||||
let tA_B = if (!restA.is_empty()) && (!restB.is_empty()) {
|
||||
// this just relies on the fact that any remaining duplicates between A and B are idempotent
|
||||
// TODO: compute common elements between restA & restB, and handle them specifically (dedup)
|
||||
let appAB = restA
|
||||
.iter()
|
||||
.chain(restB.iter())
|
||||
.copied()
|
||||
.collect::<Vec<_>>();
|
||||
let appBA = restB
|
||||
.into_iter()
|
||||
.chain(restA.into_iter())
|
||||
.collect::<Vec<_>>();
|
||||
// run them...
|
||||
let (data1, data2) = (data.clone(), data.clone());
|
||||
let (changes1, changes2) = (changes.try_clone()?, changes.try_clone()?);
|
||||
fn run_chain(
|
||||
mut data: Vec<u64>,
|
||||
chain: Vec<(X, [u8; 32])>,
|
||||
changes: byr_core::MassChangesGet,
|
||||
pbar: ProgressBar,
|
||||
) -> IoResult<Vec<u64>> {
|
||||
for (idx, i) in pbar.wrap_iter(chain.into_iter()) {
|
||||
let mut p = fogtix_vm::Process {
|
||||
stack: core::mem::take(&mut data),
|
||||
callstack: Vec::new(),
|
||||
m: &changes.get(&i)?,
|
||||
instrp: 0,
|
||||
};
|
||||
p.run(None).map_err(|e| {
|
||||
std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidInput,
|
||||
format!("{:?}:{:?}", idx, e),
|
||||
)
|
||||
})?;
|
||||
data = p.stack;
|
||||
}
|
||||
Ok(data)
|
||||
}
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
let (pA, pB) = (
|
||||
ProgressBar::new(appAB.len().try_into().unwrap()).with_prefix("s|aug"),
|
||||
ProgressBar::new(appBA.len().try_into().unwrap()).with_prefix("aug|s"),
|
||||
);
|
||||
mprgs.add(pA.clone());
|
||||
mprgs.add(pB.clone());
|
||||
let tA = std::thread::spawn(move || run_chain(data1, appAB, changes1, pA));
|
||||
let tB = std::thread::spawn(move || run_chain(data2, appBA, changes2, pB));
|
||||
let (pA, pB) = (
|
||||
ProgressBar::new(appAB.len().try_into().unwrap()).with_prefix("s|aug"),
|
||||
ProgressBar::new(appBA.len().try_into().unwrap()).with_prefix("aug|s"),
|
||||
);
|
||||
mprgs.add(pA.clone());
|
||||
mprgs.add(pB.clone());
|
||||
let tA = std::thread::spawn(move || run_chain(data1, appAB, changes1, pA));
|
||||
let tB = std::thread::spawn(move || run_chain(data2, appBA, changes2, pB));
|
||||
Some((tA, tB))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let pMX =
|
||||
ProgressBar::new(appMX.len().try_into().unwrap()).with_prefix("s<m>aug");
|
||||
|
@ -390,32 +393,37 @@ fn main() {
|
|||
data = p.stack;
|
||||
}
|
||||
|
||||
let rA = tA.join().expect("s|aug thread failed")?;
|
||||
let rB = tB.join().expect("aug|s thread failed")?;
|
||||
let mut succ = true;
|
||||
if let Some((tA, tB)) = tA_B {
|
||||
let rA = tA.join().expect("s|aug thread failed")?;
|
||||
let rB = tB.join().expect("aug|s thread failed")?;
|
||||
let mut succ = true;
|
||||
|
||||
if rA != rB {
|
||||
let _ = mprgs
|
||||
.println("ERROR: the diverging parts don't commute with each other!");
|
||||
succ = false;
|
||||
}
|
||||
if rA != data {
|
||||
let _ = mprgs.println(
|
||||
"ERROR: the merged version and s|aug have mismatching results!",
|
||||
);
|
||||
succ = false;
|
||||
}
|
||||
if rB != data {
|
||||
let _ = mprgs.println(
|
||||
"ERROR: the merged version and aug|s have mismatching results!",
|
||||
);
|
||||
succ = false;
|
||||
}
|
||||
if !succ {
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidData,
|
||||
"merging failed".to_string(),
|
||||
));
|
||||
if rA != rB {
|
||||
let _ = mprgs.println(
|
||||
"ERROR: the diverging parts don't commute with each other!",
|
||||
);
|
||||
succ = false;
|
||||
}
|
||||
if rA != data {
|
||||
let _ = mprgs.println(
|
||||
"ERROR: the merged version and s|aug have mismatching results!",
|
||||
);
|
||||
succ = false;
|
||||
}
|
||||
if rB != data {
|
||||
let _ = mprgs.println(
|
||||
"ERROR: the merged version and aug|s have mismatching results!",
|
||||
);
|
||||
succ = false;
|
||||
}
|
||||
if !succ {
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidData,
|
||||
"merging failed".to_string(),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
let _ = mprgs.println("NOTE: applied fast-forward");
|
||||
}
|
||||
|
||||
data_ser(data, &mut snap.data);
|
||||
|
|
Loading…
Reference in a new issue