passes 6a, totally available single node

This commit is contained in:
Joe Ardent 2024-06-09 13:07:32 -07:00
parent 5e3e269785
commit ac5477d1d0
4 changed files with 129 additions and 1 deletions

8
Cargo.lock generated
View file

@ -53,6 +53,14 @@ dependencies = [
"serde_json",
]
[[package]]
name = "gg-txn"
version = "0.0.1"
dependencies = [
"nebkor-maelstrom",
"serde_json",
]
[[package]]
name = "gg-uid"
version = "0.0.1"

View file

@ -1,5 +1,5 @@
[workspace]
members = ["gg-echo", "gg-uid", "gg-broadcast", "gg-g_counter", "gg-kafka"]
members = ["gg-echo", "gg-uid", "gg-broadcast", "gg-g_counter", "gg-kafka", "gg-txn"]
resolver = "2"
[workspace.package]

10
gg-txn/Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[package]
name = "gg-txn"
edition = "2021"
version.workspace = true
authors.workspace = true
license-file.workspace = true
[dependencies]
nebkor-maelstrom.workspace = true
serde_json.workspace = true

110
gg-txn/src/main.rs Normal file
View file

@ -0,0 +1,110 @@
use std::collections::HashMap;
use nebkor_maelstrom::{mk_payload, Body, Message, Node, Runner};
use serde_json::Value;
type Txn = Vec<TxnOp>;
trait TxnSer {
fn serialize(&self) -> Value;
}
impl TxnSer for Txn {
fn serialize(&self) -> Value {
let out: Vec<Value> = self
.iter()
.map(|t| {
let v: Vec<Value> = vec![t.op.clone().into(), t.key.into(), t.value.into()];
v.into()
})
.collect();
out.into()
}
}
fn main() {
let node = TANode::default();
let runner = Runner::new(node);
runner.run(None);
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
struct TxnOp {
op: String,
key: u64,
value: Option<u64>,
}
#[derive(Debug, Clone, Default)]
struct TANode {
store: HashMap<u64, u64>,
}
impl TANode {
fn transact(&mut self, txn: &Txn) -> Txn {
let mut out = Txn::with_capacity(txn.len());
for txn_op in txn.iter() {
let op = txn_op.op.as_str();
match op {
"r" => {
let key = txn_op.key;
let op = TxnOp {
op: "r".into(),
key,
value: self.store.get(&key).cloned(),
};
out.push(op);
}
"w" => {
self.store.insert(txn_op.key, txn_op.value.unwrap());
out.push(txn_op.clone());
}
_ => {
eprintln!("unknown TxnOp op {op}");
}
}
}
out
}
}
impl Node for TANode {
fn handle(&mut self, runner: &Runner, msg: Message) {
let typ = msg.typ();
match typ {
"txn" => {
let txn = get_txn(&msg);
let txn = self.transact(&txn);
let payload = mk_payload(&[("txn", txn.serialize())]);
let body = Body::from_type("txn_ok").with_payload(payload);
runner.reply(&msg, body);
}
_ => {
eprintln!("unknown message type {typ}")
}
}
}
}
fn get_txn(msg: &Message) -> Txn {
msg.body
.payload
.get("txn")
.unwrap()
.as_array()
.unwrap()
.iter()
.map(|e| {
let o = e.as_array().unwrap();
TxnOp {
op: o[0].as_str().unwrap().to_string(),
key: o[1].as_u64().unwrap(),
value: o[2].as_u64(),
}
})
.collect()
}