Skip to content

Commit a585065

Browse files
committed
Add Rust implementation of two-stacks (TwoStacks)
1 parent 068da1a commit a585065

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

rust/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,6 @@ pub mod recalc;
4646

4747
/// Subtract-On-Evict
4848
pub mod soe;
49+
50+
/// Two-Stacks
51+
pub mod two_stacks;

rust/src/two_stacks/mod.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use crate::FifoWindow;
2+
use alga::general::AbstractMonoid;
3+
use alga::general::Operator;
4+
use std::marker::PhantomData;
5+
6+
#[derive(Debug)]
7+
struct Item<Value>
8+
where
9+
Value: Clone,
10+
{
11+
agg: Value,
12+
val: Value,
13+
}
14+
15+
#[derive(Debug)]
16+
pub struct TwoStacks<Value, BinOp>
17+
where
18+
Value: AbstractMonoid<BinOp> + Clone,
19+
BinOp: Operator,
20+
{
21+
front: Vec<Item<Value>>,
22+
back: Vec<Item<Value>>,
23+
op: PhantomData<BinOp>,
24+
}
25+
26+
impl<Value, BinOp> FifoWindow<Value, BinOp> for TwoStacks<Value, BinOp>
27+
where
28+
Value: AbstractMonoid<BinOp> + Clone,
29+
BinOp: Operator,
30+
{
31+
fn new() -> TwoStacks<Value, BinOp> {
32+
TwoStacks {
33+
front: Vec::new(),
34+
back: Vec::new(),
35+
op: PhantomData,
36+
}
37+
}
38+
fn push(&mut self, v: Value) {
39+
self.back.push(Item {
40+
agg: Self::agg(&self.back).operate(&v),
41+
val: v,
42+
});
43+
}
44+
fn pop(&mut self) {
45+
if self.front.is_empty() {
46+
while let Some(top) = self.back.pop() {
47+
self.front.push(Item {
48+
agg: top.val.operate(&Self::agg(&self.front)),
49+
val: top.val,
50+
})
51+
}
52+
}
53+
self.front.pop();
54+
}
55+
fn query(&self) -> Value {
56+
Self::agg(&self.front).operate(&Self::agg(&self.back))
57+
}
58+
}
59+
60+
impl<Value, BinOp> TwoStacks<Value, BinOp>
61+
where
62+
Value: AbstractMonoid<BinOp> + Clone,
63+
BinOp: Operator,
64+
{
65+
#[inline(always)]
66+
fn agg(stack: &Vec<Item<Value>>) -> Value {
67+
if let Some(top) = stack.last() {
68+
top.agg.clone()
69+
} else {
70+
Value::identity()
71+
}
72+
}
73+
}

rust/tests/fifo-window.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use alga::general::TwoSidedInverse;
1010
use rand::Rng;
1111
use swag::recalc::*;
1212
use swag::soe::*;
13+
use swag::two_stacks::*;
1314
use swag::*;
1415

1516
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
@@ -111,3 +112,13 @@ fn test1_soe() {
111112
fn test2_soe() {
112113
test2::<SoE<Value, Sum>>();
113114
}
115+
116+
#[test]
117+
fn test1_two_stacks() {
118+
test1::<TwoStacks<Value, Sum>>();
119+
}
120+
121+
#[test]
122+
fn test2_two_stacks() {
123+
test2::<TwoStacks<Value, Sum>>();
124+
}

0 commit comments

Comments
 (0)