no rwlocks
Some checks failed
ci/woodpecker/push/test Pipeline failed

This commit is contained in:
JMARyA 2025-05-04 23:52:55 +02:00
parent 6c54873ca2
commit dd4cb7fcc6
Signed by: jmarya
GPG key ID: 901B2ADDF27C2263
11 changed files with 36 additions and 26 deletions

7
Cargo.lock generated
View file

@ -106,6 +106,12 @@ dependencies = [
"num-traits",
]
[[package]]
name = "arc-swap"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
[[package]]
name = "argh"
version = "0.1.13"
@ -1230,6 +1236,7 @@ dependencies = [
name = "owl"
version = "0.1.0"
dependencies = [
"arc-swap",
"argh",
"chrono",
"crossbeam",

View file

@ -25,3 +25,4 @@ env_logger = "0.11.8"
parking_lot = { version = "0.12.3", features = ["send_guard"] }
crossbeam = { version = "0.8.4", features = ["crossbeam-channel"] }
once_cell = "1.21.3"
arc-swap = "1.7.1"

View file

@ -61,10 +61,10 @@ pub fn relation(args: TokenStream, input: TokenStream) -> TokenStream {
let relation_name = struct_name.to_string().to_case(Case::Snake);
let expanded = quote! {
#[derive(owl::Serialize, owl::Deserialize, Default)]
#[derive(owl::Serialize, owl::Deserialize, Default, Clone)]
#input_struct
#[derive(owl::Deserialize, owl::Serialize, Debug)]
#[derive(owl::Deserialize, owl::Serialize, Debug, Clone)]
pub struct #struct_ref_name {
pub id: Id,
pub inner: owl::db::relation::RelationReference
@ -166,7 +166,7 @@ pub fn model(_: TokenStream, input: TokenStream) -> TokenStream {
let relation_name = struct_name.to_string().to_case(Case::Snake);
let expanded = quote! {
#[derive(serde::Serialize, serde::Deserialize)]
#[derive(serde::Serialize, serde::Deserialize, Clone)]
#input_struct
impl owl::db::store::Saveable for #struct_name {}

View file

@ -4,7 +4,7 @@ use chrono::Utc;
use serde::{Deserialize, Deserializer, Serialize};
// historic field
#[derive(Deserialize, Serialize, Default, Debug, PartialEq)]
#[derive(Deserialize, Serialize, Default, Debug, PartialEq, Clone)]
pub struct Historic<T> {
pub values: Vec<(chrono::DateTime<Utc>, T)>,
}

View file

@ -1,3 +1,4 @@
use arc_swap::ArcSwap;
use parking_lot::{RwLock, RwLockReadGuard};
use std::{
ops::{Deref, DerefMut},
@ -170,7 +171,7 @@ impl Database {
}
/// Update every model in `entries` according to `u(_)`
pub fn update<T: 'static + Serialize + Identifiable + Send + Sync, F: Fn(&mut T)>(
pub fn update<T: 'static + Serialize + Identifiable + Send + Sync + Clone, F: Fn(&mut T)>(
&self,
entries: &mut [Model<T>],
u: F,
@ -259,7 +260,7 @@ impl Database {
)?
};
let model = Model {
inner: Arc::new(RwLock::new(m)),
inner: Arc::new(ArcSwap::new(Arc::new(m))),
};
if self.cached {
@ -284,9 +285,10 @@ impl Database {
}
let data = data.read();
let data = (*data).deref();
unsafe {
Store::save(&T::model_id(), data.deref(), self.named, &*self.storage);
Store::save(&T::model_id(), data, self.named, &*self.storage);
}
}
@ -296,7 +298,7 @@ impl Database {
data: T,
) -> Model<T> {
let model = Model {
inner: Arc::new(RwLock::new(data)),
inner: Arc::new(ArcSwap::new(Arc::new(data))),
};
self.save_model(&model);
let id = model.full_id().to_string();
@ -313,7 +315,7 @@ impl Database {
// TODO : cache eviction based on ref counts
pub struct Model<T> {
inner: Arc<RwLock<T>>,
inner: Arc<ArcSwap<T>>,
}
impl Model<File> {
@ -325,7 +327,7 @@ impl Model<File> {
impl<T: Identifiable> Model<T> {
pub fn from_raw(raw: T) -> Model<T> {
Model {
inner: Arc::new(RwLock::new(raw)),
inner: Arc::new(ArcSwap::new(Arc::new(raw))),
}
}
@ -337,23 +339,23 @@ impl<T: Identifiable> Model<T> {
self.read().reference()
}
pub fn read(&self) -> RwLockReadGuard<T> {
self.inner.read()
pub fn read(&self) -> arc_swap::Guard<Arc<T>> {
self.inner.load()
}
}
impl<T: 'static + Serialize + Identifiable + Send + Sync> Model<T> {
impl<T: 'static + Serialize + Identifiable + Send + Sync + Clone> Model<T> {
pub fn write<F: Fn(&mut T)>(&mut self, db: &Database, u: F) {
let mut me = self.inner.write();
u(me.deref_mut());
drop(me);
let mut me = (**self.inner.load()).clone();
u(&mut me);
self.inner.swap(Arc::new(me));
db.save_model(self);
}
/// Update the model inline without writing to `Database`
pub fn write_raw_inline<F: Fn(&mut T)>(&mut self, u: F) {
let mut me = self.inner.write();
u(me.deref_mut());
let mut me = (**self.inner.load()).clone();
u(&mut me);
drop(me);
}
}
@ -367,7 +369,7 @@ impl<T: 'static + Serialize + Identifiable + Send + Sync> ModelObj for Model<T>
impl<T> Clone for Model<T> {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
inner: self.inner.clone(),
}
}
}

View file

@ -17,7 +17,7 @@ fn sha256(input: &[u8]) -> String {
}
/// A generic file
#[derive(Debug, Clone)]
#[derive(Debug)]
#[model]
pub struct File {
id: Id,

View file

@ -6,7 +6,7 @@ pub use crate as owl;
use crate::db::id::Id;
/// Represents a geographical location with an ID, coordinates, and optional address
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, PartialEq)]
#[model]
pub struct Location {
pub id: Id,

View file

@ -5,7 +5,7 @@ pub use crate as owl;
use crate::db::id::Id;
/// Represents a mail address with an ID and the address itself
#[derive(Debug, Clone)]
#[derive(Debug)]
#[model]
pub struct MailAddress {
/// Unique identifier for the mail address

View file

@ -32,7 +32,7 @@ pub struct Person {
pub locations: Historic<Vec<IdRef<Location>>>,
}
#[derive(Deserialize, Serialize, Debug, PartialEq)]
#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
pub enum Gender {
Male,
Female,

View file

@ -5,7 +5,7 @@ pub use crate as owl;
use crate::db::id::Id;
/// Represents a phone number with an ID, the phone number itself, and the country code.
#[derive(Debug, Clone)]
#[derive(Debug)]
#[model]
pub struct PhoneNumber {
id: Id,

View file

@ -437,7 +437,7 @@ impl<
}
pub trait RelationRef:
Identifiable + for<'a> Deserialize<'a> + Serialize + Send + Sync + 'static
Identifiable + for<'a> Deserialize<'a> + Serialize + Send + Sync + 'static + Clone
{
fn top(&self) -> IdRef<serde_json::Value>;
fn sub(&self) -> IdRef<serde_json::Value>;
@ -445,7 +445,7 @@ pub trait RelationRef:
fn update_meta(&mut self, weight: Option<f64>, meta: Option<serde_json::Value>);
}
#[derive(Deserialize, Serialize, Debug)]
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct RelationReference {
pub top: IdRef<serde_json::Value>,
pub sub: IdRef<serde_json::Value>,