passes 6a, totally available single node
This commit is contained in:
parent
5e3e269785
commit
ac5477d1d0
4 changed files with 129 additions and 1 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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
10
gg-txn/Cargo.toml
Normal 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
110
gg-txn/src/main.rs
Normal 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()
|
||||
}
|
Loading…
Reference in a new issue