summaryrefslogtreecommitdiff
path: root/unique_ids
diff options
context:
space:
mode:
authorAria <me@aria.rip>2023-10-02 14:03:06 +0100
committerAria <me@aria.rip>2023-10-02 14:03:06 +0100
commit186087b2010f7f2b9631a28b80527d99b751b882 (patch)
tree79e02c254cbeb5e0d981dccb51cd77cf4959d71a /unique_ids
parente189bb3ec7a355e314895a77d3ed25c393cf042b (diff)
unique ids challenge
Diffstat (limited to 'unique_ids')
-rw-r--r--unique_ids/Cargo.toml12
-rw-r--r--unique_ids/src/main.rs83
2 files changed, 95 insertions, 0 deletions
diff --git a/unique_ids/Cargo.toml b/unique_ids/Cargo.toml
new file mode 100644
index 0000000..e7424bf
--- /dev/null
+++ b/unique_ids/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "unique_ids"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+serde = { version = "1.0.185", features = ["derive"] }
+serde_json = "1.0.105"
+common = { path = "../common/" }
+rand = "0.8.5"
diff --git a/unique_ids/src/main.rs b/unique_ids/src/main.rs
new file mode 100644
index 0000000..3787033
--- /dev/null
+++ b/unique_ids/src/main.rs
@@ -0,0 +1,83 @@
+use std::{
+ io,
+ time::{SystemTime, UNIX_EPOCH},
+};
+
+use common::{run_with, Handler};
+use rand::{rngs::StdRng, Rng, SeedableRng};
+use serde::{Deserialize, Serialize};
+
+fn main() {
+ run_with::<UniqueIdsHandler>(io::stdin(), io::stdout())
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+#[serde(tag = "type")]
+enum UniqueIdsBody {
+ #[serde(rename = "generate")]
+ Generate { msg_id: usize },
+
+ #[serde(rename = "generate_ok")]
+ GenerateOk {
+ msg_id: usize,
+ in_reply_to: usize,
+ id: u128,
+ },
+}
+
+type RngMethod = StdRng;
+
+struct UniqueIdsHandler {
+ rng: RngMethod,
+ next_msg_id: usize,
+}
+
+impl Handler for UniqueIdsHandler {
+ type Body = UniqueIdsBody;
+
+ fn init(_node_id: String, _node_ids: Vec<String>, _msg_id: usize) -> Self {
+ Self {
+ rng: RngMethod::from_entropy(), // TODO: This could be seeded from the node ID
+ next_msg_id: 1,
+ }
+ }
+
+ fn handle(
+ &mut self,
+ header: common::msg::MessageHeader,
+ body: Self::Body,
+ writer: &mut common::MsgWriter<impl std::io::Write>,
+ ) -> () {
+ match body {
+ UniqueIdsBody::Generate { msg_id } => {
+ let id = self.gen_id();
+ writer.write(
+ header.src,
+ &UniqueIdsBody::GenerateOk {
+ msg_id: self.next_msg_id,
+ in_reply_to: msg_id,
+ id,
+ },
+ );
+
+ self.next_msg_id += 1;
+ }
+ UniqueIdsBody::GenerateOk { .. } => (),
+ };
+ }
+}
+
+impl UniqueIdsHandler {
+ fn gen_id(&mut self) -> u128 {
+ // Time since UNIX epoch in milliseconds
+ let now = SystemTime::now();
+ let time_millis: u128 = now.duration_since(UNIX_EPOCH).unwrap().as_millis();
+
+ // 80 bits of randomness
+ let rand1: u16 = self.rng.gen();
+ let rand2: u64 = self.rng.gen();
+ let rand: u128 = rand1 as u128 | ((rand2 as u128) << 64);
+
+ (time_millis << 80) | rand
+ }
+}