Skip to content

Commit 9357ca9

Browse files
committed
Add methods to write props to GraphWriter
1 parent 37bd134 commit 9357ca9

File tree

9 files changed

+75
-39
lines changed

9 files changed

+75
-39
lines changed

db4-storage/src/api/graph.rs

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
use std::fmt::Debug;
22
use std::path::Path;
33
use crate::error::StorageError;
4-
use raphtory_core::entities::properties::props::MetadataError;
5-
use raphtory_core::entities::properties::tprop::IllegalPropType;
6-
use raphtory_core::storage::timeindex::TimeIndexEntry;
74
use raphtory_core::entities::properties::tprop::TPropCell;
85
use raphtory_api::core::entities::properties::prop::Prop;
9-
6+
use parking_lot::RwLockWriteGuard;
7+
use crate::segments::graph::segment::MemGraphSegment;
108

119
pub trait GraphSegmentOps: Send + Sync + Debug + 'static
1210
where
@@ -19,6 +17,8 @@ where
1917
fn load(path: impl AsRef<Path>) -> Result<Self, StorageError>;
2018

2119
fn entry(&self) -> Self::Entry<'_>;
20+
21+
fn head_mut(&self) -> RwLockWriteGuard<'_, MemGraphSegment>;
2222
}
2323

2424
/// Methods for reading graph properties and metadata from storage.
@@ -27,17 +27,3 @@ pub trait GraphEntryOps<'a>: Send + Sync + 'a {
2727

2828
fn get_metadata(&self, prop_id: usize) -> Option<Prop>;
2929
}
30-
31-
/// Methods for writing graph properties and metadata to storage.
32-
pub trait GraphEntryMutOps: Send + Sync {
33-
fn add_prop(
34-
&self,
35-
t: TimeIndexEntry,
36-
prop_id: usize,
37-
prop: Prop,
38-
) -> Result<(), IllegalPropType>;
39-
40-
fn add_metadata(&self, prop_id: usize, prop: Prop) -> Result<(), MetadataError>;
41-
42-
fn update_metadata(&self, prop_id: usize, prop: Prop);
43-
}

db4-storage/src/api/nodes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ pub trait NodeSegmentOps: Send + Sync + std::fmt::Debug + 'static {
7070
fn segment_id(&self) -> usize;
7171

7272
fn head_arc(&self) -> ArcRwLockReadGuard<parking_lot::RawRwLock, MemNodeSegment>;
73+
7374
fn head(&self) -> RwLockReadGuard<'_, MemNodeSegment>;
7475

7576
fn head_mut(&self) -> RwLockWriteGuard<'_, MemNodeSegment>;
Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
11
use crate::{
2-
LocalPOS, api::graph::GraphSegmentOps, error::StorageError, pages::layer_counter::GraphStats,
32
segments::graph::segment::MemGraphSegment,
43
};
5-
use std::ops::DerefMut;
4+
use raphtory_core::storage::timeindex::TimeIndexEntry;
5+
use raphtory_api::core::entities::properties::prop::Prop;
6+
use parking_lot::RwLockWriteGuard;
67

7-
pub struct GraphWriter<'a, MP: DerefMut<Target = MemGraphSegment> + 'a, GS: GraphSegmentOps> {
8-
pub page: &'a GS,
9-
pub writer: MP,
8+
/// Provides mutable access to a graph segment. Holds an exclusive write lock
9+
/// on the in-memory segment for the duration of its lifetime.
10+
pub struct GraphWriter<'a> {
11+
pub mem_segment: RwLockWriteGuard<'a, MemGraphSegment>,
1012
}
1113

12-
impl<'a, MP: DerefMut<Target = MemGraphSegment> + 'a, GS: GraphSegmentOps> GraphWriter<'a, MP, GS> {
13-
pub fn new(page: &'a GS, writer: MP) -> Self {
14-
Self { page, writer }
14+
impl<'a> GraphWriter<'a> {
15+
pub fn new(mem_segment: RwLockWriteGuard<'a, MemGraphSegment>) -> Self {
16+
Self { mem_segment }
17+
}
18+
19+
pub fn add_properties(&mut self, t: TimeIndexEntry, props: impl IntoIterator<Item = (usize, Prop)>) {
20+
self.mem_segment.add_properties(t, props)
21+
}
22+
23+
pub fn add_metadata(&mut self, props: impl IntoIterator<Item = (usize, Prop)>) {
24+
self.mem_segment.add_metadata(props)
25+
}
26+
27+
pub fn update_metadata(&mut self, props: impl IntoIterator<Item = (usize, Prop)>) {
28+
self.mem_segment.update_metadata(props)
1529
}
1630
}

db4-storage/src/pages/graph_store.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::path::{Path, PathBuf};
22
use std::sync::Arc;
33
use crate::api::graph::GraphSegmentOps;
44
use crate::error::StorageError;
5+
use crate::pages::graph_page::writer::GraphWriter;
56
use crate::persist::strategy::Config;
67
use raphtory_core::entities::properties::graph_meta::GraphMeta;
78

@@ -63,4 +64,10 @@ impl<GS: GraphSegmentOps, EXT: Config> GraphStorageInner<GS, EXT> {
6364
pub fn graph_entry(&self) -> GS::Entry<'_> {
6465
self.page.entry()
6566
}
67+
68+
pub fn writer(&self) -> GraphWriter<'_> {
69+
let head = self.page.head_mut();
70+
71+
GraphWriter::new(head)
72+
}
6673
}

db4-storage/src/pages/locked/nodes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ impl<'a, EXT, NS: NodeSegmentOps<Extension = EXT>> LockedNodePage<'a, NS> {
6363
self.layer_counter.get(layer_id);
6464
}
6565
}
66+
6667
pub struct WriteLockedNodePages<'a, NS> {
6768
writers: Vec<LockedNodePage<'a, NS>>,
6869
}

db4-storage/src/segments/graph/entry.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,25 @@ use parking_lot::RwLockReadGuard;
66

77
/// A borrowed view enabling read operations on an in-memory graph segment.
88
pub struct MemGraphEntry<'a> {
9-
mem: RwLockReadGuard<'a, MemGraphSegment>,
9+
mem_segment: RwLockReadGuard<'a, MemGraphSegment>,
1010
}
1111

1212
impl<'a> MemGraphEntry<'a> {
13-
pub fn new(mem: RwLockReadGuard<'a, MemGraphSegment>) -> Self {
14-
Self { mem }
13+
pub fn new(mem_segment: RwLockReadGuard<'a, MemGraphSegment>) -> Self {
14+
Self { mem_segment }
1515
}
1616
}
1717

1818
impl<'a> GraphEntryOps<'a> for MemGraphEntry<'a> {
1919
fn get_temporal_prop(&self, prop_id: usize) -> Option<TPropCell<'_>> {
20-
let row = 0; // GraphSegment has only one row
20+
let layer = &self.mem_segment.layers().get(MemGraphSegment::LAYER).expect("GraphSegment has no layers");
2121

22-
// TODO: handle multiple layers
23-
let layer = &self.mem.layers().get(0).expect("GraphSegment has no layers");
24-
25-
layer.t_prop(row, prop_id)
22+
layer.t_prop(MemGraphSegment::ROW, prop_id)
2623
}
2724

2825
fn get_metadata(&self, prop_id: usize) -> Option<Prop> {
29-
let row = 0; // GraphSegment has only one row
30-
31-
// TODO: handle multiple layers
32-
let layer = &self.mem.layers().get(0).expect("GraphSegment has no layers");
26+
let layer = &self.mem_segment.layers().get(MemGraphSegment::LAYER).expect("GraphSegment has no layers");
3327

34-
layer.c_prop(row, prop_id)
28+
layer.c_prop(MemGraphSegment::ROW, prop_id)
3529
}
3630
}

db4-storage/src/segments/graph/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::api::graph::GraphSegmentOps;
99
use crate::error::StorageError;
1010
use crate::segments::graph::segment::MemGraphSegment;
1111
use crate::segments::graph::entry::MemGraphEntry;
12+
use parking_lot::RwLockWriteGuard;
1213

1314
/// `GraphSegmentView` manages graph temporal properties and graph metadata
1415
/// (constant properties). Reads / writes are always served from the in-memory segment.
@@ -38,6 +39,11 @@ impl GraphSegmentOps for GraphSegmentView {
3839

3940
fn entry(&self) -> Self::Entry<'_> {
4041
let head = self.head.read();
42+
4143
MemGraphEntry::new(head)
4244
}
45+
46+
fn head_mut(&self) -> RwLockWriteGuard<'_, MemGraphSegment> {
47+
self.head.write()
48+
}
4349
}

db4-storage/src/segments/graph/segment.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use crate::segments::graph::entry::MemGraphEntry;
77
use crate::segments::{HasRow, SegmentContainer};
88
use parking_lot::RwLock;
99
use raphtory_api::core::entities::properties::meta::Meta;
10+
use raphtory_core::storage::timeindex::TimeIndexEntry;
11+
use raphtory_api::core::entities::properties::prop::Prop;
1012

1113
/// In-memory segment that contains graph temporal properties and graph metadata.
1214
#[derive(Debug)]
@@ -32,6 +34,12 @@ impl HasRow for GraphSegmentEntry {
3234
}
3335

3436
impl MemGraphSegment {
37+
/// Graph segments only have a single row.
38+
pub const ROW: usize = 0;
39+
40+
/// Graph segments are currently only written to a single layer.
41+
pub const LAYER: usize = 0;
42+
3543
pub fn new() -> Self {
3644
// Technically, these aren't used since there is always only one graph segment.
3745
let segment_id = 0;
@@ -46,4 +54,22 @@ impl MemGraphSegment {
4654
pub fn layers(&self) -> &[SegmentContainer<GraphSegmentEntry>] {
4755
&self.layers
4856
}
57+
58+
pub fn add_properties(&mut self, t: TimeIndexEntry, props: impl IntoIterator<Item = (usize, Prop)>) {
59+
let layer = &mut self.layers[Self::LAYER];
60+
61+
layer.properties_mut().get_mut_entry(Self::ROW).append_t_props(t, props);
62+
}
63+
64+
pub fn add_metadata(&mut self, props: impl IntoIterator<Item = (usize, Prop)>) {
65+
let layer = &mut self.layers[Self::LAYER];
66+
67+
layer.properties_mut().get_mut_entry(Self::ROW).append_const_props(props);
68+
}
69+
70+
pub fn update_metadata(&mut self, props: impl IntoIterator<Item = (usize, Prop)>) {
71+
let layer = &mut self.layers[Self::LAYER];
72+
73+
layer.properties_mut().get_mut_entry(Self::ROW).append_const_props(props);
74+
}
4975
}

raphtory/src/db/api/mutation/property_addition_ops.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub trait PropertyAdditionOps:
1818
) -> Result<(), GraphError>;
1919

2020
fn add_metadata<PI: CollectProperties>(&self, props: PI) -> Result<(), GraphError>;
21+
2122
fn update_metadata<PI: CollectProperties>(&self, props: PI) -> Result<(), GraphError>;
2223
}
2324

0 commit comments

Comments
 (0)