Skip to content

Commit e74c805

Browse files
committed
feat: Implement in-memory storage with UUIDs
1 parent 7c4a006 commit e74c805

5 files changed

Lines changed: 99 additions & 4 deletions

File tree

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ pgwire = "0.37.0"
88
sqlparser = "0.60.0"
99
serde = { version = "1.0", features = ["derive"] }
1010
serde_json = "1.0"
11+
uuid = { version = "1.8.0", features = ["v7", "serde"] }

ROADMAP.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ This stage will implement a basic version of JSON Schema discovery to be used in
99

1010
This stage will implement a simple in-memory version of ArgusDB that will serve as the first layer of the LSM tree.
1111

12-
- [] Accept documents for insertion into an in-memory data structure and infer a schema
13-
- [] Add documents to an in-memory data structure and update the inferred schema
14-
- [] Allow deletion of documents by ID
15-
- [] Allow updating of documents by ID
12+
- [x] Accept documents for insertion into an in-memory data structure and infer a schema
13+
- [x] Add documents to an in-memory data structure and update the inferred schema
14+
- [x] Allow deletion of documents by ID
15+
- [x] Allow updating of documents by ID
1616

1717
# Stage 3 - Logging
1818

src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
pub mod schema;
2+
pub mod storage;
3+
14
fn main() {
25
println!("Hello, world!");
36
}

src/storage.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use crate::schema::{infer_schema, Schema};
2+
use serde_json::Value;
3+
use std::collections::BTreeMap;
4+
use uuid::Uuid;
5+
6+
pub struct MemTable {
7+
documents: BTreeMap<String, Value>,
8+
schema: Schema,
9+
}
10+
11+
impl MemTable {
12+
pub fn new() -> Self {
13+
MemTable {
14+
documents: BTreeMap::new(),
15+
schema: Schema {
16+
types: vec![],
17+
properties: None,
18+
items: None,
19+
},
20+
}
21+
}
22+
23+
pub fn insert(&mut self, doc: Value) -> String {
24+
let doc_schema = infer_schema(&doc);
25+
self.schema.merge(doc_schema);
26+
let id = Uuid::now_v7().to_string();
27+
self.documents.insert(id.clone(), doc);
28+
id
29+
}
30+
31+
pub fn delete(&mut self, id: &str) {
32+
self.documents.remove(id);
33+
}
34+
35+
pub fn update(&mut self, id: &str, doc: Value) {
36+
let doc_schema = infer_schema(&doc);
37+
self.schema.merge(doc_schema);
38+
self.documents.insert(id.to_string(), doc);
39+
}
40+
}
41+
42+
#[cfg(test)]
43+
mod tests {
44+
use super::*;
45+
use crate::schema::SchemaType;
46+
use serde_json::json;
47+
48+
#[test]
49+
fn test_memtable_insert() {
50+
let mut memtable = MemTable::new();
51+
memtable.insert(json!({"a": 1}));
52+
memtable.insert(json!({"b": "hello"}));
53+
54+
assert_eq!(memtable.documents.len(), 2);
55+
56+
let schema = memtable.schema;
57+
assert_eq!(schema.types, vec![SchemaType::Object]);
58+
let props = schema.properties.unwrap();
59+
assert_eq!(props.get("a").unwrap().types, vec![SchemaType::Integer]);
60+
assert_eq!(props.get("b").unwrap().types, vec![SchemaType::String]);
61+
}
62+
63+
#[test]
64+
fn test_memtable_delete() {
65+
let mut memtable = MemTable::new();
66+
let id = memtable.insert(json!({"a": 1}));
67+
assert_eq!(memtable.documents.len(), 1);
68+
memtable.delete(&id);
69+
assert_eq!(memtable.documents.len(), 0);
70+
}
71+
72+
#[test]
73+
fn test_memtable_update() {
74+
let mut memtable = MemTable::new();
75+
let id = memtable.insert(json!({"a": 1}));
76+
memtable.update(&id, json!({"b": "hello"}));
77+
78+
assert_eq!(memtable.documents.len(), 1);
79+
let doc = memtable.documents.get(&id).unwrap();
80+
assert_eq!(*doc, json!({"b": "hello"}));
81+
82+
let schema = memtable.schema;
83+
assert_eq!(schema.types, vec![SchemaType::Object]);
84+
let props = schema.properties.unwrap();
85+
assert_eq!(props.get("a").unwrap().types, vec![SchemaType::Integer]);
86+
assert_eq!(props.get("b").unwrap().types, vec![SchemaType::String]);
87+
}
88+
}

0 commit comments

Comments
 (0)