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

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(())
}