improve database memory usage

This commit is contained in:
2025-06-16 17:41:09 +02:00
parent 34818ce050
commit 2931cf2927
5 changed files with 67 additions and 24 deletions

46
Cargo.lock generated
View File

@@ -22,6 +22,7 @@ name = "archive"
version = "0.1.0"
dependencies = [
"bytes",
"byteyarn",
"thiserror",
"tokio",
]
@@ -53,12 +54,36 @@ version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]]
name = "buf-trait"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21eaafc770e8c073d6c3facafe7617e774305d4954aa6351b9c452eb37ee17b4"
dependencies = [
"zerocopy",
]
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
[[package]]
name = "byteyarn"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b93e51d26468a15ea59f8525e0c13dc405db43e644a0b1e6d44346c72cf4cf7b"
dependencies = [
"buf-trait",
]
[[package]]
name = "cfg-if"
version = "1.0.1"
@@ -368,3 +393,24 @@ name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"byteorder",
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View File

@@ -5,5 +5,6 @@ edition = "2024"
[dependencies]
bytes = "1.10.1"
byteyarn = "0.5.1"
thiserror = "2.0.12"
tokio = { version = "1.45.1", features = ["full"] }

View File

@@ -11,12 +11,7 @@ use get::Get;
use has::Has;
use set::Set;
use crate::{
Result,
connection::Connection,
database::{Database, Value},
errors::AppError,
};
use crate::{Result, connection::Connection, database::Database, errors::AppError};
#[derive(Debug)]
pub enum Command {

View File

@@ -1,28 +1,31 @@
use std::{collections::HashMap, sync::Arc};
use std::{collections::BTreeMap, sync::Arc};
use bytes::{BufMut, Bytes, BytesMut};
use byteyarn::Yarn;
use tokio::sync::Mutex;
use crate::Result;
#[derive(Debug, Clone)]
pub struct Database {
entries: Arc<Mutex<HashMap<String, Value>>>,
entries: Arc<Mutex<BTreeMap<Yarn, Value>>>,
}
#[derive(Debug, Clone)]
pub struct Value {
data: Bytes,
data: Box<[u8]>,
}
impl Value {
pub fn new(data: Bytes) -> Self {
Self { data }
Self {
data: data.into_iter().collect(),
}
}
pub fn from_string(data: String) -> Self {
Self {
data: Bytes::from(data),
data: data.as_bytes().into(),
}
}
@@ -39,7 +42,7 @@ impl Database {
}
}
pub async fn get(&self, key: &str) -> Option<Bytes> {
pub async fn get(&self, key: &str) -> Option<Box<[u8]>> {
let entries = self.entries.lock().await;
entries.get(key).map(|v| v.data.clone())
@@ -48,12 +51,12 @@ impl Database {
pub async fn set(&self, key: String, value: Value) -> Result<()> {
let mut entries = self.entries.lock().await;
entries.insert(key, value);
entries.insert(key.into(), value);
Ok(())
}
pub async fn delete(&self, key: &str) -> Option<Bytes> {
pub async fn delete(&self, key: &str) -> Option<Box<[u8]>> {
let mut entries = self.entries.lock().await;
entries.remove(key).map(|v| v.data)

View File

@@ -1,4 +1,3 @@
use bytes::Bytes;
use client::Client;
use database::Value;
use errors::AppError;
@@ -18,7 +17,7 @@ pub type Result<T> = std::result::Result<T, AppError>;
async fn main() -> Result<()> {
let mut server = Server::new("127.0.0.1:6171").await?;
tokio::spawn(client("client-1".into()));
// tokio::spawn(client());
server.run().await?;
@@ -26,16 +25,15 @@ async fn main() -> Result<()> {
}
// Test stuff
async fn client(v: String) -> Result<()> {
async fn client() -> Result<()> {
let mut client = Client::new("127.0.0.1:6171").await?;
client
.set(&v, Value::from_string(format!("{v}'s value")))
.await?;
assert_eq!(
client.get(&v).await.unwrap().unwrap(),
Bytes::from(format!("{v}'s value"))
);
for i in 0..1_000_000 {
let key = format!("key-{i}");
client.set(&key, Value::from_string(i.to_string())).await?;
}
println!("Finished writing keys");
Ok(())
}