Skip to content

Commit f90192a

Browse files
committed
Merge db_v4 into db_v4_gql_avoid_collect
2 parents 91aef41 + 8f54d88 commit f90192a

File tree

76 files changed

+6098
-2005
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+6098
-2005
lines changed

.github/workflows/stress-test.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@ jobs:
2121
uses: Swatinem/rust-cache@v2
2222
with:
2323
cache-all-crates: true
24-
- name: Install maturin
25-
run: pip install maturin==1.8.3
26-
- name: Build raphtory
27-
run: make install-python
24+
- uses: ./.github/actions/setup_rust
25+
name: Setup Rust
2826
- name: Set up pnpm
2927
uses: pnpm/action-setup@v4
3028
with:
@@ -33,9 +31,12 @@ jobs:
3331
with:
3432
k6-version: '1.0.0'
3533
- name: Run stress test
34+
env:
35+
RUST_BACKTRACE: 1
3636
run: |
37+
cargo build --package raphtory-graphql --bin raphtory-graphql --profile=build-fast
38+
./target/build-fast/raphtory-graphql server --work-dir graphs &
3739
cd graphql-bench
38-
raphtory server &
3940
make stress-test
4041
- name: Upload k6 report
4142
if: always()

Cargo.lock

Lines changed: 4 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 & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ reqwest = { version = "0.12.8", default-features = false, features = [
7878
boxcar = "0.2.14"
7979
iter-enum = { version = "1.2.0", features = ["rayon"] }
8080
serde = { version = "1.0.197", features = ["derive", "rc"] }
81-
serde_json = "1.0.114"
81+
serde_json = { version = "1.0.114", features = ["float_roundtrip"] }
8282
pyo3 = { version = "0.27.2", features = ["multiple-pymethods", "chrono"] }
8383
pyo3-build-config = "0.27.2"
8484
pyo3-arrow = "0.15.0"

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ build-python:
8484
cd python && maturin develop -r --extras=dev
8585

8686
debug-python:
87-
cd python && maturin develop --profile=debug --extras=dev
87+
cd python && maturin develop --profile=dev --extras=dev
8888

8989
# Testing
9090
python-test:

db4-graph/src/lib.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ where
187187
// VIDs in the resolver may not be initialised yet, need to double-check the node actually exists!
188188
let nodes = self.storage().nodes();
189189
let (page_id, pos) = nodes.resolve_pos(vid);
190-
let node_page = nodes.segments().get(page_id)?;
190+
let node_page = nodes.get_segment(page_id)?;
191191

192192
if pos.0 < node_page.num_nodes() {
193193
Some(vid)
@@ -357,16 +357,16 @@ where
357357
self.graph
358358
}
359359

360-
pub fn resize_chunks_to_vid(&mut self, vid: VID) {
361-
let (chunks_needed, _) = self.graph.storage.nodes().resolve_pos(vid);
362-
self.graph.storage().nodes().grow(chunks_needed + 1);
360+
pub fn resize_segments_to_vid(&mut self, vid: VID) {
361+
let (segment_id, _) = self.graph.storage.nodes().resolve_pos(vid);
362+
self.graph.storage().nodes().grow(segment_id + 1);
363363
std::mem::take(&mut self.nodes);
364364
self.nodes = self.graph.storage.nodes().write_locked();
365365
}
366366

367-
pub fn resize_chunks_to_eid(&mut self, eid: EID) {
368-
let (chunks_needed, _) = self.graph.storage.edges().resolve_pos(eid);
369-
self.graph.storage().edges().grow(chunks_needed + 1);
367+
pub fn resize_segments_to_eid(&mut self, eid: EID) {
368+
let (segment_id, _) = self.graph.storage.edges().resolve_pos(eid);
369+
self.graph.storage().edges().grow(segment_id + 1);
370370
std::mem::take(&mut self.edges);
371371
self.edges = self.graph.storage.edges().write_locked();
372372
}

db4-graph/src/replay.rs

Lines changed: 109 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ use raphtory_api::core::{
1616
use storage::{
1717
api::{edges::EdgeSegmentOps, graph_props::GraphPropSegmentOps, nodes::NodeSegmentOps},
1818
error::StorageError,
19-
pages::resolve_pos,
20-
persist::{config::ConfigOps, strategy::PersistenceStrategy},
19+
persist::strategy::PersistenceStrategy,
2120
resolver::GIDResolverOps,
2221
wal::{GraphReplay, TransactionID, LSN},
2322
ES, GS, NS,
@@ -33,7 +32,7 @@ where
3332
fn replay_add_edge(
3433
&mut self,
3534
lsn: LSN,
36-
transaction_id: TransactionID,
35+
_transaction_id: TransactionID,
3736
t: EventTime,
3837
src_name: Option<GID>,
3938
src_id: VID,
@@ -44,14 +43,7 @@ where
4443
layer_id: usize,
4544
props: Vec<(String, usize, Prop)>,
4645
) -> Result<(), StorageError> {
47-
let node_max_page_len = self.graph().extension().config().max_node_page_len();
48-
let edge_max_page_len = self.graph().extension().config().max_edge_page_len();
49-
50-
// 1. Insert prop ids into edge meta.
51-
// No need to validate props again since they are already validated before
52-
// being logged to the WAL.
53-
54-
// 2. Insert node ids into resolver.
46+
// Insert node ids into resolver.
5547
if let Some(src_name) = src_name.as_ref() {
5648
self.graph()
5749
.logical_to_physical
@@ -64,16 +56,16 @@ where
6456
.set(dst_name.as_ref(), dst_id)?;
6557
}
6658

67-
// 4. Grab src writer and add edge data.
68-
let (src_segment_id, src_pos) = resolve_pos(src_id, node_max_page_len);
69-
let resize_vid = VID::from(src_id.index() + 1);
70-
self.resize_chunks_to_vid(resize_vid); // Create enough segments.
59+
// Grab src writer and add edge data.
60+
let (src_segment_id, src_pos) = self.graph().storage().nodes().resolve_pos(src_id);
61+
self.resize_segments_to_vid(src_id); // Create enough segments.
7162

7263
let segment = self
7364
.graph()
7465
.storage()
7566
.nodes()
7667
.get_or_create_segment(src_segment_id);
68+
7769
let immut_lsn = segment.immut_lsn();
7870

7971
// Replay this entry only if it doesn't exist in immut.
@@ -112,16 +104,16 @@ where
112104
drop(src_writer);
113105
}
114106

115-
// 5. Grab dst writer and add edge data.
116-
let (dst_segment_id, dst_pos) = resolve_pos(dst_id, node_max_page_len);
117-
let resize_vid = VID::from(dst_id.index() + 1);
118-
self.resize_chunks_to_vid(resize_vid);
107+
// Grab dst writer and add edge data.
108+
let (dst_segment_id, dst_pos) = self.graph().storage().nodes().resolve_pos(dst_id);
109+
self.resize_segments_to_vid(dst_id);
119110

120111
let segment = self
121112
.graph()
122113
.storage()
123114
.nodes()
124115
.get_or_create_segment(dst_segment_id);
116+
125117
let immut_lsn = segment.immut_lsn();
126118

127119
// Replay this entry only if it doesn't exist in immut.
@@ -157,24 +149,26 @@ where
157149
drop(dst_writer);
158150
}
159151

160-
// 6. Grab edge writer and add temporal props & metadata.
161-
let (edge_segment_id, edge_pos) = resolve_pos(eid, edge_max_page_len);
162-
let resize_eid = EID::from(eid.index() + 1);
163-
self.resize_chunks_to_eid(resize_eid);
152+
// Grab edge writer and add temporal props & metadata.
153+
let (edge_segment_id, edge_pos) = self.graph().storage().edges().resolve_pos(eid);
154+
self.resize_segments_to_eid(eid);
164155

165156
let segment = self
166157
.graph()
167158
.storage()
168159
.edges()
169160
.get_or_create_segment(edge_segment_id);
161+
170162
let immut_lsn = segment.immut_lsn();
171163

172164
// Replay this entry only if it doesn't exist in immut.
173165
if immut_lsn < lsn {
174166
let edge_meta = self.graph().edge_meta();
175167

168+
// Insert prop ids into edge meta.
176169
for (prop_name, prop_id, prop_value) in &props {
177170
let prop_mapper = edge_meta.temporal_prop_mapper();
171+
178172
match prop_mapper.get_dtype(*prop_id) {
179173
None => {
180174
prop_mapper.set_id_and_dtype(
@@ -194,7 +188,7 @@ where
194188
}
195189
}
196190

197-
// 3. Insert layer id into the layer meta of both edge and node.
191+
// Insert layer id into the layer meta of both edge and node.
198192
let node_meta = self.graph().node_meta();
199193

200194
edge_meta
@@ -233,4 +227,95 @@ where
233227

234228
Ok(())
235229
}
230+
231+
fn replay_add_node(
232+
&mut self,
233+
lsn: LSN,
234+
_transaction_id: TransactionID,
235+
t: EventTime,
236+
node_name: Option<GID>,
237+
node_id: VID,
238+
node_type_and_id: Option<(String, usize)>,
239+
props: Vec<(String, usize, Prop)>,
240+
) -> Result<(), StorageError> {
241+
// Insert node id into resolver.
242+
if let Some(ref name) = node_name {
243+
self.graph()
244+
.logical_to_physical
245+
.set(name.as_ref(), node_id)?;
246+
}
247+
248+
// Resolve segment and check LSN.
249+
let (segment_id, pos) = self.graph().storage().nodes().resolve_pos(node_id);
250+
self.resize_segments_to_vid(node_id);
251+
252+
let segment = self
253+
.graph()
254+
.storage()
255+
.nodes()
256+
.get_or_create_segment(segment_id);
257+
258+
let immut_lsn = segment.immut_lsn();
259+
260+
// Replay this entry only if it doesn't exist in immut.
261+
if immut_lsn < lsn {
262+
let node_meta = self.graph().node_meta();
263+
264+
for (prop_name, prop_id, prop_value) in &props {
265+
let prop_mapper = node_meta.temporal_prop_mapper();
266+
match prop_mapper.get_dtype(*prop_id) {
267+
None => {
268+
prop_mapper.set_id_and_dtype(
269+
prop_name.as_str(),
270+
*prop_id,
271+
prop_value.dtype(),
272+
);
273+
}
274+
Some(old_dtype) => {
275+
let dtype = prop_value.dtype();
276+
let mut unified = false;
277+
let new_dtype = unify_types(&old_dtype, &dtype, &mut unified)?;
278+
if unified {
279+
prop_mapper.set_dtype(*prop_id, new_dtype);
280+
}
281+
}
282+
}
283+
}
284+
285+
// Set node type metadata early to prevent issues with borrowing node_writer.
286+
if let Some((ref node_type, node_type_id)) = node_type_and_id {
287+
node_meta
288+
.node_type_meta()
289+
.set_id(node_type.as_str(), node_type_id);
290+
}
291+
292+
let mut node_writer = self.nodes.get_mut(segment_id).unwrap().writer();
293+
294+
if !node_writer.has_node(pos, STATIC_GRAPH_LAYER_ID) {
295+
node_writer.increment_seg_num_nodes();
296+
}
297+
298+
if let Some(name) = node_name {
299+
node_writer.store_node_id(pos, STATIC_GRAPH_LAYER_ID, name);
300+
}
301+
302+
if let Some((_, node_type_id)) = node_type_and_id {
303+
node_writer.store_node_type(pos, STATIC_GRAPH_LAYER_ID, node_type_id);
304+
}
305+
306+
// Add the node with its timestamp and props.
307+
node_writer.add_props(
308+
t,
309+
pos,
310+
STATIC_GRAPH_LAYER_ID,
311+
props
312+
.into_iter()
313+
.map(|(_, prop_id, prop_value)| (prop_id, prop_value)),
314+
);
315+
316+
node_writer.mut_segment.set_lsn(lsn);
317+
}
318+
319+
Ok(())
320+
}
236321
}

db4-storage/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ iter-enum = { workspace = true, features = ["rayon"] }
3333
chrono = { workspace = true, optional = true }
3434
clap.workspace = true
3535
tracing.workspace = true
36+
dashmap.workspace = true
37+
lock_api.workspace = true
38+
once_cell.workspace = true
3639

3740
[dev-dependencies]
3841
proptest.workspace = true

db4-storage/src/api/edges.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ pub trait LockedESegment: Send + Sync + std::fmt::Debug {
126126
&'a self,
127127
layer_ids: &'b LayerIds,
128128
) -> impl ParallelIterator<Item = Self::EntryRef<'a>> + Sync + 'a;
129+
130+
fn num_edges(&self) -> u32;
129131
}
130132

131133
pub trait EdgeEntryOps<'a>: Send + Sync {

db4-storage/src/api/nodes.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ pub trait NodeSegmentOps: Send + Sync + Debug + 'static {
110110

111111
fn entry(&self, pos: impl Into<LocalPOS>) -> Self::Entry<'_>;
112112

113-
fn locked(self: &Arc<Self>) -> Self::ArcLockedSegment;
113+
fn locked(&self) -> Self::ArcLockedSegment;
114114

115115
fn flush(&self) -> Result<(), StorageError>;
116116

@@ -129,7 +129,7 @@ pub trait NodeSegmentOps: Send + Sync + Debug + 'static {
129129
fn nodes_counter(&self) -> &AtomicU32;
130130

131131
fn increment_num_nodes(&self, max_page_len: u32) {
132-
increment_and_clamp(self.nodes_counter(), max_page_len);
132+
increment_and_clamp(self.nodes_counter(), 1, max_page_len);
133133
}
134134

135135
fn num_nodes(&self) -> u32 {

db4-storage/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,9 @@ pub type GraphTProps<'a> = GenericTProps<'a, MemGraphPropRef<'a>>;
8181
pub mod error {
8282
use std::{path::PathBuf, sync::Arc};
8383

84+
use crate::resolver::mapping_resolver::InvalidNodeId;
8485
use raphtory_api::core::{entities::properties::prop::PropError, utils::time::ParseTimeError};
85-
use raphtory_core::entities::{
86-
graph::logical_to_physical::InvalidNodeId, properties::props::MetadataError,
87-
};
86+
use raphtory_core::entities::properties::props::MetadataError;
8887

8988
#[derive(thiserror::Error, Debug)]
9089
pub enum StorageError {

0 commit comments

Comments
 (0)