Skip to content

Commit dad8702

Browse files
authored
Merge pull request #8 from NagaraTech/sprint_01
Sprint 01: new features This pull request mainly contains two features: init node basic version. Merge pull request init node basic version #1 from sglk123/poc_1 feat: add new vlc-dag demos of poc. Merge pull request feat: add new vlc-dag demos of poc #3 from NagaraTech/feat/vlc-dag
2 parents de71b36 + b1c8714 commit dad8702

File tree

7 files changed

+913
-0
lines changed

7 files changed

+913
-0
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ members = [
1515
"zchronod/zchronod",
1616
"demos/test_conflict",
1717
"demos/coll-tx",
18+
"demos/vlc-dag"
1819
]
1920

2021
[profile.release]

crates/vlc/src/lib.rs

+50
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ impl Clock {
5959
*value += 1;
6060
}
6161

62+
/// Get the clock count by id
63+
pub fn get(&mut self, id: u128) -> u128 {
64+
let value = self.values.entry(id).or_insert(0);
65+
*value
66+
}
67+
6268
/// Reset the clock.
6369
pub fn clear(&mut self) {
6470
self.values.clear();
@@ -73,6 +79,50 @@ impl Clock {
7379
}
7480
}
7581
}
82+
83+
/// Diff is local clock minus another clock
84+
pub fn diff(&self, other: &Clock) -> Clock {
85+
let mut ret = Clock::new();
86+
for (id, v1) in &self.values {
87+
let v2 = other.values.get(id).unwrap_or(&0);
88+
if v1 > v2 {
89+
ret.values.insert(*id, v1-v2);
90+
} else {
91+
ret.values.insert(*id, 0);
92+
}
93+
}
94+
ret
95+
}
96+
97+
/// return index key of clock
98+
pub fn index_key(&self) -> String {
99+
let mut key: String = String::new();
100+
for (index, value) in &self.values {
101+
key = format!("{}{}-{}-", key, index, value);
102+
}
103+
key
104+
}
105+
106+
/// return common base clock of two clock
107+
pub fn base_common(&self, other: &Clock) -> Clock {
108+
let mut ret = Clock::new();
109+
for (id, v1) in &self.values {
110+
let v2 = other.values.get(id).unwrap_or(&0);
111+
if v1 <= v2 {
112+
ret.values.insert(*id, *v1);
113+
} else {
114+
ret.values.insert(*id, *v2);
115+
}
116+
}
117+
ret
118+
}
119+
120+
/// return true when all value is zero in clock dimensions
121+
pub fn is_genesis(&self) -> bool {
122+
let sum: u128 = self.values.values().sum();
123+
sum == 0
124+
}
125+
76126
}
77127

78128
#[cfg(test)]

demos/vlc-dag/Cargo.toml

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[package]
2+
name = "vlc-dag"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
vlc = { version = "0.1.0", path = "../../crates/vlc" }
10+
serde = { version = "1", features = ["derive"] }
11+
serde_json = { version = "1" }
12+
clap = { version = "4", features = ["derive"] }
13+
tokio = { version = "1", features = [
14+
"net",
15+
"rt-multi-thread",
16+
"macros",
17+
"time",
18+
] }
19+
rand = { version = "0.8" }
20+
lmdb-rs = "0.7.6"
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use crate::{lmdb::{DbFlags, DbHandle, Environment}, ClockInfo, MergeLog};
2+
3+
#[derive(Clone)]
4+
pub struct VLCLLDb {
5+
env: Environment,
6+
merge_log: DbHandle,
7+
clock_infos: DbHandle,
8+
cur_count: DbHandle,
9+
}
10+
11+
impl VLCLLDb {
12+
pub fn new(path: &str, mode: Option<u32>) -> Self {
13+
let mut USER_DIR_MODE: u32 = 0o777;
14+
if let Some(mode) = mode {
15+
USER_DIR_MODE = mode;
16+
}
17+
18+
let env = Environment::new()
19+
.max_dbs(5)
20+
.open(path, USER_DIR_MODE)
21+
.expect("Failed to open the environment");
22+
23+
let merge_log = env
24+
.create_db("merge_log", DbFlags::empty())
25+
.expect("Failed to create the merge_log database");
26+
27+
let clock_infos = env
28+
.create_db("clock_infos", DbFlags::empty())
29+
.expect("Failed to create the clock_infos database");
30+
31+
let cur_count = env
32+
.create_db("cur_count", DbFlags::empty())
33+
.expect("Failed to create the cur_count database");
34+
35+
VLCLLDb { env, merge_log, clock_infos, cur_count }
36+
}
37+
38+
pub(crate) fn add_clock_infos(&mut self, key: String, clock_info: ClockInfo) {
39+
let txn = self.env.new_transaction().unwrap();
40+
let db = txn.bind(&self.clock_infos);
41+
42+
let _ = db.set(&key, &serde_json::to_string(&clock_info).unwrap());
43+
println!("[insert clock to DB]: \nkey: {},\nvalue: {:#?}", key, clock_info);
44+
}
45+
46+
pub(crate) fn add_merge_log(&mut self, key: String, merge_log: MergeLog) {
47+
let txn = self.env.new_transaction().unwrap();
48+
let db = txn.bind(&self.merge_log);
49+
50+
let _ = db.set(&key, &serde_json::to_string(&merge_log).unwrap());
51+
println!("[insert merge_log to DB]: \nkey: {},\nvalue: {:#?}", key, merge_log);
52+
}
53+
54+
pub fn get_clock_info(&mut self, key: String) -> String {
55+
let txn = self.env.new_transaction().unwrap();
56+
let db = txn.bind(&self.clock_infos);
57+
db.get::<&str>(&key).unwrap_or("").to_string()
58+
}
59+
}
+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
use lmdb_rs as lmdb;
2+
use lmdb::{DbFlags, DbHandle, Environment};
3+
use serde::{Deserialize, Serialize};
4+
use std::collections::HashSet;
5+
6+
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
7+
struct Commit {
8+
pub id: String,
9+
parent_ids: HashSet<String>,
10+
message: String,
11+
}
12+
13+
struct Repository {
14+
env: Environment,
15+
commits_db: DbHandle,
16+
}
17+
18+
impl Repository {
19+
20+
fn new(path: &str, db: &str) -> Self {
21+
const USER_DIR: u32 = 0o777;
22+
let env = Environment::new()
23+
.max_dbs(5)
24+
.open(path, USER_DIR)
25+
.expect("Failed to open the environment");
26+
27+
let commits_db = env
28+
.create_db(db, DbFlags::empty())
29+
.expect("Failed to create the commits database");
30+
31+
Repository { env, commits_db }
32+
}
33+
34+
fn add_commit(&mut self, commit: &Commit) {
35+
// let db = self.env.get_default_db(DbFlags::empty()).unwrap();
36+
let txn = self.env.new_transaction().unwrap();
37+
let db = txn.bind(&self.commits_db);
38+
39+
let _ = db.set(&commit.id, &serde_json::to_string(&commit).unwrap());
40+
println!("Get From DB: {}", db.get::<&str>(&commit.id).unwrap());
41+
}
42+
43+
// other methods
44+
}
45+
46+
#[cfg(test)]
47+
mod tests {
48+
49+
use super::*;
50+
51+
#[test]
52+
fn submit_to_repo() {
53+
let mut repo = Repository::new("./db", "commit");
54+
55+
let commit1 = Commit {
56+
id: "commit1".to_string(),
57+
parent_ids: HashSet::new(),
58+
message: "Initial commit".to_string(),
59+
};
60+
repo.add_commit(&commit1);
61+
62+
let commit2 = Commit {
63+
id: "commit2".to_string(),
64+
parent_ids: vec!["commit1".to_string()].into_iter().collect(),
65+
message: "Add feature X".to_string(),
66+
};
67+
repo.add_commit(&commit2);
68+
69+
let commit3 = Commit {
70+
id: "commit3".to_string(),
71+
parent_ids: vec!["commit1".to_string()].into_iter().collect(),
72+
message: "Add feature Y".to_string(),
73+
};
74+
repo.add_commit(&commit3);
75+
76+
let commit4 = Commit {
77+
id: "commit4".to_string(),
78+
parent_ids: vec!["commit2".to_string(), "commit3".to_string()]
79+
.into_iter()
80+
.collect(),
81+
message: "Merge feature X and Y".to_string(),
82+
};
83+
repo.add_commit(&commit4);
84+
}
85+
}

demos/vlc-dag/src/db_client/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod lldb_client;
2+
mod lldb_test;

0 commit comments

Comments
 (0)