model.rs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. use std::collections::HashMap;
  2. use crate::Operation;
  3. pub trait Model:
  4. std::cmp::Eq + std::clone::Clone + std::hash::Hash + std::fmt::Debug
  5. {
  6. type Input: std::fmt::Debug;
  7. type Output: std::fmt::Debug;
  8. fn create() -> Self;
  9. fn partition(
  10. history: &[Operation<Self::Input, Self::Output>],
  11. ) -> Vec<Vec<&Operation<Self::Input, Self::Output>>> {
  12. let history: Vec<&Operation<Self::Input, Self::Output>> =
  13. history.iter().collect();
  14. vec![history]
  15. }
  16. fn step(&mut self, input: &Self::Input, output: &Self::Output) -> bool;
  17. }
  18. #[derive(Clone, Debug)]
  19. pub enum KvOp {
  20. Get,
  21. Put,
  22. Append,
  23. }
  24. #[derive(Clone, Debug)]
  25. pub struct KvInput {
  26. pub op: KvOp,
  27. pub key: String,
  28. pub value: String,
  29. }
  30. pub type KvOutput = String;
  31. unsafe impl Sync for KvInput {}
  32. #[derive(Clone, Debug, Eq, PartialEq, Hash)]
  33. pub struct KvModel {
  34. expected_output: String,
  35. }
  36. impl Model for KvModel {
  37. type Input = KvInput;
  38. type Output = KvOutput;
  39. fn create() -> Self {
  40. KvModel {
  41. expected_output: String::new(),
  42. }
  43. }
  44. fn partition(
  45. history: &[Operation<KvInput, KvOutput>],
  46. ) -> Vec<Vec<&Operation<KvInput, KvOutput>>> {
  47. let mut by_key =
  48. HashMap::<String, Vec<&Operation<KvInput, KvOutput>>>::new();
  49. for op in history {
  50. by_key.entry(op.call_op.key.clone()).or_default().push(op);
  51. }
  52. let mut result = vec![];
  53. for (_, values) in by_key {
  54. result.push(values);
  55. }
  56. result
  57. }
  58. fn step(&mut self, input: &KvInput, output: &KvOutput) -> bool {
  59. match input.op {
  60. KvOp::Get => self.expected_output == *output,
  61. KvOp::Put => {
  62. self.expected_output = input.value.clone();
  63. true
  64. }
  65. KvOp::Append => {
  66. self.expected_output += &input.value;
  67. true
  68. }
  69. }
  70. }
  71. }