-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Commit de145c5
authored
Refactor: use compile time type state pattern (#17083)
This PR implements the state machines using the type state pattern at
compile time (via generic types) instead of a runtime state variable.
There is no runtime check to see what state we are in, instead we
transition to the new state when it's necessary.
This has some nice performance improvements for some of the state
machines, e.g.:
```diff
- ArbitraryVariableMachine: Throughput: 744.92 MB/s
+ ArbitraryVariableMachine: Throughput: 1.21 GB/s
```
We also don't have to store the current state because each machine runs
to completion. It's during execution that we can move to a new state if
necessary.
Unfortunately the diff is a tiny bit annoying to read, but essentially
this is what happened:
### The `enum` is split up in it's individual states as structs:
```rs
enum State {
A,
B,
C,
}
```
Becomes:
```rs
struct A;
struct B;
struct C;
```
### Generics
The current machine will receive a generic `State` that we can default
to the `IdleState`. Then we use `PhantomData` to "use" the type because
the generic type is otherwise not used as a concrete value, it's just a
marker.
```rs
struct MyMachine {}
```
Becomes:
```rs
struct MyMachine<State = Idle> {
_state: std::marker::PhantomData<State>
}
```
### Split
Next, the `next` function used to match on the current state, but now
each match arm is moved to a dedicated implementation instead:
```rs
impl Machine for MyMachine {
fn next(&mut self) -> MachineState {
match self.state {
State::A => { /* … */ },
State::B => { /* … */ },
State::C => { /* … */ },
}
}
}
```
Becomes:
```rs
impl Machine for MyMachine<A> {
fn next(&mut self) -> MachineState {
/* … */
}
}
impl Machine for MyMachine<B> {
fn next(&mut self) -> MachineState {
/* … */
}
}
impl Machine for MyMachine<C> {
fn next(&mut self) -> MachineState {
/* … */
}
}
```
It's a bit more verbose, but now each state is implemented in its own
block. This also removes 2 levels of nesting which is a nice benefit.1 parent cc3e852 commit de145c5Copy full SHA for de145c5
File tree
Expand file treeCollapse file tree
4 files changed
+886
-817
lines changedFilter options
- crates/oxide/src/extractor
Expand file treeCollapse file tree
4 files changed
+886
-817
lines changed
0 commit comments