From 615fc27861fccf0e278017aa8f29baddad3c61ec Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 25 Mar 2024 11:32:21 +0200 Subject: [PATCH 01/57] wip delta matrix --- deps/FalkorDB-rs | 2 +- src/algorithms/all_neighbors.c | 2 +- .../algebraic_expression_add.c | 4 +- src/bulk_insert/bulk_insert.c | 2 + src/constraint/constraint.c | 39 +- .../ops/op_conditional_traverse.c | 8 +- src/execution_plan/ops/op_expand_into.c | 6 +- .../ops/shared/create_functions.c | 2 + src/graph/graph.c | 574 ++++++------ src/graph/graph.h | 37 +- src/graph/graph_delete_nodes.c | 28 +- src/graph/graph_statistics.c | 73 -- src/graph/graph_statistics.h | 102 --- src/graph/rg_matrix/rg_add.c | 70 -- src/graph/rg_matrix/rg_copy.c | 56 -- src/graph/rg_matrix/rg_export.c | 82 -- src/graph/rg_matrix/rg_extract.c | 75 -- src/graph/rg_matrix/rg_free.c | 80 -- src/graph/rg_matrix/rg_matrix.c | 186 ---- src/graph/rg_matrix/rg_matrix.h | 107 +-- src/graph/rg_matrix/rg_matrix_iter.c | 348 -------- src/graph/rg_matrix/rg_matrix_iter.h | 26 +- src/graph/rg_matrix/rg_mxm.c | 106 --- src/graph/rg_matrix/rg_new.c | 93 -- src/graph/rg_matrix/rg_pending.c | 54 -- src/graph/rg_matrix/rg_remove_element.c | 166 ---- src/graph/rg_matrix/rg_remove_entry.c | 154 ---- src/graph/rg_matrix/rg_resize.c | 39 - src/graph/rg_matrix/rg_set_element_bool.c | 58 -- src/graph/rg_matrix/rg_set_element_uint64.c | 133 --- src/graph/rg_matrix/rg_utils.c | 118 --- src/graph/rg_matrix/rg_utils.h | 31 - src/graph/rg_matrix/rg_wait.c | 145 --- src/index/index_construct.c | 50 +- .../decoders/current/v14/decode_graph.c | 5 - .../decoders/prev/v10/decode_graph.c | 5 - .../decoders/prev/v11/decode_graph.c | 5 - .../decoders/prev/v12/decode_graph.c | 5 - .../decoders/prev/v13/decode_graph.c | 5 - .../decoders/prev/v9/decode_graph.c | 16 +- src/serializers/encode_context.c | 34 - src/serializers/encode_context.h | 20 - .../encoder/v14/encode_graph_entities.c | 116 +-- src/serializers/graph_extensions.c | 48 +- src/undo_log/undo_log.h | 5 +- tests/unit/test_algebraic_expression.c | 48 +- tests/unit/test_all_paths.c | 3 +- tests/unit/test_rg_matrix.c | 826 +----------------- tests/unit/test_rg_matrix_iter.c | 100 +-- 49 files changed, 602 insertions(+), 3695 deletions(-) delete mode 100644 src/graph/graph_statistics.c delete mode 100644 src/graph/graph_statistics.h delete mode 100644 src/graph/rg_matrix/rg_add.c delete mode 100644 src/graph/rg_matrix/rg_copy.c delete mode 100644 src/graph/rg_matrix/rg_export.c delete mode 100644 src/graph/rg_matrix/rg_extract.c delete mode 100644 src/graph/rg_matrix/rg_free.c delete mode 100644 src/graph/rg_matrix/rg_matrix.c delete mode 100644 src/graph/rg_matrix/rg_matrix_iter.c delete mode 100644 src/graph/rg_matrix/rg_mxm.c delete mode 100644 src/graph/rg_matrix/rg_new.c delete mode 100644 src/graph/rg_matrix/rg_pending.c delete mode 100644 src/graph/rg_matrix/rg_remove_element.c delete mode 100644 src/graph/rg_matrix/rg_remove_entry.c delete mode 100644 src/graph/rg_matrix/rg_resize.c delete mode 100644 src/graph/rg_matrix/rg_set_element_bool.c delete mode 100644 src/graph/rg_matrix/rg_set_element_uint64.c delete mode 100644 src/graph/rg_matrix/rg_utils.c delete mode 100644 src/graph/rg_matrix/rg_utils.h delete mode 100644 src/graph/rg_matrix/rg_wait.c diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index cd6f01f9e..264f3317c 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit cd6f01f9eda6a08a579e1fe28ecb423e9e8a3018 +Subproject commit 264f3317c42ff27e499f4f1607583fe228b5ac19 diff --git a/src/algorithms/all_neighbors.c b/src/algorithms/all_neighbors.c index 8c59a19bd..4d71bfcac 100644 --- a/src/algorithms/all_neighbors.c +++ b/src/algorithms/all_neighbors.c @@ -115,7 +115,7 @@ EntityID AllNeighborsCtx_NextNeighbor RG_MatrixTupleIter *it = &ctx->levels[ctx->current_level]; GrB_Index dest_id; - GrB_Info info = RG_MatrixTupleIter_next_UINT64(it, NULL, &dest_id, NULL); + GrB_Info info = RG_MatrixTupleIter_next_BOOL(it, NULL, &dest_id, NULL); if(info == GxB_EXHAUSTED) { // backtrack diff --git a/src/arithmetic/algebraic_expression/algebraic_expression_add.c b/src/arithmetic/algebraic_expression/algebraic_expression_add.c index 1d0068ec4..d7f6e8220 100644 --- a/src/arithmetic/algebraic_expression/algebraic_expression_add.c +++ b/src/arithmetic/algebraic_expression/algebraic_expression_add.c @@ -47,7 +47,7 @@ RG_Matrix _Eval_Add // `res` is in use, create an additional matrix RG_Matrix_nrows(&nrows, res); RG_Matrix_ncols(&ncols, res); - info = RG_Matrix_new(&inter, GrB_BOOL, nrows, ncols); + info = RG_Matrix_new(&inter, GrB_BOOL, nrows, ncols, false); ASSERT(info == GrB_SUCCESS); B = AlgebraicExpression_Eval(right, inter); } else { @@ -78,7 +78,7 @@ RG_Matrix _Eval_Add // can't use `res`, use an intermidate matrix RG_Matrix_nrows(&nrows, res); RG_Matrix_ncols(&ncols, res); - info = RG_Matrix_new(&inter, GrB_BOOL, nrows, ncols); + info = RG_Matrix_new(&inter, GrB_BOOL, nrows, ncols, false); ASSERT(info == GrB_SUCCESS); } AlgebraicExpression_Eval(right, inter); diff --git a/src/bulk_insert/bulk_insert.c b/src/bulk_insert/bulk_insert.c index 039c0d84b..8bc4242c8 100644 --- a/src/bulk_insert/bulk_insert.c +++ b/src/bulk_insert/bulk_insert.c @@ -272,6 +272,8 @@ static int _BulkInsert_ProcessEdgeFile // sync matrix once ASSERT(Graph_GetMatrixPolicy(gc->g) == SYNC_POLICY_RESIZE); Graph_GetRelationMatrix(gc->g, type_id, false); + Graph_GetSourceRelationMatrix(gc->g, type_id, false); + Graph_GetTargetRelationMatrix(gc->g, type_id, false); Graph_GetAdjacencyMatrix(gc->g, false); Graph_SetMatrixPolicy(gc->g, SYNC_POLICY_NOP); diff --git a/src/constraint/constraint.c b/src/constraint/constraint.c index e4bdb41b9..4373c7d10 100644 --- a/src/constraint/constraint.c +++ b/src/constraint/constraint.c @@ -503,7 +503,7 @@ void Constraint_EnforceEdges EntityID dest_id = 0; // current processed column idx EntityID edge_id = 0; // current processed edge id EntityID prev_src_id = 0; // last processed row idx - EntityID prev_dest_id = 0; // last processed column idx + EntityID prev_edge_id = 0; // last processed column idx int enforced = 0; // # entities enforced in batch int schema_id = c->schema_id; // edge relationship type ID int batch_size = 1000; // max number of entities to enforce @@ -523,11 +523,11 @@ void Constraint_EnforceEdges // reset number of enforced edges in batch enforced = 0; prev_src_id = src_id; - prev_dest_id = dest_id; + prev_edge_id = edge_id; // fetch relation matrix ASSERT(Graph_GetMatrixPolicy(g) == SYNC_POLICY_FLUSH_RESIZE); - const RG_Matrix m = Graph_GetRelationMatrix(g, schema_id, false); + const RG_Matrix m = Graph_GetSourceRelationMatrix(g, schema_id, false); ASSERT(m != NULL); //---------------------------------------------------------------------- @@ -538,10 +538,10 @@ void Constraint_EnforceEdges ASSERT(info == GrB_SUCCESS); // skip previously enforced edges - while((info = RG_MatrixTupleIter_next_UINT64(&it, &src_id, &dest_id, - &edge_id)) == GrB_SUCCESS && + while((info = RG_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, + NULL)) == GrB_SUCCESS && src_id == prev_src_id && - dest_id < prev_dest_id); + edge_id != prev_edge_id); // process only if iterator is on an active entry if(info != GrB_SUCCESS) { @@ -558,30 +558,15 @@ void Constraint_EnforceEdges e.dest_id = dest_id; e.relationID = schema_id; - if(SINGLE_EDGE(edge_id)) { - bool res = Graph_GetEdge(g, edge_id, &e); - assert(res == true); - if(!c->enforce(c, (GraphEntity*)&e, NULL)) { - holds = false; - break; - } - } else { - EdgeID *edgeIds = (EdgeID *)(CLEAR_MSB(edge_id)); - uint edgeCount = array_len(edgeIds); - - for(uint i = 0; i < edgeCount; i++) { - edge_id = edgeIds[i]; - bool res = Graph_GetEdge(g, edge_id, &e); - assert(res == true); - if(!c->enforce(c, (GraphEntity*)&e, NULL)) { - holds = false; - break; - } - } + bool res = Graph_GetEdge(g, edge_id, &e); + assert(res == true); + if(!c->enforce(c, (GraphEntity*)&e, NULL)) { + holds = false; + break; } enforced++; // single/multi edge are counted similarly } while(enforced < batch_size && - RG_MatrixTupleIter_next_UINT64(&it, &src_id, &dest_id, &edge_id) + RG_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, NULL) == GrB_SUCCESS && holds); //---------------------------------------------------------------------- diff --git a/src/execution_plan/ops/op_conditional_traverse.c b/src/execution_plan/ops/op_conditional_traverse.c index f7a7c14fd..2fb9d9653 100644 --- a/src/execution_plan/ops/op_conditional_traverse.c +++ b/src/execution_plan/ops/op_conditional_traverse.c @@ -25,7 +25,7 @@ static void CondTraverseToString(const OpBase *ctx, sds *buf) { } static void _populate_filter_matrix(OpCondTraverse *op) { - GrB_Matrix FM = RG_MATRIX_M(op->F); + GrB_Matrix FM = RG_Matrix_m(op->F); // clear filter matrix GrB_Matrix_clear(FM); @@ -51,8 +51,8 @@ void _traverse(OpCondTraverse *op) { if(op->F == NULL) { // create both filter and result matrices size_t required_dim = Graph_RequiredMatrixDim(op->graph); - RG_Matrix_new(&op->M, GrB_BOOL, op->record_cap, required_dim); - RG_Matrix_new(&op->F, GrB_BOOL, op->record_cap, required_dim); + RG_Matrix_new(&op->M, GrB_BOOL, op->record_cap, required_dim, false); + RG_Matrix_new(&op->F, GrB_BOOL, op->record_cap, required_dim, false); // prepend filter matrix to algebraic expression as the leftmost operand AlgebraicExpression_MultiplyToTheLeft(&op->ae, op->F); @@ -142,7 +142,7 @@ static Record CondTraverseConsume(OpBase *opBase) { NodeID dest_id = INVALID_ENTITY_ID; while(true) { - GrB_Info info = RG_MatrixTupleIter_next_UINT64(&op->iter, &src_id, &dest_id, NULL); + GrB_Info info = RG_MatrixTupleIter_next_BOOL(&op->iter, &src_id, &dest_id, NULL); // Managed to get a tuple, break. if(info == GrB_SUCCESS) break; diff --git a/src/execution_plan/ops/op_expand_into.c b/src/execution_plan/ops/op_expand_into.c index 0e5655634..0b1dd6bff 100644 --- a/src/execution_plan/ops/op_expand_into.c +++ b/src/execution_plan/ops/op_expand_into.c @@ -34,7 +34,7 @@ static void _populate_filter_matrix ( OpExpandInto *op ) { - GrB_Matrix FM = RG_MATRIX_M(op->F); + GrB_Matrix FM = RG_Matrix_m(op->F); // clear filter matrix GrB_Matrix_clear(FM); @@ -65,8 +65,8 @@ static void _traverse if(op->F == NULL) { // create both filter matrix F and result matrix M size_t required_dim = Graph_RequiredMatrixDim(op->graph); - RG_Matrix_new(&op->M, GrB_BOOL, op->record_cap, required_dim); - RG_Matrix_new(&op->F, GrB_BOOL, op->record_cap, required_dim); + RG_Matrix_new(&op->M, GrB_BOOL, op->record_cap, required_dim, false); + RG_Matrix_new(&op->F, GrB_BOOL, op->record_cap, required_dim, false); // prepend the filter matrix to algebraic expression // as the leftmost operand diff --git a/src/execution_plan/ops/shared/create_functions.c b/src/execution_plan/ops/shared/create_functions.c index f7fca1a8e..efda72c9d 100644 --- a/src/execution_plan/ops/shared/create_functions.c +++ b/src/execution_plan/ops/shared/create_functions.c @@ -123,6 +123,8 @@ static void _CommitEdgesBlueprint // calling Graph_GetRelationMatrix will make sure relationship matrix // is of the right dimensions Graph_GetRelationMatrix(g, Schema_GetID(s), false); + Graph_GetSourceRelationMatrix(g, Schema_GetID(s), false); + Graph_GetTargetRelationMatrix(g, Schema_GetID(s), false); } // call Graph_GetAdjacencyMatrix will make sure the adjacency matrix diff --git a/src/graph/graph.c b/src/graph/graph.c index 8c2e3b2d9..df5b8b9ee 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -11,11 +11,6 @@ #include "rg_matrix/rg_matrix_iter.h" #include "../util/datablock/oo_datablock.h" -//------------------------------------------------------------------------------ -// Forward declarations -//------------------------------------------------------------------------------ -void _MatrixResizeToCapacity(const Graph *g, RG_Matrix m); - //------------------------------------------------------------------------------ // Synchronization functions //------------------------------------------------------------------------------ @@ -95,42 +90,6 @@ static inline size_t _Graph_NodeCap(const Graph *g) { return g->nodes->itemCap; } -static void _CollectEdgesFromEntry -( - const Graph *g, - NodeID src, - NodeID dest, - RelationID r, - EdgeID edgeId, - Edge **edges -) { - Edge e = {0}; - - e.src_id = src; - e.dest_id = dest; - e.relationID = r; - - if(SINGLE_EDGE(edgeId)) { - e.id = edgeId; - e.attributes = DataBlock_GetItem(g->edges, edgeId); - ASSERT(e.attributes); - array_append(*edges, e); - } else { - // multiple edges connecting src to dest, - // entry is a pointer to an array of edge IDs - EdgeID *edgeIds = (EdgeID *)(CLEAR_MSB(edgeId)); - uint edgeCount = array_len(edgeIds); - - for(uint i = 0; i < edgeCount; i++) { - edgeId = edgeIds[i]; - e.id = edgeId; - e.attributes = DataBlock_GetItem(g->edges, edgeId); - ASSERT(e.attributes); - array_append(*edges, e); - } - } -} - // Locates edges connecting src to destination. void _Graph_GetEdgesConnectingNodes ( @@ -147,14 +106,44 @@ void _Graph_GetEdgesConnectingNodes ASSERT(dest < Graph_RequiredMatrixDim(g)); // relation map, maps (src, dest, r) to edge IDs. - EdgeID id = INVALID_ENTITY_ID; RG_Matrix M = Graph_GetRelationMatrix(g, r, false); - GrB_Info res = RG_Matrix_extractElement_UINT64(&id, M, src, dest); + GrB_Info res = RG_Matrix_extractElement_BOOL(NULL, M, src, dest); // no entry at [dest, src], src is not connected to dest with relation R if(res == GrB_NO_VALUE) return; - _CollectEdgesFromEntry(g, src, dest, r, id, edges); + Edge e = {.src_id = src, .dest_id = dest, .relationID = r}; + RG_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); + RG_Matrix T = Graph_GetTargetRelationMatrix(g, r, true); + GrB_Vector src_vec; + GrB_Vector dst_vec; + GrB_Info info; + info = GrB_Vector_new(&src_vec, GrB_BOOL, g->edges->itemCap); + ASSERT(info == GrB_SUCCESS); + info = GrB_Vector_new(&dst_vec, GrB_BOOL, g->edges->itemCap); + ASSERT(info == GrB_SUCCESS); + info = RG_Matrix_extract_row(S, src_vec, src); + ASSERT(info == GrB_SUCCESS); + info = RG_Matrix_extract_row(T, dst_vec, dest); + ASSERT(info == GrB_SUCCESS); + info = GrB_Vector_eWiseMult_Semiring(src_vec, NULL, NULL, GxB_ANY_PAIR_BOOL, src_vec, dst_vec, GrB_DESC_R); + ASSERT(info == GrB_SUCCESS); + struct GB_Iterator_opaque it; + info = GxB_Vector_Iterator_attach(&it, src_vec, NULL); + ASSERT(info == GrB_SUCCESS); + info = GxB_Vector_Iterator_seek((&it), 0); + while (info != GxB_EXHAUSTED) { + GrB_Index edgeId = GxB_Vector_Iterator_getIndex((&it)); + e.id = edgeId; + e.relationID = r; + e.attributes = DataBlock_GetItem(g->edges, edgeId); + ASSERT(e.attributes); + array_append(*edges, e); + + info = GxB_Vector_Iterator_next((&it)); + } + GrB_Vector_free(&src_vec); + GrB_Vector_free(&dst_vec); } static inline AttributeSet *_Graph_GetEntity(const DataBlock *entities, EntityID id) { @@ -171,80 +160,30 @@ static inline AttributeSet *_Graph_GetEntity(const DataBlock *entities, EntityID void _MatrixSynchronize ( const Graph *g, - RG_Matrix m + RG_Matrix m, + GrB_Index nrows, + GrB_Index ncols ) { - GrB_Info info; - GrB_Index n_rows; - GrB_Index n_cols; - - RG_Matrix_nrows(&n_rows, m); - RG_Matrix_ncols(&n_cols, m); - - bool dirty = RG_Matrix_isDirty(m); - GrB_Index dims = Graph_RequiredMatrixDim(g); - - UNUSED(info); - - // matrix must be resized if its dimensions missmatch required dimensions - bool require_resize = (n_rows != dims || n_cols != dims); - - // matrix fully synced, nothing to do - if(!require_resize && !dirty) { - return; - } - - // lock matrix - RG_Matrix_Lock(m); - - // recheck - RG_Matrix_nrows(&n_rows, m); - RG_Matrix_ncols(&n_cols, m); - dirty = RG_Matrix_isDirty(m); - dims = Graph_RequiredMatrixDim(g); - require_resize = (n_rows != dims || n_cols != dims); - - // some other thread performed sync - if(!require_resize && !dirty) { - goto cleanup; - } - - // resize if required - if(require_resize) { - info = RG_Matrix_resize(m, dims, dims); - ASSERT(info == GrB_SUCCESS); - } - - // flush pending changes if dirty - // we need to call 'RG_Matrix_isDirty' again - // as 'RG_Matrix_resize' might require 'wait' for HyperSparse matrices - if(RG_Matrix_isDirty(m)) { - info = RG_Matrix_wait(m, false); - ASSERT(info == GrB_SUCCESS); - } - - ASSERT(RG_Matrix_isDirty(m) == false); - -cleanup: - // unlock matrix mutex - RG_Matrix_Unlock(m); + RG_Matrix_synchronize(m, nrows, ncols); } // resize matrix to node capacity void _MatrixResizeToCapacity ( const Graph *g, - RG_Matrix m + RG_Matrix m, + GrB_Index nrows, + GrB_Index ncols ) { - GrB_Index nrows; - GrB_Index ncols; - RG_Matrix_ncols(&ncols, m); - RG_Matrix_nrows(&nrows, m); - GrB_Index cap = Graph_RequiredMatrixDim(g); + GrB_Index n_rows; + GrB_Index n_cols; + RG_Matrix_nrows(&n_rows, m); + RG_Matrix_ncols(&n_cols, m); // this policy should only be used in a thread-safe context, // so no locking is required - if(nrows != cap || ncols != cap) { - GrB_Info res = RG_Matrix_resize(m, cap, cap); + if(n_rows < nrows || n_cols < ncols) { + GrB_Info res = RG_Matrix_resize(m, nrows, ncols); ASSERT(res == GrB_SUCCESS); } } @@ -253,7 +192,9 @@ void _MatrixResizeToCapacity void _MatrixNOP ( const Graph *g, - RG_Matrix matrix + RG_Matrix matrix, + GrB_Index nrows, + GrB_Index ncols ) { return; } @@ -351,6 +292,10 @@ void Graph_ApplyAllPending for(int i = 0; i < n; i ++) { M = Graph_GetRelationMatrix(g, i, false); RG_Matrix_wait(M, force_flush); + M = Graph_GetSourceRelationMatrix(g, i, false); + RG_Matrix_wait(M, force_flush); + M = Graph_GetTargetRelationMatrix(g, i, false); + RG_Matrix_wait(M, force_flush); } // restore previous matrix sync policy @@ -423,7 +368,7 @@ bool Graph_Pending n = array_len(g->relations); for(int i = 0; i < n; i ++) { - M = g->relations[i]; + M = g->relations[i].R; info = RG_Matrix_pending(M, &pending); ASSERT(info == GrB_SUCCESS); if(pending) { @@ -450,19 +395,15 @@ Graph *Graph_New g->nodes = DataBlock_New(node_cap, node_cap, sizeof(AttributeSet), cb); g->edges = DataBlock_New(edge_cap, edge_cap, sizeof(AttributeSet), cb); g->labels = array_new(RG_Matrix, GRAPH_DEFAULT_LABEL_CAP); - g->relations = array_new(RG_Matrix, GRAPH_DEFAULT_RELATION_TYPE_CAP); + g->relations = array_new(Relation, GRAPH_DEFAULT_RELATION_TYPE_CAP); GrB_Info info; UNUSED(info); GrB_Index n = Graph_RequiredMatrixDim(g); - RG_Matrix_new(&g->node_labels, GrB_BOOL, n, n); - RG_Matrix_new(&g->adjacency_matrix, GrB_BOOL, n, n); - RG_Matrix_new(&g->adjacency_matrix->transposed, GrB_BOOL, n, n); - RG_Matrix_new(&g->_zero_matrix, GrB_BOOL, n, n); - - // init graph statistics - GraphStatistics_init(&g->stats); + RG_Matrix_new(&g->node_labels, GrB_BOOL, n, n, false); + RG_Matrix_new(&g->adjacency_matrix, GrB_BOOL, n, n, true); + RG_Matrix_new(&g->_zero_matrix, GrB_BOOL, n, n, false); // initialize a read-write lock scoped to the individual graph _CreateRWLock(g); @@ -499,7 +440,13 @@ uint64_t Graph_LabeledNodeCount const Graph *g, LabelID label ) { - return GraphStatistics_NodeCount(&g->stats, label); + ASSERT(g); + + RG_Matrix L = Graph_GetLabelMatrix(g, label); + GrB_Index nvals; + GrB_Info info = RG_Matrix_nvals(&nvals, L); + ASSERT(info == GrB_SUCCESS); + return nvals; } size_t Graph_EdgeCount(const Graph *g) { @@ -512,7 +459,14 @@ uint64_t Graph_RelationEdgeCount const Graph *g, RelationID relation ) { - return GraphStatistics_EdgeCount(&g->stats, relation); + ASSERT(g); + + RG_Matrix S = Graph_GetSourceRelationMatrix(g, relation, false); + ASSERT(S != NULL); + GrB_Index nvals; + GrB_Info info = RG_Matrix_nvals(&nvals, S); + ASSERT(info == GrB_SUCCESS); + return nvals; } uint Graph_DeletedEdgeCount(const Graph *g) { @@ -588,29 +542,17 @@ RelationID Graph_GetEdgeRelation for(uint i = 0; i < n; i++) { EdgeID edgeId = 0; RG_Matrix M = Graph_GetRelationMatrix(g, i, false); - info = RG_Matrix_extractElement_UINT64(&edgeId, M, src_id, dest_id); + RG_Matrix S = Graph_GetSourceRelationMatrix(g, i, false); + RG_Matrix T = Graph_GetTargetRelationMatrix(g, i, false); + info = RG_Matrix_extractElement_BOOL(NULL, M, src_id, dest_id); if(info != GrB_SUCCESS) continue; - - if(SINGLE_EDGE(edgeId)) { - EdgeID curEdgeID = edgeId; - if(curEdgeID == id) { - Edge_SetRelationID(e, i); - rel = i; - break; - } - } else { - // multiple edges exists between src and dest - // see if given edge is one of them - EdgeID *edges = (EdgeID *)(CLEAR_MSB(edgeId)); - int edge_count = array_len(edges); - for(int j = 0; j < edge_count; j++) { - if(edges[j] == id) { - Edge_SetRelationID(e, i); - rel = i; - break; - } - } - } + info = RG_Matrix_extractElement_BOOL(NULL, S, src_id, id); + if(info != GrB_SUCCESS) continue; + info = RG_Matrix_extractElement_BOOL(NULL, T, id, dest_id); + if(info != GrB_SUCCESS) continue; + Edge_SetRelationID(e, i); + rel = i; + break; } // we must be able to find edge relation @@ -735,9 +677,6 @@ void Graph_LabelNode // map this label in this node's set of labels info = RG_Matrix_setElement_BOOL(nl, id, l); ASSERT(info == GrB_SUCCESS); - - // update labels statistics - GraphStatistics_IncNodeCount(&g->stats, l, 1); } } @@ -787,9 +726,6 @@ void Graph_RemoveNodeLabels // remove this label from node's set of labels info = RG_Matrix_removeElement_BOOL(nl, id, l); ASSERT(info == GrB_SUCCESS); - - // a label was removed from node, update statistics - GraphStatistics_DecNodeCount(&g->stats, l, 1); } } @@ -806,6 +742,8 @@ bool Graph_FormConnection GrB_Info info; UNUSED(info); RG_Matrix M = Graph_GetRelationMatrix(g, r, false); + RG_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); + RG_Matrix T = Graph_GetTargetRelationMatrix(g, r, false); RG_Matrix adj = Graph_GetAdjacencyMatrix(g, false); // rows represent source nodes, columns represent destination nodes @@ -814,13 +752,14 @@ bool Graph_FormConnection // exit early if(info != GrB_SUCCESS) return false; - info = RG_Matrix_setElement_UINT64(M, edge_id, src, dest); + info = RG_Matrix_setElement_BOOL(M, src, dest); if(info != GrB_SUCCESS) return false; - // an edge of type r has just been created, update statistics - GraphStatistics_IncEdgeCount(&g->stats, r, 1); + info = RG_Matrix_setElement_BOOL(S, src, edge_id); + if(info != GrB_SUCCESS) return false; - return true; + info = RG_Matrix_setElement_BOOL(T, edge_id, dest); + return info == GrB_SUCCESS; } void Graph_CreateEdge @@ -854,9 +793,59 @@ void Graph_CreateEdge Graph_FormConnection(g, src, dest, id, r); } -// retrieves all either incoming or outgoing edges -// to/from given node N, depending on given direction -void Graph_GetNodeEdges +void _GetOutgoingNodeEdges +( + const Graph *g, // graph to collect edges from + const Node *n, // either source or destination node + GRAPH_EDGE_DIR dir, // edge direction ->, <-, <-> + RelationID edgeType, // relationship type + Edge **edges // [output] array of edges +) { + ASSERT(g); + ASSERT(n); + ASSERT(edges); + ASSERT(edgeType != GRAPH_NO_RELATION && edgeType != GRAPH_UNKNOWN_RELATION); + + GrB_Info info; + RG_MatrixTupleIter it_s = {0}; + RG_MatrixTupleIter it_t = {0}; + RG_Matrix S = NULL; + RG_Matrix T = NULL; + NodeID src_id = ENTITY_GET_ID(n); + NodeID dest_id = INVALID_ENTITY_ID; + EdgeID edge_id = INVALID_ENTITY_ID; + UNUSED(info); + + S = Graph_GetSourceRelationMatrix(g, edgeType, false); + T = Graph_GetTargetRelationMatrix(g, edgeType, false); + + info = RG_MatrixTupleIter_AttachRange(&it_s, S, src_id, src_id); + ASSERT(info == GrB_SUCCESS); + info = RG_MatrixTupleIter_attach(&it_t, T); + ASSERT(info == GrB_SUCCESS); + + while(RG_MatrixTupleIter_next_BOOL(&it_s, NULL, &edge_id, NULL) == GrB_SUCCESS) { + info = RG_MatrixTupleIter_iterate_row(&it_t, edge_id); + ASSERT(info == GrB_SUCCESS); + info = RG_MatrixTupleIter_next_BOOL(&it_t, NULL, &dest_id, NULL); + ASSERT(info == GrB_SUCCESS); + + Edge e = {0}; + e.src_id = src_id; + e.dest_id = dest_id; + e.id = edge_id; + e.relationID = edgeType; + e.attributes = DataBlock_GetItem(g->edges, edge_id); + ASSERT(e.attributes); + array_append(*edges, e); + } + info = RG_MatrixTupleIter_detach(&it_s); + ASSERT(info == GrB_SUCCESS); + info = RG_MatrixTupleIter_detach(&it_t); + ASSERT(info == GrB_SUCCESS); +} + +void _GetIncomingNodeEdges ( const Graph *g, // graph to collect edges from const Node *n, // either source or destination node @@ -867,17 +856,60 @@ void Graph_GetNodeEdges ASSERT(g); ASSERT(n); ASSERT(edges); + ASSERT(edgeType != GRAPH_NO_RELATION && edgeType != GRAPH_UNKNOWN_RELATION); - GrB_Type t; GrB_Info info; - RG_MatrixTupleIter it = {0}; - RG_Matrix M = NULL; - RG_Matrix TM = NULL; - NodeID srcID = ENTITY_GET_ID(n); - NodeID destID = INVALID_ENTITY_ID; - EdgeID edgeID = INVALID_ENTITY_ID; + RG_MatrixTupleIter it_s = {0}; + RG_MatrixTupleIter it_t = {0}; + RG_Matrix S = NULL; + RG_Matrix T = NULL; + NodeID src_id = ENTITY_GET_ID(n); + NodeID dest_id = INVALID_ENTITY_ID; + EdgeID edge_id = INVALID_ENTITY_ID; UNUSED(info); + S = Graph_GetSourceRelationMatrix(g, edgeType, true); + T = Graph_GetTargetRelationMatrix(g, edgeType, true); + + info = RG_MatrixTupleIter_AttachRange(&it_t, T, src_id, src_id); + ASSERT(info == GrB_SUCCESS); + info = RG_MatrixTupleIter_attach(&it_s, S); + ASSERT(info == GrB_SUCCESS); + while(RG_MatrixTupleIter_next_BOOL(&it_t, NULL, &edge_id, NULL) == GrB_SUCCESS) { + info = RG_MatrixTupleIter_iterate_row(&it_s, edge_id); + ASSERT(info == GrB_SUCCESS); + info = RG_MatrixTupleIter_next_BOOL(&it_s, NULL, &dest_id, NULL); + ASSERT(info == GrB_SUCCESS); + if(dir == GRAPH_EDGE_DIR_BOTH && src_id == dest_id) continue; + Edge e = {0}; + e.src_id = dest_id; + e.dest_id = src_id; + e.id = edge_id; + e.relationID = edgeType; + e.attributes = DataBlock_GetItem(g->edges, edge_id); + ASSERT(e.attributes); + array_append(*edges, e); + } + info = RG_MatrixTupleIter_detach(&it_s); + ASSERT(info == GrB_SUCCESS); + info = RG_MatrixTupleIter_detach(&it_t); + ASSERT(info == GrB_SUCCESS); +} + +// retrieves all either incoming or outgoing edges +// to/from given node N, depending on given direction +void Graph_GetNodeEdges +( + const Graph *g, // graph to collect edges from + const Node *n, // either source or destination node + GRAPH_EDGE_DIR dir, // edge direction ->, <-, <-> + RelationID edgeType, // relationship type + Edge **edges // [output] array of edges +) { + ASSERT(g); + ASSERT(n); + ASSERT(edges); + if(edgeType == GRAPH_UNKNOWN_RELATION) return; bool outgoing = (dir == GRAPH_EDGE_DIR_OUTGOING || @@ -886,59 +918,28 @@ void Graph_GetNodeEdges bool incoming = (dir == GRAPH_EDGE_DIR_INCOMING || dir == GRAPH_EDGE_DIR_BOTH); - // if a relationship type is specified, - // retrieve the appropriate relation matrix - // otherwise use the overall adjacency matrix - M = Graph_GetRelationMatrix(g, edgeType, false); - if(outgoing) { - info = RG_Matrix_type(&t, M); - ASSERT(info == GrB_SUCCESS); - ASSERT(t == GrB_UINT64 || t == GrB_BOOL); - // construct an iterator to traverse over the source node row, - // containing all outgoing edges - RG_MatrixTupleIter_AttachRange(&it, M, srcID, srcID); - if(t == GrB_UINT64) { - while(RG_MatrixTupleIter_next_UINT64(&it, NULL, &destID, &edgeID) == GrB_SUCCESS) { - // collect all edges (src)->(dest) - _CollectEdgesFromEntry(g, srcID, destID, edgeType, edgeID, edges); - } + if(edgeType != GRAPH_NO_RELATION) { + _GetOutgoingNodeEdges(g, n, dir, edgeType, edges); } else { - while(RG_MatrixTupleIter_next_BOOL(&it, NULL, &destID, NULL) == GrB_SUCCESS) { - Graph_GetEdgesConnectingNodes(g, srcID, destID, edgeType, edges); + // relation type missing, scan through each edge type + int relationCount = Graph_RelationTypeCount(g); + for(int i = 0; i < relationCount; i++) { + _GetOutgoingNodeEdges(g, n, dir, i, edges); } } - RG_MatrixTupleIter_detach(&it); } if(incoming) { - // if a relationship type is specified, retrieve the appropriate - // transposed relation matrix, - // otherwise use the transposed adjacency matrix - TM = Graph_GetRelationMatrix(g, edgeType, true); - - info = RG_Matrix_type(&t, M); - ASSERT(info == GrB_SUCCESS); - ASSERT(t == GrB_UINT64 || t == GrB_BOOL); - - // construct an iterator to traverse over the source node row, - // containing all incoming edges - RG_MatrixTupleIter_AttachRange(&it, TM, srcID, srcID); - - if(t == GrB_UINT64) { - while(RG_MatrixTupleIter_next_UINT64(&it, NULL, &destID, NULL) == GrB_SUCCESS) { - RG_Matrix_extractElement_UINT64(&edgeID, M, destID, srcID); - if(dir == GRAPH_EDGE_DIR_BOTH && srcID == destID) continue; - // collect all edges connecting destId to srcId - _CollectEdgesFromEntry(g, destID, srcID, edgeType, edgeID, edges); - } + if(edgeType != GRAPH_NO_RELATION) { + _GetIncomingNodeEdges(g, n, dir, edgeType, edges); } else { - while(RG_MatrixTupleIter_next_BOOL(&it, NULL, &destID, NULL) == GrB_SUCCESS) { - if(dir == GRAPH_EDGE_DIR_BOTH && srcID == destID) continue; - Graph_GetEdgesConnectingNodes(g, destID, srcID, edgeType, edges); + // relation type missing, scan through each edge type + int relationCount = Graph_RelationTypeCount(g); + for(int i = 0; i < relationCount; i++) { + _GetIncomingNodeEdges(g, n, dir, i, edges); } } - RG_MatrixTupleIter_detach(&it); } } @@ -987,30 +988,20 @@ uint64_t Graph_GetNodeDegree // for each relationship type to consider for(edgeType = start_rel; edgeType < end_rel; edgeType++) { - M = Graph_GetRelationMatrix(g, edgeType, false); + M = Graph_GetSourceRelationMatrix(g, edgeType, false); //---------------------------------------------------------------------- // outgoing edges //---------------------------------------------------------------------- - // TODO: revisit once we get rid of MULTI-EDGE hack if(outgoing) { // construct an iterator to traverse over the source node row, // containing all outgoing edges RG_MatrixTupleIter_AttachRange(&it, M, srcID, srcID); // scan row - while(RG_MatrixTupleIter_next_UINT64(&it, NULL, &destID, &edgeID) + while(RG_MatrixTupleIter_next_BOOL(&it, NULL, NULL, NULL) == GrB_SUCCESS) { - - // check for edge type single/multi - if(SINGLE_EDGE(edgeID)) { - edge_count++; - } else { - // multiple edges connecting src to dest - // entry is a pointer to an array of edge IDs - EdgeID *multi_edge = (EdgeID *)(CLEAR_MSB(edgeID)); - edge_count += array_len(multi_edge); - } + edge_count++; } RG_MatrixTupleIter_detach(&it); } @@ -1021,24 +1012,14 @@ uint64_t Graph_GetNodeDegree if(incoming) { // transposed relation matrix - TM = Graph_GetRelationMatrix(g, edgeType, true); + TM = Graph_GetTargetRelationMatrix(g, edgeType, true); // construct an iterator to traverse over the source node row, // containing all incoming edges RG_MatrixTupleIter_AttachRange(&it, TM, srcID, srcID); - while(RG_MatrixTupleIter_next_BOOL(&it, NULL, &destID, NULL) + while(RG_MatrixTupleIter_next_BOOL(&it, NULL, NULL, NULL) == GrB_SUCCESS) { - - // check for edge type single/multi - RG_Matrix_extractElement_UINT64(&edgeID, M, destID, srcID); - if(SINGLE_EDGE(edgeID)) { - edge_count++; - } else { - // multiple edges connecting src to dest - // entry is a pointer to an array of edge IDs - EdgeID *multi_edge = (EdgeID *)(CLEAR_MSB(edgeID)); - edge_count += array_len(multi_edge); - } + edge_count++; } RG_MatrixTupleIter_detach(&it); } @@ -1063,7 +1044,6 @@ uint Graph_GetNodeLabels GrB_Info res; UNUSED(res); - // GrB_Col_extract will iterate over the range of the output size RG_Matrix M = Graph_GetNodeLabelMatrix(g); EntityID id = ENTITY_GET_ID(n); @@ -1099,9 +1079,11 @@ void Graph_DeleteEdges uint64_t x; RG_Matrix R; + RG_Matrix S; + RG_Matrix T; + RG_Matrix TT; RG_Matrix M; GrB_Info info; - bool entry_deleted; MATRIX_POLICY policy = Graph_SetMatrixPolicy(g, SYNC_POLICY_NOP); @@ -1113,26 +1095,45 @@ void Graph_DeleteEdges ASSERT(!DataBlock_ItemIsDeleted((void *)e->attributes)); - // an edge of type r has just been deleted, update statistics - GraphStatistics_DecEdgeCount(&g->stats, r, 1); - R = Graph_GetRelationMatrix(g, r, false); + S = Graph_GetSourceRelationMatrix(g, r, false); + T = Graph_GetTargetRelationMatrix(g, r, false); - // single edge of type R connecting src to dest, delete entry - info = RG_Matrix_removeEntry_UINT64(R, src_id, dest_id, ENTITY_GET_ID(e), &entry_deleted); + info = RG_Matrix_removeElement_BOOL(S, src_id, ENTITY_GET_ID(e)); + ASSERT(info == GrB_SUCCESS); + info = RG_Matrix_removeElement_BOOL(T, ENTITY_GET_ID(e), dest_id); + ASSERT(info == GrB_SUCCESS); + + GrB_Vector src_vec; + GrB_Vector dst_vec; + info = GrB_Vector_new(&src_vec, GrB_BOOL, g->edges->itemCap); + ASSERT(info == GrB_SUCCESS); + info = GrB_Vector_new(&dst_vec, GrB_BOOL, g->edges->itemCap); + ASSERT(info == GrB_SUCCESS); + info = RG_Matrix_extract_row(S, src_vec, src_id); + ASSERT(info == GrB_SUCCESS); + info = RG_Matrix_extract_row(RG_Matrix_getTranspose(T), dst_vec, dest_id); + ASSERT(info == GrB_SUCCESS); + info = GrB_Vector_eWiseMult_Semiring(src_vec, NULL, NULL, GxB_ANY_PAIR_BOOL, src_vec, dst_vec, GrB_DESC_R); + GrB_Vector_nvals(&x, src_vec); + info = GrB_free(&src_vec); + ASSERT(info == GrB_SUCCESS); + info = GrB_free(&dst_vec); ASSERT(info == GrB_SUCCESS); - if(entry_deleted) { - // TODO: consider making ADJ UINT64_T where ADJ[i,j] = #connections - // drop the entry once it reaches 0 - // + if(x == 0) { + // no more edges connecting src to other nodes + // remove src from relation matrix + info = RG_Matrix_removeElement_BOOL(R, src_id, dest_id); + ASSERT(info == GrB_SUCCESS); + // see if source is connected to destination with additional edges bool connected = false; int relationCount = Graph_RelationTypeCount(g); - for(int i = 0; i < relationCount; i++) { - if(i == r) continue; - M = Graph_GetRelationMatrix(g, i, false); - info = RG_Matrix_extractElement_UINT64(&x, M, src_id, dest_id); + for(int j = 0; j < relationCount; j++) { + if(j == r) continue; + M = Graph_GetRelationMatrix(g, j, false); + info = RG_Matrix_extractElement_BOOL(NULL, M, src_id, dest_id); if(info == GrB_SUCCESS) { connected = true; break; @@ -1172,7 +1173,12 @@ static void _Graph_FreeRelationMatrices const Graph *g ) { uint relationCount = Graph_RelationTypeCount(g); - for(uint i = 0; i < relationCount; i++) RG_Matrix_free(&g->relations[i]); + for(uint i = 0; i < relationCount; i++) { + Relation *r = g->relations + i; + RG_Matrix_free(&r->R); + RG_Matrix_free(&r->S); + RG_Matrix_free(&r->T); + } } DataBlockIterator *Graph_ScanNodes(const Graph *g) { @@ -1194,13 +1200,10 @@ LabelID Graph_AddLabel RG_Matrix m; GrB_Info info; size_t n = Graph_RequiredMatrixDim(g); - RG_Matrix_new(&m, GrB_BOOL, n, n); + RG_Matrix_new(&m, GrB_BOOL, n, n, false); array_append(g->labels, m); - // adding a new label, update the stats structures to support it - GraphStatistics_IntroduceLabel(&g->stats); - LabelID l = Graph_LabelTypeCount(g) - 1; return l; } @@ -1230,15 +1233,15 @@ RelationID Graph_AddRelationType ) { ASSERT(g); - RG_Matrix m; + Relation r; size_t n = Graph_RequiredMatrixDim(g); + size_t edge_cap = g->edges->itemCap; - RG_Matrix_new(&m, GrB_UINT64, n, n); - - array_append(g->relations, m); + RG_Matrix_new(&r.R, GrB_BOOL, n, n, true); + RG_Matrix_new(&r.S, GrB_BOOL, n, edge_cap, true); + RG_Matrix_new(&r.T, GrB_BOOL, edge_cap, n, true); - // adding a new relationship type, update the stats structures to support it - GraphStatistics_IntroduceRelationship(&g->stats); + array_append(g->relations, r); RelationID relationID = Graph_RelationTypeCount(g) - 1; return relationID; @@ -1253,11 +1256,13 @@ void Graph_RemoveRelation ASSERT(relation_id == Graph_RelationTypeCount(g) - 1); #ifdef RG_DEBUG GrB_Index nvals; - GrB_Info info = RG_Matrix_nvals(&nvals, g->relations[relation_id]); + GrB_Info info = RG_Matrix_nvals(&nvals, g->relations[relation_id].R); ASSERT(info == GrB_SUCCESS); ASSERT(nvals == 0); #endif - RG_Matrix_free(&g->relations[relation_id]); + RG_Matrix_free(&g->relations[relation_id].R); + RG_Matrix_free(&g->relations[relation_id].S); + RG_Matrix_free(&g->relations[relation_id].T); g->relations = array_del(g->relations, relation_id); } @@ -1273,7 +1278,8 @@ RG_Matrix Graph_GetLabelMatrix if(label_idx < 0) return Graph_GetZeroMatrix(g); RG_Matrix m = g->labels[label_idx]; - g->SynchronizeMatrix(g, m); + size_t n = Graph_RequiredMatrixDim(g); + g->SynchronizeMatrix(g, m, n, n); return m; } @@ -1293,10 +1299,49 @@ RG_Matrix Graph_GetRelationMatrix if(relation_idx == GRAPH_NO_RELATION) { m = g->adjacency_matrix; } else { - m = g->relations[relation_idx]; + m = g->relations[relation_idx].R; } - g->SynchronizeMatrix(g, m); + size_t n = Graph_RequiredMatrixDim(g); + g->SynchronizeMatrix(g, m, n, n); + + if(transposed) m = RG_Matrix_getTranspose(m); + + return m; +} + +RG_Matrix Graph_GetSourceRelationMatrix +( + const Graph *g, + RelationID relation_idx, + bool transposed +) { + ASSERT(relation_idx != GRAPH_NO_RELATION); + + RG_Matrix m = g->relations[relation_idx].S; + + size_t n = Graph_RequiredMatrixDim(g); + size_t edge_cap = g->edges->itemCap; + g->SynchronizeMatrix(g, m, n, edge_cap); + + if(transposed) m = RG_Matrix_getTranspose(m); + + return m; +} + +RG_Matrix Graph_GetTargetRelationMatrix +( + const Graph *g, + RelationID relation_idx, + bool transposed +) { + ASSERT(relation_idx != GRAPH_NO_RELATION); + + RG_Matrix m = g->relations[relation_idx].T; + + size_t n = Graph_RequiredMatrixDim(g); + size_t edge_cap = g->edges->itemCap; + g->SynchronizeMatrix(g, m, edge_cap, n); if(transposed) m = RG_Matrix_getTranspose(m); @@ -1336,7 +1381,8 @@ RG_Matrix Graph_GetNodeLabelMatrix RG_Matrix m = g->node_labels; - g->SynchronizeMatrix(g, m); + size_t n = Graph_RequiredMatrixDim(g); + g->SynchronizeMatrix(g, m, n, n); return m; } @@ -1346,7 +1392,8 @@ RG_Matrix Graph_GetZeroMatrix const Graph *g ) { RG_Matrix z = g->_zero_matrix; - g->SynchronizeMatrix(g, z); + size_t n = Graph_RequiredMatrixDim(g); + g->SynchronizeMatrix(g, z, n, n); #if RG_DEBUG // make sure zero matrix is indeed empty @@ -1373,7 +1420,6 @@ static void _Graph_Free _Graph_FreeRelationMatrices(g); array_free(g->relations); - GraphStatistics_FreeInternals(&g->stats); uint32_t labelCount = array_len(g->labels); for(int i = 0; i < labelCount; i++) RG_Matrix_free(&g->labels[i]); diff --git a/src/graph/graph.h b/src/graph/graph.h index 13a63ac30..0dc4a769d 100644 --- a/src/graph/graph.h +++ b/src/graph/graph.h @@ -8,11 +8,13 @@ #include +#include "RG.h" #include "rax.h" +#include "../util/arr.h" #include "entities/node.h" #include "entities/edge.h" #include "../redismodule.h" -#include "graph_statistics.h" +#include "../util/rmalloc.h" #include "rg_matrix/rg_matrix.h" #include "../util/datablock/datablock.h" #include "../util/datablock/datablock_iterator.h" @@ -41,7 +43,13 @@ typedef enum { // forward declaration of Graph struct typedef struct Graph Graph; // typedef for synchronization function pointer -typedef void (*SyncMatrixFunc)(const Graph *, RG_Matrix); +typedef void (*SyncMatrixFunc)(const Graph *, RG_Matrix, GrB_Index, GrB_Index); + +typedef struct { + RG_Matrix R; // relation matrix + RG_Matrix S; // sources matrix + RG_Matrix T; // targets matrix +} Relation; struct Graph { int reserved_node_count; // number of nodes not commited yet @@ -50,12 +58,11 @@ struct Graph { RG_Matrix adjacency_matrix; // adjacency matrix, holds all graph connections RG_Matrix *labels; // label matrices RG_Matrix node_labels; // mapping of all node IDs to all labels possessed by each node - RG_Matrix *relations; // relation matrices + Relation *relations; // relation matrices RG_Matrix _zero_matrix; // zero matrix pthread_rwlock_t _rwlock; // read-write lock scoped to this specific graph bool _writelocked; // true if the read-write lock was acquired by a writer SyncMatrixFunc SynchronizeMatrix; // function pointer to matrix synchronization routine - GraphStatistics stats; // graph related statistics }; // graph synchronization functions @@ -403,8 +410,26 @@ RG_Matrix Graph_GetLabelMatrix // matrix is resized if its size doesn't match graph's node count RG_Matrix Graph_GetRelationMatrix ( - const Graph *g, // graph from which to get adjacency matrix - int relation, // relation described by matrix + const Graph *g, // graph from which to get adjacency matrix + RelationID relation_idx, // relation described by matrix + bool transposed +); + +// retrieves a source matrix +// matrix is resized if its size doesn't match graph's node count +RG_Matrix Graph_GetSourceRelationMatrix +( + const Graph *g, // graph from which to get adjacency matrix + RelationID relation_idx, // relation described by matrix + bool transposed +); + +// retrieves a target matrix +// matrix is resized if its size doesn't match graph's node count +RG_Matrix Graph_GetTargetRelationMatrix +( + const Graph *g, // graph from which to get adjacency matrix + RelationID relation_idx, // relation described by matrix bool transposed ); diff --git a/src/graph/graph_delete_nodes.c b/src/graph/graph_delete_nodes.c index 6e3ba73eb..50c68f370 100644 --- a/src/graph/graph_delete_nodes.c +++ b/src/graph/graph_delete_nodes.c @@ -59,19 +59,12 @@ void Graph_DeleteNodes //-------------------------------------------------------------------------- GrB_Index j; // iterated entry col idx - GrB_Scalar s; // empty scalar - GrB_Matrix M; // delta M - GrB_Matrix DP; // delta plus - GrB_Matrix DM; // delta minus GrB_Info info; // GraphBLAS return code GrB_Index nrows; // lbls row count GrB_Index ncols; // lbls col count GrB_Matrix lbls_mask; // lbls mask RG_MatrixTupleIter it; // matrix iterator - // create empty scalar - GrB_Scalar_new(&s, GrB_BOOL); - // get labels matrix RG_Matrix lbls = Graph_GetNodeLabelMatrix(g); @@ -109,9 +102,6 @@ void Graph_DeleteNodes RG_Matrix L = Graph_GetLabelMatrix(g, j); info = RG_Matrix_removeElement_BOOL(L, id, id); ASSERT(info == GrB_SUCCESS); - - // a label was removed from node, update statistics - GraphStatistics_DecNodeCount(&g->stats, j, 1); } // remove node from datablock @@ -122,27 +112,11 @@ void Graph_DeleteNodes // phase two //-------------------------------------------------------------------------- - // update labels matrix - M = RG_MATRIX_M(lbls); - DP = RG_MATRIX_DELTA_PLUS(lbls); - DM = RG_MATRIX_DELTA_MINUS(lbls); - - info = GrB_Matrix_assign_Scalar(DP, lbls_mask, NULL, s, GrB_ALL, nrows, - GrB_ALL, ncols, GrB_DESC_S); - ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_assign(DM, lbls_mask, NULL, M, GrB_ALL, nrows, GrB_ALL, - ncols, GrB_DESC_S); - ASSERT(info == GrB_SUCCESS); - - // mark labels matrix as dirty - RG_Matrix_setDirty(lbls); + RG_Matrix_removeElements(lbls, lbls_mask); // restore matrix sync policy Graph_SetMatrixPolicy(g, policy); - // clean up - GrB_free(&s); GrB_free(&lbls_mask); } diff --git a/src/graph/graph_statistics.c b/src/graph/graph_statistics.c deleted file mode 100644 index 9a1c592e1..000000000 --- a/src/graph/graph_statistics.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "graph_statistics.h" - -// Initialize the node_count and edge_count arrays -void GraphStatistics_init -( - GraphStatistics *stats -) { - ASSERT(stats); - stats->node_count = array_new(uint64_t, 0); - stats->edge_count = array_new(uint64_t, 0); -} - -void GraphStatistics_IntroduceRelationship -( - GraphStatistics *stats -) { - ASSERT(stats && stats->edge_count); - array_append(stats->edge_count, 0); -} - -void GraphStatistics_IntroduceLabel -( - GraphStatistics *stats -) { - ASSERT(stats && stats->node_count); - array_append(stats->node_count, 0); -} - -uint64_t GraphStatistics_EdgeCount -( - const GraphStatistics *stats, - RelationID r -) { - ASSERT(stats != NULL); - ASSERT(r < ((RelationID)array_len(stats->edge_count))); - - if(r < 0) { - return 0; - } - - return stats->edge_count[r]; -} - -uint64_t GraphStatistics_NodeCount -( - const GraphStatistics *stats, - LabelID l -) { - ASSERT(stats != NULL); - ASSERT(l < ((LabelID)array_len(stats->node_count))); - - if(l < 0) { - return 0; - } - - return stats->node_count[l]; -} - -void GraphStatistics_FreeInternals -( - GraphStatistics *stats -) { - ASSERT(stats); - if(stats->node_count) array_free(stats->node_count); - if(stats->edge_count) array_free(stats->edge_count); -} - diff --git a/src/graph/graph_statistics.h b/src/graph/graph_statistics.h deleted file mode 100644 index f17a6270f..000000000 --- a/src/graph/graph_statistics.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#pragma once - -#include -#include "../util/arr.h" -#include "entities/node.h" -#include "entities/edge.h" - -// graph related statistics - -typedef struct { - uint64_t *node_count; // array of node count per label matrix - uint64_t *edge_count; // array of edge count per relationship matrix -} GraphStatistics; - -// initialize the node_count and edge_count arrays -void GraphStatistics_init -( - GraphStatistics *stats -); - -// new relationship is added, resize the edge_count array -void GraphStatistics_IntroduceRelationship -( - GraphStatistics *stats -); - -// new label is added, resize the node_count array -void GraphStatistics_IntroduceLabel -( - GraphStatistics *stats -); - -// increment the edge counter by amount -static inline void GraphStatistics_IncEdgeCount -( - GraphStatistics *stats, - RelationID r, - uint64_t amount -) { - ASSERT(r < array_len(stats->edge_count)); - stats->edge_count[r] += amount; -} - -// decrement the edge counter by amount -static inline void GraphStatistics_DecEdgeCount -( - GraphStatistics *stats, - RelationID r, - uint64_t amount -) { - ASSERT(r < array_len(stats->edge_count) && stats->edge_count[r] >= amount); - stats->edge_count[r] -= amount; -} - -// increment the node counter by amount -static inline void GraphStatistics_IncNodeCount -( - GraphStatistics *stats, - LabelID l, - uint64_t amount -) { - ASSERT(l < array_len(stats->node_count)); - stats->node_count[l] += amount; -} - -// decrement the node counter by amount -static inline void GraphStatistics_DecNodeCount -( - GraphStatistics *stats, - int l, - uint64_t amount -) { - ASSERT(l < array_len(stats->node_count) && stats->node_count[l] >= amount); - stats->node_count[l] -= amount; -} - -// retrieves edge count for given relationship type -uint64_t GraphStatistics_EdgeCount -( - const GraphStatistics *stats, - RelationID r -); - -// retrieves node count for given label -uint64_t GraphStatistics_NodeCount -( - const GraphStatistics *stats, - LabelID l -); - -// free the internal structures -void GraphStatistics_FreeInternals -( - GraphStatistics *stats -); - diff --git a/src/graph/rg_matrix/rg_add.c b/src/graph/rg_matrix/rg_add.c deleted file mode 100644 index b1d9b0013..000000000 --- a/src/graph/rg_matrix/rg_add.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_matrix.h" - -GrB_Info RG_eWiseAdd // C = A + B -( - RG_Matrix C, // input/output matrix for results - const GrB_Semiring semiring, // defines '+' for T=A+B - const RG_Matrix A, // first input: matrix A - const RG_Matrix B // second input: matrix B -) { - ASSERT(A != NULL); - ASSERT(B != NULL); - ASSERT(C != NULL); - ASSERT(semiring != NULL); - - GrB_Info info; - GrB_Index nrows; - GrB_Index ncols; - GrB_Index DM_nvals; - GrB_Index DP_nvals; - - GrB_Matrix _A = NULL; - GrB_Matrix _B = NULL; - GrB_Matrix _C = RG_MATRIX_M(C); - GrB_Matrix AM = RG_MATRIX_M(A); - GrB_Matrix BM = RG_MATRIX_M(B); - GrB_Matrix ADP = RG_MATRIX_DELTA_PLUS(A); - GrB_Matrix ADM = RG_MATRIX_DELTA_MINUS(A); - GrB_Matrix BDP = RG_MATRIX_DELTA_PLUS(B); - GrB_Matrix BDM = RG_MATRIX_DELTA_MINUS(B); - - // TODO: check A, B and C are compatible - - GrB_Matrix_nvals(&DM_nvals, ADM); - GrB_Matrix_nvals(&DP_nvals, ADP); - if(DM_nvals > 0 || DP_nvals > 0) { - info = RG_Matrix_export(&_A, A); - ASSERT(info == GrB_SUCCESS); - } else { - _A = AM; - } - - GrB_Matrix_nvals(&DM_nvals, BDM); - GrB_Matrix_nvals(&DP_nvals, BDP); - if(DM_nvals > 0 || DP_nvals > 0) { - info = RG_Matrix_export(&_B, B); - ASSERT(info == GrB_SUCCESS); - } else { - _B = BM; - } - - //-------------------------------------------------------------------------- - // C = A + B - //-------------------------------------------------------------------------- - - info = GrB_Matrix_eWiseAdd_Semiring(_C, NULL, NULL, semiring, _A, _B, NULL); - ASSERT(info == GrB_SUCCESS); - - if(_A != AM) GrB_free(&_A); - if(_B != BM) GrB_free(&_B); - - return info; -} - diff --git a/src/graph/rg_matrix/rg_copy.c b/src/graph/rg_matrix/rg_copy.c deleted file mode 100644 index d182b597b..000000000 --- a/src/graph/rg_matrix/rg_copy.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_utils.h" -#include "rg_matrix.h" -#include "../../util/rmalloc.h" - -static void _copyMatrix -( - const GrB_Matrix in, - GrB_Matrix out -) { - GrB_Index nvals; - GrB_Info info = GrB_SUCCESS; - - UNUSED(info); - - info = GrB_Matrix_nvals(&nvals, in); - ASSERT(info == GrB_SUCCESS); - - if(nvals > 0) { - info = GrB_Matrix_apply(out, NULL, NULL, GrB_IDENTITY_BOOL, in, - GrB_DESC_R); - } - else { - GrB_Matrix_clear(out); - } - - ASSERT(info == GrB_SUCCESS); -} - -GrB_Info RG_Matrix_copy -( - RG_Matrix C, - const RG_Matrix A -) { - RG_Matrix_checkCompatible(C, A); - - GrB_Matrix in_m = RG_MATRIX_M(A); - GrB_Matrix out_m = RG_MATRIX_M(C); - GrB_Matrix in_delta_plus = RG_MATRIX_DELTA_PLUS(A); - GrB_Matrix in_delta_minus = RG_MATRIX_DELTA_MINUS(A); - GrB_Matrix out_delta_plus = RG_MATRIX_DELTA_PLUS(C); - GrB_Matrix out_delta_minus = RG_MATRIX_DELTA_MINUS(C); - - _copyMatrix(in_m, out_m); - _copyMatrix(in_delta_plus, out_delta_plus); - _copyMatrix(in_delta_minus, out_delta_minus); - - return GrB_SUCCESS; -} - diff --git a/src/graph/rg_matrix/rg_export.c b/src/graph/rg_matrix/rg_export.c deleted file mode 100644 index dec65a4e7..000000000 --- a/src/graph/rg_matrix/rg_export.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_matrix.h" -#include "../../util/rmalloc.h" - -GrB_Info RG_Matrix_export -( - GrB_Matrix *A, - RG_Matrix C -) { - ASSERT(C != NULL); - ASSERT(A != NULL); - - GrB_Type t; - GrB_Index nrows; - GrB_Index ncols; - GrB_Index dp_nvals; - GrB_Index dm_nvals; - GrB_Matrix a = NULL; - GrB_Matrix m = RG_MATRIX_M(C); - GrB_Info info = GrB_SUCCESS; - GrB_Matrix dp = RG_MATRIX_DELTA_PLUS(C); - GrB_Matrix dm = RG_MATRIX_DELTA_MINUS(C); - - info = GxB_Matrix_type(&t, m); - ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_nrows(&nrows, m); - ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_ncols(&ncols, m); - ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_new(&a, t, nrows, ncols); - ASSERT(info == GrB_SUCCESS); - - info = GrB_wait(dp, GrB_MATERIALIZE); - ASSERT(info == GrB_SUCCESS); - - info = GrB_wait(dm, GrB_MATERIALIZE); - ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_nvals(&dp_nvals, dp); - ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_nvals(&dm_nvals, dm); - ASSERT(info == GrB_SUCCESS); - - bool additions = dp_nvals > 0; - bool deletions = dm_nvals > 0; - - //-------------------------------------------------------------------------- - // perform copy and deletions if needed - //-------------------------------------------------------------------------- - - // in case there are items to delete use mask otherwise just copy - GrB_Matrix mask = deletions ? dm : NULL; - GrB_Descriptor desc = deletions ? GrB_DESC_RSCT0 : GrB_DESC_RT0; - info = GrB_transpose(a, mask, NULL, m, desc); - ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // perform additions - //-------------------------------------------------------------------------- - - if(additions) { - GrB_Semiring s; - s = (t == GrB_BOOL) ? GxB_ANY_PAIR_BOOL : GxB_ANY_PAIR_UINT64; - info = GrB_Matrix_eWiseAdd_Semiring(a, NULL, NULL, s, a, dp, - NULL); - ASSERT(info == GrB_SUCCESS); - } - - *A = a; - - return info; -} - diff --git a/src/graph/rg_matrix/rg_extract.c b/src/graph/rg_matrix/rg_extract.c deleted file mode 100644 index 665dc9355..000000000 --- a/src/graph/rg_matrix/rg_extract.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_matrix.h" - -GrB_Info RG_Matrix_extractElement_BOOL // x = A(i,j) -( - bool *x, // extracted scalar - const RG_Matrix A, // matrix to extract a scalar from - GrB_Index i, // row index - GrB_Index j // column index -) { - ASSERT(x != NULL); - ASSERT(A != NULL); - - GrB_Info info; - GrB_Matrix m = RG_MATRIX_M(A); - GrB_Matrix dp = RG_MATRIX_DELTA_PLUS(A); - GrB_Matrix dm = RG_MATRIX_DELTA_MINUS(A); - - // if 'delta-plus' exists return dp[i,j] - info = GrB_Matrix_extractElement(x, dp, i, j); - if(info == GrB_SUCCESS) { - return info; - } - - // if dm[i,j] exists, return no value - info = GrB_Matrix_extractElement(x, dm, i, j); - if(info == GrB_SUCCESS) { - // entry marked for deletion - return GrB_NO_VALUE; - } - - // entry isn't marked for deletion, see if it exists in 'm' - info = GrB_Matrix_extractElement(x, m, i, j); - return info; -} - -GrB_Info RG_Matrix_extractElement_UINT64 // x = A(i,j) -( - uint64_t *x, // extracted scalar - const RG_Matrix A, // matrix to extract a scalar from - GrB_Index i, // row index - GrB_Index j // column index -) { - ASSERT(x != NULL); - ASSERT(A != NULL); - - GrB_Info info; - GrB_Matrix m = RG_MATRIX_M(A); - GrB_Matrix dp = RG_MATRIX_DELTA_PLUS(A); - GrB_Matrix dm = RG_MATRIX_DELTA_MINUS(A); - - // if dp[i,j] exists return it - info = GrB_Matrix_extractElement(x, dp, i, j); - if(info == GrB_SUCCESS) { - return info; - } - - // if dm[i,j] exists, return no value - info = GrB_Matrix_extractElement(x, dm, i, j); - if(info == GrB_SUCCESS) { - // entry marked for deletion - return GrB_NO_VALUE; - } - - // entry isn't marked for deletion, see if it exists in 'm' - info = GrB_Matrix_extractElement(x, m, i, j); - return info; -} - diff --git a/src/graph/rg_matrix/rg_free.c b/src/graph/rg_matrix/rg_free.c deleted file mode 100644 index 6d240b233..000000000 --- a/src/graph/rg_matrix/rg_free.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_matrix.h" -#include "../../util/arr.h" -#include "../../util/rmalloc.h" -#include "../entities/graph_entity.h" - -// free multi-edge arrays GraphBLAS unary operation -static GrB_UnaryOp free_multi_edge_op = NULL; - -// unary GraphBLAS operation which frees all multi-edge array entries -// within a matrix -static void free_multiedge_array(void *out, const void *in) { - EdgeID *_out = (EdgeID *)out; - const EdgeID *id = (const EdgeID *)in; - - if(!(SINGLE_EDGE(*id))) { - // entry is a pointer to dynamic array, free it - EdgeID *ids = (EdgeID *)(CLEAR_MSB(*id)); - array_free(ids); - } - - // set out to 0 - *_out = 0; -} - -// free RG_Matrix's internal matrices: -// M, delta-plus, delta-minus and transpose -void RG_Matrix_free -( - RG_Matrix *C -) { - ASSERT(C != NULL); - RG_Matrix M = *C; - - GrB_Info info; - UNUSED(info); - - if(RG_MATRIX_MAINTAIN_TRANSPOSE(M)) RG_Matrix_free(&M->transposed); - - GrB_Matrix m = RG_MATRIX_M(M); - GrB_Matrix dp = RG_MATRIX_DELTA_PLUS(M); - - // free edges - if(RG_MATRIX_MULTI_EDGE(M)) { - if(free_multi_edge_op == NULL) { - // create unary operation - info = GrB_UnaryOp_new(&free_multi_edge_op, free_multiedge_array, - GrB_UINT64, GrB_UINT64); - ASSERT(info == GrB_SUCCESS); - } - - // frees multi-edge arrays - info = GrB_Matrix_apply(m, NULL, NULL, free_multi_edge_op, m, NULL); - ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_apply(dp, NULL, NULL, free_multi_edge_op, dp, NULL); - ASSERT(info == GrB_SUCCESS); - } - - info = GrB_Matrix_free(&M->matrix); - ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_free(&M->delta_plus); - ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_free(&M->delta_minus); - ASSERT(info == GrB_SUCCESS); - - pthread_mutex_destroy(&M->mutex); - - rm_free(M); - - *C = NULL; -} - diff --git a/src/graph/rg_matrix/rg_matrix.c b/src/graph/rg_matrix/rg_matrix.c deleted file mode 100644 index 2caa87811..000000000 --- a/src/graph/rg_matrix/rg_matrix.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_matrix.h" -#include "../../util/rmalloc.h" - -void RG_Matrix_setDirty -( - RG_Matrix C -) { - ASSERT(C); - C->dirty = true; - if(RG_MATRIX_MAINTAIN_TRANSPOSE(C)) C->transposed->dirty = true; -} - -RG_Matrix RG_Matrix_getTranspose -( - const RG_Matrix C -) { - ASSERT(C != NULL); - return C->transposed; -} - -bool RG_Matrix_isDirty -( - const RG_Matrix C -) { - ASSERT(C); - - if(C->dirty) { - return true; - } - - bool pending_M; - bool pending_DP; - bool pending_DM; - - GxB_Matrix_Pending(RG_MATRIX_M(C), &pending_M); - GxB_Matrix_Pending(RG_MATRIX_DELTA_PLUS(C), &pending_DP); - GxB_Matrix_Pending(RG_MATRIX_DELTA_MINUS(C), &pending_DM); - - return (pending_M | pending_DM | pending_DP); -} - -// checks if C is fully synced -// a synced delta matrix does not contains any entries in -// either its delta-plus and delta-minus internal matrices -bool RG_Matrix_Synced -( - const RG_Matrix C // matrix to inquery -) { - ASSERT(C); - - // quick indication, if the matrix is marked as dirty that means - // entires exists in either DP or DM - if(C->dirty) { - return false; - } - - GrB_Index dp_nvals; - GrB_Index dm_nvals; - GrB_Matrix_nvals(&dp_nvals, RG_MATRIX_DELTA_PLUS(C)); - GrB_Matrix_nvals(&dm_nvals, RG_MATRIX_DELTA_MINUS(C)); - - return ((dp_nvals + dm_nvals) == 0); -} - -// locks the matrix -void RG_Matrix_Lock -( - RG_Matrix C -) { - ASSERT(C); - pthread_mutex_lock(&C->mutex); -} - -// unlocks the matrix -void RG_Matrix_Unlock -( - RG_Matrix C -) { - ASSERT(C); - pthread_mutex_unlock(&C->mutex); -} - -GrB_Info RG_Matrix_nrows -( - GrB_Index *nrows, - const RG_Matrix C -) { - ASSERT(C); - ASSERT(nrows); - - GrB_Matrix m = RG_MATRIX_M(C); - return GrB_Matrix_nrows(nrows, m); -} - -GrB_Info RG_Matrix_ncols -( - GrB_Index *ncols, - const RG_Matrix C -) { - ASSERT(C); - ASSERT(ncols); - - GrB_Matrix m = RG_MATRIX_M(C); - return GrB_Matrix_ncols(ncols, m); -} - -GrB_Info RG_Matrix_nvals // get the number of entries in a matrix -( - GrB_Index *nvals, // matrix has nvals entries - const RG_Matrix A // matrix to query -) { - ASSERT(A != NULL); - ASSERT(nvals != NULL); - - GrB_Matrix m; - GrB_Matrix dp; - GrB_Matrix dm; - GrB_Info info; - - GrB_Index m_nvals = 0; - GrB_Index dp_nvals = 0; - GrB_Index dm_nvals = 0; - - // nvals = nvals(M) + nvals(DP) - nvals(DM) - - m = RG_MATRIX_M(A); - dp = RG_MATRIX_DELTA_PLUS(A); - dm = RG_MATRIX_DELTA_MINUS(A); - - info = GrB_Matrix_nvals(&m_nvals, m); - ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_nvals(&dp_nvals, dp); - ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_nvals(&dm_nvals, dm); - ASSERT(info == GrB_SUCCESS); - - *nvals = m_nvals + dp_nvals - dm_nvals; - return info; -} - -GrB_Info RG_Matrix_clear -( - RG_Matrix A -) { - ASSERT(A != NULL); - - GrB_Matrix m = RG_MATRIX_M(A); - GrB_Info info = GrB_SUCCESS; - GrB_Matrix delta_plus = RG_MATRIX_DELTA_PLUS(A); - GrB_Matrix delta_minus = RG_MATRIX_DELTA_MINUS(A); - - info = GrB_Matrix_clear(m); - ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_clear(m); - ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_clear(m); - ASSERT(info == GrB_SUCCESS); - - A->dirty = false; - if(RG_MATRIX_MAINTAIN_TRANSPOSE(A)) A->transposed->dirty = false; - - return info; -} - -GrB_Info RG_Matrix_type -( - GrB_Type *type, - RG_Matrix A -) { - ASSERT(A != NULL); - ASSERT(type != NULL); - - GrB_Matrix M = RG_MATRIX_M(A); - GrB_Info info = GxB_Matrix_type(type, M); - ASSERT(info == GrB_SUCCESS) - return info; -} diff --git a/src/graph/rg_matrix/rg_matrix.h b/src/graph/rg_matrix/rg_matrix.h index d930ab546..269e6aa93 100644 --- a/src/graph/rg_matrix/rg_matrix.h +++ b/src/graph/rg_matrix/rg_matrix.h @@ -1,7 +1,6 @@ /* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). + * Copyright FalkorDB Ltd. 2023 - present + * Licensed under the Server Side Public License v1 (SSPLv1). */ #pragma once @@ -15,26 +14,6 @@ typedef struct _RG_Matrix _RG_Matrix; typedef _RG_Matrix *RG_Matrix; -// Checks if X represents edge ID. -#define SINGLE_EDGE(x) !((x) & MSB_MASK) - -#define RG_MATRIX_M(C) (C)->matrix -#define RG_MATRIX_DELTA_PLUS(C) (C)->delta_plus -#define RG_MATRIX_DELTA_MINUS(C) (C)->delta_minus - -#define RG_MATRIX_TM(C) (C)->transposed->matrix -#define RG_MATRIX_TDELTA_PLUS(C) (C)->transposed->delta_plus -#define RG_MATRIX_TDELTA_MINUS(C) (C)->transposed->delta_minus - -#define RG_MATRIX_MAINTAIN_TRANSPOSE(C) (C)->transposed != NULL - -#define RG_MATRIX_MULTI_EDGE(M) __extension__({ \ - GrB_Type t; \ - GrB_Matrix m = RG_MATRIX_M(M); \ - GxB_Matrix_type(&t, m); \ - (t == GrB_UINT64); \ -}) - //------------------------------------------------------------------------------ // @@ -118,21 +97,13 @@ typedef _RG_Matrix *RG_Matrix; // //------------------------------------------------------------------------------ -struct _RG_Matrix { - volatile bool dirty; // Indicates if matrix requires sync - GrB_Matrix matrix; // Underlying GrB_Matrix - GrB_Matrix delta_plus; // Pending additions - GrB_Matrix delta_minus; // Pending deletions - RG_Matrix transposed; // Transposed matrix - pthread_mutex_t mutex; // Lock -}; - GrB_Info RG_Matrix_new ( RG_Matrix *A, // handle of matrix to create GrB_Type type, // type of matrix to create GrB_Index nrows, // matrix dimension is nrows-by-ncols - GrB_Index ncols + GrB_Index ncols, + bool transpose // if true, create a transpose of the matrix ); // returns transposed matrix of C @@ -141,35 +112,24 @@ RG_Matrix RG_Matrix_getTranspose const RG_Matrix C ); -// mark matrix as dirty -void RG_Matrix_setDirty -( - RG_Matrix C -); - bool RG_Matrix_isDirty ( const RG_Matrix C ); -// checks if C is fully synced -// a synced delta matrix does not contains any entries in -// either its delta-plus and delta-minus internal matrices -bool RG_Matrix_Synced +GrB_Matrix RG_Matrix_m ( - const RG_Matrix C // matrix to inquery + const RG_Matrix C ); -// locks the matrix -void RG_Matrix_Lock +GrB_Matrix RG_Matrix_dp ( - RG_Matrix C + const RG_Matrix C ); -// unlocks the matrix -void RG_Matrix_Unlock +GrB_Matrix RG_Matrix_dm ( - RG_Matrix C + const RG_Matrix C ); GrB_Info RG_Matrix_nrows @@ -204,14 +164,6 @@ GrB_Info RG_Matrix_setElement_BOOL // C (i,j) = x GrB_Index j // column index ); -GrB_Info RG_Matrix_setElement_UINT64 // C (i,j) = x -( - RG_Matrix C, // matrix to modify - uint64_t x, // scalar to assign to C(i,j) - GrB_Index i, // row index - GrB_Index j // column index -); - GrB_Info RG_Matrix_extractElement_BOOL // x = A(i,j) ( bool *x, // extracted scalar @@ -220,37 +172,32 @@ GrB_Info RG_Matrix_extractElement_BOOL // x = A(i,j) GrB_Index j // column index ) ; -GrB_Info RG_Matrix_extractElement_UINT64 // x = A(i,j) +GrB_Info RG_Matrix_extract_row ( - uint64_t *x, // extracted scalar - const RG_Matrix A, // matrix to extract a scalar from - GrB_Index i, // row index - GrB_Index j // column index + const RG_Matrix A, // matrix to extract a vector from + GrB_Vector v, // vector to extract + GrB_Index i // row index ) ; -// remove entry at position C[i,j] -GrB_Info RG_Matrix_removeElement_BOOL +GrB_Info RG_Matrix_extract_col ( - RG_Matrix C, // matrix to remove entry from - GrB_Index i, // row index - GrB_Index j // column index -); + const RG_Matrix A, // matrix to extract a vector from + GrB_Vector v, // vector to extract + GrB_Index j // row index +) ; -GrB_Info RG_Matrix_removeElement_UINT64 +// remove entry at position C[i,j] +GrB_Info RG_Matrix_removeElement_BOOL ( RG_Matrix C, // matrix to remove entry from GrB_Index i, // row index GrB_Index j // column index ); -// remove value 'v' from multi-value entry at position C[i,j] -GrB_Info RG_Matrix_removeEntry_UINT64 +GrB_Info RG_Matrix_removeElements ( RG_Matrix C, // matrix to remove entry from - GrB_Index i, // row index - GrB_Index j, // column index - uint64_t v, // value to remove - bool *entry_deleted // is entry deleted + GrB_Matrix m // elements to remove ); GrB_Info RG_mxm // C = A * B @@ -300,11 +247,11 @@ GrB_Info RG_Matrix_wait bool force_sync ); -// get the type of the M matrix -GrB_Info RG_Matrix_type +void RG_Matrix_synchronize ( - GrB_Type *type, - RG_Matrix A + RG_Matrix C, + GrB_Index nrows, + GrB_Index ncols ); void RG_Matrix_free diff --git a/src/graph/rg_matrix/rg_matrix_iter.c b/src/graph/rg_matrix/rg_matrix_iter.c deleted file mode 100644 index 60402ba77..000000000 --- a/src/graph/rg_matrix/rg_matrix_iter.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "./rg_matrix_iter.h" -#include "../../util/rmalloc.h" - -// returns true if iterator is detached from a matrix -#define IS_DETACHED(iter) ((iter) == NULL || (iter)->A == NULL) - -static inline void _set_iter_range -( - GxB_Iterator it, - GrB_Index min_row, - GrB_Index max_row, - bool *depleted -) { - GrB_Info info = GxB_rowIterator_seekRow (it, min_row) ; - - switch (info) - { - case GxB_EXHAUSTED: - // no values to iterate on - *depleted = true ; - break ; - case GrB_NO_VALUE: - // in sparse matrix no value in the current row - // seek to first none empty row - while (info == GrB_NO_VALUE && GxB_rowIterator_getRowIndex(it) < max_row) { - info = GxB_rowIterator_nextRow (it) ; - } - - *depleted = (info != GrB_SUCCESS || - GxB_rowIterator_getRowIndex(it) > max_row) ; - break ; - case GrB_SUCCESS: - // in hypersparse matrix iterator move to the next row with values - // make sure seekRow didn't over-reached - *depleted = GxB_rowIterator_getRowIndex (it) > max_row; - break ; - default: - ASSERT(false); - break; - } -} - -static inline void _init_iter -( - GxB_Iterator it, - GrB_Matrix m, - GrB_Index min_row, - GrB_Index max_row, - bool *depleted -) { - ASSERT(it != NULL) ; - ASSERT(m != NULL) ; - ASSERT(min_row <= max_row) ; - ASSERT(depleted != NULL) ; - - *depleted = true ; // default - - GrB_Info info ; - UNUSED(info) ; - - info = GxB_rowIterator_attach(it, m, NULL) ; - ASSERT(info == GrB_SUCCESS) ; - _set_iter_range(it, min_row, max_row, depleted) ; -} - -GrB_Info RG_MatrixTupleIter_iterate_row -( - RG_MatrixTupleIter *iter, - GrB_Index rowIdx -) { - if(IS_DETACHED(iter)) return GrB_NULL_POINTER ; - - iter->min_row = rowIdx ; - iter->max_row = rowIdx ; - - _set_iter_range(&iter->m_it, iter->min_row, iter->max_row, &iter->m_depleted) ; - _set_iter_range(&iter->dp_it, iter->min_row, iter->max_row, &iter->dp_depleted) ; - - return GrB_SUCCESS ; -} - -GrB_Info RG_MatrixTupleIter_iterate_range -( - RG_MatrixTupleIter *iter, // iterator to use - GrB_Index startRowIdx, // row index to start with - GrB_Index endRowIdx // row index to finish with -) { - if(IS_DETACHED(iter)) return GrB_NULL_POINTER ; - - iter->min_row = startRowIdx ; - iter->max_row = endRowIdx ; - - _set_iter_range(&iter->m_it, iter->min_row, iter->max_row, &iter->m_depleted) ; - _set_iter_range(&iter->dp_it, iter->min_row, iter->max_row, &iter->dp_depleted) ; - - return GrB_SUCCESS ; -} - -static void _iter_next -( - GxB_Iterator it, - GrB_Index max_row, - bool *depleted -) { - GrB_Info info ; - - info = GxB_rowIterator_nextCol (it) ; - if (info != GrB_SUCCESS) { - info = GxB_rowIterator_nextRow (it) ; - // in-case iterator maintains number of yield values, we can use nvals here - // for a quick return! - while(info == GrB_NO_VALUE && GxB_rowIterator_getRowIndex(it) < max_row) { - info = GxB_rowIterator_nextRow (it) ; - } - - // prep for next call to `_next_m_iter` - *depleted = info != GrB_SUCCESS || GxB_rowIterator_getRowIndex(it) > max_row ; - } -} - -// iterate over M matrix -static GrB_Info _next_m_iter_bool -( - RG_MatrixTupleIter *iter, // iterator scanning M - const GrB_Matrix DM, // delta-minus, masked entries - GrB_Index *row, // optional extracted row index - GrB_Index *col, // optional extracted column index - bool *val, // optional extracted value - bool *depleted // [output] true if iterator depleted -) { - ASSERT(iter != NULL) ; - ASSERT(DM != NULL) ; - ASSERT(depleted != NULL) ; - - GrB_Index _row ; - GrB_Index _col ; - - GxB_Iterator m_it = &iter->m_it ; - - do { - // iterator depleted, return - if(*depleted) return GrB_NO_VALUE ; - - _row = GxB_rowIterator_getRowIndex (m_it) ; - _col = GxB_rowIterator_getColIndex (m_it) ; - if(val) *val = GxB_Iterator_get_BOOL (m_it) ; - - // prep value for next iteration - _iter_next(m_it, iter->max_row, depleted); - - bool x ; - GrB_Info delete_info = GrB_Matrix_extractElement_BOOL(&x, DM, _row, _col) ; - if(delete_info == GrB_NO_VALUE) break ; // entry isn't deleted, return - } while (true) ; - - if(row) *row = _row ; - if(col) *col = _col ; - - return GrB_SUCCESS ; -} - -// advance iterator -GrB_Info RG_MatrixTupleIter_next_BOOL -( - RG_MatrixTupleIter *iter, // iterator to consume - GrB_Index *row, // optional output row index - GrB_Index *col, // optional output column index - bool *val // optional value at A[row, col] -) { - if(IS_DETACHED(iter)) return GrB_NULL_POINTER ; - - GrB_Info info = GrB_SUCCESS ; - GrB_Matrix DM = RG_MATRIX_DELTA_MINUS(iter->A) ; - GxB_Iterator dp_it = &iter->dp_it ; - - if(!iter->m_depleted) { - info = _next_m_iter_bool(iter, DM, row, col, val, &iter->m_depleted) ; - if(info == GrB_SUCCESS) return GrB_SUCCESS ; - } - - if(iter->dp_depleted) { - return GxB_EXHAUSTED ; - } - - if(row) *row = GxB_rowIterator_getRowIndex (dp_it) ; - if(col) *col = GxB_rowIterator_getColIndex (dp_it) ; - if(val) *val = GxB_Iterator_get_BOOL (dp_it) ; - - // prep value for next iteration - _iter_next(dp_it, iter->max_row, &iter->dp_depleted); - - return GrB_SUCCESS ; -} - -// iterate over M matrix -static GrB_Info _next_m_iter_uint64 -( - RG_MatrixTupleIter *iter, // iterator scanning M - const GrB_Matrix DM, // delta-minus, masked entries - GrB_Index *row, // optional extracted row index - GrB_Index *col, // optional extracted column index - uint64_t *val, // optional extracted value - bool *depleted // [output] true if iterator depleted -) { - ASSERT(iter != NULL) ; - ASSERT(DM != NULL) ; - ASSERT(depleted != NULL) ; - - GrB_Index _row ; - GrB_Index _col ; - - GxB_Iterator m_it = &iter->m_it ; - - do { - // iterator depleted, return - if(*depleted) return GrB_NO_VALUE; - - _row = GxB_rowIterator_getRowIndex (m_it) ; - _col = GxB_rowIterator_getColIndex (m_it) ; - if(val) *val = GxB_Iterator_get_UINT64 (m_it) ; - - // prep value for next iteration - _iter_next(m_it, iter->max_row, depleted); - - bool x ; - GrB_Info delete_info = GrB_Matrix_extractElement_BOOL(&x, DM, _row, _col) ; - if(delete_info == GrB_NO_VALUE) break ; // entry isn't deleted, return - } while (true) ; - - if(row) *row = _row ; - if(col) *col = _col ; - - return GrB_SUCCESS ; -} - -// advance iterator -GrB_Info RG_MatrixTupleIter_next_UINT64 -( - RG_MatrixTupleIter *iter, // iterator to consume - GrB_Index *row, // optional output row index - GrB_Index *col, // optional output column index - uint64_t *val // optional value at A[row, col] -) { - if(IS_DETACHED(iter)) return GrB_NULL_POINTER ; - - GrB_Info info = GrB_SUCCESS ; - GrB_Matrix DM = RG_MATRIX_DELTA_MINUS(iter->A) ; - GxB_Iterator dp_it = &iter->dp_it ; - - if(!iter->m_depleted) { - info = _next_m_iter_uint64(iter, DM, row, col, val, &iter->m_depleted) ; - if(info == GrB_SUCCESS) return GrB_SUCCESS ; - } - - if(iter->dp_depleted) { - return GxB_EXHAUSTED ; - } - - if(row) *row = GxB_rowIterator_getRowIndex (dp_it) ; - if(col) *col = GxB_rowIterator_getColIndex (dp_it) ; - if(val) *val = GxB_Iterator_get_UINT64 (dp_it) ; - - // prep value for next iteration - _iter_next(dp_it, iter->max_row, &iter->dp_depleted); - - return GrB_SUCCESS ; -} - -// reset iterator, assumes the iterator is valid -GrB_Info RG_MatrixTupleIter_reset -( - RG_MatrixTupleIter *iter // iterator to reset -) { - GrB_Info info = GrB_SUCCESS; - - if(IS_DETACHED(iter)) return GrB_NULL_POINTER ; - - _set_iter_range(&iter->m_it, iter->min_row, iter->max_row, &iter->m_depleted) ; - _set_iter_range(&iter->dp_it, iter->min_row, iter->max_row, &iter->dp_depleted) ; - - return info ; -} - -// returns true if iterator is attached to given matrix false otherwise -bool RG_MatrixTupleIter_is_attached -( - const RG_MatrixTupleIter *iter, // iterator to check - const RG_Matrix M // matrix attached to -) { - ASSERT(iter != NULL); - - return iter->A == M; -} - -// update iterator to scan given matrix -GrB_Info RG_MatrixTupleIter_attach -( - RG_MatrixTupleIter *iter, // iterator to update - const RG_Matrix A // matrix to scan -) { - return RG_MatrixTupleIter_AttachRange(iter, A, RG_ITER_MIN_ROW, - RG_ITER_MAX_ROW); -} - -// update iterator to scan given matrix -GrB_Info RG_MatrixTupleIter_AttachRange -( - RG_MatrixTupleIter *iter, // iterator to update - const RG_Matrix A, // matrix to scan - GrB_Index min_row, // minimum row for iteration - GrB_Index max_row // maximum row for iteration -) { - if(A == NULL) return GrB_NULL_POINTER ; - if(iter == NULL) return GrB_NULL_POINTER ; - - GrB_Matrix M = RG_MATRIX_M(A) ; - GrB_Matrix DP = RG_MATRIX_DELTA_PLUS(A) ; - - iter->A = A ; - iter->min_row = min_row ; - iter->max_row = max_row ; - - _init_iter(&iter->m_it, M, iter->min_row, iter->max_row, &iter->m_depleted) ; - _init_iter(&iter->dp_it, DP, iter->min_row, iter->max_row, &iter->dp_depleted) ; - - return GrB_SUCCESS ; -} - -// free iterator data -GrB_Info RG_MatrixTupleIter_detach -( - RG_MatrixTupleIter *iter // iterator to free -) { - ASSERT(iter != NULL) ; - - iter->A = NULL ; - iter->m_depleted = true ; - iter->dp_depleted = true ; - - return GrB_SUCCESS ; -} diff --git a/src/graph/rg_matrix/rg_matrix_iter.h b/src/graph/rg_matrix/rg_matrix_iter.h index 81b10ba03..734afbbc3 100644 --- a/src/graph/rg_matrix/rg_matrix_iter.h +++ b/src/graph/rg_matrix/rg_matrix_iter.h @@ -7,24 +7,20 @@ #pragma once #include -#include "./rg_matrix.h" -#include "../../deps/GraphBLAS/Include/GraphBLAS.h" +#include "rg_matrix.h" +#include "GraphBLAS.h" #define RG_ITER_MIN_ROW 0 #define RG_ITER_MAX_ROW ULLONG_MAX // TuplesIter maintains information required // to iterate over a RG_Matrix -typedef struct +struct Opaque_RG_MatrixTupleIter { - RG_Matrix A; // matrix iterated - struct GB_Iterator_opaque m_it; // internal m iterator - struct GB_Iterator_opaque dp_it; // internal delta plus iterator - bool m_depleted; // is m iterator depleted - bool dp_depleted; // is dp iterator depleted - GrB_Index min_row; // minimum row for iteration - GrB_Index max_row; // maximum row for iteration -} RG_MatrixTupleIter ; + char _private[296]; +}; + +typedef struct Opaque_RG_MatrixTupleIter RG_MatrixTupleIter ; // attach iterator to matrix GrB_Info RG_MatrixTupleIter_attach @@ -77,14 +73,6 @@ GrB_Info RG_MatrixTupleIter_next_BOOL bool *val // optional value at A[row, col] ); -GrB_Info RG_MatrixTupleIter_next_UINT64 -( - RG_MatrixTupleIter *iter, // iterator to consume - GrB_Index *row, // optional output row index - GrB_Index *col, // optional output column index - uint64_t *val // optional value at A[row, col] -); - // reset iterator GrB_Info RG_MatrixTupleIter_reset ( diff --git a/src/graph/rg_matrix/rg_mxm.c b/src/graph/rg_matrix/rg_mxm.c deleted file mode 100644 index 549f66951..000000000 --- a/src/graph/rg_matrix/rg_mxm.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_matrix.h" - -GrB_Info RG_mxm // C = A * B -( - RG_Matrix C, // input/output matrix for results - const GrB_Semiring semiring, // defines '+' and '*' for A*B - const RG_Matrix A, // first input: matrix A - const RG_Matrix B // second input: matrix B -) { - ASSERT(C != NULL); - ASSERT(A != NULL); - ASSERT(B != NULL); - - // multiply RG_Matrix by RG_Matrix - // A * B - // where A is fully synced! - // - // it is possible for either 'delta-plus' or 'delta-minus' to be empty - // this operation performs: A * B by computing: - // (A * (M + 'delta-plus')) - - // validate A doesn't contains entries in either delta-plus or delta-minus - ASSERT(RG_Matrix_Synced(A)); - - // validate C doesn't contains entries in either delta-plus or delta-minus - ASSERT(RG_Matrix_Synced(C)); - - GrB_Info info; - GrB_Index nrows; // number of rows in result matrix - GrB_Index ncols; // number of columns in result matrix - GrB_Index dp_nvals; // number of entries in A * 'dp' - GrB_Index dm_nvals; // number of entries in A * 'dm' - - GrB_Matrix _A = RG_MATRIX_M(A); - GrB_Matrix _B = RG_MATRIX_M(B); - GrB_Matrix _C = RG_MATRIX_M(C); - GrB_Matrix dp = RG_MATRIX_DELTA_PLUS(B); - GrB_Matrix dm = RG_MATRIX_DELTA_MINUS(B); - GrB_Matrix mask = NULL; // entities removed - GrB_Matrix accum = NULL; // entities added - - RG_Matrix_nrows(&nrows, C); - RG_Matrix_ncols(&ncols, C); - GrB_Matrix_nvals(&dp_nvals, dp); - GrB_Matrix_nvals(&dm_nvals, dm); - - if(dm_nvals > 0) { - // compute A * 'delta-minus' - info = GrB_Matrix_new(&mask, GrB_BOOL, nrows, ncols); - ASSERT(info == GrB_SUCCESS); - - info = GrB_mxm(mask, NULL, NULL, GxB_ANY_PAIR_BOOL, _A, dm, NULL); - ASSERT(info == GrB_SUCCESS); - - // update 'dm_nvals' - info = GrB_Matrix_nvals(&dm_nvals, mask); - ASSERT(info == GrB_SUCCESS); - } - - if(dp_nvals > 0) { - // compute A * 'delta-plus' - info = GrB_Matrix_new(&accum, GrB_BOOL, nrows, ncols); - ASSERT(info == GrB_SUCCESS); - - info = GrB_mxm(accum, NULL, NULL, semiring, _A, dp, NULL); - ASSERT(info == GrB_SUCCESS); - - // update 'dp_nvals' - info = GrB_Matrix_nvals(&dp_nvals, accum); - ASSERT(info == GrB_SUCCESS); - } - - GrB_Descriptor desc = NULL; - bool additions = dp_nvals > 0; - bool deletions = dm_nvals > 0; - - if (deletions) { - desc = GrB_DESC_RSC; - } else { - GrB_free(&mask); - mask = NULL; - } - - // compute (A * B) - info = GrB_mxm(_C, mask, NULL, semiring, _A, _B, desc); - ASSERT(info == GrB_SUCCESS); - - if(additions) { - info = GrB_eWiseAdd(_C, NULL, NULL, GxB_ANY_PAIR_BOOL, _C, accum, NULL); - ASSERT(info == GrB_SUCCESS); - } - - // clean up - if(mask) GrB_free(&mask); - if(accum) GrB_free(&accum); - - return info; -} - diff --git a/src/graph/rg_matrix/rg_new.c b/src/graph/rg_matrix/rg_new.c deleted file mode 100644 index 2f95213d2..000000000 --- a/src/graph/rg_matrix/rg_new.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_matrix.h" -#include "../../util/rmalloc.h" - -static GrB_Info _RG_Matrix_init -( - RG_Matrix A, - GrB_Type type, - GrB_Index nrows, - GrB_Index ncols -) { - GrB_Info info; - A->dirty = false; - - //-------------------------------------------------------------------------- - // create m, delta-plus and delta-minus - //-------------------------------------------------------------------------- - - //-------------------------------------------------------------------------- - // m, can be either hypersparse or sparse - //-------------------------------------------------------------------------- - info = GrB_Matrix_new(&A->matrix, type, nrows, ncols); - ASSERT(info == GrB_SUCCESS); - info = GxB_set(A->matrix, GxB_SPARSITY_CONTROL, GxB_SPARSE | GxB_HYPERSPARSE); - ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // delta-plus, always hypersparse - //-------------------------------------------------------------------------- - info = GrB_Matrix_new(&A->delta_plus, type, nrows, ncols); - ASSERT(info == GrB_SUCCESS); - info = GxB_set(A->delta_plus, GxB_SPARSITY_CONTROL, GxB_HYPERSPARSE); - ASSERT(info == GrB_SUCCESS); - info = GxB_set(A->delta_plus, GxB_HYPER_SWITCH, GxB_ALWAYS_HYPER); - ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // delta-minus, always hypersparse - //-------------------------------------------------------------------------- - info = GrB_Matrix_new(&A->delta_minus, GrB_BOOL, nrows, ncols); - ASSERT(info == GrB_SUCCESS); - info = GxB_set(A->delta_minus, GxB_SPARSITY_CONTROL, GxB_HYPERSPARSE); - ASSERT(info == GrB_SUCCESS); - info = GxB_set(A->delta_minus, GxB_HYPER_SWITCH, GxB_ALWAYS_HYPER); - ASSERT(info == GrB_SUCCESS); - - return info; -} - -// creates a new matrix -GrB_Info RG_Matrix_new -( - RG_Matrix *A, - GrB_Type type, - GrB_Index nrows, - GrB_Index ncols -) { - GrB_Info info; - RG_Matrix matrix = rm_calloc(1, sizeof(_RG_Matrix)); - - //-------------------------------------------------------------------------- - // input validations - //-------------------------------------------------------------------------- - - // supported types: boolean and uint64 - ASSERT(type == GrB_BOOL || type == GrB_UINT64); - - info = _RG_Matrix_init(matrix, type, nrows, ncols); - ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // create transpose matrix if required - //-------------------------------------------------------------------------- - - if(type == GrB_UINT64) { - matrix->transposed = rm_calloc(1, sizeof(_RG_Matrix)); - info = _RG_Matrix_init(matrix->transposed, GrB_BOOL, ncols, nrows); - ASSERT(info == GrB_SUCCESS); - } - - int mutex_res = pthread_mutex_init(&matrix->mutex, NULL); - ASSERT(mutex_res == 0); - - *A = matrix; - return info; -} - diff --git a/src/graph/rg_matrix/rg_pending.c b/src/graph/rg_matrix/rg_pending.c deleted file mode 100644 index cfb112dcb..000000000 --- a/src/graph/rg_matrix/rg_pending.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_matrix.h" - -GrB_Info RG_Matrix_pending -( - const RG_Matrix C, // matrix to query - bool *pending // are there any pending operations -) { - ASSERT(C != NULL); - ASSERT(pending != NULL); - - GrB_Info info; - bool p = false; - bool res = false; - GrB_Matrix M = RG_MATRIX_M(C); - GrB_Matrix DP = RG_MATRIX_DELTA_PLUS(C); - GrB_Matrix DM = RG_MATRIX_DELTA_MINUS(C); - - if(RG_MATRIX_MAINTAIN_TRANSPOSE(C)) { - info = RG_Matrix_pending(C->transposed, &res); - ASSERT(info == GrB_SUCCESS); - if(res == true) { - *pending = true; - return GrB_SUCCESS; - } - } - - // check if M contains pending changes - info = GxB_Matrix_Pending(M, &p); - ASSERT(info == GrB_SUCCESS); - res |= p; - - // check if delta-plus contains pending changes - info = GxB_Matrix_Pending(DP, &p); - ASSERT(info == GrB_SUCCESS); - res |= p; - - // check if delta-plus contains pending changes - info = GxB_Matrix_Pending(DM, &p); - ASSERT(info == GrB_SUCCESS); - res |= p; - - // set output - *pending = res; - - return info; -} - diff --git a/src/graph/rg_matrix/rg_remove_element.c b/src/graph/rg_matrix/rg_remove_element.c deleted file mode 100644 index 1b66e6d6e..000000000 --- a/src/graph/rg_matrix/rg_remove_element.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_matrix.h" -#include "rg_utils.h" -#include "../../util/arr.h" -#include "../../util/rmalloc.h" - -GrB_Info RG_Matrix_removeElement_BOOL -( - RG_Matrix C, // matrix to remove entry from - GrB_Index i, // row index - GrB_Index j // column index -) { - ASSERT(C); - RG_Matrix_checkBounds(C, i, j); - - bool m_x; - bool dm_x; - bool dp_x; - GrB_Info info; - GrB_Type type; - bool in_m = false; - bool in_dp = false; - bool in_dm = false; - GrB_Matrix m = RG_MATRIX_M(C); - GrB_Matrix dp = RG_MATRIX_DELTA_PLUS(C); - GrB_Matrix dm = RG_MATRIX_DELTA_MINUS(C); - -#ifdef RG_DEBUG - info = GxB_Matrix_type(&type, m); - ASSERT(info == GrB_SUCCESS); - ASSERT(type == GrB_BOOL); - - info = GrB_Matrix_extractElement(&dm_x, dm, i, j); - ASSERT(info == GrB_NO_VALUE); -#endif - - if(RG_MATRIX_MAINTAIN_TRANSPOSE(C)) { - info = RG_Matrix_removeElement_BOOL(C->transposed, j, i); - if(info != GrB_SUCCESS) { - return info; - } - } - - //-------------------------------------------------------------------------- - // entry exists in 'M' - //-------------------------------------------------------------------------- - - info = GrB_Matrix_extractElement(&m_x, m, i, j); - in_m = (info == GrB_SUCCESS); - - if(in_m) { - // mark deletion in delta minus - info = GrB_Matrix_setElement(dm, true, i, j); - ASSERT(info == GrB_SUCCESS); - RG_Matrix_setDirty(C); - return info; - } - - //-------------------------------------------------------------------------- - // entry exists in 'delta-plus' - //-------------------------------------------------------------------------- - - - // remove entry from 'dp' - info = GrB_Matrix_removeElement(dp, i, j); - ASSERT(info == GrB_SUCCESS); - RG_Matrix_setDirty(C); - return info; -} - -GrB_Info RG_Matrix_removeElement_UINT64 -( - RG_Matrix C, // matrix to remove entry from - GrB_Index i, // row index - GrB_Index j // column index -) { - ASSERT(C); - RG_Matrix_checkBounds(C, i, j); - - uint64_t m_x; - uint64_t dm_x; - uint64_t dp_x; - GrB_Info info; - GrB_Type type; - bool in_m = false; - bool in_dp = false; - bool in_dm = false; - GrB_Matrix m = RG_MATRIX_M(C); - GrB_Matrix dp = RG_MATRIX_DELTA_PLUS(C); - GrB_Matrix dm = RG_MATRIX_DELTA_MINUS(C); - -#ifdef RG_DEBUG - info = GxB_Matrix_type(&type, m); - ASSERT(info == GrB_SUCCESS); - ASSERT(type == GrB_UINT64); -#endif - - if(RG_MATRIX_MAINTAIN_TRANSPOSE(C)) { - info = RG_Matrix_removeElement_BOOL(C->transposed, j, i); - if(info != GrB_SUCCESS) { - return info; - } - } - - info = GrB_Matrix_extractElement(&m_x, m, i, j); - in_m = (info == GrB_SUCCESS); - - info = GrB_Matrix_extractElement(&dp_x, dp, i, j); - in_dp = (info == GrB_SUCCESS); - - info = GrB_Matrix_extractElement(&dm_x, dm, i, j); - in_dm = (info == GrB_SUCCESS); - - // mask 'in_m' incase it is marked for deletion - in_m = in_m && !(in_dm); - - // entry missing from both 'm' and 'dp' - if(!(in_m || in_dp)) { - return GrB_NO_VALUE; - } - - // entry can't exists in both 'm' and 'dp' - ASSERT(in_m != in_dp); - - //-------------------------------------------------------------------------- - // entry exists in 'M' - //-------------------------------------------------------------------------- - - if(in_m) { - // free multi-edge entry, leave M[i,j] dirty - if((SINGLE_EDGE(m_x)) == false) { - m_x = CLEAR_MSB(m_x); - array_free((uint64_t *)m_x); - } - - // mark deletion in delta minus - info = GrB_Matrix_setElement(dm, true, i, j); - ASSERT(info == GrB_SUCCESS); - } - - //-------------------------------------------------------------------------- - // entry exists in 'delta-plus' - //-------------------------------------------------------------------------- - - if(in_dp) { - // free multi-edge entry - if((SINGLE_EDGE(dp_x)) == false) { - dp_x = CLEAR_MSB(dp_x); - array_free((uint64_t *)dp_x); - } - - // remove entry from 'dp' - info = GrB_Matrix_removeElement(dp, i, j); - ASSERT(info == GrB_SUCCESS); - } - - RG_Matrix_setDirty(C); - return info; -} - diff --git a/src/graph/rg_matrix/rg_remove_entry.c b/src/graph/rg_matrix/rg_remove_entry.c deleted file mode 100644 index a30d9ccae..000000000 --- a/src/graph/rg_matrix/rg_remove_entry.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_utils.h" -#include "rg_matrix.h" -#include "../../util/arr.h" -#include "../../util/rmalloc.h" - -static bool _removeEntryFromMultiValArr -( - uint64_t **entries, // multi-value array - uint64_t entry // element to remove output new value -) { - ASSERT(*entries != NULL); - - uint i = 0; - uint n = array_len(*entries); - - // search for entry - for(; i < n; i++) { - if((*entries)[i] == entry) { - break; - } - } - - ASSERT(i < n); - - // remove located entry - // migrate last element and reduce array size - array_del_fast(*entries, i); - - // incase we're left with a single entry revert back to scalar - if(array_len(*entries) == 1) { - entry = (*entries)[0]; - array_free(*entries); - *entries = (uint64_t *)entry; - return true; - } - - return false; -} - -static GrB_Info _removeElementMultiVal -( - GrB_Matrix A, // matrix to remove entry from - GrB_Index i, // row index - GrB_Index j, // column index - uint64_t v // value to remove -) { - ASSERT(A); - - uint64_t x; - uint64_t tx; - GrB_Info info; - - info = GrB_Matrix_extractElement(&x, A, i, j); - ASSERT(info == GrB_SUCCESS); - ASSERT((SINGLE_EDGE(x)) == false); - - // remove entry from multi-value - x = CLEAR_MSB(x); - uint64_t *entries = (uint64_t *)x; - if(_removeEntryFromMultiValArr(&entries, v)) { - // update entry - x = (uint64_t)entries; - info = GrB_Matrix_setElement(A, x, i, j); - } - - return info; -} - -GrB_Info RG_Matrix_removeEntry_UINT64 -( - RG_Matrix C, // matrix to remove entry from - GrB_Index i, // row index - GrB_Index j, // column index - uint64_t v, // value to remove - bool *entry_deleted // is entry deleted -) { - ASSERT(C); - ASSERT(entry_deleted != NULL); - RG_Matrix_checkBounds(C, i, j); - - uint64_t m_x; - uint64_t dp_x; - GrB_Info info; - GrB_Type type; - bool in_m = false; - GrB_Matrix m = RG_MATRIX_M(C); - GrB_Matrix dp = RG_MATRIX_DELTA_PLUS(C); - GrB_Matrix dm = RG_MATRIX_DELTA_MINUS(C); - - *entry_deleted = false; - - -#ifdef RG_DEBUG - info = GxB_Matrix_type(&type, m); - ASSERT(info == GrB_SUCCESS); - ASSERT(type == GrB_UINT64); - - bool dm_x; - info = GrB_Matrix_extractElement(&dm_x, dm, i, j); - ASSERT(info == GrB_NO_VALUE); -#endif - - // entry should exists in either delta-plus or main - // locate entry - info = GrB_Matrix_extractElement(&m_x, m, i, j); - in_m = (info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // entry exists in 'M' - //-------------------------------------------------------------------------- - - if(in_m) { - if(SINGLE_EDGE(m_x)) { - *entry_deleted = true; - // mark deletion in delta minus - info = GrB_Matrix_setElement(dm, true, i, j); - ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_removeElement_BOOL(C->transposed, j, i); - ASSERT(info == GrB_SUCCESS) - RG_Matrix_setDirty(C); - } else { - info = _removeElementMultiVal(m, i, j, v); - ASSERT(info == GrB_SUCCESS); - } - return info; - } - - //-------------------------------------------------------------------------- - // entry exists in 'delta-plus' - //-------------------------------------------------------------------------- - - info = GrB_Matrix_extractElement(&dp_x, dp, i, j); - if(info != GrB_SUCCESS) return info; - - if(SINGLE_EDGE(dp_x)) { - *entry_deleted = true; - info = GrB_Matrix_removeElement(dp, i, j); - ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_removeElement_BOOL(C->transposed, j, i); - ASSERT(info == GrB_SUCCESS) - RG_Matrix_setDirty(C); - } else { - info = _removeElementMultiVal(dp, i, j, v); - ASSERT(info == GrB_SUCCESS); - } - return info; -} diff --git a/src/graph/rg_matrix/rg_resize.c b/src/graph/rg_matrix/rg_resize.c deleted file mode 100644 index cab625c09..000000000 --- a/src/graph/rg_matrix/rg_resize.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_matrix.h" - -GrB_Info RG_Matrix_resize // change the size of a matrix -( - RG_Matrix C, // matrix to modify - GrB_Index nrows_new, // new number of rows in matrix - GrB_Index ncols_new // new number of columns in matrix -) { - ASSERT(C != NULL); - GrB_Info info; - - if(RG_MATRIX_MAINTAIN_TRANSPOSE(C)) { - info = RG_Matrix_resize(C->transposed, ncols_new, nrows_new); - ASSERT(info == GrB_SUCCESS); - } - - GrB_Matrix m = RG_MATRIX_M(C); - GrB_Matrix delta_plus = RG_MATRIX_DELTA_PLUS(C); - GrB_Matrix delta_minus = RG_MATRIX_DELTA_MINUS(C); - - info = GrB_Matrix_resize(m, nrows_new, ncols_new); - ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_resize(delta_plus, nrows_new, ncols_new); - ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_resize(delta_minus, nrows_new, ncols_new); - ASSERT(info == GrB_SUCCESS); - - return info; -} - diff --git a/src/graph/rg_matrix/rg_set_element_bool.c b/src/graph/rg_matrix/rg_set_element_bool.c deleted file mode 100644 index 3c1a996e3..000000000 --- a/src/graph/rg_matrix/rg_set_element_bool.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_utils.h" -#include "rg_matrix.h" - -GrB_Info RG_Matrix_setElement_BOOL // C (i,j) = x -( - RG_Matrix C, // matrix to modify - GrB_Index i, // row index - GrB_Index j // column index -) { - ASSERT(C != NULL); - ASSERT(!RG_MATRIX_MULTI_EDGE(C)); - RG_Matrix_checkBounds(C, i, j); - - bool v; - GrB_Info info; - - GrB_Matrix m = RG_MATRIX_M(C); - GrB_Matrix dp = RG_MATRIX_DELTA_PLUS(C); - GrB_Matrix dm = RG_MATRIX_DELTA_MINUS(C); - - bool already_allocated = false; // M[i,j] exists - bool marked_for_deletion = false; // dm[i,j] exists - - if(RG_MATRIX_MAINTAIN_TRANSPOSE(C)) { - info = RG_Matrix_setElement_BOOL(C->transposed, j, i); - ASSERT(info == GrB_SUCCESS); - } - - info = GrB_Matrix_extractElement(&v, dm, i, j); - marked_for_deletion = (info == GrB_SUCCESS); - - if(marked_for_deletion) { - // unset delta-minus m already assign to true - info = GrB_Matrix_removeElement(dm, i, j); - ASSERT(info == GrB_SUCCESS); - } else { - info = GrB_Matrix_extractElement(&v, m, i, j); - already_allocated = (info == GrB_SUCCESS); - - if(!already_allocated) { - // update entry to dp[i, j] - info = GrB_Matrix_setElement_BOOL(dp, true, i, j); - ASSERT(info == GrB_SUCCESS); - } - } - - RG_Matrix_setDirty(C); - - return info; -} - diff --git a/src/graph/rg_matrix/rg_set_element_uint64.c b/src/graph/rg_matrix/rg_set_element_uint64.c deleted file mode 100644 index 37f61da5b..000000000 --- a/src/graph/rg_matrix/rg_set_element_uint64.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_utils.h" -#include "rg_matrix.h" -#include "../../util/arr.h" - -static GrB_BinaryOp _graph_edge_accum = NULL; - -void _edge_accum(void *_z, const void *_x, const void *_y) { - uint64_t *ids; - uint64_t *z = (uint64_t *) _z; - const uint64_t *x = (const uint64_t *) _x; - const uint64_t *y = (const uint64_t *) _y; - - // single edge ID, - // switching from single edge ID to multiple IDs - if(SINGLE_EDGE(*x)) { - ids = array_new(uint64_t, 2); - array_append(ids, *x); - array_append(ids, *y); - } else { - // multiple edges, adding another edge - ids = (uint64_t *)(CLEAR_MSB(*x)); - array_append(ids, *y); - } - - *z = (uint64_t)SET_MSB(ids); -} - -// dealing with multi-value entries -static GrB_Info setMultiEdgeEntry -( - GrB_Matrix A, // matrix to modify - uint64_t x, // scalar to assign to A(i,j) - GrB_Index i, // row index - GrB_Index j // column index -) { - GrB_Info info; - - // create edge accumulator binary function - // TODO: remove if condition, initialize binary operation at module load - if(!_graph_edge_accum) { - info = GrB_BinaryOp_new(&_graph_edge_accum, _edge_accum, GrB_UINT64, - GrB_UINT64, GrB_UINT64); - ASSERT(info == GrB_SUCCESS); - } - - info = GxB_Matrix_subassign_UINT64(A, NULL, _graph_edge_accum, - x, &i, 1, &j, 1, NULL); - ASSERT(info == GrB_SUCCESS); - - return info; -} - -GrB_Info RG_Matrix_setElement_UINT64 // C (i,j) = x -( - RG_Matrix C, // matrix to modify - uint64_t x, // scalar to assign to C(i,j) - GrB_Index i, // row index - GrB_Index j // column index -) { - ASSERT(C != NULL); - RG_Matrix_checkBounds(C, i, j); - - uint64_t v; - GrB_Info info; - bool entry_exists = false; // M[i,j] exists - bool mark_for_deletion = false; // dm[i,j] exists - - if(RG_MATRIX_MAINTAIN_TRANSPOSE(C)) { - info = RG_Matrix_setElement_BOOL(C->transposed, j, i); - if(info != GrB_SUCCESS) { - return info; - } - } - - GrB_Matrix m = RG_MATRIX_M(C); - GrB_Matrix dp = RG_MATRIX_DELTA_PLUS(C); - GrB_Matrix dm = RG_MATRIX_DELTA_MINUS(C); - -#if RG_DEBUG - //-------------------------------------------------------------------------- - // validate type - //-------------------------------------------------------------------------- - - GrB_Type t; - info = GxB_Matrix_type(&t, m); - ASSERT(info == GrB_SUCCESS); - ASSERT(t == GrB_UINT64); -#endif - - //-------------------------------------------------------------------------- - // check deleted - //-------------------------------------------------------------------------- - - info = GrB_Matrix_extractElement(&v, dm, i, j); - mark_for_deletion = (info == GrB_SUCCESS); - - if(mark_for_deletion) { // m contains single edge, simple replace - // clear dm[i,j] - info = GrB_Matrix_removeElement(dm, i, j); - ASSERT(info == GrB_SUCCESS); - - // overwrite m[i,j] - info = GrB_Matrix_setElement(m, x, i, j); - ASSERT(info == GrB_SUCCESS); - } else { - // entry isn't marked for deletion - // see if entry already exists in 'm' - // we'll prefer setting entry in 'm' incase it already exists - // otherwise we'll set the entry in 'delta-plus' - info = GrB_Matrix_extractElement_UINT64(&v, m, i, j); - entry_exists = (info == GrB_SUCCESS); - - if(entry_exists) { - // update entry at m[i,j] - info = setMultiEdgeEntry(m, x, i, j); - } else { - // update entry at dp[i,j] - info = setMultiEdgeEntry(dp, x, i, j); - } - } - - RG_Matrix_setDirty(C); - - return info; -} - diff --git a/src/graph/rg_matrix/rg_utils.c b/src/graph/rg_matrix/rg_utils.c deleted file mode 100644 index 1e1366f99..000000000 --- a/src/graph/rg_matrix/rg_utils.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_matrix.h" - -// check if i and j are within matrix boundries -// i < nrows -// j < ncols -void RG_Matrix_checkBounds -( - const RG_Matrix C, - GrB_Index i, - GrB_Index j -) { -#if RG_DEBUG - GrB_Matrix m = RG_MATRIX_M(C); - // check bounds - GrB_Index nrows; - GrB_Index ncols; - GrB_Matrix_nrows(&nrows, m); - GrB_Matrix_ncols(&ncols, m); - ASSERT(i < nrows); - ASSERT(j < ncols); -#endif -} - -// check 2 matrices have same type nrows and ncols -void RG_Matrix_checkCompatible -( - const RG_Matrix M, - const RG_Matrix N -) { -#if RG_DEBUG - GrB_Matrix m = RG_MATRIX_M(M); - GrB_Matrix n = RG_MATRIX_M(N); - - GrB_Type m_type; - GrB_Type n_type; - GxB_Matrix_type(&m_type, m); - GxB_Matrix_type(&n_type, n); - ASSERT(m_type == n_type); - - GrB_Index m_nrows; - GrB_Index m_ncols; - GrB_Index n_nrows; - GrB_Index n_ncols; - GrB_Matrix_nrows(&m_nrows, m); - GrB_Matrix_ncols(&m_ncols, m); - GrB_Matrix_nrows(&n_nrows, n); - GrB_Matrix_ncols(&n_ncols, n); - ASSERT(m_nrows == n_nrows); - ASSERT(m_ncols == n_ncols); -#endif -} - -void RG_Matrix_validateState -( - const RG_Matrix C, - GrB_Index i, - GrB_Index j -) { -#ifdef RG_DEBUG - bool x_m = false; - bool x_dp = false; - bool x_dm = false; - bool existing_entry = false; - bool pending_addition = false; - bool pending_deletion = false; - GrB_Info info_m = GrB_SUCCESS; - GrB_Info info_dp = GrB_SUCCESS; - GrB_Info info_dm = GrB_SUCCESS; - GrB_Matrix m = RG_MATRIX_M(C); - GrB_Matrix dp = RG_MATRIX_DELTA_PLUS(C); - GrB_Matrix dm = RG_MATRIX_DELTA_MINUS(C); - - // find out which entries exists - info_m = GrB_Matrix_extractElement(&x_m, m, i, j); - info_dp = GrB_Matrix_extractElement(&x_dp, dp, i, j); - info_dm = GrB_Matrix_extractElement(&x_dm, dm, i, j); - - UNUSED(existing_entry); - UNUSED(pending_addition); - UNUSED(pending_deletion); - - existing_entry = info_m == GrB_SUCCESS; - pending_addition = info_dp == GrB_SUCCESS; - pending_deletion = info_dm == GrB_SUCCESS; - - //-------------------------------------------------------------------------- - // impossible states - //-------------------------------------------------------------------------- - - // matrix disjoint - ASSERT(!(existing_entry && - pending_addition && - pending_deletion)); - - // deletion only - ASSERT(!(!existing_entry && - !pending_addition && - pending_deletion)); - - // addition to already existing entry - ASSERT(!(existing_entry && - pending_addition && - !pending_deletion)); - - // pending deletion and pending addition - ASSERT(!(!existing_entry && - pending_addition && - pending_deletion)); -#endif -} - diff --git a/src/graph/rg_matrix/rg_utils.h b/src/graph/rg_matrix/rg_utils.h deleted file mode 100644 index 2c3b30b06..000000000 --- a/src/graph/rg_matrix/rg_utils.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#pragma once - -#include "rg_matrix.h" - -void RG_Matrix_checkBounds -( - const RG_Matrix C, - GrB_Index i, - GrB_Index j -); - -void RG_Matrix_checkCompatible -( - const RG_Matrix M, - const RG_Matrix N -); - -// validate 'C' isn't in an invalid state -void RG_Matrix_validateState -( - const RG_Matrix C, - GrB_Index i, - GrB_Index j -); - diff --git a/src/graph/rg_matrix/rg_wait.c b/src/graph/rg_matrix/rg_wait.c deleted file mode 100644 index bb3092236..000000000 --- a/src/graph/rg_matrix/rg_wait.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "RG.h" -#include "rg_matrix.h" -#include "../../util/rmalloc.h" -#include "configuration/config.h" - -static inline void _SetUndirty -( - RG_Matrix C -) { - ASSERT(C); - - C->dirty = false; - - if(RG_MATRIX_MAINTAIN_TRANSPOSE(C)) { - C->transposed->dirty = false; - } -} - -static void RG_Matrix_sync_deletions -( - RG_Matrix C -) { - ASSERT(C != NULL); - - GrB_Matrix m = RG_MATRIX_M(C); - GrB_Matrix dm = RG_MATRIX_DELTA_MINUS(C); - - GrB_Info info; - - info = GrB_transpose(m, dm, GrB_NULL, m, GrB_DESC_RSCT0); - ASSERT(info == GrB_SUCCESS); - - // clear delta minus - info = GrB_Matrix_clear(dm); - ASSERT(info == GrB_SUCCESS); -} - -static void RG_Matrix_sync_additions -( - RG_Matrix C -) { - ASSERT(C != NULL); - - GrB_Matrix m = RG_MATRIX_M(C); - GrB_Matrix dp = RG_MATRIX_DELTA_PLUS(C); - - GrB_Info info; - GrB_Index nrows; - GrB_Index ncols; - - info = GrB_Matrix_nrows(&nrows, m); - ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_ncols(&ncols, m); - ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_assign(m, dp, NULL, dp, GrB_ALL, nrows, GrB_ALL, ncols, - GrB_DESC_S); - ASSERT(info == GrB_SUCCESS); - - // clear delta plus - info = GrB_Matrix_clear(dp); - ASSERT(info == GrB_SUCCESS); -} - -static void RG_Matrix_sync -( - RG_Matrix C, - bool force_sync, - uint64_t delta_max_pending_changes -) { - ASSERT(C != NULL); - - GrB_Matrix m = RG_MATRIX_M(C); - GrB_Matrix dp = RG_MATRIX_DELTA_PLUS(C); - GrB_Matrix dm = RG_MATRIX_DELTA_MINUS(C); - - if(force_sync) { - RG_Matrix_sync_deletions(C); - RG_Matrix_sync_additions(C); - } else { - GrB_Index dp_nvals; - GrB_Index dm_nvals; - - //---------------------------------------------------------------------- - // determin change set - //---------------------------------------------------------------------- - - GrB_Matrix_nvals(&dp_nvals, dp); - GrB_Matrix_nvals(&dm_nvals, dm); - - //---------------------------------------------------------------------- - // perform deletions - //---------------------------------------------------------------------- - - if(dm_nvals >= delta_max_pending_changes) { - RG_Matrix_sync_deletions(C); - } - - //---------------------------------------------------------------------- - // perform additions - //---------------------------------------------------------------------- - - if(dp_nvals >= delta_max_pending_changes) { - RG_Matrix_sync_additions(C); - } - } - - // wait on all 3 matrices - GrB_Info info = GrB_wait(m, GrB_MATERIALIZE); - ASSERT(info == GrB_SUCCESS); - - info = GrB_wait(dm, GrB_MATERIALIZE); - ASSERT(info == GrB_SUCCESS); - - info = GrB_wait(dp, GrB_MATERIALIZE); - ASSERT(info == GrB_SUCCESS); -} - -GrB_Info RG_Matrix_wait -( - RG_Matrix A, - bool force_sync -) { - ASSERT(A != NULL); - if(RG_MATRIX_MAINTAIN_TRANSPOSE(A)) { - RG_Matrix_wait(A->transposed, force_sync); - } - - uint64_t delta_max_pending_changes; - Config_Option_get(Config_DELTA_MAX_PENDING_CHANGES, - &delta_max_pending_changes); - - RG_Matrix_sync(A, force_sync, delta_max_pending_changes); - - _SetUndirty(A); - - return GrB_SUCCESS; -} - diff --git a/src/index/index_construct.c b/src/index/index_construct.c index 563fbbab6..bd8b144ca 100644 --- a/src/index/index_construct.c +++ b/src/index/index_construct.c @@ -122,7 +122,7 @@ static void _Index_PopulateEdgeIndex EntityID dest_id = 0; // current processed column idx EntityID edge_id = 0; // current processed edge id EntityID prev_src_id = 0; // last processed row idx - EntityID prev_dest_id = 0; // last processed column idx + EntityID prev_edge_id = 0; // last processed column idx int indexed = 0; // number of entities indexed in current batch int batch_size = 1000; // max number of entities to index in one go RG_MatrixTupleIter it = {0}; @@ -142,27 +142,29 @@ static void _Index_PopulateEdgeIndex // reset number of indexed edges in batch indexed = 0; prev_src_id = src_id; - prev_dest_id = dest_id; + prev_edge_id = edge_id; // fetch relation matrix - const RG_Matrix m = Graph_GetRelationMatrix(g, Index_GetLabelID(idx), - false); - ASSERT(m != NULL); + int label_id = Index_GetLabelID(idx); + RG_Matrix S = Graph_GetSourceRelationMatrix(g, label_id, false); + ASSERT(S != NULL); + RG_Matrix T = Graph_GetTargetRelationMatrix(g, label_id, false); + ASSERT(T != NULL); + RG_MatrixTupleIter it_dst = {0}; + RG_MatrixTupleIter_attach(&it_dst, T); //---------------------------------------------------------------------- // resume scanning from previous row/col indices //---------------------------------------------------------------------- - info = RG_MatrixTupleIter_attach(&it, m); - ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_iterate_range(&it, src_id, UINT64_MAX); + info = RG_MatrixTupleIter_AttachRange(&it, S, src_id, UINT64_MAX); ASSERT(info == GrB_SUCCESS); // skip previously indexed edges - while((info = RG_MatrixTupleIter_next_UINT64(&it, &src_id, &dest_id, - &edge_id)) == GrB_SUCCESS && + while((info = RG_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, + NULL)) == GrB_SUCCESS && src_id == prev_src_id && - dest_id < prev_dest_id); + edge_id < prev_edge_id); // process only if iterator is on an active entry if(info != GrB_SUCCESS) { @@ -174,27 +176,19 @@ static void _Index_PopulateEdgeIndex //---------------------------------------------------------------------- do { + RG_MatrixTupleIter_iterate_row(&it_dst, edge_id); + RG_MatrixTupleIter_next_BOOL(&it_dst, NULL, &dest_id, NULL); + Edge e; e.src_id = src_id; e.dest_id = dest_id; - e.relationID = Index_GetLabelID(idx); - - if(SINGLE_EDGE(edge_id)) { - Graph_GetEdge(g, edge_id, &e); - Index_IndexEdge(idx, &e); - } else { - EdgeID *edgeIds = (EdgeID *)(CLEAR_MSB(edge_id)); - uint edgeCount = array_len(edgeIds); - - for(uint i = 0; i < edgeCount; i++) { - edge_id = edgeIds[i]; - Graph_GetEdge(g, edge_id, &e); - Index_IndexEdge(idx, &e); - } - } - indexed++; // single/multi edge are counted similarly + e.relationID = label_id; + Graph_GetEdge(g, edge_id, &e); + Index_IndexEdge(idx, &e); + + indexed++; } while(indexed < batch_size && - RG_MatrixTupleIter_next_UINT64(&it, &src_id, &dest_id, &edge_id) + RG_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, NULL) == GrB_SUCCESS); //---------------------------------------------------------------------- diff --git a/src/serializers/decoders/current/v14/decode_graph.c b/src/serializers/decoders/current/v14/decode_graph.c index 613e74496..505be0d05 100644 --- a/src/serializers/decoders/current/v14/decode_graph.c +++ b/src/serializers/decoders/current/v14/decode_graph.c @@ -222,11 +222,6 @@ GraphContext *RdbLoadGraphContext_latest // update the node statistics, enable node indices for(uint i = 0; i < label_count; i++) { - GrB_Index nvals; - RG_Matrix L = Graph_GetLabelMatrix(g, i); - RG_Matrix_nvals(&nvals, L); - GraphStatistics_IncNodeCount(&g->stats, i, nvals); - Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); idx = PENDING_IDX(s); diff --git a/src/serializers/decoders/prev/v10/decode_graph.c b/src/serializers/decoders/prev/v10/decode_graph.c index 4ef5b307b..f41c45c9d 100644 --- a/src/serializers/decoders/prev/v10/decode_graph.c +++ b/src/serializers/decoders/prev/v10/decode_graph.c @@ -201,11 +201,6 @@ GraphContext *RdbLoadGraphContext_v10(RedisModuleIO *rdb) { // update the node statistics, enable node indices for(uint i = 0; i < label_count; i++) { - GrB_Index nvals; - RG_Matrix L = Graph_GetLabelMatrix(g, i); - RG_Matrix_nvals(&nvals, L); - GraphStatistics_IncNodeCount(&g->stats, i, nvals); - Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); idx = PENDING_IDX(s); diff --git a/src/serializers/decoders/prev/v11/decode_graph.c b/src/serializers/decoders/prev/v11/decode_graph.c index 97f838232..0352eaedf 100644 --- a/src/serializers/decoders/prev/v11/decode_graph.c +++ b/src/serializers/decoders/prev/v11/decode_graph.c @@ -208,11 +208,6 @@ GraphContext *RdbLoadGraphContext_v11 // update the node statistics, enable node indices for(uint i = 0; i < label_count; i++) { - GrB_Index nvals; - RG_Matrix L = Graph_GetLabelMatrix(g, i); - RG_Matrix_nvals(&nvals, L); - GraphStatistics_IncNodeCount(&g->stats, i, nvals); - Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); idx = PENDING_IDX(s); diff --git a/src/serializers/decoders/prev/v12/decode_graph.c b/src/serializers/decoders/prev/v12/decode_graph.c index 335a04865..9d4820843 100644 --- a/src/serializers/decoders/prev/v12/decode_graph.c +++ b/src/serializers/decoders/prev/v12/decode_graph.c @@ -216,11 +216,6 @@ GraphContext *RdbLoadGraphContext_v12 // update the node statistics, enable node indices for(uint i = 0; i < label_count; i++) { - GrB_Index nvals; - RG_Matrix L = Graph_GetLabelMatrix(g, i); - RG_Matrix_nvals(&nvals, L); - GraphStatistics_IncNodeCount(&g->stats, i, nvals); - Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); idx = PENDING_IDX(s); diff --git a/src/serializers/decoders/prev/v13/decode_graph.c b/src/serializers/decoders/prev/v13/decode_graph.c index 9d60bbf29..77cc632b4 100644 --- a/src/serializers/decoders/prev/v13/decode_graph.c +++ b/src/serializers/decoders/prev/v13/decode_graph.c @@ -222,11 +222,6 @@ GraphContext *RdbLoadGraphContext_v13 // update the node statistics, enable node indices for(uint i = 0; i < label_count; i++) { - GrB_Index nvals; - RG_Matrix L = Graph_GetLabelMatrix(g, i); - RG_Matrix_nvals(&nvals, L); - GraphStatistics_IncNodeCount(&g->stats, i, nvals); - Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); idx = PENDING_IDX(s); diff --git a/src/serializers/decoders/prev/v9/decode_graph.c b/src/serializers/decoders/prev/v9/decode_graph.c index 078d49627..5cbb22324 100644 --- a/src/serializers/decoders/prev/v9/decode_graph.c +++ b/src/serializers/decoders/prev/v9/decode_graph.c @@ -187,26 +187,12 @@ GraphContext *RdbLoadGraphContext_v9(RedisModuleIO *rdb) { // revert to default synchronization behavior Graph_SetMatrixPolicy(g, SYNC_POLICY_FLUSH_RESIZE); - - uint node_schemas_count = array_len(gc->node_schemas); - // update the node statistics - for(uint i = 0; i < node_schemas_count; i++) { - GrB_Index nvals; - RG_Matrix L = g->labels[i]; - RG_Matrix_nvals(&nvals, L); - GraphStatistics_IncNodeCount(&g->stats, i, nvals); - } uint rel_count = Graph_RelationTypeCount(g); uint label_count = Graph_LabelTypeCount(g); - // update the node statistics, enable node indices + // enable node indices for(uint i = 0; i < label_count; i++) { - GrB_Index nvals; - RG_Matrix L = Graph_GetLabelMatrix(g, i); - RG_Matrix_nvals(&nvals, L); - GraphStatistics_IncNodeCount(&g->stats, i, nvals); - Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); idx = PENDING_IDX(s); diff --git a/src/serializers/encode_context.c b/src/serializers/encode_context.c index b1f38fb2d..4dd7684d3 100644 --- a/src/serializers/encode_context.c +++ b/src/serializers/encode_context.c @@ -43,11 +43,7 @@ void GraphEncodeContext_Reset(GraphEncodeContext *ctx) { ctx->offset = 0; ctx->keys_processed = 0; ctx->state = ENCODE_STATE_INIT; - ctx->multiple_edges_src_id = 0; - ctx->multiple_edges_dest_id = 0; - ctx->multiple_edges_array = NULL; ctx->current_relation_matrix_id = 0; - ctx->multiple_edges_current_index = 0; Config_Option_get(Config_VKEY_MAX_ENTITY_COUNT, &ctx->vkey_entity_count); @@ -169,36 +165,6 @@ RG_MatrixTupleIter *GraphEncodeContext_GetMatrixTupleIterator( return &ctx->matrix_tuple_iterator; } -void GraphEncodeContext_SetMutipleEdgesArray(GraphEncodeContext *ctx, EdgeID *edges, - uint current_index, NodeID src, NodeID dest) { - ASSERT(ctx); - ctx->multiple_edges_array = edges; - ctx->multiple_edges_current_index = current_index; - ctx->multiple_edges_src_id = src; - ctx->multiple_edges_dest_id = dest; -} - -EdgeID *GraphEncodeContext_GetMultipleEdgesArray(const GraphEncodeContext *ctx) { - ASSERT(ctx); - return ctx->multiple_edges_array; -} - -uint GraphEncodeContext_GetMultipleEdgesCurrentIndex(const GraphEncodeContext *ctx) { - ASSERT(ctx); - return ctx->multiple_edges_current_index; -} - - -NodeID GraphEncodeContext_GetMultipleEdgesSourceNode(const GraphEncodeContext *ctx) { - ASSERT(ctx); - return ctx->multiple_edges_src_id; -} - -NodeID GraphEncodeContext_GetMultipleEdgesDestinationNode(const GraphEncodeContext *ctx) { - ASSERT(ctx); - return ctx->multiple_edges_dest_id; -} - bool GraphEncodeContext_Finished(const GraphEncodeContext *ctx) { ASSERT(ctx); return ctx->keys_processed == GraphEncodeContext_GetKeyCount(ctx); diff --git a/src/serializers/encode_context.h b/src/serializers/encode_context.h index aa0a55b45..3233e95ff 100644 --- a/src/serializers/encode_context.h +++ b/src/serializers/encode_context.h @@ -47,11 +47,7 @@ typedef struct { uint64_t keys_processed; // Count the number of procssed graph keys. GraphEncodeHeader header; // Header replied for each vkey uint64_t vkey_entity_count; // Number of entities in a single virtual key. - NodeID multiple_edges_src_id; // The current edges array sourc node id. - NodeID multiple_edges_dest_id; // The current edges array destination node id. - EdgeID *multiple_edges_array; // Multiple edges array, save in the context. uint current_relation_matrix_id; // Current encoded relationship matrix. - uint multiple_edges_current_index; // The current index of the encoded edges array. DataBlockIterator *datablock_iterator; // Datablock iterator to be saved in the context. RG_MatrixTupleIter matrix_tuple_iterator; // Matrix tuple iterator to be saved in the context. } GraphEncodeContext; @@ -108,22 +104,6 @@ void GraphEncodeContext_SetCurrentRelationID(GraphEncodeContext *ctx, // Retrieve stored matrix tuple iterator. RG_MatrixTupleIter *GraphEncodeContext_GetMatrixTupleIterator(GraphEncodeContext *ctx); -// Sets a multiple edges array and the current index, for saving the state of multiple edges encoding. -void GraphEncodeContext_SetMutipleEdgesArray(GraphEncodeContext *ctx, EdgeID *edges, - uint current_index, NodeID src, NodeID dest); - -// Retrive the multiple edges array, to continue array of multiple edge encoding. -EdgeID *GraphEncodeContext_GetMultipleEdgesArray(const GraphEncodeContext *ctx); - -// Retrive the multiple edges array current index, to continue array of multiple edge encoding. -uint GraphEncodeContext_GetMultipleEdgesCurrentIndex(const GraphEncodeContext *ctx); - -// Retrive the multiple edges array source node. -NodeID GraphEncodeContext_GetMultipleEdgesSourceNode(const GraphEncodeContext *ctx); - -// Retrive the multiple edges array destination node. -NodeID GraphEncodeContext_GetMultipleEdgesDestinationNode(const GraphEncodeContext *ctx); - // Returns if the the number of processed keys is equal to the total number of graph keys. bool GraphEncodeContext_Finished(const GraphEncodeContext *ctx); diff --git a/src/serializers/encoder/v14/encode_graph_entities.c b/src/serializers/encoder/v14/encode_graph_entities.c index 422fa00f3..0d6404f2c 100644 --- a/src/serializers/encoder/v14/encode_graph_entities.c +++ b/src/serializers/encoder/v14/encode_graph_entities.c @@ -272,44 +272,6 @@ void RdbSaveNodes_v14 } } -// Auxilary function to encode a multiple edges array, -// while consdirating the allowed number of edges to encode -// returns true if the number of encoded edges has reached the capacity -static void _RdbSaveMultipleEdges -( - SerializerIO rdb, // RDB IO. - GraphContext *gc, // Graph context. - uint r, // Edges relation id. - EdgeID *multiple_edges_array, // Multiple edges array (passed by ref). - uint *multiple_edges_current_index, // Current index of the array to start encoding from (passed by ref). - uint64_t *encoded_edges, // Number of encoded edges in this phase (passed by ref). - uint64_t edges_to_encode, // Allowed capacity for encoding edges. - NodeID src, // Edges source node id. - NodeID dest // Edges destination node id. -) { - uint edgeCount = array_len(multiple_edges_array); - - // define function local variables from passed-by-reference parameters. - uint i = *multiple_edges_current_index; - uint encoded_edges_count = *encoded_edges; - - // add edges as long the number of encoded edges is in the allowed range - // and the array is not depleted - while(i < edgeCount && encoded_edges_count < edges_to_encode) { - Edge e; - EdgeID edgeID = multiple_edges_array[i++]; - e.src_id = src; - e.dest_id = dest; - Graph_GetEdge(gc->g, edgeID, &e); - _RdbSaveEdge(rdb, gc->g, &e, r); - encoded_edges_count++; - } - - // update passed-by-reference parameters - *encoded_edges = encoded_edges_count; - *multiple_edges_current_index = i; -} - void RdbSaveEdges_v14 ( SerializerIO rdb, @@ -341,46 +303,34 @@ void RdbSaveEdges_v14 // get current relation matrix uint r = GraphEncodeContext_GetCurrentRelationID(gc->encoding_context); - RG_Matrix M = Graph_GetRelationMatrix(gc->g, r, false); + RG_Matrix S = Graph_GetSourceRelationMatrix(gc->g, r, false); + ASSERT(S != NULL); + RG_Matrix T = Graph_GetTargetRelationMatrix(gc->g, r, false); + ASSERT(T != NULL); + RG_MatrixTupleIter iter_t = {0}; + RG_MatrixTupleIter_attach(&iter_t, T); // get matrix tuple iterator from context // already set to the next entry to fetch // for previous edge encide or create new one RG_MatrixTupleIter *iter = GraphEncodeContext_GetMatrixTupleIterator(gc->encoding_context); - if(!RG_MatrixTupleIter_is_attached(iter, M)) { - info = RG_MatrixTupleIter_attach(iter, M); + if(!RG_MatrixTupleIter_is_attached(iter, S)) { + info = RG_MatrixTupleIter_attach(iter, S); ASSERT(info == GrB_SUCCESS); } // first, see if the last edges encoding stopped at multiple edges array - EdgeID *multiple_edges_array = GraphEncodeContext_GetMultipleEdgesArray(gc->encoding_context); - NodeID src = GraphEncodeContext_GetMultipleEdgesSourceNode(gc->encoding_context); - NodeID dest = GraphEncodeContext_GetMultipleEdgesDestinationNode(gc->encoding_context); - uint multiple_edges_current_index = GraphEncodeContext_GetMultipleEdgesCurrentIndex( - gc->encoding_context); - if(multiple_edges_array) { - _RdbSaveMultipleEdges(rdb, gc, r, multiple_edges_array, - &multiple_edges_current_index, - &encoded_edges, edges_to_encode, src, dest); - // if the multiple edges array filled the capacity of entities allowed - // to be encoded, finish encoding - if(encoded_edges == edges_to_encode) { - goto finish; - } else { - // reset the multiple edges context for re-use - multiple_edges_array = NULL; - multiple_edges_current_index = 0; - } - } + NodeID src_id; + NodeID dest_id; + EdgeID edge_id; uint relation_count = Graph_RelationTypeCount(gc->g); // write the required number of edges while(encoded_edges < edges_to_encode) { Edge e; - EdgeID edgeID; // try to get next tuple - info = RG_MatrixTupleIter_next_UINT64(iter, &src, &dest, &edgeID); + info = RG_MatrixTupleIter_next_BOOL(iter, &src_id, &edge_id, NULL); // if iterator is depleted // get new tuple from different matrix or finish encode @@ -392,34 +342,28 @@ void RdbSaveEdges_v14 if(r == relation_count) goto finish; // get matrix and set iterator - M = Graph_GetRelationMatrix(gc->g, r, false); - info = RG_MatrixTupleIter_attach(iter, M); + S = Graph_GetSourceRelationMatrix(gc->g, r, false); + ASSERT(S != NULL); + T = Graph_GetTargetRelationMatrix(gc->g, r, false); + info = RG_MatrixTupleIter_attach(iter, S); ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_next_UINT64(iter, &src, &dest, &edgeID); + info = RG_MatrixTupleIter_attach(&iter_t, T); + ASSERT(info == GrB_SUCCESS); + info = RG_MatrixTupleIter_next_BOOL(iter, &src_id, &edge_id, NULL); } ASSERT(info == GrB_SUCCESS); - e.src_id = src; - e.dest_id = dest; - if(SINGLE_EDGE(edgeID)) { - Graph_GetEdge(gc->g, edgeID, &e); - _RdbSaveEdge(rdb, gc->g, &e, r); - encoded_edges++; - } else { - multiple_edges_array = (EdgeID *)(CLEAR_MSB(edgeID)); - _RdbSaveMultipleEdges(rdb, gc, r, multiple_edges_array, - &multiple_edges_current_index, &encoded_edges, edges_to_encode, src, dest); - // if the multiple edges array filled the capacity of entities - // allowed to be encoded, finish encoding - if(encoded_edges == edges_to_encode) { - goto finish; - } else { - // reset the multiple edges context for re-use - multiple_edges_array = NULL; - multiple_edges_current_index = 0; - } - } + info = RG_MatrixTupleIter_iterate_row(&iter_t, edge_id); + ASSERT(info == GrB_SUCCESS); + info = RG_MatrixTupleIter_next_BOOL(&iter_t, NULL, &dest_id, NULL); + ASSERT(info == GrB_SUCCESS); + + e.src_id = src_id; + e.dest_id = dest_id; + Graph_GetEdge(gc->g, edge_id, &e); + _RdbSaveEdge(rdb, gc->g, &e, r); + encoded_edges++; } finish: @@ -430,6 +374,4 @@ void RdbSaveEdges_v14 // update context GraphEncodeContext_SetCurrentRelationID(gc->encoding_context, r); - GraphEncodeContext_SetMutipleEdgesArray(gc->encoding_context, multiple_edges_array, - multiple_edges_current_index, src, dest); } diff --git a/src/serializers/graph_extensions.c b/src/serializers/graph_extensions.c index e5c3134d6..3b5f4da01 100644 --- a/src/serializers/graph_extensions.c +++ b/src/serializers/graph_extensions.c @@ -79,7 +79,7 @@ void Serializer_Graph_SetNode LabelID label = labels[i]; // set label matrix at position [id, id] RG_Matrix M = Graph_GetLabelMatrix(g, label); - GrB_Matrix m = RG_MATRIX_M(M); + GrB_Matrix m = RG_Matrix_m(M); info = GrB_Matrix_setElement_BOOL(m, true, id, id); if(info == GrB_INVALID_INDEX) { RedisModule_Log(NULL, "notice", "RESIZE LABEL MATRIX"); @@ -103,7 +103,7 @@ void Serializer_Graph_SetNodeLabels int node_count = Graph_RequiredMatrixDim(g); int label_count = Graph_LabelTypeCount(g); RG_Matrix node_labels = Graph_GetNodeLabelMatrix(g); - GrB_Matrix node_labels_m = RG_MATRIX_M(node_labels); + GrB_Matrix node_labels_m = RG_Matrix_m(node_labels); #if RG_DEBUG GrB_Index nvals; @@ -115,7 +115,7 @@ void Serializer_Graph_SetNodeLabels for(int i = 0; i < label_count; i++) { RG_Matrix M = Graph_GetLabelMatrix(g, i); - GrB_Matrix m = RG_MATRIX_M(M); + GrB_Matrix m = RG_Matrix_m(M); GxB_Vector_diag(v, m, 0, NULL); @@ -139,11 +139,17 @@ static void _OptimizedSingleEdgeFormConnection ) { GrB_Info info; RG_Matrix M = Graph_GetRelationMatrix(g, r, false); + RG_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); + RG_Matrix T = Graph_GetTargetRelationMatrix(g, r, false); RG_Matrix adj = Graph_GetAdjacencyMatrix(g, false); - GrB_Matrix m = RG_MATRIX_M(M); - GrB_Matrix tm = RG_MATRIX_TM(M); - GrB_Matrix adj_m = RG_MATRIX_M(adj); - GrB_Matrix adj_tm = RG_MATRIX_TM(adj); + GrB_Matrix m = RG_Matrix_m(M); + GrB_Matrix tm = RG_Matrix_m(RG_Matrix_getTranspose(M)); + GrB_Matrix s = RG_Matrix_m(S); + GrB_Matrix ts = RG_Matrix_m(RG_Matrix_getTranspose(S)); + GrB_Matrix t = RG_Matrix_m(T); + GrB_Matrix tt = RG_Matrix_m(RG_Matrix_getTranspose(T)); + GrB_Matrix adj_m = RG_Matrix_m(adj); + GrB_Matrix adj_tm = RG_Matrix_m(RG_Matrix_getTranspose(adj)); UNUSED(info); @@ -170,14 +176,18 @@ static void _OptimizedSingleEdgeFormConnection // update relationship matrix //-------------------------------------------------------------------------- - info = GrB_Matrix_setElement_UINT64(m, edge_id, src, dest); + info = GrB_Matrix_setElement_BOOL(m, true, src, dest); ASSERT(info == GrB_SUCCESS); info = GrB_Matrix_setElement_BOOL(tm, true, dest, src); ASSERT(info == GrB_SUCCESS); - - // an edge of type r has just been created, update statistics - // TODO: stats->edge_count[relation_idx] += nvals; - GraphStatistics_IncEdgeCount(&g->stats, r, 1); + info = GrB_Matrix_setElement_BOOL(s, true, src, edge_id); + ASSERT(info == GrB_SUCCESS); + info = GrB_Matrix_setElement_BOOL(ts, true, edge_id, src); + ASSERT(info == GrB_SUCCESS); + info = GrB_Matrix_setElement_BOOL(t, true, edge_id, dest); + ASSERT(info == GrB_SUCCESS); + info = GrB_Matrix_setElement_BOOL(tt, true, dest, edge_id); + ASSERT(info == GrB_SUCCESS); } // set a given edge in the graph - Used for deserialization of graph @@ -202,19 +212,7 @@ void Serializer_Graph_SetEdge e->attributes = set; e->relationID = r; - if(multi_edge) { - if(!Graph_FormConnection(g, src, dest, edge_id, r)) { - // resize matrices - RedisModule_Log(NULL, "notice", "RESIZE MATRIX MULTI EDGE"); - - uint64_t max_id = MAX(src, dest); - Graph_EnsureNodeCap(g, max_id); - bool res = Graph_FormConnection(g, src, dest, edge_id, r); - ASSERT(res == true); - } - } else { - _OptimizedSingleEdgeFormConnection(g, src, dest, edge_id, r); - } + _OptimizedSingleEdgeFormConnection(g, src, dest, edge_id, r); } // returns the graph deleted nodes list diff --git a/src/undo_log/undo_log.h b/src/undo_log/undo_log.h index 27b75d99a..7f01550a8 100644 --- a/src/undo_log/undo_log.h +++ b/src/undo_log/undo_log.h @@ -1,7 +1,6 @@ /* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). + * Copyright FalkorDB Ltd. 2023 - present + * Licensed under the Server Side Public License v1 (SSPLv1). */ #pragma once diff --git a/tests/unit/test_algebraic_expression.c b/tests/unit/test_algebraic_expression.c index 789a4f577..d6dd66486 100644 --- a/tests/unit/test_algebraic_expression.c +++ b/tests/unit/test_algebraic_expression.c @@ -604,14 +604,14 @@ void test_Exp_OP_ADD() { // A // 1 1 // 0 0 - RG_Matrix_new(&A, GrB_BOOL, 2, 2); + RG_Matrix_new(&A, GrB_BOOL, 2, 2, false); RG_Matrix_setElement_BOOL(A, 0, 0); RG_Matrix_setElement_BOOL(A, 0, 1); // B // 0 1 // 1 1 - RG_Matrix_new(&B, GrB_BOOL, 2, 2); + RG_Matrix_new(&B, GrB_BOOL, 2, 2, false); RG_Matrix_setElement_BOOL(B, 0, 1); RG_Matrix_setElement_BOOL(B, 1, 0); RG_Matrix_setElement_BOOL(B, 1, 1); @@ -632,7 +632,7 @@ void test_Exp_OP_ADD() { // Matrix used for intermidate computations of AlgebraicExpression_Eval // but also contains the result of expression evaluation. - RG_Matrix_new(&res, GrB_BOOL, 2, 2); + RG_Matrix_new(&res, GrB_BOOL, 2, 2, false); AlgebraicExpression_Eval(exp, res); // Using the A matrix described above, @@ -656,7 +656,7 @@ void test_Exp_OP_MUL() { // A // 1 1 // 0 0 - RG_Matrix_new(&A, GrB_BOOL, 2, 2); + RG_Matrix_new(&A, GrB_BOOL, 2, 2, false); RG_Matrix_setElement_BOOL(A, 0, 0); RG_Matrix_setElement_BOOL(A, 0, 1); RG_Matrix_wait(A, true); // force flush @@ -664,7 +664,7 @@ void test_Exp_OP_MUL() { // I // 1 0 // 0 1 - RG_Matrix_new(&I, GrB_BOOL, 2, 2); + RG_Matrix_new(&I, GrB_BOOL, 2, 2, false); RG_Matrix_setElement_BOOL(I, 0, 0); RG_Matrix_setElement_BOOL(I, 1, 1); @@ -675,7 +675,7 @@ void test_Exp_OP_MUL() { // Matrix used for intermidate computations of AlgebraicExpression_Eval // but also contains the result of expression evaluation. - RG_Matrix_new(&res, GrB_BOOL, 2, 2); + RG_Matrix_new(&res, GrB_BOOL, 2, 2, false); AlgebraicExpression_Eval(exp, res); // Using the A matrix described above, @@ -732,7 +732,7 @@ void test_Exp_OP_ADD_Transpose() { GrB_Matrix_setElement_BOOL(expected, true, 3, 0); // Matrix used for intermidate computations of AlgebraicExpression_Eval // but also contains the result of expression evaluation. - RG_Matrix_new(&res, GrB_BOOL, n, n); + RG_Matrix_new(&res, GrB_BOOL, n, n, false); AlgebraicExpression *exp = AlgebraicExpression_FromString("V+tV", _matrices); AlgebraicExpression_Eval(exp, res); @@ -784,7 +784,7 @@ void test_Exp_OP_MUL_Transpose() { // Matrix used for intermidate computations of AlgebraicExpression_Eval // but also contains the result of expression evaluation. - RG_Matrix_new(&res, GrB_BOOL, n, n); + RG_Matrix_new(&res, GrB_BOOL, n, n, false); // Transpose(A) * A AlgebraicExpression *exp = AlgebraicExpression_FromString("V*tV", _matrices); @@ -811,7 +811,7 @@ void test_Exp_OP_A_MUL_B_Plus_C() { // A // 1 1 // 0 0 - RG_Matrix_new(&A, GrB_BOOL, 2, 2); + RG_Matrix_new(&A, GrB_BOOL, 2, 2, false); RG_Matrix_setElement_BOOL(A, 0, 0); RG_Matrix_setElement_BOOL(A, 0, 1); RG_Matrix_wait(A, true); // force flush @@ -819,18 +819,18 @@ void test_Exp_OP_A_MUL_B_Plus_C() { // B // 1 0 // 0 0 - RG_Matrix_new(&B, GrB_BOOL, 2, 2); + RG_Matrix_new(&B, GrB_BOOL, 2, 2, false); RG_Matrix_setElement_BOOL(B, 0, 0); // C // 0 0 // 0 1 - RG_Matrix_new(&C, GrB_BOOL, 2, 2); + RG_Matrix_new(&C, GrB_BOOL, 2, 2, false); RG_Matrix_setElement_BOOL(C, 1, 1); // Matrix used for intermidate computations of AlgebraicExpression_Eval // but also contains the result of expression evaluation. - RG_Matrix_new(&res, GrB_BOOL, 2, 2); + RG_Matrix_new(&res, GrB_BOOL, 2, 2, false); // A * (B+C) = A.rax *matrices = raxNew(); rax *matrices = raxNew(); @@ -864,9 +864,9 @@ void test_ExpTransform_A_Times_B_Plus_C() { RG_Matrix B; RG_Matrix C; - RG_Matrix_new(&A, GrB_BOOL, 2, 2); - RG_Matrix_new(&B, GrB_BOOL, 2, 2); - RG_Matrix_new(&C, GrB_BOOL, 2, 2); + RG_Matrix_new(&A, GrB_BOOL, 2, 2, false); + RG_Matrix_new(&B, GrB_BOOL, 2, 2, false); + RG_Matrix_new(&C, GrB_BOOL, 2, 2, false); rax *matrices = raxNew(); raxInsert(matrices, (unsigned char *)"A", strlen("A"), A, NULL); @@ -913,10 +913,10 @@ void test_ExpTransform_AB_Times_C_Plus_D() { RG_Matrix C; RG_Matrix D; - RG_Matrix_new(&A, GrB_BOOL, 2, 2); - RG_Matrix_new(&B, GrB_BOOL, 2, 2); - RG_Matrix_new(&C, GrB_BOOL, 2, 2); - RG_Matrix_new(&D, GrB_BOOL, 2, 2); + RG_Matrix_new(&A, GrB_BOOL, 2, 2, false); + RG_Matrix_new(&B, GrB_BOOL, 2, 2, false); + RG_Matrix_new(&C, GrB_BOOL, 2, 2, false); + RG_Matrix_new(&D, GrB_BOOL, 2, 2, false); // A*B*(C+D) -> A*B*C + A*B*D AlgebraicExpression *exp = AlgebraicExpression_NewOperand(C, false, NULL, @@ -973,10 +973,10 @@ void test_ExpTransform_A_Plus_B_Times_C_Plus_D() { RG_Matrix B; RG_Matrix C; RG_Matrix D; - RG_Matrix_new(&A, GrB_BOOL, 2, 2); - RG_Matrix_new(&B, GrB_BOOL, 2, 2); - RG_Matrix_new(&C, GrB_BOOL, 2, 2); - RG_Matrix_new(&D, GrB_BOOL, 2, 2); + RG_Matrix_new(&A, GrB_BOOL, 2, 2, false); + RG_Matrix_new(&B, GrB_BOOL, 2, 2, false); + RG_Matrix_new(&C, GrB_BOOL, 2, 2, false); + RG_Matrix_new(&D, GrB_BOOL, 2, 2, false); rax *matrices = raxNew(); raxInsert(matrices, (unsigned char *)"A", strlen("A"), A, NULL); @@ -1516,7 +1516,7 @@ void test_ExpressionExecute() { RG_Matrix res; RG_Matrix_new(&res, GrB_BOOL, Graph_RequiredMatrixDim(g), - Graph_RequiredMatrixDim(g)); + Graph_RequiredMatrixDim(g), false); AlgebraicExpression_Eval(exp, res); // Validate result matrix. diff --git a/tests/unit/test_all_paths.c b/tests/unit/test_all_paths.c index 200b8d207..782ef5c5d 100644 --- a/tests/unit/test_all_paths.c +++ b/tests/unit/test_all_paths.c @@ -20,7 +20,8 @@ static Graph *BuildGraph() { Edge e; Node n; size_t nodeCount = 4; - Graph *g = Graph_New(nodeCount, nodeCount); + size_t edgeCount = 7; + Graph *g = Graph_New(nodeCount, edgeCount); int relation = Graph_AddRelationType(g); for(int i = 0; i < 4; i++) { n = GE_NEW_NODE(); diff --git a/tests/unit/test_rg_matrix.c b/tests/unit/test_rg_matrix.c index 53385b189..14f631a65 100644 --- a/tests/unit/test_rg_matrix.c +++ b/tests/unit/test_rg_matrix.c @@ -137,569 +137,34 @@ void test_RGMatrix_new() { GrB_Matrix M = NULL; GrB_Matrix DP = NULL; GrB_Matrix DM = NULL; - GrB_Type t = GrB_UINT64; + GrB_Type t = GrB_BOOL; GrB_Info info = GrB_SUCCESS; GrB_Index nvals = 0; GrB_Index nrows = 100; GrB_Index ncols = 100; - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_MATRIX_M(A); - DP = RG_MATRIX_DELTA_PLUS(A); - DM = RG_MATRIX_DELTA_MINUS(A); + M = RG_Matrix_m(A); + DP = RG_Matrix_dp(A); + DM = RG_Matrix_dm(A); - // uint64 matrix always maintain transpose - TEST_ASSERT(RG_MATRIX_MAINTAIN_TRANSPOSE(A)); - - // uint64 matrix always multi edge - TEST_ASSERT(RG_MATRIX_MULTI_EDGE(A)); - - // a new empty matrix should be synced - // no data in either DP or DM - TEST_ASSERT(RG_Matrix_Synced(A)); - - // test M, DP and DM hyper switch - int format; - double hyper_switch; - - // M should be either hyper-sparse or sparse - GxB_Matrix_Option_get(M, GxB_SPARSITY_CONTROL, &format); - TEST_ASSERT(format == (GxB_SPARSE | GxB_HYPERSPARSE)); - - // DP should always be hyper - GxB_Matrix_Option_get(DP, GxB_HYPER_SWITCH, &hyper_switch); - TEST_ASSERT(hyper_switch == GxB_ALWAYS_HYPER); - GxB_Matrix_Option_get(DP, GxB_SPARSITY_CONTROL, &format); - TEST_ASSERT(format == GxB_HYPERSPARSE); - - // DM should always be hyper - GxB_Matrix_Option_get(DM, GxB_HYPER_SWITCH, &hyper_switch); - TEST_ASSERT(hyper_switch == GxB_ALWAYS_HYPER); - GxB_Matrix_Option_get(DM, GxB_SPARSITY_CONTROL, &format); - TEST_ASSERT(format == GxB_HYPERSPARSE); - - // matrix should be empty - M_EMPTY(); - DP_EMPTY(); - DM_EMPTY(); - RG_Matrix_nvals(&nvals, A); - TEST_ASSERT(nvals == 0); - - RG_Matrix_free(&A); - TEST_ASSERT(A == NULL); - - t = GrB_BOOL; - - info = RG_Matrix_new(&A, t, nrows, ncols); - TEST_ASSERT(info == GrB_SUCCESS); - - // get internal matrices - M = RG_MATRIX_M(A); - DP = RG_MATRIX_DELTA_PLUS(A); - DM = RG_MATRIX_DELTA_MINUS(A); - - // bool matrix do not maintain transpose - TEST_ASSERT(!(RG_MATRIX_MAINTAIN_TRANSPOSE(A))); - - // bool matrix always not multi edge - TEST_ASSERT(!RG_MATRIX_MULTI_EDGE(A)); - - // a new empty matrix should be synced - // no data in either DP or DM - TEST_ASSERT(RG_Matrix_Synced(A)); - - // matrix should be empty - M_EMPTY(); - DP_EMPTY(); - DM_EMPTY(); - RG_Matrix_nvals(&nvals, A); - TEST_ASSERT(nvals == 0); - - RG_Matrix_free(&A); - TEST_ASSERT(A == NULL); -} - -// setting an empty entry -// M[i,j] = 1 -void test_RGMatrix_simple_set() { - GrB_Type t = GrB_UINT64; - RG_Matrix A = NULL; - GrB_Matrix M = NULL; - GrB_Matrix DP = NULL; - GrB_Matrix DM = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nvals = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - GrB_Index i = 0; - GrB_Index j = 1; - uint64_t x = 1; - - info = RG_Matrix_new(&A, t, nrows, ncols); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // set element at position i,j - //-------------------------------------------------------------------------- - - info = RG_Matrix_setElement_UINT64(A, x, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // make sure element at position i,j exists - info = RG_Matrix_extractElement_UINT64(&x, A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - TEST_ASSERT(x == 1); - - // matrix should contain a single element - RG_Matrix_nvals(&nvals, A); - TEST_ASSERT(nvals == 1); - - // matrix should be mark as dirty - TEST_ASSERT(RG_Matrix_isDirty(A)); - - // get internal matrices - M = RG_MATRIX_M(A); - DP = RG_MATRIX_DELTA_PLUS(A); - DM = RG_MATRIX_DELTA_MINUS(A); - - //-------------------------------------------------------------------------- - // validations - //-------------------------------------------------------------------------- - - // M should be empty - M_EMPTY(); - - // DM should be empty - DM_EMPTY(); - - // DP should contain a single element - DP_NOT_EMPTY(); - - //-------------------------------------------------------------------------- - // set already existing entry - //-------------------------------------------------------------------------- - - // flush matrix - RG_Matrix_wait(A, false); - - // introduce existing entry - info = RG_Matrix_setElement_UINT64(A, x, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // validations - //-------------------------------------------------------------------------- - - // M should be empty - M_EMPTY(); - - // DM should be empty - DM_EMPTY(); - - // DP should contain a multi-value entry - DP_NOT_EMPTY(); - - // clean up - RG_Matrix_free(&A); - TEST_ASSERT(A == NULL); -} - -// multiple delete scenarios -void test_RGMatrix_del() { - GrB_Type t = GrB_UINT64; - RG_Matrix A = NULL; - GrB_Matrix M = NULL; - GrB_Matrix DP = NULL; - GrB_Matrix DM = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nvals = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - GrB_Index i = 0; - GrB_Index j = 1; - uint64_t x = 1; - - info = RG_Matrix_new(&A, t, nrows, ncols); - TEST_ASSERT(info == GrB_SUCCESS); - - // get internal matrices - M = RG_MATRIX_M(A); - DP = RG_MATRIX_DELTA_PLUS(A); - DM = RG_MATRIX_DELTA_MINUS(A); - - //-------------------------------------------------------------------------- - // remove none existing entry - //-------------------------------------------------------------------------- - - info = RG_Matrix_removeElement_UINT64(A, i, j); - TEST_ASSERT(info == GrB_NO_VALUE); - - // matrix should not contain any entries in either DP or DM - TEST_ASSERT(RG_Matrix_Synced(A)); - - //-------------------------------------------------------------------------- - // remove none flushed addition - //-------------------------------------------------------------------------- - - // set element at position i,j - info = RG_Matrix_setElement_UINT64(A, x, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // remove element at position i,j - info = RG_Matrix_removeElement_UINT64(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // matrix should be mark as dirty - TEST_ASSERT(RG_Matrix_isDirty(A)); - - //-------------------------------------------------------------------------- - // validations - //-------------------------------------------------------------------------- - - // A should be empty - RG_Matrix_nvals(&nvals, A); - TEST_ASSERT(nvals == 0); - - // M should be empty - M_EMPTY(); - - // DM should be empty - DM_EMPTY(); - - // DP should be empty - DP_EMPTY(); - - //-------------------------------------------------------------------------- - // remove flushed addition - //-------------------------------------------------------------------------- - - // set element at position i,j - info = RG_Matrix_setElement_UINT64(A, x, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // force sync - // entry should migrated from 'delta-plus' to 'M' - info = RG_Matrix_wait(A, true); - - // remove element at position i,j - info = RG_Matrix_removeElement_UINT64(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // validations - //-------------------------------------------------------------------------- - - // A should be empty - RG_Matrix_nvals(&nvals, A); - TEST_ASSERT(nvals == 0); - - // M should contain a single element - M_NOT_EMPTY(); - - // DM should contain a single element - DM_NOT_EMPTY(); - - // DP should be empty - DP_EMPTY(); - - //-------------------------------------------------------------------------- - // flush - //-------------------------------------------------------------------------- - - info = RG_Matrix_wait(A, true); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // validations - //-------------------------------------------------------------------------- - - // entry should be removed from both 'delta-minus' and 'M' - // A should be empty - RG_Matrix_nvals(&nvals, A); - TEST_ASSERT(nvals == 0); - - // M should be empty - M_EMPTY(); - - // DM should be empty - DM_EMPTY(); - - // DP should be empty - DP_EMPTY(); - - //-------------------------------------------------------------------------- - - // commit an entry M[i,j] = 1 - // delete entry del DM[i,j] = true - // re-introduce entry DM[i,j] = 0, M[i,j] = 2 - // delete entry DM[i,j] = true - // commit - // M[i,j] = 0, DP[i,j] = 0, DM[i,j] = 0 - - //-------------------------------------------------------------------------- - // commit an entry M[i,j] = 1 - //-------------------------------------------------------------------------- - - // set element at position i,j - info = RG_Matrix_setElement_UINT64(A, 1, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // force sync - info = RG_Matrix_wait(A, true); - - // M should contain a single element - M_NOT_EMPTY(); - DP_EMPTY(); - DM_EMPTY(); - - //-------------------------------------------------------------------------- - // delete entry del DM[i,j] = true - //-------------------------------------------------------------------------- - - // remove element at position i,j - info = RG_Matrix_removeElement_UINT64(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - M_NOT_EMPTY(); - DP_EMPTY(); - DM_NOT_EMPTY(); - - //-------------------------------------------------------------------------- - // introduce an entry DP[i,j] = 2 - //-------------------------------------------------------------------------- - - // set element at position i,j - info = RG_Matrix_setElement_UINT64(A, 2, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // M should contain a single element - M_NOT_EMPTY(); - DP_EMPTY(); - DM_EMPTY(); - - //-------------------------------------------------------------------------- - // commit - //-------------------------------------------------------------------------- - - // force sync - info = RG_Matrix_wait(A, true); - - //-------------------------------------------------------------------------- - // M[i,j] = 2, DP[i,j] = 0, DM[i,j] = 0 - //-------------------------------------------------------------------------- - - info = RG_Matrix_extractElement_UINT64(&x, A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - TEST_ASSERT(2 == x); - - M_NOT_EMPTY(); - DP_EMPTY(); - DM_EMPTY(); - - //-------------------------------------------------------------------------- - // clean up - //-------------------------------------------------------------------------- - - RG_Matrix_free(&A); - TEST_ASSERT(A == NULL); -} - -// multiple delete entry scenarios -void test_RGMatrix_del_entry() { - GrB_Type t = GrB_UINT64; - RG_Matrix A = NULL; - GrB_Matrix M = NULL; - GrB_Matrix DP = NULL; - GrB_Matrix DM = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nvals = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - GrB_Index i = 0; - GrB_Index j = 1; - uint64_t x = 1; - bool entry_deleted = false; - - info = RG_Matrix_new(&A, t, nrows, ncols); - TEST_ASSERT(info == GrB_SUCCESS); - - // get internal matrices - M = RG_MATRIX_M(A); - DP = RG_MATRIX_DELTA_PLUS(A); - DM = RG_MATRIX_DELTA_MINUS(A); - - //-------------------------------------------------------------------------- - // remove none existing entry - //-------------------------------------------------------------------------- - - info = RG_Matrix_removeEntry_UINT64(A, i, j, x, &entry_deleted); - TEST_ASSERT(info == GrB_NO_VALUE); - - // matrix should not contain any entries in either DP or DM - TEST_ASSERT(RG_Matrix_Synced(A)); - - //-------------------------------------------------------------------------- - // remove none flushed addition - //-------------------------------------------------------------------------- - - // set element at position i,j - info = RG_Matrix_setElement_UINT64(A, x, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // remove element at position i,j - info = RG_Matrix_removeEntry_UINT64(A, i, j, x, &entry_deleted); - TEST_ASSERT(info == GrB_SUCCESS); - - // matrix should be mark as dirty - TEST_ASSERT(RG_Matrix_isDirty(A)); - - //-------------------------------------------------------------------------- - // validations - //-------------------------------------------------------------------------- + // bool matrix do not maintain transpose + TEST_ASSERT(RG_Matrix_getTranspose(A) == NULL); - // A should be empty - RG_Matrix_nvals(&nvals, A); - TEST_ASSERT(nvals == 0); + // a new empty matrix should be synced + // no data in either DP or DM + TEST_ASSERT(!RG_Matrix_isDirty(A)); - // M should be empty + // matrix should be empty M_EMPTY(); - - // DM should be empty + DP_EMPTY(); DM_EMPTY(); - - // DP should be empty - DP_EMPTY(); - - //-------------------------------------------------------------------------- - // remove flushed addition - //-------------------------------------------------------------------------- - - // set element at position i,j - info = RG_Matrix_setElement_UINT64(A, x, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // force sync - // entry should migrated from 'delta-plus' to 'M' - info = RG_Matrix_wait(A, true); - - // remove element at position i,j - info = RG_Matrix_removeEntry_UINT64(A, i, j, x, &entry_deleted); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // validations - //-------------------------------------------------------------------------- - - // A should be empty - RG_Matrix_nvals(&nvals, A); - TEST_ASSERT(nvals == 0); - - // M should contain a single element - M_NOT_EMPTY(); - - // DM should contain a single element - DM_NOT_EMPTY(); - - // DP should be empty - DP_EMPTY(); - - //-------------------------------------------------------------------------- - // flush - //-------------------------------------------------------------------------- - - info = RG_Matrix_wait(A, true); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // validations - //-------------------------------------------------------------------------- - - // entry should be removed from both 'delta-minus' and 'M' - // A should be empty RG_Matrix_nvals(&nvals, A); TEST_ASSERT(nvals == 0); - // M should be empty - M_EMPTY(); - - // DM should be empty - DM_EMPTY(); - - // DP should be empty - DP_EMPTY(); - - //-------------------------------------------------------------------------- - - // commit an entry M[i,j] = 1 - // delete entry del DM[i,j] = true - // re-introduce entry DM[i,j] = 0, M[i,j] = 2 - // delete entry DM[i,j] = true - // commit - // M[i,j] = 0, DP[i,j] = 0, DM[i,j] = 0 - - //-------------------------------------------------------------------------- - // commit an entry M[i,j] = 1 - //-------------------------------------------------------------------------- - - // set element at position i,j - info = RG_Matrix_setElement_UINT64(A, 1, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // force sync - info = RG_Matrix_wait(A, true); - - // M should contain a single element - M_NOT_EMPTY(); - DP_EMPTY(); - DM_EMPTY(); - - //-------------------------------------------------------------------------- - // delete entry del DM[i,j] = true - //-------------------------------------------------------------------------- - - // remove element at position i,j - info = RG_Matrix_removeEntry_UINT64(A, i, j, x, &entry_deleted); - TEST_ASSERT(info == GrB_SUCCESS); - - M_NOT_EMPTY(); - DP_EMPTY(); - DM_NOT_EMPTY(); - - //-------------------------------------------------------------------------- - // introduce an entry DP[i,j] = 2 - //-------------------------------------------------------------------------- - - // set element at position i,j - info = RG_Matrix_setElement_UINT64(A, 2, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // M should contain a single element - M_NOT_EMPTY(); - DP_EMPTY(); - DM_EMPTY(); - - //-------------------------------------------------------------------------- - // commit - //-------------------------------------------------------------------------- - - // force sync - info = RG_Matrix_wait(A, true); - - //-------------------------------------------------------------------------- - // M[i,j] = 2, DP[i,j] = 0, DM[i,j] = 0 - //-------------------------------------------------------------------------- - - M_NOT_EMPTY(); - DP_EMPTY(); - DM_EMPTY(); - - //-------------------------------------------------------------------------- - // clean up - //-------------------------------------------------------------------------- - RG_Matrix_free(&A); TEST_ASSERT(A == NULL); } @@ -717,13 +182,13 @@ void test_RGMatrix_set() { GrB_Index i = 0; GrB_Index j = 1; - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_MATRIX_M(A); - DP = RG_MATRIX_DELTA_PLUS(A); - DM = RG_MATRIX_DELTA_MINUS(A); + M = RG_Matrix_m(A); + DP = RG_Matrix_dp(A); + DM = RG_Matrix_dm(A); //-------------------------------------------------------------------------- // Set element that marked for deletion @@ -772,7 +237,7 @@ void test_RGMatrix_set() { } // flush simple addition -void test_RGMatrix_flus() { +void test_RGMatrix_flush() { GrB_Type t = GrB_BOOL; RG_Matrix A = NULL; GrB_Matrix M = NULL; @@ -786,7 +251,7 @@ void test_RGMatrix_flus() { GrB_Index j = 1; bool sync = false; - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // set element at position i,j @@ -794,9 +259,9 @@ void test_RGMatrix_flus() { TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_MATRIX_M(A); - DP = RG_MATRIX_DELTA_PLUS(A); - DM = RG_MATRIX_DELTA_MINUS(A); + M = RG_Matrix_m(A); + DP = RG_Matrix_dp(A); + DM = RG_Matrix_dm(A); //-------------------------------------------------------------------------- // flush matrix, no sync @@ -840,200 +305,6 @@ void test_RGMatrix_flus() { TEST_ASSERT(A == NULL); } -//------------------------------------------------------------------------------ -// transpose test -//------------------------------------------------------------------------------ - -// M[i,j] = x, M[i,j] = y -void test_GRMatrix_managed_transposed() { - GrB_Type t = GrB_UINT64; - RG_Matrix A = NULL; - RG_Matrix T = NULL; // A transposed - GrB_Matrix M = NULL; // primary internal matrix - GrB_Matrix DP = NULL; // delta plus - GrB_Matrix DM = NULL; // delta minus - GrB_Info info = GrB_SUCCESS; - GrB_Index nvals = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - GrB_Index i = 0; - GrB_Index j = 1; - uint64_t x = 0; // M[i,j] = x - bool b = false; - bool entry_deleted = false; - - //-------------------------------------------------------------------------- - // create RGMatrix - //-------------------------------------------------------------------------- - - info = RG_Matrix_new(&A, t, nrows, ncols); - TEST_ASSERT(info == GrB_SUCCESS); - - // make sure transposed was created - T = RG_Matrix_getTranspose(A); - TEST_ASSERT(T != A); - TEST_ASSERT(T != NULL); - - // get internal matrices - M = RG_MATRIX_M(T); - DP = RG_MATRIX_DELTA_PLUS(T); - DM = RG_MATRIX_DELTA_MINUS(T); - - //-------------------------------------------------------------------------- - // set element at position i,j - //-------------------------------------------------------------------------- - - info = RG_Matrix_setElement_UINT64(A, x, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // make sure element at position j,i exists - info = RG_Matrix_extractElement_BOOL(&b, T, j, i); - TEST_ASSERT(info == GrB_SUCCESS); - TEST_ASSERT(true == b); - - // matrix should contain a single element - RG_Matrix_nvals(&nvals, T); - TEST_ASSERT(nvals == 1); - - // matrix should be mark as dirty - TEST_ASSERT(RG_Matrix_isDirty(T)); - - //-------------------------------------------------------------------------- - // validations - //-------------------------------------------------------------------------- - - // TM should be empty - M_EMPTY(); - - // TDM should be empty - DM_EMPTY(); - - // TDP should contain a single element - DP_NOT_EMPTY(); - - //-------------------------------------------------------------------------- - // flush matrix - //-------------------------------------------------------------------------- - - RG_Matrix_wait(A, true); - - // flushing 'A' should flush 'T' aswell - - // TM should contain a single element - M_NOT_EMPTY(); - - // TDM should be empty - DM_EMPTY(); - - // TDP should be empty - DP_EMPTY(); - - //-------------------------------------------------------------------------- - // delete element at position i,j - //-------------------------------------------------------------------------- - - info = RG_Matrix_removeElement_UINT64(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // matrix should be mark as dirty - TEST_ASSERT(RG_Matrix_isDirty(T)); - - //-------------------------------------------------------------------------- - // validations - //-------------------------------------------------------------------------- - - // TM should contain a single element - M_NOT_EMPTY(); - - // TDM should contain a single element - DM_NOT_EMPTY(); - - // TDP should be empty - DP_EMPTY(); - - //-------------------------------------------------------------------------- - // flush matrix - //-------------------------------------------------------------------------- - - // flushing 'A' should flush 'T' aswell - - RG_Matrix_wait(A, true); - - // TM should be empty - M_EMPTY(); - - // TDM should be empty - DM_EMPTY(); - - // TDP should be empty - DP_EMPTY(); - - //-------------------------------------------------------------------------- - // delete entry at position i,j - //-------------------------------------------------------------------------- - - info = RG_Matrix_setElement_UINT64(A, x, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_setElement_UINT64(A, x + 1, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - info = RG_Matrix_removeEntry_UINT64(A, i, j, x, &entry_deleted); - - // make sure element at position j,i exists - info = RG_Matrix_extractElement_BOOL(&b, T, j, i); - TEST_ASSERT(info == GrB_SUCCESS); - TEST_ASSERT(true == b); - - info = RG_Matrix_removeEntry_UINT64(A, i, j, x + 1, &entry_deleted); - info = RG_Matrix_extractElement_BOOL(&b, T, j, i); - TEST_ASSERT(info == GrB_NO_VALUE); - - //-------------------------------------------------------------------------- - // delete flushed entry at position i,j - //-------------------------------------------------------------------------- - - info = RG_Matrix_setElement_UINT64(A, x, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_setElement_UINT64(A, x + 1, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - RG_Matrix_wait(A, true); - - info = RG_Matrix_removeEntry_UINT64(A, i, j, x, &entry_deleted); - - // make sure element at position j,i exists - info = RG_Matrix_extractElement_BOOL(&b, T, j, i); - TEST_ASSERT(info == GrB_SUCCESS); - TEST_ASSERT(true == b); - - info = RG_Matrix_removeEntry_UINT64(A, i, j, x + 1, &entry_deleted); - info = RG_Matrix_extractElement_BOOL(&b, T, j, i); - TEST_ASSERT(info == GrB_NO_VALUE); - - //-------------------------------------------------------------------------- - // revive deleted entry at position i,j - //-------------------------------------------------------------------------- - - info = RG_Matrix_setElement_UINT64(A, x, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - RG_Matrix_wait(A, true); - - info = RG_Matrix_removeElement_UINT64(A, i, j); - - info = RG_Matrix_setElement_UINT64(A, x, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // make sure element at position j,i exists - info = RG_Matrix_extractElement_BOOL(&b, T, j, i); - TEST_ASSERT(info == GrB_SUCCESS); - TEST_ASSERT(true == b); - - // clean up - RG_Matrix_free(&A); - TEST_ASSERT(A == NULL); -} - //------------------------------------------------------------------------------ // fuzzy test compare RG_Matrix to GrB_Matrix //------------------------------------------------------------------------------ @@ -1064,8 +335,7 @@ void test_RGMatrix_fuzzy() { I = (GrB_Index*) malloc(sizeof(GrB_Index) * operations); J = (GrB_Index*) malloc(sizeof(GrB_Index) * operations); - info = RG_Matrix_new(&A, t, nrows, ncols); - info = RG_Matrix_new(&A->transposed, t, ncols, nrows); + info = RG_Matrix_new(&A, t, nrows, ncols, true); TEST_ASSERT(info == GrB_SUCCESS); // make sure transposed was created @@ -1074,8 +344,8 @@ void test_RGMatrix_fuzzy() { TEST_ASSERT(T != NULL); // get internal matrices - M = RG_MATRIX_M(A); - MT = RG_MATRIX_M(T); + M = RG_Matrix_m(A); + MT = RG_Matrix_m(T); info = GrB_Matrix_new(&N, t, nrows, ncols); TEST_ASSERT(info == GrB_SUCCESS); @@ -1168,11 +438,11 @@ void test_RGMatrix_export_no_changes() { GrB_Index ncols = 100; bool sync = false; - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_MATRIX_M(A); + M = RG_Matrix_m(A); //-------------------------------------------------------------------------- // export empty matrix @@ -1234,11 +504,11 @@ void test_RGMatrix_export_pending_changes() { GrB_Index ncols = 100; bool sync = false; - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_MATRIX_M(A); + M = RG_Matrix_m(A); // set elements info = RG_Matrix_setElement_BOOL(A, 0, 0); @@ -1308,10 +578,10 @@ void test_RGMatrix_copy() { GrB_Index ncols = 100; bool sync = false; - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_new(&B, t, nrows, ncols); + info = RG_Matrix_new(&B, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // set elements @@ -1351,12 +621,12 @@ void test_RGMatrix_copy() { // validation //-------------------------------------------------------------------------- - A_M = RG_MATRIX_M(A); - B_M = RG_MATRIX_M(B); - A_DP = RG_MATRIX_DELTA_PLUS(A); - B_DP = RG_MATRIX_DELTA_PLUS(B); - A_DM = RG_MATRIX_DELTA_MINUS(A); - B_DM = RG_MATRIX_DELTA_MINUS(B); + A_M = RG_Matrix_m(A); + B_M = RG_Matrix_m(B); + A_DP = RG_Matrix_dp(A); + B_DP = RG_Matrix_dp(B); + A_DM = RG_Matrix_dm(A); + B_DM = RG_Matrix_dm(B); ASSERT_GrB_Matrices_EQ(A_M, B_M); ASSERT_GrB_Matrices_EQ(A_DP, B_DP); @@ -1382,16 +652,16 @@ void test_RGMatrix_mxm() { GrB_Index ncols = 100; bool sync = false; - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_new(&B, t, nrows, ncols); + info = RG_Matrix_new(&B, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_new(&C, t, nrows, ncols); + info = RG_Matrix_new(&C, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_new(&D, t, nrows, ncols); + info = RG_Matrix_new(&D, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // set elements @@ -1421,7 +691,7 @@ void test_RGMatrix_mxm() { info = RG_Matrix_removeElement_BOOL(B, 1, 2); TEST_ASSERT(info == GrB_SUCCESS); - // set element at position 2,2 + // set element at position 1,3 info = RG_Matrix_setElement_BOOL(B, 1, 3); TEST_ASSERT(info == GrB_SUCCESS); @@ -1439,8 +709,8 @@ void test_RGMatrix_mxm() { // validation //-------------------------------------------------------------------------- - C_M = RG_MATRIX_M(C); - D_M = RG_MATRIX_M(D); + C_M = RG_Matrix_m(C); + D_M = RG_Matrix_m(D); ASSERT_GrB_Matrices_EQ(C_M, D_M); @@ -1459,11 +729,11 @@ void test_RGMatrix_resize() { RG_Matrix A = NULL; RG_Matrix T = NULL; GrB_Info info = GrB_SUCCESS; - GrB_Type t = GrB_UINT64; + GrB_Type t = GrB_BOOL; GrB_Index nrows = 10; GrB_Index ncols = 20; - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, true); T = RG_Matrix_getTranspose(A); GrB_Index A_nrows; @@ -1541,12 +811,8 @@ void test_RGMatrix_resize() { TEST_LIST = { {"RGMatrix_new", test_RGMatrix_new}, - {"RGMatrix_simple_set", test_RGMatrix_simple_set}, - {"RGMatrix_del", test_RGMatrix_del}, - {"RGMatrix_del_entry", test_RGMatrix_del_entry}, {"RGMatrix_set", test_RGMatrix_set}, - {"RGMatrix_flus", test_RGMatrix_flus}, - {"GRMatrix_managed_transposed", test_GRMatrix_managed_transposed}, + {"RGMatrix_flush", test_RGMatrix_flush}, {"RGMatrix_fuzzy", test_RGMatrix_fuzzy}, {"RGMatrix_export_no_changes", test_RGMatrix_export_no_changes}, {"RGMatrix_export_pending_changes", test_RGMatrix_export_pending_changes}, diff --git a/tests/unit/test_rg_matrix_iter.c b/tests/unit/test_rg_matrix_iter.c index d7af07bad..3ea6fd260 100644 --- a/tests/unit/test_rg_matrix_iter.c +++ b/tests/unit/test_rg_matrix_iter.c @@ -33,21 +33,21 @@ void tearDown() { // test RGMatrixTupleIter initialization void test_RGMatrixTupleIter_attach() { RG_Matrix A = NULL; - GrB_Type t = GrB_UINT64; + GrB_Type t = GrB_BOOL; GrB_Info info = GrB_SUCCESS; GrB_Index nrows = 100; GrB_Index ncols = 100; RG_MatrixTupleIter iter; memset(&iter, 0, sizeof(RG_MatrixTupleIter)); - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); info = RG_MatrixTupleIter_attach(&iter, A); TEST_ASSERT(RG_MatrixTupleIter_is_attached(&iter, A)); RG_MatrixTupleIter_detach(&iter); - TEST_ASSERT(iter.A == NULL); + // TEST_ASSERT(iter.A == NULL); RG_Matrix_free(&A); TEST_ASSERT(A == NULL); @@ -56,7 +56,7 @@ void test_RGMatrixTupleIter_attach() { // test RGMatrixTupleIter iteration void test_RGMatrixTupleIter_next() { RG_Matrix A = NULL; - GrB_Type t = GrB_UINT64; + GrB_Type t = GrB_BOOL; GrB_Info info = GrB_SUCCESS; GrB_Index i = 1; GrB_Index j = 2; @@ -64,16 +64,16 @@ void test_RGMatrixTupleIter_next() { GrB_Index col = 0; GrB_Index nrows = 100; GrB_Index ncols = 100; - uint64_t val = 0; + bool val = 0; bool sync = false; RG_MatrixTupleIter iter; memset(&iter, 0, sizeof(RG_MatrixTupleIter)); - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // set element at position i,j - info = RG_Matrix_setElement_UINT64(A, 0, i, j); + info = RG_Matrix_setElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- @@ -89,54 +89,54 @@ void test_RGMatrixTupleIter_next() { //-------------------------------------------------------------------------- // remove element at position i,j - info = RG_Matrix_removeElement_UINT64(A, i, j); + info = RG_Matrix_removeElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); // set element at position i+1,j+1 - info = RG_Matrix_setElement_UINT64(A, 1, i+1, j+1); + info = RG_Matrix_setElement_BOOL(A, i+1, j+1); TEST_ASSERT(info == GrB_SUCCESS); info = RG_MatrixTupleIter_attach(&iter, A); TEST_ASSERT(RG_MatrixTupleIter_is_attached(&iter, A)); - info = RG_MatrixTupleIter_next_UINT64(&iter, &row, &col, &val); + info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); TEST_ASSERT(info == GrB_SUCCESS); TEST_ASSERT(row == i+1); TEST_ASSERT(col == j+1); TEST_ASSERT(val == 1); - info = RG_MatrixTupleIter_next_UINT64(&iter, &row, &col, &val); + info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); TEST_ASSERT(info == GxB_EXHAUSTED); RG_Matrix_free(&A); TEST_ASSERT(A == NULL); RG_MatrixTupleIter_detach(&iter); - TEST_ASSERT(iter.A == NULL); + // TEST_ASSERT(iter.A == NULL); } // test RGMatrixTupleIter iteration for sparse matrix void test_RGMatrixTupleIter_next_sparse() { RG_Matrix A = NULL; - GrB_Type t = GrB_UINT64; + GrB_Type t = GrB_BOOL; GrB_Info info = GrB_SUCCESS; GrB_Index row = 0; GrB_Index col = 0; GrB_Index nrows = 100; GrB_Index ncols = 100; - uint64_t val = 0; + bool val = 0; bool sync = false; RG_MatrixTupleIter iter; memset(&iter, 0, sizeof(RG_MatrixTupleIter)); - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); for (GrB_Index i = 25; i < 100; i++) { for (GrB_Index j = 25; j < 100; j++) { // set element at position i,j - info = RG_Matrix_setElement_UINT64(A, 0, i, j); + info = RG_Matrix_setElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); } } @@ -153,7 +153,7 @@ void test_RGMatrixTupleIter_next_sparse() { // check M is sparse //-------------------------------------------------------------------------- - GrB_Matrix M = RG_MATRIX_M(A); + GrB_Matrix M = RG_Matrix_m(A); int sparsity; GxB_Matrix_Option_get(M, GxB_SPARSITY_STATUS, &sparsity); @@ -166,24 +166,24 @@ void test_RGMatrixTupleIter_next_sparse() { info = RG_MatrixTupleIter_attach(&iter, A); TEST_ASSERT(RG_MatrixTupleIter_is_attached(&iter, A)); - info = RG_MatrixTupleIter_next_UINT64(&iter, &row, &col, &val); + info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); TEST_ASSERT(info == GrB_SUCCESS); TEST_ASSERT(row == 25); TEST_ASSERT(col == 25); - TEST_ASSERT(val == 0); + TEST_ASSERT(val); RG_Matrix_free(&A); TEST_ASSERT(A == NULL); RG_MatrixTupleIter_detach(&iter); - TEST_ASSERT(iter.A == NULL); + // TEST_ASSERT(iter.A == NULL); } // test RGMatrixTupleIter iteration void test_RGMatrixTupleIter_reuse() { RG_Matrix A = NULL; RG_Matrix B = NULL; - GrB_Type t = GrB_UINT64; + GrB_Type t = GrB_BOOL; GrB_Info info = GrB_SUCCESS; GrB_Index i = 1; GrB_Index j = 2; @@ -191,19 +191,19 @@ void test_RGMatrixTupleIter_reuse() { GrB_Index col = 0; GrB_Index nrows = 100; GrB_Index ncols = 100; - uint64_t val = 0; + bool val = 0; bool sync = false; RG_MatrixTupleIter iter; memset(&iter, 0, sizeof(RG_MatrixTupleIter)); - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_new(&B, t, nrows, ncols); + info = RG_Matrix_new(&B, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // set element at position i,j - info = RG_Matrix_setElement_UINT64(A, 0, i, j); + info = RG_Matrix_setElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- @@ -220,14 +220,14 @@ void test_RGMatrixTupleIter_reuse() { info = RG_MatrixTupleIter_attach(&iter, A); TEST_ASSERT(RG_MatrixTupleIter_is_attached(&iter, A)); - info = RG_MatrixTupleIter_next_UINT64(&iter, &row, &col, &val); + info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); TEST_ASSERT(info == GrB_SUCCESS); TEST_ASSERT(row == i); TEST_ASSERT(col == j); - TEST_ASSERT(val == 0); + TEST_ASSERT(val); - info = RG_MatrixTupleIter_next_UINT64(&iter, &row, &col, &val); + info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); TEST_ASSERT(info == GxB_EXHAUSTED); @@ -236,13 +236,13 @@ void test_RGMatrixTupleIter_reuse() { RG_Matrix_free(&B); TEST_ASSERT(A == NULL); RG_MatrixTupleIter_detach(&iter); - TEST_ASSERT(iter.A == NULL); + // TEST_ASSERT(iter.A == NULL); } // test RGMatrixTupleIter_iterate_row void test_RGMatrixTupleIter_iterate_row() { RG_Matrix A = NULL; - GrB_Type t = GrB_UINT64; + GrB_Type t = GrB_BOOL; GrB_Info info = GrB_SUCCESS; GrB_Index i = 1; GrB_Index j = 2; @@ -250,16 +250,16 @@ void test_RGMatrixTupleIter_iterate_row() { GrB_Index col = 0; GrB_Index nrows = 100; GrB_Index ncols = 100; - uint64_t val = 0; + bool val = 0; bool sync = false; RG_MatrixTupleIter iter; memset(&iter, 0, sizeof(RG_MatrixTupleIter)); - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // set element at position i,j - info = RG_Matrix_setElement_UINT64(A, 1, i, j); + info = RG_Matrix_setElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- @@ -275,7 +275,7 @@ void test_RGMatrixTupleIter_iterate_row() { //-------------------------------------------------------------------------- // remove element at position i,j - info = RG_Matrix_removeElement_UINT64(A, i, j); + info = RG_Matrix_removeElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); // wait, DM can't have pendding changes @@ -283,16 +283,16 @@ void test_RGMatrixTupleIter_iterate_row() { RG_Matrix_wait(A, sync); // set element at position i+1,j+1 - info = RG_Matrix_setElement_UINT64(A, 2, i+1, j+1); + info = RG_Matrix_setElement_BOOL(A, i+1, j+1); TEST_ASSERT(info == GrB_SUCCESS); info = RG_MatrixTupleIter_attach(&iter, A); - TEST_ASSERT(iter.A == A); + // TEST_ASSERT(iter.A == A); info = RG_MatrixTupleIter_iterate_row(&iter, i); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_next_UINT64(&iter, &row, &col, &val); + info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); TEST_ASSERT(info == GxB_EXHAUSTED); info = RG_MatrixTupleIter_reset(&iter); @@ -301,26 +301,26 @@ void test_RGMatrixTupleIter_iterate_row() { info = RG_MatrixTupleIter_iterate_row(&iter, i+1); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_next_UINT64(&iter, &row, &col, &val); + info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); TEST_ASSERT(info == GrB_SUCCESS); TEST_ASSERT(row == i+1); TEST_ASSERT(col == j+1); - TEST_ASSERT(val == 2); + TEST_ASSERT(val); - info = RG_MatrixTupleIter_next_UINT64(&iter, &row, &col, &val); + info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); TEST_ASSERT(info == GxB_EXHAUSTED); RG_Matrix_free(&A); TEST_ASSERT(A == NULL); RG_MatrixTupleIter_detach(&iter); - TEST_ASSERT(iter.A == NULL); + // TEST_ASSERT(iter.A == NULL); } // test RGMatrixTupleiIter_iterate_range void test_RGMatrixTupleIter_iterate_range() { RG_Matrix A = NULL; - GrB_Type t = GrB_UINT64; + GrB_Type t = GrB_BOOL; GrB_Info info = GrB_SUCCESS; GrB_Index i = 1; GrB_Index j = 2; @@ -328,16 +328,16 @@ void test_RGMatrixTupleIter_iterate_range() { GrB_Index col = 0; GrB_Index nrows = 100; GrB_Index ncols = 100; - uint64_t val = 0; + bool val = 0; bool sync = false; RG_MatrixTupleIter iter; memset(&iter, 0, sizeof(RG_MatrixTupleIter)); - info = RG_Matrix_new(&A, t, nrows, ncols); + info = RG_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // set element at position i,j - info = RG_Matrix_setElement_UINT64(A, 0, i, j); + info = RG_Matrix_setElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- @@ -353,11 +353,11 @@ void test_RGMatrixTupleIter_iterate_range() { //-------------------------------------------------------------------------- // remove element at position i,j - info = RG_Matrix_removeElement_UINT64(A, i, j); + info = RG_Matrix_removeElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); // set element at position i+1,j+1 - info = RG_Matrix_setElement_UINT64(A, 1, i+1, j+1); + info = RG_Matrix_setElement_BOOL(A, i+1, j+1); TEST_ASSERT(info == GrB_SUCCESS); info = RG_MatrixTupleIter_attach(&iter, A); @@ -366,20 +366,20 @@ void test_RGMatrixTupleIter_iterate_range() { info = RG_MatrixTupleIter_iterate_range(&iter, i+1, i+1); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_next_UINT64(&iter, &row, &col, &val); + info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); TEST_ASSERT(info == GrB_SUCCESS); TEST_ASSERT(row == i+1); TEST_ASSERT(col == j+1); TEST_ASSERT(val == 1); - info = RG_MatrixTupleIter_next_UINT64(&iter, &row, &col, &val); + info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); TEST_ASSERT(info == GxB_EXHAUSTED); RG_Matrix_free(&A); TEST_ASSERT(A == NULL); RG_MatrixTupleIter_detach(&iter); - TEST_ASSERT(iter.A == NULL); + // TEST_ASSERT(iter.A == NULL); } TEST_LIST = { From fa173319a74999eabbc9cac486aeef7718667626 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 25 Mar 2024 15:08:45 +0200 Subject: [PATCH 02/57] fix tabs and comments --- src/bulk_insert/bulk_insert.c | 142 +++++++++--------- .../decoders/current/v14/decode_graph.c | 2 +- .../decoders/prev/v10/decode_graph.c | 2 +- .../decoders/prev/v11/decode_graph.c | 2 +- .../decoders/prev/v12/decode_graph.c | 2 +- .../decoders/prev/v13/decode_graph.c | 2 +- 6 files changed, 76 insertions(+), 76 deletions(-) diff --git a/src/bulk_insert/bulk_insert.c b/src/bulk_insert/bulk_insert.c index 8bc4242c8..6ac8a945c 100644 --- a/src/bulk_insert/bulk_insert.c +++ b/src/bulk_insert/bulk_insert.c @@ -40,15 +40,15 @@ static int* _BulkInsert_ReadHeaderLabels ASSERT(data != NULL); ASSERT(data_idx != NULL); - // first sequence is entity label(s) - const char* labels = data + *data_idx; - int labels_len = strlen(labels); - *data_idx += labels_len + 1; + // first sequence is entity label(s) + const char* labels = data + *data_idx; + int labels_len = strlen(labels); + *data_idx += labels_len + 1; - // array of all label IDs - int* label_ids = array_new(int, 1); - // stack variable to contain a single label - char label[labels_len + 1]; + // array of all label IDs + int* label_ids = array_new(int, 1); + // stack variable to contain a single label + char label[labels_len + 1]; while (true) { // look for a colon delimiting another label @@ -82,7 +82,7 @@ static int* _BulkInsert_ReadHeaderLabels if (!found) break; } - return label_ids; + return label_ids; } // read the property keys from a header @@ -99,15 +99,15 @@ static AttributeID* _BulkInsert_ReadHeaderProperties ASSERT(data_idx != NULL); ASSERT(prop_count != NULL); - // next 4 bytes are property count - *prop_count = *(uint*)&data[*data_idx]; - *data_idx += sizeof(unsigned int); + // next 4 bytes are property count + *prop_count = *(uint*)&data[*data_idx]; + *data_idx += sizeof(unsigned int); - if (*prop_count == 0) return NULL; + if (*prop_count == 0) return NULL; - AttributeID* prop_indices = rm_malloc(*prop_count * sizeof(AttributeID)); + AttributeID* prop_indices = rm_malloc(*prop_count * sizeof(AttributeID)); - // the rest of the line is [char *prop_key] * prop_count + // the rest of the line is [char *prop_key] * prop_count for (uint j = 0; j < *prop_count; j++) { char* prop_key = (char*)data + *data_idx; *data_idx += strlen(prop_key) + 1; @@ -116,7 +116,7 @@ static AttributeID* _BulkInsert_ReadHeaderProperties prop_indices[j] = GraphContext_FindOrAddAttribute(gc, prop_key, NULL); } - return prop_indices; + return prop_indices; } // read an SIValue from the data stream and update the index appropriately @@ -125,7 +125,7 @@ static SIValue _BulkInsert_ReadProperty const char* data, size_t* data_idx ) { - // binary property format: + // binary property format: // - property type : 1-byte integer corresponding to TYPE enum // - Nothing if type is NULL // - 1-byte true/false if type is boolean @@ -134,16 +134,16 @@ static SIValue _BulkInsert_ReadProperty // - Null-terminated C string if type is string // - 8-byte array length followed by N values if type is array - // possible property values - bool b; - double d; - int64_t i; - int64_t len; - const char* s; + // possible property values + bool b; + double d; + int64_t i; + int64_t len; + const char* s; - SIValue v = SI_NullVal(); - TYPE t = data[*data_idx]; - *data_idx += 1; + SIValue v = SI_NullVal(); + TYPE t = data[*data_idx]; + *data_idx += 1; switch (t) { case BI_NULL: @@ -191,7 +191,7 @@ static SIValue _BulkInsert_ReadProperty break; } - return v; + return v; } static int _BulkInsert_ProcessNodeFile @@ -200,30 +200,30 @@ static int _BulkInsert_ProcessNodeFile const char* data, size_t data_len ) { - uint prop_count; - size_t data_idx = 0; - - // read the CSV file header labels and update all schemas - int* label_ids = _BulkInsert_ReadHeaderLabels(gc, SCHEMA_NODE, data, &data_idx); - uint label_count = array_len(label_ids); - // read the CSV header properties and collect their indices - AttributeID* prop_indices = _BulkInsert_ReadHeaderProperties(gc, SCHEMA_NODE, data, + uint prop_count; + size_t data_idx = 0; + + // read the CSV file header labels and update all schemas + int* label_ids = _BulkInsert_ReadHeaderLabels(gc, SCHEMA_NODE, data, &data_idx); + uint label_count = array_len(label_ids); + // read the CSV header properties and collect their indices + AttributeID* prop_indices = _BulkInsert_ReadHeaderProperties(gc, SCHEMA_NODE, data, &data_idx, &prop_count); - // sync each matrix once - ASSERT(Graph_GetMatrixPolicy(gc->g) == SYNC_POLICY_RESIZE); + // sync each matrix once + ASSERT(Graph_GetMatrixPolicy(gc->g) == SYNC_POLICY_RESIZE); for (uint i = 0; i < label_count; i++) { Graph_GetLabelMatrix(gc->g, label_ids[i]); } - // sync node-label matrix - Graph_GetNodeLabelMatrix(gc->g); - Graph_SetMatrixPolicy(gc->g, SYNC_POLICY_NOP); + // sync node-label matrix + Graph_GetNodeLabelMatrix(gc->g); + Graph_SetMatrixPolicy(gc->g, SYNC_POLICY_NOP); - //-------------------------------------------------------------------------- - // load nodes - //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + // load nodes + //-------------------------------------------------------------------------- while (data_idx < data_len) { Node n = GE_NEW_NODE(); @@ -240,11 +240,11 @@ static int _BulkInsert_ProcessNodeFile } } - Graph_SetMatrixPolicy(gc->g, SYNC_POLICY_RESIZE); - if (prop_indices) rm_free(prop_indices); - array_free(label_ids); + Graph_SetMatrixPolicy(gc->g, SYNC_POLICY_RESIZE); + if (prop_indices) rm_free(prop_indices); + array_free(label_ids); - return BULK_OK; + return BULK_OK; } static int _BulkInsert_ProcessEdgeFile @@ -253,33 +253,33 @@ static int _BulkInsert_ProcessEdgeFile const char* data, size_t data_len ) { - int relation_id; - uint prop_count; - size_t data_idx = 0; + int relation_id; + uint prop_count; + size_t data_idx = 0; - // read the CSV file header - // and commit all labels and properties it introduces - int* type_ids = _BulkInsert_ReadHeaderLabels(gc, SCHEMA_EDGE, data, &data_idx); - uint type_count = array_len(type_ids); + // read the CSV file header + // and commit all labels and properties it introduces + int* type_ids = _BulkInsert_ReadHeaderLabels(gc, SCHEMA_EDGE, data, &data_idx); + uint type_count = array_len(type_ids); - // edges can only have one type - ASSERT(type_count == 1); + // edges can only have one type + ASSERT(type_count == 1); - int type_id = type_ids[0]; - AttributeID* prop_indices = _BulkInsert_ReadHeaderProperties(gc, SCHEMA_EDGE, + int type_id = type_ids[0]; + AttributeID* prop_indices = _BulkInsert_ReadHeaderProperties(gc, SCHEMA_EDGE, data, &data_idx, &prop_count); - // sync matrix once - ASSERT(Graph_GetMatrixPolicy(gc->g) == SYNC_POLICY_RESIZE); - Graph_GetRelationMatrix(gc->g, type_id, false); + // sync matrix once + ASSERT(Graph_GetMatrixPolicy(gc->g) == SYNC_POLICY_RESIZE); + Graph_GetRelationMatrix(gc->g, type_id, false); Graph_GetSourceRelationMatrix(gc->g, type_id, false); Graph_GetTargetRelationMatrix(gc->g, type_id, false); - Graph_GetAdjacencyMatrix(gc->g, false); - Graph_SetMatrixPolicy(gc->g, SYNC_POLICY_NOP); + Graph_GetAdjacencyMatrix(gc->g, false); + Graph_SetMatrixPolicy(gc->g, SYNC_POLICY_NOP); - //-------------------------------------------------------------------------- - // load edges - //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + // load edges + //-------------------------------------------------------------------------- while (data_idx < data_len) { Edge e; @@ -307,11 +307,11 @@ static int _BulkInsert_ProcessEdgeFile } } - array_free(type_ids); - if (prop_indices) rm_free(prop_indices); - Graph_SetMatrixPolicy(gc->g, SYNC_POLICY_RESIZE); + array_free(type_ids); + if (prop_indices) rm_free(prop_indices); + Graph_SetMatrixPolicy(gc->g, SYNC_POLICY_RESIZE); - return BULK_OK; + return BULK_OK; } static int _BulkInsert_ProcessTokens @@ -332,7 +332,7 @@ static int _BulkInsert_ProcessTokens ASSERT(rc == BULK_OK); } - return BULK_OK; + return BULK_OK; } int BulkInsert diff --git a/src/serializers/decoders/current/v14/decode_graph.c b/src/serializers/decoders/current/v14/decode_graph.c index 505be0d05..c31780617 100644 --- a/src/serializers/decoders/current/v14/decode_graph.c +++ b/src/serializers/decoders/current/v14/decode_graph.c @@ -220,7 +220,7 @@ GraphContext *RdbLoadGraphContext_latest uint rel_count = Graph_RelationTypeCount(g); uint label_count = Graph_LabelTypeCount(g); - // update the node statistics, enable node indices + // enable node indices for(uint i = 0; i < label_count; i++) { Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); diff --git a/src/serializers/decoders/prev/v10/decode_graph.c b/src/serializers/decoders/prev/v10/decode_graph.c index f41c45c9d..11750ea2f 100644 --- a/src/serializers/decoders/prev/v10/decode_graph.c +++ b/src/serializers/decoders/prev/v10/decode_graph.c @@ -199,7 +199,7 @@ GraphContext *RdbLoadGraphContext_v10(RedisModuleIO *rdb) { uint rel_count = Graph_RelationTypeCount(g); uint label_count = Graph_LabelTypeCount(g); - // update the node statistics, enable node indices + // enable node indices for(uint i = 0; i < label_count; i++) { Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); diff --git a/src/serializers/decoders/prev/v11/decode_graph.c b/src/serializers/decoders/prev/v11/decode_graph.c index 0352eaedf..b5f83cf34 100644 --- a/src/serializers/decoders/prev/v11/decode_graph.c +++ b/src/serializers/decoders/prev/v11/decode_graph.c @@ -206,7 +206,7 @@ GraphContext *RdbLoadGraphContext_v11 uint rel_count = Graph_RelationTypeCount(g); uint label_count = Graph_LabelTypeCount(g); - // update the node statistics, enable node indices + // enable node indices for(uint i = 0; i < label_count; i++) { Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); diff --git a/src/serializers/decoders/prev/v12/decode_graph.c b/src/serializers/decoders/prev/v12/decode_graph.c index 9d4820843..4b060d71b 100644 --- a/src/serializers/decoders/prev/v12/decode_graph.c +++ b/src/serializers/decoders/prev/v12/decode_graph.c @@ -214,7 +214,7 @@ GraphContext *RdbLoadGraphContext_v12 uint rel_count = Graph_RelationTypeCount(g); uint label_count = Graph_LabelTypeCount(g); - // update the node statistics, enable node indices + // enable node indices for(uint i = 0; i < label_count; i++) { Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); diff --git a/src/serializers/decoders/prev/v13/decode_graph.c b/src/serializers/decoders/prev/v13/decode_graph.c index 77cc632b4..1e546c8a2 100644 --- a/src/serializers/decoders/prev/v13/decode_graph.c +++ b/src/serializers/decoders/prev/v13/decode_graph.c @@ -220,7 +220,7 @@ GraphContext *RdbLoadGraphContext_v13 uint rel_count = Graph_RelationTypeCount(g); uint label_count = Graph_LabelTypeCount(g); - // update the node statistics, enable node indices + // enable node indices for(uint i = 0; i < label_count; i++) { Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); From cbbb241183da00f1f48da4c821e301b8c470cc00 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Tue, 26 Mar 2024 10:01:35 +0200 Subject: [PATCH 03/57] fix tests --- deps/FalkorDB-rs | 2 +- src/graph/graph.c | 6 +++--- src/graph/rg_matrix/rg_matrix.h | 7 ------- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 264f3317c..c94260c46 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 264f3317c42ff27e499f4f1607583fe228b5ac19 +Subproject commit c94260c462d44fdff2cd8ec628b36baabf770563 diff --git a/src/graph/graph.c b/src/graph/graph.c index df5b8b9ee..1a8d01ea3 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -112,16 +112,16 @@ void _Graph_GetEdgesConnectingNodes // no entry at [dest, src], src is not connected to dest with relation R if(res == GrB_NO_VALUE) return; - Edge e = {.src_id = src, .dest_id = dest, .relationID = r}; + Edge e = {.src_id = src, .dest_id = dest, .relationID = r}; RG_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); RG_Matrix T = Graph_GetTargetRelationMatrix(g, r, true); GrB_Vector src_vec; GrB_Vector dst_vec; - GrB_Info info; + GrB_Info info; info = GrB_Vector_new(&src_vec, GrB_BOOL, g->edges->itemCap); ASSERT(info == GrB_SUCCESS); info = GrB_Vector_new(&dst_vec, GrB_BOOL, g->edges->itemCap); - ASSERT(info == GrB_SUCCESS); + ASSERT(info == GrB_SUCCESS); info = RG_Matrix_extract_row(S, src_vec, src); ASSERT(info == GrB_SUCCESS); info = RG_Matrix_extract_row(T, dst_vec, dest); diff --git a/src/graph/rg_matrix/rg_matrix.h b/src/graph/rg_matrix/rg_matrix.h index 269e6aa93..e5d16d400 100644 --- a/src/graph/rg_matrix/rg_matrix.h +++ b/src/graph/rg_matrix/rg_matrix.h @@ -179,13 +179,6 @@ GrB_Info RG_Matrix_extract_row GrB_Index i // row index ) ; -GrB_Info RG_Matrix_extract_col -( - const RG_Matrix A, // matrix to extract a vector from - GrB_Vector v, // vector to extract - GrB_Index j // row index -) ; - // remove entry at position C[i,j] GrB_Info RG_Matrix_removeElement_BOOL ( From 89d6c988d23279d44431d1f2c313f0bb3073eb40 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Tue, 26 Mar 2024 10:21:54 +0200 Subject: [PATCH 04/57] update --- deps/FalkorDB-rs | 2 +- src/graph/graph.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index c94260c46..5823f9444 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit c94260c462d44fdff2cd8ec628b36baabf770563 +Subproject commit 5823f9444d2a94704c97590b618c6a7c4154d7a3 diff --git a/src/graph/graph.c b/src/graph/graph.c index 1a8d01ea3..8ea7cfb86 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -121,7 +121,7 @@ void _Graph_GetEdgesConnectingNodes info = GrB_Vector_new(&src_vec, GrB_BOOL, g->edges->itemCap); ASSERT(info == GrB_SUCCESS); info = GrB_Vector_new(&dst_vec, GrB_BOOL, g->edges->itemCap); - ASSERT(info == GrB_SUCCESS); + ASSERT(info == GrB_SUCCESS); info = RG_Matrix_extract_row(S, src_vec, src); ASSERT(info == GrB_SUCCESS); info = RG_Matrix_extract_row(T, dst_vec, dest); From 33940a563ab301ac95c2605c1d1acba910e084fe Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Thu, 28 Mar 2024 10:45:23 +0200 Subject: [PATCH 05/57] fix build --- CMakeLists.txt | 2 +- deps/FalkorDB-rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 137351109..5cb469110 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,7 @@ set(FALKORDB_OBJECTS $) find_package(OpenSSL) lists_from_env(GRAPHBLAS LIBXXHASH RAX LIBCYPHER_PARSER REDISEARCH_LIBS UTF8PROC ONIGURUMA FalkorDBRS) -set(FALKORDB_LIBS ${GRAPHBLAS} ${LIBXXHASH} ${RAX} ${LIBCYPHER_PARSER} ${REDISEARCH_LIBS} ${UTF8PROC} ${ONIGURUMA} ${FalkorDBRS} OpenSSL::SSL) +set(FALKORDB_LIBS ${FalkorDBRS} ${GRAPHBLAS} ${LIBXXHASH} ${RAX} ${LIBCYPHER_PARSER} ${REDISEARCH_LIBS} ${UTF8PROC} ${ONIGURUMA} OpenSSL::SSL) target_link_options(falkordb PRIVATE ${CMAKE_LD_FLAGS_LIST} ${CMAKE_SO_LD_FLAGS_LIST}) target_link_libraries(falkordb PRIVATE ${FALKORDB_LIBS} ${CMAKE_LD_LIBS}) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 5823f9444..078f10588 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 5823f9444d2a94704c97590b618c6a7c4154d7a3 +Subproject commit 078f105886073157ba375a797ce3db8ee318f923 From abdfff5dfcf9d2ee23a4362f4f5690d135231e43 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Thu, 28 Mar 2024 15:33:56 +0200 Subject: [PATCH 06/57] update --- deps/FalkorDB-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 078f10588..7853fa472 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 078f105886073157ba375a797ce3db8ee318f923 +Subproject commit 7853fa472108d38fc71f3f82351457c6d8e94801 From f3e5f0116adc38eedf867ed6762928c4b0f7f564 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Thu, 28 Mar 2024 17:07:39 +0200 Subject: [PATCH 07/57] update --- deps/FalkorDB-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 7853fa472..ab13be737 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 7853fa472108d38fc71f3f82351457c6d8e94801 +Subproject commit ab13be737692a67850ba4194f4ea2b0f15f0c4d9 From ace5c2bd1256ed3508e6fa43f6a1459b6c69c7d5 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Tue, 2 Apr 2024 13:59:40 +0300 Subject: [PATCH 08/57] update --- deps/FalkorDB-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index ab13be737..5499b0aa8 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit ab13be737692a67850ba4194f4ea2b0f15f0c4d9 +Subproject commit 5499b0aa88becf48bac9d77efeba8797cdba5a72 From 49378991145efeca8ed85a9df9d8ed2a4aba0a18 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Tue, 16 Apr 2024 12:10:20 +0300 Subject: [PATCH 09/57] address review --- deps/FalkorDB-rs | 2 +- .../ops/op_conditional_traverse.c | 2 +- src/execution_plan/ops/op_expand_into.c | 2 +- src/graph/graph.c | 6 +-- src/graph/graph.h | 13 +++--- src/graph/graph_delete_nodes.c | 10 ++--- src/graph/rg_matrix/rg_matrix.h | 6 +-- src/serializers/graph_extensions.c | 22 +++++----- tests/unit/test_rg_matrix.c | 42 +++++++++---------- tests/unit/test_rg_matrix_iter.c | 2 +- 10 files changed, 53 insertions(+), 54 deletions(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 5499b0aa8..f8fecc1be 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 5499b0aa88becf48bac9d77efeba8797cdba5a72 +Subproject commit f8fecc1bea65147dc317ce6756f9c6e9136f2388 diff --git a/src/execution_plan/ops/op_conditional_traverse.c b/src/execution_plan/ops/op_conditional_traverse.c index 2fb9d9653..80907da8a 100644 --- a/src/execution_plan/ops/op_conditional_traverse.c +++ b/src/execution_plan/ops/op_conditional_traverse.c @@ -25,7 +25,7 @@ static void CondTraverseToString(const OpBase *ctx, sds *buf) { } static void _populate_filter_matrix(OpCondTraverse *op) { - GrB_Matrix FM = RG_Matrix_m(op->F); + GrB_Matrix FM = RG_Matrix_M(op->F); // clear filter matrix GrB_Matrix_clear(FM); diff --git a/src/execution_plan/ops/op_expand_into.c b/src/execution_plan/ops/op_expand_into.c index 0b1dd6bff..a6a38fa07 100644 --- a/src/execution_plan/ops/op_expand_into.c +++ b/src/execution_plan/ops/op_expand_into.c @@ -34,7 +34,7 @@ static void _populate_filter_matrix ( OpExpandInto *op ) { - GrB_Matrix FM = RG_Matrix_m(op->F); + GrB_Matrix FM = RG_Matrix_M(op->F); // clear filter matrix GrB_Matrix_clear(FM); diff --git a/src/graph/graph.c b/src/graph/graph.c index 8ea7cfb86..bca6bc57f 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -395,7 +395,7 @@ Graph *Graph_New g->nodes = DataBlock_New(node_cap, node_cap, sizeof(AttributeSet), cb); g->edges = DataBlock_New(edge_cap, edge_cap, sizeof(AttributeSet), cb); g->labels = array_new(RG_Matrix, GRAPH_DEFAULT_LABEL_CAP); - g->relations = array_new(Relation, GRAPH_DEFAULT_RELATION_TYPE_CAP); + g->relations = array_new(RelationMatrices, GRAPH_DEFAULT_RELATION_TYPE_CAP); GrB_Info info; UNUSED(info); @@ -1174,7 +1174,7 @@ static void _Graph_FreeRelationMatrices ) { uint relationCount = Graph_RelationTypeCount(g); for(uint i = 0; i < relationCount; i++) { - Relation *r = g->relations + i; + RelationMatrices *r = g->relations + i; RG_Matrix_free(&r->R); RG_Matrix_free(&r->S); RG_Matrix_free(&r->T); @@ -1233,7 +1233,7 @@ RelationID Graph_AddRelationType ) { ASSERT(g); - Relation r; + RelationMatrices r; size_t n = Graph_RequiredMatrixDim(g); size_t edge_cap = g->edges->itemCap; diff --git a/src/graph/graph.h b/src/graph/graph.h index 0dc4a769d..74307834b 100644 --- a/src/graph/graph.h +++ b/src/graph/graph.h @@ -14,7 +14,6 @@ #include "entities/node.h" #include "entities/edge.h" #include "../redismodule.h" -#include "../util/rmalloc.h" #include "rg_matrix/rg_matrix.h" #include "../util/datablock/datablock.h" #include "../util/datablock/datablock_iterator.h" @@ -49,7 +48,7 @@ typedef struct { RG_Matrix R; // relation matrix RG_Matrix S; // sources matrix RG_Matrix T; // targets matrix -} Relation; +} RelationMatrices; struct Graph { int reserved_node_count; // number of nodes not commited yet @@ -58,7 +57,7 @@ struct Graph { RG_Matrix adjacency_matrix; // adjacency matrix, holds all graph connections RG_Matrix *labels; // label matrices RG_Matrix node_labels; // mapping of all node IDs to all labels possessed by each node - Relation *relations; // relation matrices + RelationMatrices *relations; // relation matrices RG_Matrix _zero_matrix; // zero matrix pthread_rwlock_t _rwlock; // read-write lock scoped to this specific graph bool _writelocked; // true if the read-write lock was acquired by a writer @@ -415,8 +414,8 @@ RG_Matrix Graph_GetRelationMatrix bool transposed ); -// retrieves a source matrix -// matrix is resized if its size doesn't match graph's node count +// retrieves a relation edge source matrix +// matrix is resized if its dimensions doesn't match graph's node count & graph's edge count RG_Matrix Graph_GetSourceRelationMatrix ( const Graph *g, // graph from which to get adjacency matrix @@ -424,8 +423,8 @@ RG_Matrix Graph_GetSourceRelationMatrix bool transposed ); -// retrieves a target matrix -// matrix is resized if its size doesn't match graph's node count +// retrieves a relation edge target matrix +// matrix is resized if its dimensions doesn't match graph's edge count & graph's node count RG_Matrix Graph_GetTargetRelationMatrix ( const Graph *g, // graph from which to get adjacency matrix diff --git a/src/graph/graph_delete_nodes.c b/src/graph/graph_delete_nodes.c index 50c68f370..a775cd366 100644 --- a/src/graph/graph_delete_nodes.c +++ b/src/graph/graph_delete_nodes.c @@ -62,7 +62,7 @@ void Graph_DeleteNodes GrB_Info info; // GraphBLAS return code GrB_Index nrows; // lbls row count GrB_Index ncols; // lbls col count - GrB_Matrix lbls_mask; // lbls mask + GrB_Matrix elems; // elements to delete RG_MatrixTupleIter it; // matrix iterator // get labels matrix @@ -73,7 +73,7 @@ void Graph_DeleteNodes ASSERT(info == GrB_SUCCESS); info = RG_Matrix_ncols(&ncols, lbls); ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_new(&lbls_mask, GrB_BOOL, nrows, ncols); + info = GrB_Matrix_new(&elems, GrB_BOOL, nrows, ncols); ASSERT(info == GrB_SUCCESS); // attach iterator to lbls matrix @@ -95,7 +95,7 @@ void Graph_DeleteNodes // for each deleted node label while(RG_MatrixTupleIter_next_BOOL(&it, NULL, &j, NULL) == GrB_SUCCESS) { // populate lbls mask - info = GrB_Matrix_setElement_BOOL(lbls_mask, true, id, j); + info = GrB_Matrix_setElement_BOOL(elems, true, id, j); ASSERT(info == GrB_SUCCESS); // clear label matrix j at position [id,id] @@ -112,11 +112,11 @@ void Graph_DeleteNodes // phase two //-------------------------------------------------------------------------- - RG_Matrix_removeElements(lbls, lbls_mask); + RG_Matrix_removeElements(lbls, elems); // restore matrix sync policy Graph_SetMatrixPolicy(g, policy); - GrB_free(&lbls_mask); + GrB_free(&elems); } diff --git a/src/graph/rg_matrix/rg_matrix.h b/src/graph/rg_matrix/rg_matrix.h index e5d16d400..e168f1156 100644 --- a/src/graph/rg_matrix/rg_matrix.h +++ b/src/graph/rg_matrix/rg_matrix.h @@ -117,17 +117,17 @@ bool RG_Matrix_isDirty const RG_Matrix C ); -GrB_Matrix RG_Matrix_m +GrB_Matrix RG_Matrix_M ( const RG_Matrix C ); -GrB_Matrix RG_Matrix_dp +GrB_Matrix RG_Matrix_DP ( const RG_Matrix C ); -GrB_Matrix RG_Matrix_dm +GrB_Matrix RG_Matrix_DM ( const RG_Matrix C ); diff --git a/src/serializers/graph_extensions.c b/src/serializers/graph_extensions.c index 3b5f4da01..c70ef8d8c 100644 --- a/src/serializers/graph_extensions.c +++ b/src/serializers/graph_extensions.c @@ -79,7 +79,7 @@ void Serializer_Graph_SetNode LabelID label = labels[i]; // set label matrix at position [id, id] RG_Matrix M = Graph_GetLabelMatrix(g, label); - GrB_Matrix m = RG_Matrix_m(M); + GrB_Matrix m = RG_Matrix_M(M); info = GrB_Matrix_setElement_BOOL(m, true, id, id); if(info == GrB_INVALID_INDEX) { RedisModule_Log(NULL, "notice", "RESIZE LABEL MATRIX"); @@ -103,7 +103,7 @@ void Serializer_Graph_SetNodeLabels int node_count = Graph_RequiredMatrixDim(g); int label_count = Graph_LabelTypeCount(g); RG_Matrix node_labels = Graph_GetNodeLabelMatrix(g); - GrB_Matrix node_labels_m = RG_Matrix_m(node_labels); + GrB_Matrix node_labels_m = RG_Matrix_M(node_labels); #if RG_DEBUG GrB_Index nvals; @@ -115,7 +115,7 @@ void Serializer_Graph_SetNodeLabels for(int i = 0; i < label_count; i++) { RG_Matrix M = Graph_GetLabelMatrix(g, i); - GrB_Matrix m = RG_Matrix_m(M); + GrB_Matrix m = RG_Matrix_M(M); GxB_Vector_diag(v, m, 0, NULL); @@ -142,14 +142,14 @@ static void _OptimizedSingleEdgeFormConnection RG_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); RG_Matrix T = Graph_GetTargetRelationMatrix(g, r, false); RG_Matrix adj = Graph_GetAdjacencyMatrix(g, false); - GrB_Matrix m = RG_Matrix_m(M); - GrB_Matrix tm = RG_Matrix_m(RG_Matrix_getTranspose(M)); - GrB_Matrix s = RG_Matrix_m(S); - GrB_Matrix ts = RG_Matrix_m(RG_Matrix_getTranspose(S)); - GrB_Matrix t = RG_Matrix_m(T); - GrB_Matrix tt = RG_Matrix_m(RG_Matrix_getTranspose(T)); - GrB_Matrix adj_m = RG_Matrix_m(adj); - GrB_Matrix adj_tm = RG_Matrix_m(RG_Matrix_getTranspose(adj)); + GrB_Matrix m = RG_Matrix_M(M); + GrB_Matrix tm = RG_Matrix_M(RG_Matrix_getTranspose(M)); + GrB_Matrix s = RG_Matrix_M(S); + GrB_Matrix ts = RG_Matrix_M(RG_Matrix_getTranspose(S)); + GrB_Matrix t = RG_Matrix_M(T); + GrB_Matrix tt = RG_Matrix_M(RG_Matrix_getTranspose(T)); + GrB_Matrix adj_m = RG_Matrix_M(adj); + GrB_Matrix adj_tm = RG_Matrix_M(RG_Matrix_getTranspose(adj)); UNUSED(info); diff --git a/tests/unit/test_rg_matrix.c b/tests/unit/test_rg_matrix.c index a41e53c7c..fdadfbfc1 100644 --- a/tests/unit/test_rg_matrix.c +++ b/tests/unit/test_rg_matrix.c @@ -147,9 +147,9 @@ void test_RGMatrix_new() { TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_Matrix_m(A); - DP = RG_Matrix_dp(A); - DM = RG_Matrix_dm(A); + M = RG_Matrix_M(A); + DP = RG_Matrix_DP(A); + DM = RG_Matrix_DM(A); // bool matrix do not maintain transpose TEST_ASSERT(RG_Matrix_getTranspose(A) == NULL); @@ -186,9 +186,9 @@ void test_RGMatrix_set() { TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_Matrix_m(A); - DP = RG_Matrix_dp(A); - DM = RG_Matrix_dm(A); + M = RG_Matrix_M(A); + DP = RG_Matrix_DP(A); + DM = RG_Matrix_DM(A); //-------------------------------------------------------------------------- // Set element that marked for deletion @@ -259,9 +259,9 @@ void test_RGMatrix_flush() { TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_Matrix_m(A); - DP = RG_Matrix_dp(A); - DM = RG_Matrix_dm(A); + M = RG_Matrix_M(A); + DP = RG_Matrix_DP(A); + DM = RG_Matrix_DM(A); //-------------------------------------------------------------------------- // flush matrix, no sync @@ -344,8 +344,8 @@ void test_RGMatrix_fuzzy() { TEST_ASSERT(T != NULL); // get internal matrices - M = RG_Matrix_m(A); - MT = RG_Matrix_m(T); + M = RG_Matrix_M(A); + MT = RG_Matrix_M(T); info = GrB_Matrix_new(&N, t, nrows, ncols); TEST_ASSERT(info == GrB_SUCCESS); @@ -442,7 +442,7 @@ void test_RGMatrix_export_no_changes() { TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_Matrix_m(A); + M = RG_Matrix_M(A); //-------------------------------------------------------------------------- // export empty matrix @@ -508,7 +508,7 @@ void test_RGMatrix_export_pending_changes() { TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_Matrix_m(A); + M = RG_Matrix_M(A); // set elements info = RG_Matrix_setElement_BOOL(A, 0, 0); @@ -621,12 +621,12 @@ void test_RGMatrix_copy() { // validation //-------------------------------------------------------------------------- - A_M = RG_Matrix_m(A); - B_M = RG_Matrix_m(B); - A_DP = RG_Matrix_dp(A); - B_DP = RG_Matrix_dp(B); - A_DM = RG_Matrix_dm(A); - B_DM = RG_Matrix_dm(B); + A_M = RG_Matrix_M(A); + B_M = RG_Matrix_M(B); + A_DP = RG_Matrix_DP(A); + B_DP = RG_Matrix_DP(B); + A_DM = RG_Matrix_DM(A); + B_DM = RG_Matrix_DM(B); ASSERT_GrB_Matrices_EQ(A_M, B_M); ASSERT_GrB_Matrices_EQ(A_DP, B_DP); @@ -709,8 +709,8 @@ void test_RGMatrix_mxm() { // validation //-------------------------------------------------------------------------- - C_M = RG_Matrix_m(C); - D_M = RG_Matrix_m(D); + C_M = RG_Matrix_M(C); + D_M = RG_Matrix_M(D); ASSERT_GrB_Matrices_EQ(C_M, D_M); diff --git a/tests/unit/test_rg_matrix_iter.c b/tests/unit/test_rg_matrix_iter.c index 3ea6fd260..d07d42590 100644 --- a/tests/unit/test_rg_matrix_iter.c +++ b/tests/unit/test_rg_matrix_iter.c @@ -153,7 +153,7 @@ void test_RGMatrixTupleIter_next_sparse() { // check M is sparse //-------------------------------------------------------------------------- - GrB_Matrix M = RG_Matrix_m(A); + GrB_Matrix M = RG_Matrix_M(A); int sparsity; GxB_Matrix_Option_get(M, GxB_SPARSITY_STATUS, &sparsity); From 4cf3f0d93559964c579fd7edb8e0e78b4f4ec53b Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Tue, 16 Apr 2024 14:57:52 +0300 Subject: [PATCH 10/57] rename RG to Delta --- deps/FalkorDB-rs | 2 +- src/algorithms/all_neighbors.c | 28 +- src/algorithms/all_neighbors.h | 32 +- src/arithmetic/algebraic_expression.h | 18 +- .../algebraic_expression.c | 10 +- .../algebraic_expression_add.c | 28 +- .../algebraic_expression_debug.c | 4 +- .../algebraic_expression_eval.c | 20 +- .../algebraic_expression_mul.c | 14 +- src/arithmetic/algebraic_expression/utils.c | 6 +- src/arithmetic/entity_funcs/entity_funcs.c | 4 +- src/arithmetic/path_funcs/path_funcs.c | 8 +- src/configuration/config.c | 10 +- src/configuration/config.h | 2 +- src/constraint/constraint.c | 28 +- .../ops/op_cond_var_len_traverse.h | 2 +- .../ops/op_conditional_traverse.c | 20 +- .../ops/op_conditional_traverse.h | 22 +- src/execution_plan/ops/op_expand_into.c | 14 +- src/execution_plan/ops/op_expand_into.h | 4 +- .../ops/op_node_by_label_scan.c | 14 +- .../ops/op_node_by_label_scan.h | 12 +- .../delta_matrix.h} | 116 ++-- src/graph/delta_matrix/delta_matrix_iter.h | 81 +++ src/graph/graph.c | 310 +++++------ src/graph/graph.h | 34 +- src/graph/graph_delete_nodes.c | 32 +- src/graph/graph_hub.c | 2 +- src/graph/rg_matrix/rg_matrix_iter.h | 81 --- src/index/index_construct.c | 54 +- src/index/index_edge.c | 2 +- src/index/index_node.c | 2 +- src/procedures/proc_bfs.c | 4 +- src/procedures/proc_pagerank.c | 6 +- src/serializers/encode_context.c | 4 +- src/serializers/encode_context.h | 6 +- .../encoder/v14/encode_graph_entities.c | 28 +- src/serializers/graph_extensions.c | 48 +- tests/flow/test_graph_deletion.py | 2 +- tests/unit/test_algebraic_expression.c | 208 ++++---- .../{test_rg_matrix.c => test_delta_matrix.c} | 498 +++++++++--------- tests/unit/test_delta_matrix_iter.c | 393 ++++++++++++++ tests/unit/test_graph.c | 22 +- tests/unit/test_rg_matrix_iter.c | 393 -------------- 44 files changed, 1314 insertions(+), 1314 deletions(-) rename src/graph/{rg_matrix/rg_matrix.h => delta_matrix/delta_matrix.h} (61%) create mode 100644 src/graph/delta_matrix/delta_matrix_iter.h delete mode 100644 src/graph/rg_matrix/rg_matrix_iter.h rename tests/unit/{test_rg_matrix.c => test_delta_matrix.c} (61%) create mode 100644 tests/unit/test_delta_matrix_iter.c delete mode 100644 tests/unit/test_rg_matrix_iter.c diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index f8fecc1be..f93be5173 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit f8fecc1bea65147dc317ce6756f9c6e9136f2388 +Subproject commit f93be5173f6dc7cde35f57745a3f1089b473bab9 diff --git a/src/algorithms/all_neighbors.c b/src/algorithms/all_neighbors.c index 4d71bfcac..ac99df9bb 100644 --- a/src/algorithms/all_neighbors.c +++ b/src/algorithms/all_neighbors.c @@ -16,11 +16,11 @@ static void _AllNeighborsCtx_CollectNeighbors ) { ctx->current_level++; if(ctx->current_level == array_len(ctx->levels)) { - RG_MatrixTupleIter iter = {0}; - RG_MatrixTupleIter_AttachRange(&iter, ctx->M, id, id); + Delta_MatrixTupleIter iter = {0}; + Delta_MatrixTupleIter_AttachRange(&iter, ctx->M, id, id); array_append(ctx->levels, iter); } else { - RG_MatrixTupleIter_iterate_row(&ctx->levels[ctx->current_level], id); + Delta_MatrixTupleIter_iterate_row(&ctx->levels[ctx->current_level], id); } } @@ -28,7 +28,7 @@ void AllNeighborsCtx_Reset ( AllNeighborsCtx *ctx, // all neighbors context to reset EntityID src, // source node from which to traverse - RG_Matrix M, // matrix describing connections + Delta_Matrix M, // matrix describing connections uint minLen, // minimum traversal depth uint maxLen // maximum traversal depth ) { @@ -53,15 +53,15 @@ void AllNeighborsCtx_Reset ctx->visited_nodes = HashTableCreate(&def_dt); // dummy iterator at level 0 - array_append(ctx->levels, (RG_MatrixTupleIter) {0}); + array_append(ctx->levels, (Delta_MatrixTupleIter) {0}); } AllNeighborsCtx *AllNeighborsCtx_New ( - EntityID src, // source node from which to traverse - RG_Matrix M, // matrix describing connections - uint minLen, // minimum traversal depth - uint maxLen // maximum traversal depth + EntityID src, // source node from which to traverse + Delta_Matrix M, // matrix describing connections + uint minLen, // minimum traversal depth + uint maxLen // maximum traversal depth ) { ASSERT(M != NULL); ASSERT(src != INVALID_ENTITY_ID); @@ -72,14 +72,14 @@ AllNeighborsCtx *AllNeighborsCtx_New ctx->src = src; ctx->minLen = minLen; ctx->maxLen = maxLen; - ctx->levels = array_new(RG_MatrixTupleIter, 1); + ctx->levels = array_new(Delta_MatrixTupleIter, 1); ctx->visited = array_new(EntityID, 1); ctx->first_pull = true; ctx->current_level = 0; ctx->visited_nodes = HashTableCreate(&def_dt); // Dummy iterator at level 0 - array_append(ctx->levels, (RG_MatrixTupleIter) {0}); + array_append(ctx->levels, (Delta_MatrixTupleIter) {0}); return ctx; } @@ -112,10 +112,10 @@ EntityID AllNeighborsCtx_NextNeighbor while(ctx->current_level > 0) { ASSERT(ctx->current_level < array_len(ctx->levels)); - RG_MatrixTupleIter *it = &ctx->levels[ctx->current_level]; + Delta_MatrixTupleIter *it = &ctx->levels[ctx->current_level]; GrB_Index dest_id; - GrB_Info info = RG_MatrixTupleIter_next_BOOL(it, NULL, &dest_id, NULL); + GrB_Info info = Delta_MatrixTupleIter_next_BOOL(it, NULL, &dest_id, NULL); if(info == GxB_EXHAUSTED) { // backtrack @@ -160,7 +160,7 @@ void AllNeighborsCtx_Free uint count = array_len(ctx->levels); for (uint i = 0; i < count; i++) { - RG_MatrixTupleIter_detach(ctx->levels + i); + Delta_MatrixTupleIter_detach(ctx->levels + i); } array_free(ctx->levels); array_free(ctx->visited); diff --git a/src/algorithms/all_neighbors.h b/src/algorithms/all_neighbors.h index cba920159..753fb7a51 100644 --- a/src/algorithms/all_neighbors.h +++ b/src/algorithms/all_neighbors.h @@ -8,8 +8,8 @@ #include "../../deps/GraphBLAS/Include/GraphBLAS.h" #include "../util/dict.h" -#include "../graph/rg_matrix/rg_matrix.h" -#include "../graph/rg_matrix/rg_matrix_iter.h" +#include "../graph/delta_matrix/delta_matrix.h" +#include "../graph/delta_matrix/delta_matrix_iter.h" #include "../graph/entities/node.h" // performs iterative DFS from 'src' @@ -22,32 +22,32 @@ // current path typedef struct { - EntityID src; // traverse begin here - RG_Matrix M; // adjacency matrix - uint minLen; // minimum required depth - uint maxLen; // maximum allowed depth - int current_level; // current depth - bool first_pull; // first call to Next - EntityID *visited; // visited nodes - RG_MatrixTupleIter *levels; // array of neighbors iterator - dict *visited_nodes; // visited nodes + EntityID src; // traverse begin here + Delta_Matrix M; // adjacency matrix + uint minLen; // minimum required depth + uint maxLen; // maximum allowed depth + int current_level; // current depth + bool first_pull; // first call to Next + EntityID *visited; // visited nodes + Delta_MatrixTupleIter *levels; // array of neighbors iterator + dict *visited_nodes; // visited nodes } AllNeighborsCtx; void AllNeighborsCtx_Reset ( AllNeighborsCtx *ctx, // all neighbors context to reset EntityID src, // source node from which to traverse - RG_Matrix M, // matrix describing connections + Delta_Matrix M, // matrix describing connections uint minLen, // minimum traversal depth uint maxLen // maximum traversal depth ); AllNeighborsCtx *AllNeighborsCtx_New ( - EntityID src, // source node from which to traverse - RG_Matrix M, // matrix describing connections - uint minLen, // minimum traversal depth - uint maxLen // maximum traversal depth + EntityID src, // source node from which to traverse + Delta_Matrix M, // matrix describing connections + uint minLen, // minimum traversal depth + uint maxLen // maximum traversal depth ); // produce next reachable destination node diff --git a/src/arithmetic/algebraic_expression.h b/src/arithmetic/algebraic_expression.h index 1fd4deeaa..4abde25e1 100644 --- a/src/arithmetic/algebraic_expression.h +++ b/src/arithmetic/algebraic_expression.h @@ -9,7 +9,7 @@ #include "../graph/graph.h" #include "../graph/query_graph.h" -static RG_Matrix IDENTITY_MATRIX = (RG_Matrix)0x31032017; // identity matrix +static Delta_Matrix IDENTITY_MATRIX = (Delta_Matrix)0x31032017; // identity matrix // Matrix, vector operations typedef enum { @@ -40,7 +40,7 @@ struct AlgebraicExpression { const char *dest; // alias given to operand's columns const char *edge; // alias given to operand (edge) const char *label; // label attached to matrix - RG_Matrix matrix; // matrix + Delta_Matrix matrix; // matrix } operand; struct { AL_EXP_OP op; // operation: `*`,`+`,`transpose` @@ -72,7 +72,7 @@ AlgebraicExpression *AlgebraicExpression_NewOperation // Create a new AlgebraicExpression operand node. AlgebraicExpression *AlgebraicExpression_NewOperand ( - RG_Matrix mat, // Matrix. + Delta_Matrix mat, // Matrix. bool diagonal, // Is operand a diagonal matrix? const char *src, // Operand row domain (src node). const char *dest, // Operand column domain (destination node). @@ -185,7 +185,7 @@ AlgebraicExpression *AlgebraicExpression_RemoveDest void AlgebraicExpression_MultiplyToTheLeft ( AlgebraicExpression **root, - RG_Matrix m + Delta_Matrix m ); // Multiply expression to the right by operand @@ -193,7 +193,7 @@ void AlgebraicExpression_MultiplyToTheLeft void AlgebraicExpression_MultiplyToTheRight ( AlgebraicExpression **root, - RG_Matrix m + Delta_Matrix m ); // Add expression to the left by operand @@ -201,7 +201,7 @@ void AlgebraicExpression_MultiplyToTheRight void AlgebraicExpression_AddToTheLeft ( AlgebraicExpression **root, - RG_Matrix m + Delta_Matrix m ); // Add expression to the right by operand @@ -209,7 +209,7 @@ void AlgebraicExpression_AddToTheLeft void AlgebraicExpression_AddToTheRight ( AlgebraicExpression **root, - RG_Matrix m + Delta_Matrix m ); // Transpose expression @@ -220,10 +220,10 @@ void AlgebraicExpression_Transpose ); // Evaluate expression tree. -RG_Matrix AlgebraicExpression_Eval +Delta_Matrix AlgebraicExpression_Eval ( const AlgebraicExpression *exp, // Root node - RG_Matrix res // Result output + Delta_Matrix res // Result output ); // locates operand based on row,column domain and edge or label diff --git a/src/arithmetic/algebraic_expression/algebraic_expression.c b/src/arithmetic/algebraic_expression/algebraic_expression.c index 977dfa11a..41479581d 100644 --- a/src/arithmetic/algebraic_expression/algebraic_expression.c +++ b/src/arithmetic/algebraic_expression/algebraic_expression.c @@ -171,7 +171,7 @@ AlgebraicExpression *AlgebraicExpression_NewOperation // Create a new AlgebraicExpression operand node AlgebraicExpression *AlgebraicExpression_NewOperand ( - RG_Matrix mat, // Matrix + Delta_Matrix mat, // Matrix bool diagonal, // Is operand a diagonal matrix? const char *src, // Operand row domain (src node) const char *dest, // Operand column domain (destination node) @@ -490,7 +490,7 @@ AlgebraicExpression *AlgebraicExpression_RemoveDest void AlgebraicExpression_MultiplyToTheLeft ( AlgebraicExpression **root, - RG_Matrix m + Delta_Matrix m ) { ASSERT(root && m); AlgebraicExpression *rhs = *root; @@ -508,7 +508,7 @@ void AlgebraicExpression_MultiplyToTheLeft void AlgebraicExpression_MultiplyToTheRight ( AlgebraicExpression **root, - RG_Matrix m + Delta_Matrix m ) { ASSERT(root && m); AlgebraicExpression *lhs = *root; @@ -526,7 +526,7 @@ void AlgebraicExpression_MultiplyToTheRight void AlgebraicExpression_AddToTheLeft ( AlgebraicExpression **root, - RG_Matrix m + Delta_Matrix m ) { ASSERT(root && m); AlgebraicExpression *rhs = *root; @@ -545,7 +545,7 @@ void AlgebraicExpression_AddToTheLeft void AlgebraicExpression_AddToTheRight ( AlgebraicExpression **root, - RG_Matrix m + Delta_Matrix m ) { ASSERT(root && m); AlgebraicExpression *lhs = *root; diff --git a/src/arithmetic/algebraic_expression/algebraic_expression_add.c b/src/arithmetic/algebraic_expression/algebraic_expression_add.c index d7f6e8220..22bcf3c9c 100644 --- a/src/arithmetic/algebraic_expression/algebraic_expression_add.c +++ b/src/arithmetic/algebraic_expression/algebraic_expression_add.c @@ -8,10 +8,10 @@ #include "../../query_ctx.h" #include "../algebraic_expression.h" -RG_Matrix _Eval_Add +Delta_Matrix _Eval_Add ( const AlgebraicExpression *exp, - RG_Matrix res + Delta_Matrix res ) { ASSERT(exp); ASSERT(AlgebraicExpression_ChildCount(exp) > 1); @@ -22,9 +22,9 @@ RG_Matrix _Eval_Add GrB_Index ncols; // number of columns of operand bool res_in_use = false; // can we use `res` for intermediate evaluation - RG_Matrix A = NULL; // left operand - RG_Matrix B = NULL; // right operand - RG_Matrix inter = NULL; // intermediate matrix + Delta_Matrix A = NULL; // left operand + Delta_Matrix B = NULL; // right operand + Delta_Matrix inter = NULL; // intermediate matrix // get left and right operands AlgebraicExpression *left = CHILD_AT(exp, 0); @@ -45,9 +45,9 @@ RG_Matrix _Eval_Add if(right->type == AL_OPERATION) { if(res_in_use) { // `res` is in use, create an additional matrix - RG_Matrix_nrows(&nrows, res); - RG_Matrix_ncols(&ncols, res); - info = RG_Matrix_new(&inter, GrB_BOOL, nrows, ncols, false); + Delta_Matrix_nrows(&nrows, res); + Delta_Matrix_ncols(&ncols, res); + info = Delta_Matrix_new(&inter, GrB_BOOL, nrows, ncols, false); ASSERT(info == GrB_SUCCESS); B = AlgebraicExpression_Eval(right, inter); } else { @@ -62,7 +62,7 @@ RG_Matrix _Eval_Add // perform addition //-------------------------------------------------------------------------- - info = RG_eWiseAdd(res, GxB_ANY_PAIR_BOOL, A, B); + info = Delta_eWiseAdd(res, GxB_ANY_PAIR_BOOL, A, B); ASSERT(info == GrB_SUCCESS); uint child_count = AlgebraicExpression_ChildCount(exp); @@ -76,9 +76,9 @@ RG_Matrix _Eval_Add // 'right' represents either + or * operation if(inter == NULL) { // can't use `res`, use an intermidate matrix - RG_Matrix_nrows(&nrows, res); - RG_Matrix_ncols(&ncols, res); - info = RG_Matrix_new(&inter, GrB_BOOL, nrows, ncols, false); + Delta_Matrix_nrows(&nrows, res); + Delta_Matrix_ncols(&ncols, res); + info = Delta_Matrix_new(&inter, GrB_BOOL, nrows, ncols, false); ASSERT(info == GrB_SUCCESS); } AlgebraicExpression_Eval(right, inter); @@ -86,11 +86,11 @@ RG_Matrix _Eval_Add } // perform addition - info = RG_eWiseAdd(res, GxB_ANY_PAIR_BOOL, res, B); + info = Delta_eWiseAdd(res, GxB_ANY_PAIR_BOOL, res, B); ASSERT(info == GrB_SUCCESS); } - if(inter != NULL) RG_Matrix_free(&inter); + if(inter != NULL) Delta_Matrix_free(&inter); return res; } diff --git a/src/arithmetic/algebraic_expression/algebraic_expression_debug.c b/src/arithmetic/algebraic_expression/algebraic_expression_debug.c index 93c308faa..197adb750 100644 --- a/src/arithmetic/algebraic_expression/algebraic_expression_debug.c +++ b/src/arithmetic/algebraic_expression/algebraic_expression_debug.c @@ -30,7 +30,7 @@ AlgebraicExpression *_AlgebraicExpression_FromString int len = 0; char *alias; const char *operand; - RG_Matrix m; + Delta_Matrix m; AlgebraicExpression *op; AlgebraicExpression *rhs; AlgebraicExpression *root = NULL; @@ -83,7 +83,7 @@ AlgebraicExpression *_AlgebraicExpression_FromString m = NULL; if(matrices) { - m = (RG_Matrix)raxFind(matrices, (unsigned char *)alias, strlen(alias)); + m = (Delta_Matrix)raxFind(matrices, (unsigned char *)alias, strlen(alias)); ASSERT(m != raxNotFound && "Missing matrix"); } root = AlgebraicExpression_NewOperand(m, false, alias, alias, NULL, NULL); diff --git a/src/arithmetic/algebraic_expression/algebraic_expression_eval.c b/src/arithmetic/algebraic_expression/algebraic_expression_eval.c index 12476bcc8..d1c309c0f 100644 --- a/src/arithmetic/algebraic_expression/algebraic_expression_eval.c +++ b/src/arithmetic/algebraic_expression/algebraic_expression_eval.c @@ -9,28 +9,28 @@ #include "../algebraic_expression.h" // forward declarations -RG_Matrix _AlgebraicExpression_Eval +Delta_Matrix _AlgebraicExpression_Eval ( const AlgebraicExpression *exp, - RG_Matrix res + Delta_Matrix res ); -RG_Matrix _Eval_Mul +Delta_Matrix _Eval_Mul ( const AlgebraicExpression *exp, - RG_Matrix res + Delta_Matrix res ); -RG_Matrix _Eval_Add +Delta_Matrix _Eval_Add ( const AlgebraicExpression *exp, - RG_Matrix res + Delta_Matrix res ); -RG_Matrix _AlgebraicExpression_Eval +Delta_Matrix _AlgebraicExpression_Eval ( const AlgebraicExpression *exp, - RG_Matrix res + Delta_Matrix res ) { ASSERT(exp); @@ -64,10 +64,10 @@ RG_Matrix _AlgebraicExpression_Eval return res; } -RG_Matrix AlgebraicExpression_Eval +Delta_Matrix AlgebraicExpression_Eval ( const AlgebraicExpression *exp, - RG_Matrix res + Delta_Matrix res ) { ASSERT(exp != NULL); return _AlgebraicExpression_Eval(exp, res); diff --git a/src/arithmetic/algebraic_expression/algebraic_expression_mul.c b/src/arithmetic/algebraic_expression/algebraic_expression_mul.c index 6de8e6fb3..fece5a380 100644 --- a/src/arithmetic/algebraic_expression/algebraic_expression_mul.c +++ b/src/arithmetic/algebraic_expression/algebraic_expression_mul.c @@ -8,10 +8,10 @@ #include "../../query_ctx.h" #include "../algebraic_expression.h" -RG_Matrix _Eval_Mul +Delta_Matrix _Eval_Mul ( const AlgebraicExpression *exp, - RG_Matrix res + Delta_Matrix res ) { //-------------------------------------------------------------------------- // validate expression @@ -22,13 +22,13 @@ RG_Matrix _Eval_Mul ASSERT(AlgebraicExpression_OperationCount(exp, AL_EXP_MUL) == 1) ; GrB_Info info ; - RG_Matrix M ; // current operand + Delta_Matrix M ; // current operand GrB_Index nvals ; // NNZ in res AlgebraicExpression *c ; // current child node UNUSED(info) ; - RG_Matrix A = NULL ; + Delta_Matrix A = NULL ; bool res_modified = false ; GrB_Semiring semiring = GxB_ANY_PAIR_BOOL ; uint child_count = AlgebraicExpression_ChildCount(exp) ; @@ -46,19 +46,19 @@ RG_Matrix _Eval_Mul } // both A and M are valid matrices, perform multiplication - info = RG_mxm(res, semiring, A, M) ; + info = Delta_mxm(res, semiring, A, M) ; res_modified = true ; // setup for next iteration A = res ; // exit early if 'res' is empty 0 * A = 0 - info = RG_Matrix_nvals(&nvals, res); + info = Delta_Matrix_nvals(&nvals, res); ASSERT(info == GrB_SUCCESS) ; if(nvals == 0) break ; } if(!res_modified) { - info = RG_Matrix_copy(res, A) ; + info = Delta_Matrix_copy(res, A) ; ASSERT(info == GrB_SUCCESS) ; } diff --git a/src/arithmetic/algebraic_expression/utils.c b/src/arithmetic/algebraic_expression/utils.c index 7e19cc9ec..a9fbf20bf 100644 --- a/src/arithmetic/algebraic_expression/utils.c +++ b/src/arithmetic/algebraic_expression/utils.c @@ -203,7 +203,7 @@ void _AlgebraicExpression_FreeOperand ) { ASSERT(node && node->type == AL_OPERAND); if(node->operand.bfree) { - RG_Matrix_free(&node->operand.matrix); + Delta_Matrix_free(&node->operand.matrix); } } @@ -257,7 +257,7 @@ static void _AlgebraicExpression_PopulateOperand(AlgebraicExpression *operand, Graph *g = gc->g; Schema *s = NULL; - RG_Matrix m = NULL; + Delta_Matrix m = NULL; const char *label = operand->operand.label; if(label == NULL) { @@ -298,7 +298,7 @@ static void _AlgebraicExpression_PopulateTransposedOperand(AlgebraicExpression * if(operand->operand.matrix != NULL) return; Schema *s = NULL; - RG_Matrix m = NULL; + Delta_Matrix m = NULL; const char *label = operand->operand.label; if(label == NULL) { diff --git a/src/arithmetic/entity_funcs/entity_funcs.c b/src/arithmetic/entity_funcs/entity_funcs.c index 247d750c8..21f6563fa 100644 --- a/src/arithmetic/entity_funcs/entity_funcs.c +++ b/src/arithmetic/entity_funcs/entity_funcs.c @@ -75,10 +75,10 @@ SIValue AR_HAS_LABELS(SIValue *argv, int argc, void *private_data) { // validate label is set bool x; - RG_Matrix M = Graph_GetLabelMatrix(g, Schema_GetID(s)); + Delta_Matrix M = Graph_GetLabelMatrix(g, Schema_GetID(s)); ASSERT(M != NULL); - if(RG_Matrix_extractElement_BOOL(&x, M, id, id) == GrB_NO_VALUE) { + if(Delta_Matrix_extractElement_BOOL(&x, M, id, id) == GrB_NO_VALUE) { res = false; break; } diff --git a/src/arithmetic/path_funcs/path_funcs.c b/src/arithmetic/path_funcs/path_funcs.c index 96752d987..d7d7f4c4e 100644 --- a/src/arithmetic/path_funcs/path_funcs.c +++ b/src/arithmetic/path_funcs/path_funcs.c @@ -162,18 +162,18 @@ SIValue AR_SHORTEST_PATH(SIValue *argv, int argc, void *private_data) { if(ctx->reltypes == NULL) { // No edge types were specified, use the overall adjacency matrix. ctx->free_matrices = true; - res = RG_Matrix_export(&ctx->R, Graph_GetAdjacencyMatrix(gc->g, + res = Delta_Matrix_export(&ctx->R, Graph_GetAdjacencyMatrix(gc->g, false)); ASSERT(res == GrB_SUCCESS); } else if(ctx->reltype_count == 0) { // If edge types were specified but none were valid, // use the zero matrix ctx->free_matrices = true; - res = RG_Matrix_export(&ctx->R, Graph_GetZeroMatrix(gc->g)); + res = Delta_Matrix_export(&ctx->R, Graph_GetZeroMatrix(gc->g)); ASSERT(res == GrB_SUCCESS); } else if(ctx->reltype_count == 1) { ctx->free_matrices = true; - res = RG_Matrix_export(&ctx->R, Graph_GetRelationMatrix(gc->g, + res = Delta_Matrix_export(&ctx->R, Graph_GetRelationMatrix(gc->g, ctx->reltypes[0], false)); ASSERT(res == GrB_SUCCESS); } else { @@ -185,7 +185,7 @@ SIValue AR_SHORTEST_PATH(SIValue *argv, int argc, void *private_data) { for(uint i = 0; i < ctx->reltype_count; i ++) { GrB_Matrix adj; - res = RG_Matrix_export(&adj, Graph_GetRelationMatrix(gc->g, + res = Delta_Matrix_export(&adj, Graph_GetRelationMatrix(gc->g, ctx->reltypes[i], false)); ASSERT(res == GrB_SUCCESS); res = GrB_eWiseAdd(ctx->R, GrB_NULL, GrB_NULL, diff --git a/src/configuration/config.c b/src/configuration/config.c index 478c82301..ec5bb8cd9 100644 --- a/src/configuration/config.c +++ b/src/configuration/config.c @@ -49,7 +49,7 @@ // Max mem(bytes) that query/thread can utilize at any given time #define QUERY_MEM_CAPACITY "QUERY_MEM_CAPACITY" -// number of pending changed befor RG_Matrix flushed +// number of pending changed befor Delta_Matrix flushed #define DELTA_MAX_PENDING_CHANGES "DELTA_MAX_PENDING_CHANGES" // size of node creation buffer @@ -93,7 +93,7 @@ typedef struct { uint64_t max_queued_queries; // max number of queued queries int64_t query_mem_capacity; // Max mem(bytes) that query/thread can utilize at any given time uint64_t node_creation_buffer; // Number of extra node creations to buffer as margin in matrices - int64_t delta_max_pending_changes; // number of pending changed befor RG_Matrix flushed + int64_t delta_max_pending_changes; // number of pending changed befor Delta_Matrix flushed Config_on_change cb; // callback function which being called when config param changed bool cmd_info_on; // If true, the GRAPH.INFO is enabled. uint64_t effects_threshold; // replicate via effects when runtime exceeds threshold @@ -636,7 +636,7 @@ static void _Config_SetToDefaults(void) { // no limit on query memory capacity config.query_mem_capacity = QUERY_MEM_CAPACITY_UNLIMITED; - // number of pending changed befor RG_Matrix flushed + // number of pending changed befor Delta_Matrix flushed config.delta_max_pending_changes = DELTA_MAX_PENDING_CHANGES_DEFAULT; // the amount of empty space to reserve for node creations in matrices @@ -891,7 +891,7 @@ bool Config_Option_get break; //---------------------------------------------------------------------- - // number of pending changed befor RG_Matrix flushed + // number of pending changed befor Delta_Matrix flushed //---------------------------------------------------------------------- case Config_DELTA_MAX_PENDING_CHANGES: { @@ -1138,7 +1138,7 @@ bool Config_Option_set break; //---------------------------------------------------------------------- - // number of pending changed befor RG_Matrix flushed + // number of pending changed befor Delta_Matrix flushed //---------------------------------------------------------------------- case Config_DELTA_MAX_PENDING_CHANGES: { diff --git a/src/configuration/config.h b/src/configuration/config.h index 6acd599d4..b55ee5671 100644 --- a/src/configuration/config.h +++ b/src/configuration/config.h @@ -28,7 +28,7 @@ typedef enum { Config_VKEY_MAX_ENTITY_COUNT = 8, // max number of elements in vkey Config_MAX_QUEUED_QUERIES = 9, // max number of queued queries Config_QUERY_MEM_CAPACITY = 10, // max mem(bytes) that query/thread can utilize at any given time - Config_DELTA_MAX_PENDING_CHANGES = 11, // number of pending changes before RG_Matrix flushed + Config_DELTA_MAX_PENDING_CHANGES = 11, // number of pending changes before Delta_Matrix flushed Config_NODE_CREATION_BUFFER = 12, // size of buffer to maintain as margin in matrices Config_CMD_INFO = 13, // toggle on/off the GRAPH.INFO Config_CMD_INFO_MAX_QUERY_COUNT = 14, // the max number of info queries count diff --git a/src/constraint/constraint.c b/src/constraint/constraint.c index 4373c7d10..5712d25e8 100644 --- a/src/constraint/constraint.c +++ b/src/constraint/constraint.c @@ -12,7 +12,7 @@ #include "../util/thpool/pools.h" #include "../graph//graphcontext.h" #include "../graph/entities/attribute_set.h" -#include "../graph/rg_matrix/rg_matrix_iter.h" +#include "../graph/delta_matrix/delta_matrix_iter.h" #include @@ -408,7 +408,7 @@ void Constraint_EnforceNodes ASSERT(c != NULL); ASSERT(g != NULL); - RG_MatrixTupleIter it = {0}; // matrix iterator + Delta_MatrixTupleIter it = {0}; // matrix iterator bool holds = true; // constraint holds GrB_Index rowIdx = 0; // current row being scanned int enforced = 0; // #entities in current batch @@ -427,7 +427,7 @@ void Constraint_EnforceNodes break; } - const RG_Matrix m = Graph_GetLabelMatrix(g, schema_id); + const Delta_Matrix m = Graph_GetLabelMatrix(g, schema_id); ASSERT(m != NULL); // reset number of enforce nodes in batch @@ -438,7 +438,7 @@ void Constraint_EnforceNodes //---------------------------------------------------------------------- GrB_Info info; - info = RG_MatrixTupleIter_AttachRange(&it, m, rowIdx, UINT64_MAX); + info = Delta_MatrixTupleIter_AttachRange(&it, m, rowIdx, UINT64_MAX); ASSERT(info == GrB_SUCCESS); //---------------------------------------------------------------------- @@ -447,7 +447,7 @@ void Constraint_EnforceNodes EntityID id; while(enforced < batch_size && - RG_MatrixTupleIter_next_BOOL(&it, &id, NULL, NULL) == GrB_SUCCESS) + Delta_MatrixTupleIter_next_BOOL(&it, &id, NULL, NULL) == GrB_SUCCESS) { Node n; Graph_GetNode(g, id, &n); @@ -471,7 +471,7 @@ void Constraint_EnforceNodes Graph_ReleaseLock(g); // finished current batch - RG_MatrixTupleIter_detach(&it); + Delta_MatrixTupleIter_detach(&it); // continue next batch from row id+1 // this is true because we're iterating over a diagonal matrix @@ -479,7 +479,7 @@ void Constraint_EnforceNodes } } - RG_MatrixTupleIter_detach(&it); + Delta_MatrixTupleIter_detach(&it); // update constraint status ConstraintStatus status = (holds) ? CT_ACTIVE : CT_FAILED; @@ -496,7 +496,7 @@ void Constraint_EnforceEdges Graph *g ) { GrB_Info info; - RG_MatrixTupleIter it = {0}; + Delta_MatrixTupleIter it = {0}; bool holds = true; // constraint holds EntityID src_id = 0; // current processed row idx @@ -527,18 +527,18 @@ void Constraint_EnforceEdges // fetch relation matrix ASSERT(Graph_GetMatrixPolicy(g) == SYNC_POLICY_FLUSH_RESIZE); - const RG_Matrix m = Graph_GetSourceRelationMatrix(g, schema_id, false); + const Delta_Matrix m = Graph_GetSourceRelationMatrix(g, schema_id, false); ASSERT(m != NULL); //---------------------------------------------------------------------- // resume scanning from previous row/col indices //---------------------------------------------------------------------- - info = RG_MatrixTupleIter_AttachRange(&it, m, src_id, UINT64_MAX); + info = Delta_MatrixTupleIter_AttachRange(&it, m, src_id, UINT64_MAX); ASSERT(info == GrB_SUCCESS); // skip previously enforced edges - while((info = RG_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, + while((info = Delta_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, NULL)) == GrB_SUCCESS && src_id == prev_src_id && edge_id != prev_edge_id); @@ -566,7 +566,7 @@ void Constraint_EnforceEdges } enforced++; // single/multi edge are counted similarly } while(enforced < batch_size && - RG_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, NULL) + Delta_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, NULL) == GrB_SUCCESS && holds); //---------------------------------------------------------------------- @@ -580,11 +580,11 @@ void Constraint_EnforceEdges // finished current batch // release read lock Graph_ReleaseLock(g); - RG_MatrixTupleIter_detach(&it); + Delta_MatrixTupleIter_detach(&it); } } - RG_MatrixTupleIter_detach(&it); + Delta_MatrixTupleIter_detach(&it); // update constraint status ConstraintStatus status = (holds) ? CT_ACTIVE : CT_FAILED; diff --git a/src/execution_plan/ops/op_cond_var_len_traverse.h b/src/execution_plan/ops/op_cond_var_len_traverse.h index 0515f66ea..8d0c783d7 100644 --- a/src/execution_plan/ops/op_cond_var_len_traverse.h +++ b/src/execution_plan/ops/op_cond_var_len_traverse.h @@ -17,7 +17,7 @@ typedef struct { OpBase op; Graph *g; Record r; - RG_Matrix M; /* Traversed matrix if using the SimpleConsume routine. */ + Delta_Matrix M; /* Traversed matrix if using the SimpleConsume routine. */ int edgesIdx; /* Edges set by operation. */ int srcNodeIdx; /* Node set by operation. */ int destNodeIdx; /* Node set by operation. */ diff --git a/src/execution_plan/ops/op_conditional_traverse.c b/src/execution_plan/ops/op_conditional_traverse.c index 80907da8a..417e72afd 100644 --- a/src/execution_plan/ops/op_conditional_traverse.c +++ b/src/execution_plan/ops/op_conditional_traverse.c @@ -25,7 +25,7 @@ static void CondTraverseToString(const OpBase *ctx, sds *buf) { } static void _populate_filter_matrix(OpCondTraverse *op) { - GrB_Matrix FM = RG_Matrix_M(op->F); + GrB_Matrix FM = Delta_Matrix_M(op->F); // clear filter matrix GrB_Matrix_clear(FM); @@ -51,8 +51,8 @@ void _traverse(OpCondTraverse *op) { if(op->F == NULL) { // create both filter and result matrices size_t required_dim = Graph_RequiredMatrixDim(op->graph); - RG_Matrix_new(&op->M, GrB_BOOL, op->record_cap, required_dim, false); - RG_Matrix_new(&op->F, GrB_BOOL, op->record_cap, required_dim, false); + Delta_Matrix_new(&op->M, GrB_BOOL, op->record_cap, required_dim, false); + Delta_Matrix_new(&op->F, GrB_BOOL, op->record_cap, required_dim, false); // prepend filter matrix to algebraic expression as the leftmost operand AlgebraicExpression_MultiplyToTheLeft(&op->ae, op->F); @@ -67,7 +67,7 @@ void _traverse(OpCondTraverse *op) { // evaluate expression AlgebraicExpression_Eval(op->ae, op->M); - RG_MatrixTupleIter_attach(&op->iter, op->M); + Delta_MatrixTupleIter_attach(&op->iter, op->M); } OpBase *NewCondTraverseOp @@ -142,7 +142,7 @@ static Record CondTraverseConsume(OpBase *opBase) { NodeID dest_id = INVALID_ENTITY_ID; while(true) { - GrB_Info info = RG_MatrixTupleIter_next_BOOL(&op->iter, &src_id, &dest_id, NULL); + GrB_Info info = Delta_MatrixTupleIter_next_BOOL(&op->iter, &src_id, &dest_id, NULL); // Managed to get a tuple, break. if(info == GrB_SUCCESS) break; @@ -209,10 +209,10 @@ static OpResult CondTraverseReset(OpBase *ctx) { if(op->edge_ctx) EdgeTraverseCtx_Reset(op->edge_ctx); - GrB_Info info = RG_MatrixTupleIter_detach(&op->iter); + GrB_Info info = Delta_MatrixTupleIter_detach(&op->iter); ASSERT(info == GrB_SUCCESS); - if(op->F != NULL) RG_Matrix_clear(op->F); + if(op->F != NULL) Delta_Matrix_clear(op->F); return OP_OK; } @@ -226,16 +226,16 @@ static inline OpBase *CondTraverseClone(const ExecutionPlan *plan, const OpBase static void CondTraverseFree(OpBase *ctx) { OpCondTraverse *op = (OpCondTraverse *)ctx; - GrB_Info info = RG_MatrixTupleIter_detach(&op->iter); + GrB_Info info = Delta_MatrixTupleIter_detach(&op->iter); ASSERT(info == GrB_SUCCESS); if(op->F != NULL) { - RG_Matrix_free(&op->F); + Delta_Matrix_free(&op->F); op->F = NULL; } if(op->M != NULL) { - RG_Matrix_free(&op->M); + Delta_Matrix_free(&op->M); op->M = NULL; } diff --git a/src/execution_plan/ops/op_conditional_traverse.h b/src/execution_plan/ops/op_conditional_traverse.h index b1e9edcfe..b03412ac4 100644 --- a/src/execution_plan/ops/op_conditional_traverse.h +++ b/src/execution_plan/ops/op_conditional_traverse.h @@ -9,7 +9,7 @@ #include "op.h" #include "../execution_plan.h" #include "shared/traverse_functions.h" -#include "../../graph/rg_matrix/rg_matrix_iter.h" +#include "../../graph/delta_matrix/delta_matrix_iter.h" #include "../../arithmetic/algebraic_expression.h" #include "../../../deps/GraphBLAS/Include/GraphBLAS.h" @@ -18,16 +18,16 @@ typedef struct { OpBase op; Graph *graph; AlgebraicExpression *ae; - RG_Matrix F; // Filter matrix. - RG_Matrix M; // Algebraic expression result. - EdgeTraverseCtx *edge_ctx; // Edge collection data if the edge needs to be set. - RG_MatrixTupleIter iter; // Iterator over M. - int srcNodeIdx; // Source node index into record. - int destNodeIdx; // Destination node index into record. - uint64_t record_count; // Number of held records. - uint64_t record_cap; // Max number of records to process. - Record *records; // Array of records. - Record r; // Currently selected record. + Delta_Matrix F; // Filter matrix. + Delta_Matrix M; // Algebraic expression result. + EdgeTraverseCtx *edge_ctx; // Edge collection data if the edge needs to be set. + Delta_MatrixTupleIter iter; // Iterator over M. + int srcNodeIdx; // Source node index into record. + int destNodeIdx; // Destination node index into record. + uint64_t record_count; // Number of held records. + uint64_t record_cap; // Max number of records to process. + Record *records; // Array of records. + Record r; // Currently selected record. } OpCondTraverse; /* Creates a new Traverse operation */ diff --git a/src/execution_plan/ops/op_expand_into.c b/src/execution_plan/ops/op_expand_into.c index a6a38fa07..17146f2b7 100644 --- a/src/execution_plan/ops/op_expand_into.c +++ b/src/execution_plan/ops/op_expand_into.c @@ -34,7 +34,7 @@ static void _populate_filter_matrix ( OpExpandInto *op ) { - GrB_Matrix FM = RG_Matrix_M(op->F); + GrB_Matrix FM = Delta_Matrix_M(op->F); // clear filter matrix GrB_Matrix_clear(FM); @@ -65,8 +65,8 @@ static void _traverse if(op->F == NULL) { // create both filter matrix F and result matrix M size_t required_dim = Graph_RequiredMatrixDim(op->graph); - RG_Matrix_new(&op->M, GrB_BOOL, op->record_cap, required_dim, false); - RG_Matrix_new(&op->F, GrB_BOOL, op->record_cap, required_dim, false); + Delta_Matrix_new(&op->M, GrB_BOOL, op->record_cap, required_dim, false); + Delta_Matrix_new(&op->F, GrB_BOOL, op->record_cap, required_dim, false); // prepend the filter matrix to algebraic expression // as the leftmost operand @@ -226,9 +226,9 @@ static Record _handoff NodeID col = ENTITY_GET_ID(destNode); // TODO: in the case of multiple operands ()-[:A]->()-[:B]->() // M is the result of F*A*B, in which case we can switch from - // M being a RG_Matrix to a GrB_Matrix, making the extract element + // M being a Delta_Matrix to a GrB_Matrix, making the extract element // operation a bit cheaper to compute - GrB_Info res = RG_Matrix_extractElement_BOOL(&x, op->M, row, col); + GrB_Info res = Delta_Matrix_extractElement_BOOL(&x, op->M, row, col); // src is not connected to dest, free the current record and continue if(res != GrB_SUCCESS) { @@ -354,14 +354,14 @@ static void ExpandIntoFree OpExpandInto *op = (OpExpandInto *)ctx; if(op->F != NULL) { - RG_Matrix_free(&op->F); + Delta_Matrix_free(&op->F); op->F = NULL; } if(op->ae != NULL) { // M was allocated by us if(op->M != NULL && !op->single_operand) { - RG_Matrix_free(&op->M); + Delta_Matrix_free(&op->M); op->M = NULL; } diff --git a/src/execution_plan/ops/op_expand_into.h b/src/execution_plan/ops/op_expand_into.h index 558789c8d..10d18683e 100644 --- a/src/execution_plan/ops/op_expand_into.h +++ b/src/execution_plan/ops/op_expand_into.h @@ -17,8 +17,8 @@ typedef struct { OpBase op; Graph *graph; AlgebraicExpression *ae; - RG_Matrix F; // filter matrix - RG_Matrix M; // algebraic expression result + Delta_Matrix F; // filter matrix + Delta_Matrix M; // algebraic expression result EdgeTraverseCtx *edge_ctx; // edge collection data if the edge needs to be set int srcNodeIdx; // source node index into record int destNodeIdx; // destination node index into record diff --git a/src/execution_plan/ops/op_node_by_label_scan.c b/src/execution_plan/ops/op_node_by_label_scan.c index 37c4f3e1a..423dd4e92 100644 --- a/src/execution_plan/ops/op_node_by_label_scan.c +++ b/src/execution_plan/ops/op_node_by_label_scan.c @@ -84,8 +84,8 @@ static GrB_Info _ConstructIterator NodeID maxId; GrB_Index nrows; - RG_Matrix L = Graph_GetLabelMatrix(QueryCtx_GetGraph(), op->n->label_id); - info = RG_Matrix_nrows(&nrows, L); + Delta_Matrix L = Graph_GetLabelMatrix(QueryCtx_GetGraph(), op->n->label_id); + info = Delta_Matrix_nrows(&nrows, L); ASSERT(info == GrB_SUCCESS); // make sure range is within matrix bounds @@ -100,7 +100,7 @@ static GrB_Info _ConstructIterator if(op->id_range->include_max) maxId = op->id_range->max; else maxId = op->id_range->max - 1; - info = RG_MatrixTupleIter_AttachRange(&op->iter, L, minId, maxId); + info = Delta_MatrixTupleIter_AttachRange(&op->iter, L, minId, maxId); ASSERT(info == GrB_SUCCESS); return info; @@ -163,7 +163,7 @@ static Record NodeByLabelScanConsumeFromChild // try to get new nodeID GrB_Index nodeId; - GrB_Info info = RG_MatrixTupleIter_next_BOOL(&op->iter, &nodeId, NULL, NULL); + GrB_Info info = Delta_MatrixTupleIter_next_BOOL(&op->iter, &nodeId, NULL, NULL); while(info == GrB_NULL_POINTER || op->child_record == NULL || info == GxB_EXHAUSTED) { // try to get a new record if(op->child_record != NULL) { @@ -189,7 +189,7 @@ static Record NodeByLabelScanConsumeFromChild } // try to get new NodeID - info = RG_MatrixTupleIter_next_BOOL(&op->iter, &nodeId, NULL, NULL); + info = Delta_MatrixTupleIter_next_BOOL(&op->iter, &nodeId, NULL, NULL); } // we've got a record and NodeID @@ -205,7 +205,7 @@ static Record NodeByLabelScanConsume(OpBase *opBase) { NodeByLabelScan *op = (NodeByLabelScan *)opBase; GrB_Index nodeId; - GrB_Info info = RG_MatrixTupleIter_next_BOOL(&op->iter, &nodeId, NULL, NULL); + GrB_Info info = Delta_MatrixTupleIter_next_BOOL(&op->iter, &nodeId, NULL, NULL); if(info == GxB_EXHAUSTED) return NULL; ASSERT(info == GrB_SUCCESS); @@ -252,7 +252,7 @@ static OpBase *NodeByLabelScanClone(const ExecutionPlan *plan, const OpBase *opB static void NodeByLabelScanFree(OpBase *op) { NodeByLabelScan *nodeByLabelScan = (NodeByLabelScan *)op; - GrB_Info info = RG_MatrixTupleIter_detach(&(nodeByLabelScan->iter)); + GrB_Info info = Delta_MatrixTupleIter_detach(&(nodeByLabelScan->iter)); ASSERT(info == GrB_SUCCESS); if(nodeByLabelScan->child_record) { diff --git a/src/execution_plan/ops/op_node_by_label_scan.h b/src/execution_plan/ops/op_node_by_label_scan.h index 13147caa8..f964b04cc 100644 --- a/src/execution_plan/ops/op_node_by_label_scan.h +++ b/src/execution_plan/ops/op_node_by_label_scan.h @@ -13,18 +13,18 @@ #include "../../graph/entities/node.h" #include "../../../deps/GraphBLAS/Include/GraphBLAS.h" #include "../../util/range/unsigned_range.h" -#include "../../graph/rg_matrix/rg_matrix_iter.h" +#include "../../graph/delta_matrix/delta_matrix_iter.h" /* NodeByLabelScan, scans entire label. */ typedef struct { OpBase op; Graph *g; - NodeScanCtx *n; // Label data of node being scanned - unsigned int nodeRecIdx; // Node position within record - UnsignedRange *id_range; // ID range to iterate over - RG_MatrixTupleIter iter; // Iterator over label matrix - Record child_record; // The Record this op acts on if it is not a tap + NodeScanCtx *n; // Label data of node being scanned + unsigned int nodeRecIdx; // Node position within record + UnsignedRange *id_range; // ID range to iterate over + Delta_MatrixTupleIter iter; // Iterator over label matrix + Record child_record; // The Record this op acts on if it is not a tap } NodeByLabelScan; /* Creates a new NodeByLabelScan operation */ diff --git a/src/graph/rg_matrix/rg_matrix.h b/src/graph/delta_matrix/delta_matrix.h similarity index 61% rename from src/graph/rg_matrix/rg_matrix.h rename to src/graph/delta_matrix/delta_matrix.h index e168f1156..09a5038af 100644 --- a/src/graph/rg_matrix/rg_matrix.h +++ b/src/graph/delta_matrix/delta_matrix.h @@ -10,9 +10,9 @@ #include -// forward declaration of RG_Matrix type -typedef struct _RG_Matrix _RG_Matrix; -typedef _RG_Matrix *RG_Matrix; +// forward declaration of Delta_Matrix type +typedef struct _Delta_Matrix _Delta_Matrix; +typedef _Delta_Matrix *Delta_Matrix; //------------------------------------------------------------------------------ @@ -97,9 +97,9 @@ typedef _RG_Matrix *RG_Matrix; // //------------------------------------------------------------------------------ -GrB_Info RG_Matrix_new +GrB_Info Delta_Matrix_new ( - RG_Matrix *A, // handle of matrix to create + Delta_Matrix *A, // handle of matrix to create GrB_Type type, // type of matrix to create GrB_Index nrows, // matrix dimension is nrows-by-ncols GrB_Index ncols, @@ -107,148 +107,148 @@ GrB_Info RG_Matrix_new ); // returns transposed matrix of C -RG_Matrix RG_Matrix_getTranspose +Delta_Matrix Delta_Matrix_getTranspose ( - const RG_Matrix C + const Delta_Matrix C ); -bool RG_Matrix_isDirty +bool Delta_Matrix_isDirty ( - const RG_Matrix C + const Delta_Matrix C ); -GrB_Matrix RG_Matrix_M +GrB_Matrix Delta_Matrix_M ( - const RG_Matrix C + const Delta_Matrix C ); -GrB_Matrix RG_Matrix_DP +GrB_Matrix Delta_Matrix_DP ( - const RG_Matrix C + const Delta_Matrix C ); -GrB_Matrix RG_Matrix_DM +GrB_Matrix Delta_Matrix_DM ( - const RG_Matrix C + const Delta_Matrix C ); -GrB_Info RG_Matrix_nrows +GrB_Info Delta_Matrix_nrows ( GrB_Index *nrows, - const RG_Matrix C + const Delta_Matrix C ); -GrB_Info RG_Matrix_ncols +GrB_Info Delta_Matrix_ncols ( GrB_Index *ncols, - const RG_Matrix C + const Delta_Matrix C ); -GrB_Info RG_Matrix_nvals // get the number of entries in a matrix +GrB_Info Delta_Matrix_nvals // get the number of entries in a matrix ( GrB_Index *nvals, // matrix has nvals entries - const RG_Matrix A // matrix to query + const Delta_Matrix A // matrix to query ); -GrB_Info RG_Matrix_resize // change the size of a matrix +GrB_Info Delta_Matrix_resize // change the size of a matrix ( - RG_Matrix C, // matrix to modify + Delta_Matrix C, // matrix to modify GrB_Index nrows_new, // new number of rows in matrix GrB_Index ncols_new // new number of columns in matrix ); -GrB_Info RG_Matrix_setElement_BOOL // C (i,j) = x +GrB_Info Delta_Matrix_setElement_BOOL // C (i,j) = x ( - RG_Matrix C, // matrix to modify + Delta_Matrix C, // matrix to modify GrB_Index i, // row index GrB_Index j // column index ); -GrB_Info RG_Matrix_extractElement_BOOL // x = A(i,j) +GrB_Info Delta_Matrix_extractElement_BOOL // x = A(i,j) ( bool *x, // extracted scalar - const RG_Matrix A, // matrix to extract a scalar from + const Delta_Matrix A, // matrix to extract a scalar from GrB_Index i, // row index GrB_Index j // column index ) ; -GrB_Info RG_Matrix_extract_row +GrB_Info Delta_Matrix_extract_row ( - const RG_Matrix A, // matrix to extract a vector from + const Delta_Matrix A, // matrix to extract a vector from GrB_Vector v, // vector to extract GrB_Index i // row index ) ; // remove entry at position C[i,j] -GrB_Info RG_Matrix_removeElement_BOOL +GrB_Info Delta_Matrix_removeElement_BOOL ( - RG_Matrix C, // matrix to remove entry from + Delta_Matrix C, // matrix to remove entry from GrB_Index i, // row index GrB_Index j // column index ); -GrB_Info RG_Matrix_removeElements +GrB_Info Delta_Matrix_removeElements ( - RG_Matrix C, // matrix to remove entry from + Delta_Matrix C, // matrix to remove entry from GrB_Matrix m // elements to remove ); -GrB_Info RG_mxm // C = A * B +GrB_Info Delta_mxm // C = A * B ( - RG_Matrix C, // input/output matrix for results - const GrB_Semiring semiring, // defines '+' and '*' for A*B - const RG_Matrix A, // first input: matrix A - const RG_Matrix B // second input: matrix B + Delta_Matrix C, // input/output matrix for results + const GrB_Semiring semiring, // defines '+' and '*' for A*B + const Delta_Matrix A, // first input: matrix A + const Delta_Matrix B // second input: matrix B ); -GrB_Info RG_eWiseAdd // C = A + B +GrB_Info Delta_eWiseAdd // C = A + B ( - RG_Matrix C, // input/output matrix for results - const GrB_Semiring semiring, // defines '+' for T=A+B - const RG_Matrix A, // first input: matrix A - const RG_Matrix B // second input: matrix B + Delta_Matrix C, // input/output matrix for results + const GrB_Semiring semiring, // defines '+' for T=A+B + const Delta_Matrix A, // first input: matrix A + const Delta_Matrix B // second input: matrix B ); -GrB_Info RG_Matrix_clear // clear a matrix of all entries; +GrB_Info Delta_Matrix_clear // clear a matrix of all entries; ( // type and dimensions remain unchanged - RG_Matrix A // matrix to clear + Delta_Matrix A // matrix to clear ); -GrB_Info RG_Matrix_copy // copy matrix A to matrix C +GrB_Info Delta_Matrix_copy // copy matrix A to matrix C ( - RG_Matrix C, // output matrix - const RG_Matrix A // input matrix + Delta_Matrix C, // output matrix + const Delta_Matrix A // input matrix ); // get matrix C without writing to internal matrix -GrB_Info RG_Matrix_export +GrB_Info Delta_Matrix_export ( GrB_Matrix *A, - RG_Matrix C + Delta_Matrix C ); // checks to see if matrix has pending operations -GrB_Info RG_Matrix_pending +GrB_Info Delta_Matrix_pending ( - const RG_Matrix C, // matrix to query + const Delta_Matrix C, // matrix to query bool *pending // are there any pending operations ); -GrB_Info RG_Matrix_wait +GrB_Info Delta_Matrix_wait ( - RG_Matrix C, + Delta_Matrix C, bool force_sync ); -void RG_Matrix_synchronize +void Delta_Matrix_synchronize ( - RG_Matrix C, + Delta_Matrix C, GrB_Index nrows, GrB_Index ncols ); -void RG_Matrix_free +void Delta_Matrix_free ( - RG_Matrix *C + Delta_Matrix *C ); diff --git a/src/graph/delta_matrix/delta_matrix_iter.h b/src/graph/delta_matrix/delta_matrix_iter.h new file mode 100644 index 000000000..734b6854e --- /dev/null +++ b/src/graph/delta_matrix/delta_matrix_iter.h @@ -0,0 +1,81 @@ +/* + * Copyright Redis Ltd. 2018 - present + * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or + * the Server Side Public License v1 (SSPLv1). + */ + +#pragma once + +#include +#include "delta_matrix.h" +#include "GraphBLAS.h" + +#define RG_ITER_MIN_ROW 0 +#define RG_ITER_MAX_ROW ULLONG_MAX + +// TuplesIter maintains information required +// to iterate over a Delta_Matrix +struct Opaque_Delta_MatrixTupleIter +{ + char _private[296]; +}; + +typedef struct Opaque_Delta_MatrixTupleIter Delta_MatrixTupleIter ; + +// attach iterator to matrix +GrB_Info Delta_MatrixTupleIter_attach +( + Delta_MatrixTupleIter *iter, // iterator to update + const Delta_Matrix A // matrix to scan +); + +// attach iterator to matrix governing the specified range +GrB_Info Delta_MatrixTupleIter_AttachRange +( + Delta_MatrixTupleIter *iter, // iterator to update + const Delta_Matrix A, // matrix to scan + GrB_Index min_row, // minimum row for iteration + GrB_Index max_row // maximum row for iteration +); + +// free iterator internals, keeping the iterator intact +GrB_Info Delta_MatrixTupleIter_detach +( + Delta_MatrixTupleIter *iter // iterator to free +); + +// returns true if iterator is attached to given matrix false otherwise +bool Delta_MatrixTupleIter_is_attached +( + const Delta_MatrixTupleIter *iter, // iterator to check + const Delta_Matrix M // matrix attached to +); + +GrB_Info Delta_MatrixTupleIter_iterate_row +( + Delta_MatrixTupleIter *iter, // iterator to use + GrB_Index rowIdx // row to iterate +); + +GrB_Info Delta_MatrixTupleIter_iterate_range +( + Delta_MatrixTupleIter *iter, // iterator to use + GrB_Index startRowIdx, // row index to start with + GrB_Index endRowIdx // row index to finish with +); + +// advance iterator +GrB_Info Delta_MatrixTupleIter_next_BOOL +( + Delta_MatrixTupleIter *iter, // iterator to consume + GrB_Index *row, // optional output row index + GrB_Index *col, // optional output column index + bool *val // optional value at A[row, col] +); + +// reset iterator +GrB_Info Delta_MatrixTupleIter_reset +( + Delta_MatrixTupleIter *iter // iterator to reset +); + diff --git a/src/graph/graph.c b/src/graph/graph.c index bca6bc57f..8b847e7d1 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -8,7 +8,7 @@ #include "graph.h" #include "../util/arr.h" #include "../util/rmalloc.h" -#include "rg_matrix/rg_matrix_iter.h" +#include "delta_matrix/delta_matrix_iter.h" #include "../util/datablock/oo_datablock.h" //------------------------------------------------------------------------------ @@ -106,15 +106,15 @@ void _Graph_GetEdgesConnectingNodes ASSERT(dest < Graph_RequiredMatrixDim(g)); // relation map, maps (src, dest, r) to edge IDs. - RG_Matrix M = Graph_GetRelationMatrix(g, r, false); - GrB_Info res = RG_Matrix_extractElement_BOOL(NULL, M, src, dest); + Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); + GrB_Info res = Delta_Matrix_extractElement_BOOL(NULL, M, src, dest); // no entry at [dest, src], src is not connected to dest with relation R if(res == GrB_NO_VALUE) return; Edge e = {.src_id = src, .dest_id = dest, .relationID = r}; - RG_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); - RG_Matrix T = Graph_GetTargetRelationMatrix(g, r, true); + Delta_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); + Delta_Matrix T = Graph_GetTargetRelationMatrix(g, r, true); GrB_Vector src_vec; GrB_Vector dst_vec; GrB_Info info; @@ -122,9 +122,9 @@ void _Graph_GetEdgesConnectingNodes ASSERT(info == GrB_SUCCESS); info = GrB_Vector_new(&dst_vec, GrB_BOOL, g->edges->itemCap); ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_extract_row(S, src_vec, src); + info = Delta_Matrix_extract_row(S, src_vec, src); ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_extract_row(T, dst_vec, dest); + info = Delta_Matrix_extract_row(T, dst_vec, dest); ASSERT(info == GrB_SUCCESS); info = GrB_Vector_eWiseMult_Semiring(src_vec, NULL, NULL, GxB_ANY_PAIR_BOOL, src_vec, dst_vec, GrB_DESC_R); ASSERT(info == GrB_SUCCESS); @@ -160,30 +160,30 @@ static inline AttributeSet *_Graph_GetEntity(const DataBlock *entities, EntityID void _MatrixSynchronize ( const Graph *g, - RG_Matrix m, + Delta_Matrix m, GrB_Index nrows, GrB_Index ncols ) { - RG_Matrix_synchronize(m, nrows, ncols); + Delta_Matrix_synchronize(m, nrows, ncols); } // resize matrix to node capacity void _MatrixResizeToCapacity ( const Graph *g, - RG_Matrix m, + Delta_Matrix m, GrB_Index nrows, GrB_Index ncols ) { GrB_Index n_rows; GrB_Index n_cols; - RG_Matrix_nrows(&n_rows, m); - RG_Matrix_ncols(&n_cols, m); + Delta_Matrix_nrows(&n_rows, m); + Delta_Matrix_ncols(&n_cols, m); // this policy should only be used in a thread-safe context, // so no locking is required if(n_rows < nrows || n_cols < ncols) { - GrB_Info res = RG_Matrix_resize(m, nrows, ncols); + GrB_Info res = Delta_Matrix_resize(m, nrows, ncols); ASSERT(res == GrB_SUCCESS); } } @@ -192,7 +192,7 @@ void _MatrixResizeToCapacity void _MatrixNOP ( const Graph *g, - RG_Matrix matrix, + Delta_Matrix matrix, GrB_Index nrows, GrB_Index ncols ) { @@ -259,7 +259,7 @@ void Graph_ApplyAllPending ASSERT(g != NULL); uint n = 0; - RG_Matrix M = NULL; + Delta_Matrix M = NULL; // set matrix sync policy, backup previous sync policy MATRIX_POLICY policy = Graph_SetMatrixPolicy(g, SYNC_POLICY_FLUSH_RESIZE); @@ -270,32 +270,32 @@ void Graph_ApplyAllPending // sync the adjacency matrix M = Graph_GetAdjacencyMatrix(g, false); - RG_Matrix_wait(M, force_flush); + Delta_Matrix_wait(M, force_flush); // sync node labels matrix M = Graph_GetNodeLabelMatrix(g); - RG_Matrix_wait(M, force_flush); + Delta_Matrix_wait(M, force_flush); // sync the zero matrix M = Graph_GetZeroMatrix(g); - RG_Matrix_wait(M, force_flush); + Delta_Matrix_wait(M, force_flush); // sync each label matrix n = array_len(g->labels); for(int i = 0; i < n; i ++) { M = Graph_GetLabelMatrix(g, i); - RG_Matrix_wait(M, force_flush); + Delta_Matrix_wait(M, force_flush); } // sync each relation matrix n = array_len(g->relations); for(int i = 0; i < n; i ++) { M = Graph_GetRelationMatrix(g, i, false); - RG_Matrix_wait(M, force_flush); + Delta_Matrix_wait(M, force_flush); M = Graph_GetSourceRelationMatrix(g, i, false); - RG_Matrix_wait(M, force_flush); + Delta_Matrix_wait(M, force_flush); M = Graph_GetTargetRelationMatrix(g, i, false); - RG_Matrix_wait(M, force_flush); + Delta_Matrix_wait(M, force_flush); } // restore previous matrix sync policy @@ -312,7 +312,7 @@ bool Graph_Pending UNUSED(info); uint n = 0; - RG_Matrix M = NULL; + Delta_Matrix M = NULL; bool pending = false; //-------------------------------------------------------------------------- @@ -320,7 +320,7 @@ bool Graph_Pending //-------------------------------------------------------------------------- M = g->adjacency_matrix; - info = RG_Matrix_pending(M, &pending); + info = Delta_Matrix_pending(M, &pending); ASSERT(info == GrB_SUCCESS); if(pending) { return true; @@ -331,7 +331,7 @@ bool Graph_Pending //-------------------------------------------------------------------------- M = g->node_labels; - info = RG_Matrix_pending(M, &pending); + info = Delta_Matrix_pending(M, &pending); ASSERT(info == GrB_SUCCESS); if(pending) { return true; @@ -342,7 +342,7 @@ bool Graph_Pending //-------------------------------------------------------------------------- M = g->_zero_matrix; - info = RG_Matrix_pending(M, &pending); + info = Delta_Matrix_pending(M, &pending); ASSERT(info == GrB_SUCCESS); if(pending) { return true; @@ -355,7 +355,7 @@ bool Graph_Pending n = array_len(g->labels); for(int i = 0; i < n; i ++) { M = g->labels[i]; - info = RG_Matrix_pending(M, &pending); + info = Delta_Matrix_pending(M, &pending); ASSERT(info == GrB_SUCCESS); if(pending) { return true; @@ -369,7 +369,7 @@ bool Graph_Pending n = array_len(g->relations); for(int i = 0; i < n; i ++) { M = g->relations[i].R; - info = RG_Matrix_pending(M, &pending); + info = Delta_Matrix_pending(M, &pending); ASSERT(info == GrB_SUCCESS); if(pending) { return true; @@ -394,16 +394,16 @@ Graph *Graph_New g->nodes = DataBlock_New(node_cap, node_cap, sizeof(AttributeSet), cb); g->edges = DataBlock_New(edge_cap, edge_cap, sizeof(AttributeSet), cb); - g->labels = array_new(RG_Matrix, GRAPH_DEFAULT_LABEL_CAP); + g->labels = array_new(Delta_Matrix, GRAPH_DEFAULT_LABEL_CAP); g->relations = array_new(RelationMatrices, GRAPH_DEFAULT_RELATION_TYPE_CAP); GrB_Info info; UNUSED(info); GrB_Index n = Graph_RequiredMatrixDim(g); - RG_Matrix_new(&g->node_labels, GrB_BOOL, n, n, false); - RG_Matrix_new(&g->adjacency_matrix, GrB_BOOL, n, n, true); - RG_Matrix_new(&g->_zero_matrix, GrB_BOOL, n, n, false); + Delta_Matrix_new(&g->node_labels, GrB_BOOL, n, n, false); + Delta_Matrix_new(&g->adjacency_matrix, GrB_BOOL, n, n, true); + Delta_Matrix_new(&g->_zero_matrix, GrB_BOOL, n, n, false); // initialize a read-write lock scoped to the individual graph _CreateRWLock(g); @@ -442,9 +442,9 @@ uint64_t Graph_LabeledNodeCount ) { ASSERT(g); - RG_Matrix L = Graph_GetLabelMatrix(g, label); + Delta_Matrix L = Graph_GetLabelMatrix(g, label); GrB_Index nvals; - GrB_Info info = RG_Matrix_nvals(&nvals, L); + GrB_Info info = Delta_Matrix_nvals(&nvals, L); ASSERT(info == GrB_SUCCESS); return nvals; } @@ -461,10 +461,10 @@ uint64_t Graph_RelationEdgeCount ) { ASSERT(g); - RG_Matrix S = Graph_GetSourceRelationMatrix(g, relation, false); + Delta_Matrix S = Graph_GetSourceRelationMatrix(g, relation, false); ASSERT(S != NULL); GrB_Index nvals; - GrB_Info info = RG_Matrix_nvals(&nvals, S); + GrB_Info info = Delta_Matrix_nvals(&nvals, S); ASSERT(info == GrB_SUCCESS); return nvals; } @@ -541,14 +541,14 @@ RelationID Graph_GetEdgeRelation uint n = array_len(g->relations); for(uint i = 0; i < n; i++) { EdgeID edgeId = 0; - RG_Matrix M = Graph_GetRelationMatrix(g, i, false); - RG_Matrix S = Graph_GetSourceRelationMatrix(g, i, false); - RG_Matrix T = Graph_GetTargetRelationMatrix(g, i, false); - info = RG_Matrix_extractElement_BOOL(NULL, M, src_id, dest_id); + Delta_Matrix M = Graph_GetRelationMatrix(g, i, false); + Delta_Matrix S = Graph_GetSourceRelationMatrix(g, i, false); + Delta_Matrix T = Graph_GetTargetRelationMatrix(g, i, false); + info = Delta_Matrix_extractElement_BOOL(NULL, M, src_id, dest_id); if(info != GrB_SUCCESS) continue; - info = RG_Matrix_extractElement_BOOL(NULL, S, src_id, id); + info = Delta_Matrix_extractElement_BOOL(NULL, S, src_id, id); if(info != GrB_SUCCESS) continue; - info = RG_Matrix_extractElement_BOOL(NULL, T, id, dest_id); + info = Delta_Matrix_extractElement_BOOL(NULL, T, id, dest_id); if(info != GrB_SUCCESS) continue; Edge_SetRelationID(e, i); rel = i; @@ -665,17 +665,17 @@ void Graph_LabelNode GrB_Info info; UNUSED(info); - RG_Matrix nl = Graph_GetNodeLabelMatrix(g); + Delta_Matrix nl = Graph_GetNodeLabelMatrix(g); for(uint i = 0; i < lbl_count; i++) { LabelID l = lbls[i]; - RG_Matrix L = Graph_GetLabelMatrix(g, l); + Delta_Matrix L = Graph_GetLabelMatrix(g, l); // set matrix at position [id, id] - info = RG_Matrix_setElement_BOOL(L, id, id); + info = Delta_Matrix_setElement_BOOL(L, id, id); ASSERT(info == GrB_SUCCESS); // map this label in this node's set of labels - info = RG_Matrix_setElement_BOOL(nl, id, l); + info = Delta_Matrix_setElement_BOOL(nl, id, l); ASSERT(info == GrB_SUCCESS); } } @@ -692,8 +692,8 @@ bool Graph_IsNodeLabeled bool x; // consult with labels matrix - RG_Matrix nl = Graph_GetNodeLabelMatrix(g); - GrB_Info info = RG_Matrix_extractElement_BOOL(&x, nl, id, l); + Delta_Matrix nl = Graph_GetNodeLabelMatrix(g); + GrB_Info info = Delta_Matrix_extractElement_BOOL(&x, nl, id, l); ASSERT(info == GrB_SUCCESS || info == GrB_NO_VALUE); return info == GrB_SUCCESS; } @@ -714,17 +714,17 @@ void Graph_RemoveNodeLabels GrB_Info info; UNUSED(info); - RG_Matrix nl = Graph_GetNodeLabelMatrix(g); + Delta_Matrix nl = Graph_GetNodeLabelMatrix(g); for(uint i = 0; i < lbl_count; i++) { LabelID l = lbls[i]; - RG_Matrix M = Graph_GetLabelMatrix(g, l); + Delta_Matrix M = Graph_GetLabelMatrix(g, l); // remove matrix at position [id, id] - info = RG_Matrix_removeElement_BOOL(M, id, id); + info = Delta_Matrix_removeElement_BOOL(M, id, id); ASSERT(info == GrB_SUCCESS); // remove this label from node's set of labels - info = RG_Matrix_removeElement_BOOL(nl, id, l); + info = Delta_Matrix_removeElement_BOOL(nl, id, l); ASSERT(info == GrB_SUCCESS); } } @@ -741,24 +741,24 @@ bool Graph_FormConnection GrB_Info info; UNUSED(info); - RG_Matrix M = Graph_GetRelationMatrix(g, r, false); - RG_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); - RG_Matrix T = Graph_GetTargetRelationMatrix(g, r, false); - RG_Matrix adj = Graph_GetAdjacencyMatrix(g, false); + Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); + Delta_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); + Delta_Matrix T = Graph_GetTargetRelationMatrix(g, r, false); + Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); // rows represent source nodes, columns represent destination nodes - info = RG_Matrix_setElement_BOOL(adj, src, dest); + info = Delta_Matrix_setElement_BOOL(adj, src, dest); // incase of decoding it is possible to write outside of matrix bounds // exit early if(info != GrB_SUCCESS) return false; - info = RG_Matrix_setElement_BOOL(M, src, dest); + info = Delta_Matrix_setElement_BOOL(M, src, dest); if(info != GrB_SUCCESS) return false; - info = RG_Matrix_setElement_BOOL(S, src, edge_id); + info = Delta_Matrix_setElement_BOOL(S, src, edge_id); if(info != GrB_SUCCESS) return false; - info = RG_Matrix_setElement_BOOL(T, edge_id, dest); + info = Delta_Matrix_setElement_BOOL(T, edge_id, dest); return info == GrB_SUCCESS; } @@ -807,27 +807,27 @@ void _GetOutgoingNodeEdges ASSERT(edgeType != GRAPH_NO_RELATION && edgeType != GRAPH_UNKNOWN_RELATION); GrB_Info info; - RG_MatrixTupleIter it_s = {0}; - RG_MatrixTupleIter it_t = {0}; - RG_Matrix S = NULL; - RG_Matrix T = NULL; - NodeID src_id = ENTITY_GET_ID(n); - NodeID dest_id = INVALID_ENTITY_ID; - EdgeID edge_id = INVALID_ENTITY_ID; + Delta_MatrixTupleIter it_s = {0}; + Delta_MatrixTupleIter it_t = {0}; + Delta_Matrix S = NULL; + Delta_Matrix T = NULL; + NodeID src_id = ENTITY_GET_ID(n); + NodeID dest_id = INVALID_ENTITY_ID; + EdgeID edge_id = INVALID_ENTITY_ID; UNUSED(info); S = Graph_GetSourceRelationMatrix(g, edgeType, false); T = Graph_GetTargetRelationMatrix(g, edgeType, false); - info = RG_MatrixTupleIter_AttachRange(&it_s, S, src_id, src_id); + info = Delta_MatrixTupleIter_AttachRange(&it_s, S, src_id, src_id); ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_attach(&it_t, T); + info = Delta_MatrixTupleIter_attach(&it_t, T); ASSERT(info == GrB_SUCCESS); - while(RG_MatrixTupleIter_next_BOOL(&it_s, NULL, &edge_id, NULL) == GrB_SUCCESS) { - info = RG_MatrixTupleIter_iterate_row(&it_t, edge_id); + while(Delta_MatrixTupleIter_next_BOOL(&it_s, NULL, &edge_id, NULL) == GrB_SUCCESS) { + info = Delta_MatrixTupleIter_iterate_row(&it_t, edge_id); ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_next_BOOL(&it_t, NULL, &dest_id, NULL); + info = Delta_MatrixTupleIter_next_BOOL(&it_t, NULL, &dest_id, NULL); ASSERT(info == GrB_SUCCESS); Edge e = {0}; @@ -839,9 +839,9 @@ void _GetOutgoingNodeEdges ASSERT(e.attributes); array_append(*edges, e); } - info = RG_MatrixTupleIter_detach(&it_s); + info = Delta_MatrixTupleIter_detach(&it_s); ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_detach(&it_t); + info = Delta_MatrixTupleIter_detach(&it_t); ASSERT(info == GrB_SUCCESS); } @@ -859,26 +859,26 @@ void _GetIncomingNodeEdges ASSERT(edgeType != GRAPH_NO_RELATION && edgeType != GRAPH_UNKNOWN_RELATION); GrB_Info info; - RG_MatrixTupleIter it_s = {0}; - RG_MatrixTupleIter it_t = {0}; - RG_Matrix S = NULL; - RG_Matrix T = NULL; - NodeID src_id = ENTITY_GET_ID(n); - NodeID dest_id = INVALID_ENTITY_ID; - EdgeID edge_id = INVALID_ENTITY_ID; + Delta_MatrixTupleIter it_s = {0}; + Delta_MatrixTupleIter it_t = {0}; + Delta_Matrix S = NULL; + Delta_Matrix T = NULL; + NodeID src_id = ENTITY_GET_ID(n); + NodeID dest_id = INVALID_ENTITY_ID; + EdgeID edge_id = INVALID_ENTITY_ID; UNUSED(info); S = Graph_GetSourceRelationMatrix(g, edgeType, true); T = Graph_GetTargetRelationMatrix(g, edgeType, true); - info = RG_MatrixTupleIter_AttachRange(&it_t, T, src_id, src_id); + info = Delta_MatrixTupleIter_AttachRange(&it_t, T, src_id, src_id); ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_attach(&it_s, S); + info = Delta_MatrixTupleIter_attach(&it_s, S); ASSERT(info == GrB_SUCCESS); - while(RG_MatrixTupleIter_next_BOOL(&it_t, NULL, &edge_id, NULL) == GrB_SUCCESS) { - info = RG_MatrixTupleIter_iterate_row(&it_s, edge_id); + while(Delta_MatrixTupleIter_next_BOOL(&it_t, NULL, &edge_id, NULL) == GrB_SUCCESS) { + info = Delta_MatrixTupleIter_iterate_row(&it_s, edge_id); ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_next_BOOL(&it_s, NULL, &dest_id, NULL); + info = Delta_MatrixTupleIter_next_BOOL(&it_s, NULL, &dest_id, NULL); ASSERT(info == GrB_SUCCESS); if(dir == GRAPH_EDGE_DIR_BOTH && src_id == dest_id) continue; Edge e = {0}; @@ -890,9 +890,9 @@ void _GetIncomingNodeEdges ASSERT(e.attributes); array_append(*edges, e); } - info = RG_MatrixTupleIter_detach(&it_s); + info = Delta_MatrixTupleIter_detach(&it_s); ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_detach(&it_t); + info = Delta_MatrixTupleIter_detach(&it_t); ASSERT(info == GrB_SUCCESS); } @@ -954,13 +954,13 @@ uint64_t Graph_GetNodeDegree ASSERT(g != NULL); ASSERT(n != NULL); - NodeID srcID = ENTITY_GET_ID(n); - NodeID destID = INVALID_ENTITY_ID; - EdgeID edgeID = INVALID_ENTITY_ID; - uint64_t edge_count = 0; - RG_Matrix M = NULL; - RG_Matrix TM = NULL; - RG_MatrixTupleIter it = {0}; + NodeID srcID = ENTITY_GET_ID(n); + NodeID destID = INVALID_ENTITY_ID; + EdgeID edgeID = INVALID_ENTITY_ID; + uint64_t edge_count = 0; + Delta_Matrix M = NULL; + Delta_Matrix TM = NULL; + Delta_MatrixTupleIter it = {0}; if(edgeType == GRAPH_UNKNOWN_RELATION) { return 0; // no edges @@ -997,13 +997,13 @@ uint64_t Graph_GetNodeDegree if(outgoing) { // construct an iterator to traverse over the source node row, // containing all outgoing edges - RG_MatrixTupleIter_AttachRange(&it, M, srcID, srcID); + Delta_MatrixTupleIter_AttachRange(&it, M, srcID, srcID); // scan row - while(RG_MatrixTupleIter_next_BOOL(&it, NULL, NULL, NULL) + while(Delta_MatrixTupleIter_next_BOOL(&it, NULL, NULL, NULL) == GrB_SUCCESS) { edge_count++; } - RG_MatrixTupleIter_detach(&it); + Delta_MatrixTupleIter_detach(&it); } //---------------------------------------------------------------------- @@ -1016,12 +1016,12 @@ uint64_t Graph_GetNodeDegree // construct an iterator to traverse over the source node row, // containing all incoming edges - RG_MatrixTupleIter_AttachRange(&it, TM, srcID, srcID); - while(RG_MatrixTupleIter_next_BOOL(&it, NULL, NULL, NULL) + Delta_MatrixTupleIter_AttachRange(&it, TM, srcID, srcID); + while(Delta_MatrixTupleIter_next_BOOL(&it, NULL, NULL, NULL) == GrB_SUCCESS) { edge_count++; } - RG_MatrixTupleIter_detach(&it); + Delta_MatrixTupleIter_detach(&it); } } @@ -1044,24 +1044,24 @@ uint Graph_GetNodeLabels GrB_Info res; UNUSED(res); - RG_Matrix M = Graph_GetNodeLabelMatrix(g); + Delta_Matrix M = Graph_GetNodeLabelMatrix(g); EntityID id = ENTITY_GET_ID(n); - RG_MatrixTupleIter iter = {0}; - res = RG_MatrixTupleIter_AttachRange(&iter, M, id, id); + Delta_MatrixTupleIter iter = {0}; + res = Delta_MatrixTupleIter_AttachRange(&iter, M, id, id); ASSERT(res == GrB_SUCCESS); uint i = 0; for(; i < label_count; i++) { GrB_Index col; - res = RG_MatrixTupleIter_next_BOOL(&iter, NULL, &col, NULL); + res = Delta_MatrixTupleIter_next_BOOL(&iter, NULL, &col, NULL); labels[i] = col; if(res == GxB_EXHAUSTED) break; } - RG_MatrixTupleIter_detach(&iter); + Delta_MatrixTupleIter_detach(&iter); return i; } @@ -1078,11 +1078,11 @@ void Graph_DeleteEdges ASSERT(edges != NULL); uint64_t x; - RG_Matrix R; - RG_Matrix S; - RG_Matrix T; - RG_Matrix TT; - RG_Matrix M; + Delta_Matrix R; + Delta_Matrix S; + Delta_Matrix T; + Delta_Matrix TT; + Delta_Matrix M; GrB_Info info; MATRIX_POLICY policy = Graph_SetMatrixPolicy(g, SYNC_POLICY_NOP); @@ -1099,9 +1099,9 @@ void Graph_DeleteEdges S = Graph_GetSourceRelationMatrix(g, r, false); T = Graph_GetTargetRelationMatrix(g, r, false); - info = RG_Matrix_removeElement_BOOL(S, src_id, ENTITY_GET_ID(e)); + info = Delta_Matrix_removeElement_BOOL(S, src_id, ENTITY_GET_ID(e)); ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_removeElement_BOOL(T, ENTITY_GET_ID(e), dest_id); + info = Delta_Matrix_removeElement_BOOL(T, ENTITY_GET_ID(e), dest_id); ASSERT(info == GrB_SUCCESS); GrB_Vector src_vec; @@ -1110,9 +1110,9 @@ void Graph_DeleteEdges ASSERT(info == GrB_SUCCESS); info = GrB_Vector_new(&dst_vec, GrB_BOOL, g->edges->itemCap); ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_extract_row(S, src_vec, src_id); + info = Delta_Matrix_extract_row(S, src_vec, src_id); ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_extract_row(RG_Matrix_getTranspose(T), dst_vec, dest_id); + info = Delta_Matrix_extract_row(Delta_Matrix_getTranspose(T), dst_vec, dest_id); ASSERT(info == GrB_SUCCESS); info = GrB_Vector_eWiseMult_Semiring(src_vec, NULL, NULL, GxB_ANY_PAIR_BOOL, src_vec, dst_vec, GrB_DESC_R); GrB_Vector_nvals(&x, src_vec); @@ -1124,7 +1124,7 @@ void Graph_DeleteEdges if(x == 0) { // no more edges connecting src to other nodes // remove src from relation matrix - info = RG_Matrix_removeElement_BOOL(R, src_id, dest_id); + info = Delta_Matrix_removeElement_BOOL(R, src_id, dest_id); ASSERT(info == GrB_SUCCESS); // see if source is connected to destination with additional edges @@ -1133,7 +1133,7 @@ void Graph_DeleteEdges for(int j = 0; j < relationCount; j++) { if(j == r) continue; M = Graph_GetRelationMatrix(g, j, false); - info = RG_Matrix_extractElement_BOOL(NULL, M, src_id, dest_id); + info = Delta_Matrix_extractElement_BOOL(NULL, M, src_id, dest_id); if(info == GrB_SUCCESS) { connected = true; break; @@ -1144,7 +1144,7 @@ void Graph_DeleteEdges // remove edge from THE adjacency matrix if(!connected) { M = Graph_GetAdjacencyMatrix(g, false); - info = RG_Matrix_removeElement_BOOL(M, src_id, dest_id); + info = Delta_Matrix_removeElement_BOOL(M, src_id, dest_id); ASSERT(info == GrB_SUCCESS); } } @@ -1175,9 +1175,9 @@ static void _Graph_FreeRelationMatrices uint relationCount = Graph_RelationTypeCount(g); for(uint i = 0; i < relationCount; i++) { RelationMatrices *r = g->relations + i; - RG_Matrix_free(&r->R); - RG_Matrix_free(&r->S); - RG_Matrix_free(&r->T); + Delta_Matrix_free(&r->R); + Delta_Matrix_free(&r->S); + Delta_Matrix_free(&r->T); } } @@ -1197,10 +1197,10 @@ LabelID Graph_AddLabel ) { ASSERT(g != NULL); - RG_Matrix m; + Delta_Matrix m; GrB_Info info; size_t n = Graph_RequiredMatrixDim(g); - RG_Matrix_new(&m, GrB_BOOL, n, n, false); + Delta_Matrix_new(&m, GrB_BOOL, n, n, false); array_append(g->labels, m); @@ -1218,12 +1218,12 @@ void Graph_RemoveLabel #ifdef RG_DEBUG GrB_Index nvals; - GrB_Info info = RG_Matrix_nvals(&nvals, g->labels[label_id]); + GrB_Info info = Delta_Matrix_nvals(&nvals, g->labels[label_id]); ASSERT(info == GrB_SUCCESS); ASSERT(nvals == 0); #endif - RG_Matrix_free(&g->labels[label_id]); + Delta_Matrix_free(&g->labels[label_id]); g->labels = array_del(g->labels, label_id); } @@ -1237,9 +1237,9 @@ RelationID Graph_AddRelationType size_t n = Graph_RequiredMatrixDim(g); size_t edge_cap = g->edges->itemCap; - RG_Matrix_new(&r.R, GrB_BOOL, n, n, true); - RG_Matrix_new(&r.S, GrB_BOOL, n, edge_cap, true); - RG_Matrix_new(&r.T, GrB_BOOL, edge_cap, n, true); + Delta_Matrix_new(&r.R, GrB_BOOL, n, n, true); + Delta_Matrix_new(&r.S, GrB_BOOL, n, edge_cap, true); + Delta_Matrix_new(&r.T, GrB_BOOL, edge_cap, n, true); array_append(g->relations, r); @@ -1256,17 +1256,17 @@ void Graph_RemoveRelation ASSERT(relation_id == Graph_RelationTypeCount(g) - 1); #ifdef RG_DEBUG GrB_Index nvals; - GrB_Info info = RG_Matrix_nvals(&nvals, g->relations[relation_id].R); + GrB_Info info = Delta_Matrix_nvals(&nvals, g->relations[relation_id].R); ASSERT(info == GrB_SUCCESS); ASSERT(nvals == 0); #endif - RG_Matrix_free(&g->relations[relation_id].R); - RG_Matrix_free(&g->relations[relation_id].S); - RG_Matrix_free(&g->relations[relation_id].T); + Delta_Matrix_free(&g->relations[relation_id].R); + Delta_Matrix_free(&g->relations[relation_id].S); + Delta_Matrix_free(&g->relations[relation_id].T); g->relations = array_del(g->relations, relation_id); } -RG_Matrix Graph_GetLabelMatrix +Delta_Matrix Graph_GetLabelMatrix ( const Graph *g, LabelID label_idx @@ -1277,14 +1277,14 @@ RG_Matrix Graph_GetLabelMatrix // return zero matrix if label_idx is out of range if(label_idx < 0) return Graph_GetZeroMatrix(g); - RG_Matrix m = g->labels[label_idx]; + Delta_Matrix m = g->labels[label_idx]; size_t n = Graph_RequiredMatrixDim(g); g->SynchronizeMatrix(g, m, n, n); return m; } -RG_Matrix Graph_GetRelationMatrix +Delta_Matrix Graph_GetRelationMatrix ( const Graph *g, RelationID relation_idx, @@ -1294,7 +1294,7 @@ RG_Matrix Graph_GetRelationMatrix ASSERT(relation_idx == GRAPH_NO_RELATION || relation_idx < Graph_RelationTypeCount(g)); - RG_Matrix m = GrB_NULL; + Delta_Matrix m = GrB_NULL; if(relation_idx == GRAPH_NO_RELATION) { m = g->adjacency_matrix; @@ -1305,12 +1305,12 @@ RG_Matrix Graph_GetRelationMatrix size_t n = Graph_RequiredMatrixDim(g); g->SynchronizeMatrix(g, m, n, n); - if(transposed) m = RG_Matrix_getTranspose(m); + if(transposed) m = Delta_Matrix_getTranspose(m); return m; } -RG_Matrix Graph_GetSourceRelationMatrix +Delta_Matrix Graph_GetSourceRelationMatrix ( const Graph *g, RelationID relation_idx, @@ -1318,18 +1318,18 @@ RG_Matrix Graph_GetSourceRelationMatrix ) { ASSERT(relation_idx != GRAPH_NO_RELATION); - RG_Matrix m = g->relations[relation_idx].S; + Delta_Matrix m = g->relations[relation_idx].S; size_t n = Graph_RequiredMatrixDim(g); size_t edge_cap = g->edges->itemCap; g->SynchronizeMatrix(g, m, n, edge_cap); - if(transposed) m = RG_Matrix_getTranspose(m); + if(transposed) m = Delta_Matrix_getTranspose(m); return m; } -RG_Matrix Graph_GetTargetRelationMatrix +Delta_Matrix Graph_GetTargetRelationMatrix ( const Graph *g, RelationID relation_idx, @@ -1337,18 +1337,18 @@ RG_Matrix Graph_GetTargetRelationMatrix ) { ASSERT(relation_idx != GRAPH_NO_RELATION); - RG_Matrix m = g->relations[relation_idx].T; + Delta_Matrix m = g->relations[relation_idx].T; size_t n = Graph_RequiredMatrixDim(g); size_t edge_cap = g->edges->itemCap; g->SynchronizeMatrix(g, m, edge_cap, n); - if(transposed) m = RG_Matrix_getTranspose(m); + if(transposed) m = Delta_Matrix_getTranspose(m); return m; } -RG_Matrix Graph_GetAdjacencyMatrix +Delta_Matrix Graph_GetAdjacencyMatrix ( const Graph *g, bool transposed @@ -1367,19 +1367,19 @@ bool Graph_RelationshipContainsMultiEdge ASSERT(Graph_RelationTypeCount(g) > r); GrB_Index nvals; // A relationship matrix contains multi-edge if nvals < number of edges with type r. - RG_Matrix R = Graph_GetRelationMatrix(g, r, transpose); - RG_Matrix_nvals(&nvals, R); + Delta_Matrix R = Graph_GetRelationMatrix(g, r, transpose); + Delta_Matrix_nvals(&nvals, R); return (Graph_RelationEdgeCount(g, r) > nvals); } -RG_Matrix Graph_GetNodeLabelMatrix +Delta_Matrix Graph_GetNodeLabelMatrix ( const Graph *g ) { ASSERT(g != NULL); - RG_Matrix m = g->node_labels; + Delta_Matrix m = g->node_labels; size_t n = Graph_RequiredMatrixDim(g); g->SynchronizeMatrix(g, m, n, n); @@ -1387,18 +1387,18 @@ RG_Matrix Graph_GetNodeLabelMatrix return m; } -RG_Matrix Graph_GetZeroMatrix +Delta_Matrix Graph_GetZeroMatrix ( const Graph *g ) { - RG_Matrix z = g->_zero_matrix; + Delta_Matrix z = g->_zero_matrix; size_t n = Graph_RequiredMatrixDim(g); g->SynchronizeMatrix(g, z, n, n); #if RG_DEBUG // make sure zero matrix is indeed empty GrB_Index nvals; - RG_Matrix_nvals(&nvals, z); + Delta_Matrix_nvals(&nvals, z); ASSERT(nvals == 0); #endif @@ -1415,16 +1415,16 @@ static void _Graph_Free AttributeSet *set; DataBlockIterator *it; - RG_Matrix_free(&g->_zero_matrix); - RG_Matrix_free(&g->adjacency_matrix); + Delta_Matrix_free(&g->_zero_matrix); + Delta_Matrix_free(&g->adjacency_matrix); _Graph_FreeRelationMatrices(g); array_free(g->relations); uint32_t labelCount = array_len(g->labels); - for(int i = 0; i < labelCount; i++) RG_Matrix_free(&g->labels[i]); + for(int i = 0; i < labelCount; i++) Delta_Matrix_free(&g->labels[i]); array_free(g->labels); - RG_Matrix_free(&g->node_labels); + Delta_Matrix_free(&g->node_labels); it = is_full_graph ? Graph_ScanNodes(g) : DataBlock_FullScan(g->nodes); while((set = (AttributeSet *)DataBlockIterator_Next(it, NULL)) != NULL) { diff --git a/src/graph/graph.h b/src/graph/graph.h index 74307834b..5a6aae1b1 100644 --- a/src/graph/graph.h +++ b/src/graph/graph.h @@ -14,7 +14,7 @@ #include "entities/node.h" #include "entities/edge.h" #include "../redismodule.h" -#include "rg_matrix/rg_matrix.h" +#include "delta_matrix/delta_matrix.h" #include "../util/datablock/datablock.h" #include "../util/datablock/datablock_iterator.h" #include "../../deps/GraphBLAS/Include/GraphBLAS.h" @@ -42,23 +42,23 @@ typedef enum { // forward declaration of Graph struct typedef struct Graph Graph; // typedef for synchronization function pointer -typedef void (*SyncMatrixFunc)(const Graph *, RG_Matrix, GrB_Index, GrB_Index); +typedef void (*SyncMatrixFunc)(const Graph *, Delta_Matrix, GrB_Index, GrB_Index); typedef struct { - RG_Matrix R; // relation matrix - RG_Matrix S; // sources matrix - RG_Matrix T; // targets matrix + Delta_Matrix R; // relation matrix + Delta_Matrix S; // sources matrix + Delta_Matrix T; // targets matrix } RelationMatrices; struct Graph { int reserved_node_count; // number of nodes not commited yet DataBlock *nodes; // graph nodes stored in blocks DataBlock *edges; // graph edges stored in blocks - RG_Matrix adjacency_matrix; // adjacency matrix, holds all graph connections - RG_Matrix *labels; // label matrices - RG_Matrix node_labels; // mapping of all node IDs to all labels possessed by each node + Delta_Matrix adjacency_matrix; // adjacency matrix, holds all graph connections + Delta_Matrix *labels; // label matrices + Delta_Matrix node_labels; // mapping of all node IDs to all labels possessed by each node RelationMatrices *relations; // relation matrices - RG_Matrix _zero_matrix; // zero matrix + Delta_Matrix _zero_matrix; // zero matrix pthread_rwlock_t _rwlock; // read-write lock scoped to this specific graph bool _writelocked; // true if the read-write lock was acquired by a writer SyncMatrixFunc SynchronizeMatrix; // function pointer to matrix synchronization routine @@ -391,7 +391,7 @@ uint Graph_GetNodeLabels // retrieves the adjacency matrix // matrix is resized if its size doesn't match graph's node count -RG_Matrix Graph_GetAdjacencyMatrix +Delta_Matrix Graph_GetAdjacencyMatrix ( const Graph *g, bool transposed @@ -399,7 +399,7 @@ RG_Matrix Graph_GetAdjacencyMatrix // retrieves a label matrix // matrix is resized if its size doesn't match graph's node count -RG_Matrix Graph_GetLabelMatrix +Delta_Matrix Graph_GetLabelMatrix ( const Graph *g, // graph from which to get adjacency matrix int label // label described by matrix @@ -407,7 +407,7 @@ RG_Matrix Graph_GetLabelMatrix // retrieves a typed adjacency matrix // matrix is resized if its size doesn't match graph's node count -RG_Matrix Graph_GetRelationMatrix +Delta_Matrix Graph_GetRelationMatrix ( const Graph *g, // graph from which to get adjacency matrix RelationID relation_idx, // relation described by matrix @@ -416,7 +416,7 @@ RG_Matrix Graph_GetRelationMatrix // retrieves a relation edge source matrix // matrix is resized if its dimensions doesn't match graph's node count & graph's edge count -RG_Matrix Graph_GetSourceRelationMatrix +Delta_Matrix Graph_GetSourceRelationMatrix ( const Graph *g, // graph from which to get adjacency matrix RelationID relation_idx, // relation described by matrix @@ -425,7 +425,7 @@ RG_Matrix Graph_GetSourceRelationMatrix // retrieves a relation edge target matrix // matrix is resized if its dimensions doesn't match graph's edge count & graph's node count -RG_Matrix Graph_GetTargetRelationMatrix +Delta_Matrix Graph_GetTargetRelationMatrix ( const Graph *g, // graph from which to get adjacency matrix RelationID relation_idx, // relation described by matrix @@ -434,7 +434,7 @@ RG_Matrix Graph_GetTargetRelationMatrix // retrieves the node-label mapping matrix, // matrix is resized if its size doesn't match graph's node count. -RG_Matrix Graph_GetNodeLabelMatrix +Delta_Matrix Graph_GetNodeLabelMatrix ( const Graph *g ); @@ -442,12 +442,12 @@ RG_Matrix Graph_GetNodeLabelMatrix // retrieves the zero matrix // the function will resize it to match all other // internal matrices, caller mustn't modify it in any way -RG_Matrix Graph_GetZeroMatrix +Delta_Matrix Graph_GetZeroMatrix ( const Graph *g ); -RG_Matrix Graph_GetLabelRGMatrix +Delta_Matrix Graph_GetLabelMatrix ( const Graph *g, int label_idx diff --git a/src/graph/graph_delete_nodes.c b/src/graph/graph_delete_nodes.c index a775cd366..091635f01 100644 --- a/src/graph/graph_delete_nodes.c +++ b/src/graph/graph_delete_nodes.c @@ -6,7 +6,7 @@ #include "RG.h" #include "graph.h" -#include "rg_matrix/rg_matrix_iter.h" +#include "delta_matrix/delta_matrix_iter.h" // deletes nodes from the graph // @@ -58,26 +58,26 @@ void Graph_DeleteNodes // update label matrices //-------------------------------------------------------------------------- - GrB_Index j; // iterated entry col idx - GrB_Info info; // GraphBLAS return code - GrB_Index nrows; // lbls row count - GrB_Index ncols; // lbls col count - GrB_Matrix elems; // elements to delete - RG_MatrixTupleIter it; // matrix iterator + GrB_Index j; // iterated entry col idx + GrB_Info info; // GraphBLAS return code + GrB_Index nrows; // lbls row count + GrB_Index ncols; // lbls col count + GrB_Matrix elems; // elements to delete + Delta_MatrixTupleIter it; // matrix iterator // get labels matrix - RG_Matrix lbls = Graph_GetNodeLabelMatrix(g); + Delta_Matrix lbls = Graph_GetNodeLabelMatrix(g); // create lbls mask - info = RG_Matrix_nrows(&nrows, lbls); + info = Delta_Matrix_nrows(&nrows, lbls); ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_ncols(&ncols, lbls); + info = Delta_Matrix_ncols(&ncols, lbls); ASSERT(info == GrB_SUCCESS); info = GrB_Matrix_new(&elems, GrB_BOOL, nrows, ncols); ASSERT(info == GrB_SUCCESS); // attach iterator to lbls matrix - RG_MatrixTupleIter_attach(&it, lbls); + Delta_MatrixTupleIter_attach(&it, lbls); //-------------------------------------------------------------------------- // phase one @@ -89,18 +89,18 @@ void Graph_DeleteNodes Node *n = nodes + i; EntityID id = ENTITY_GET_ID(n); - info = RG_MatrixTupleIter_iterate_row(&it, id); + info = Delta_MatrixTupleIter_iterate_row(&it, id); ASSERT(info == GrB_SUCCESS); // for each deleted node label - while(RG_MatrixTupleIter_next_BOOL(&it, NULL, &j, NULL) == GrB_SUCCESS) { + while(Delta_MatrixTupleIter_next_BOOL(&it, NULL, &j, NULL) == GrB_SUCCESS) { // populate lbls mask info = GrB_Matrix_setElement_BOOL(elems, true, id, j); ASSERT(info == GrB_SUCCESS); // clear label matrix j at position [id,id] - RG_Matrix L = Graph_GetLabelMatrix(g, j); - info = RG_Matrix_removeElement_BOOL(L, id, id); + Delta_Matrix L = Graph_GetLabelMatrix(g, j); + info = Delta_Matrix_removeElement_BOOL(L, id, id); ASSERT(info == GrB_SUCCESS); } @@ -112,7 +112,7 @@ void Graph_DeleteNodes // phase two //-------------------------------------------------------------------------- - RG_Matrix_removeElements(lbls, elems); + Delta_Matrix_removeElements(lbls, elems); // restore matrix sync policy Graph_SetMatrixPolicy(g, policy); diff --git a/src/graph/graph_hub.c b/src/graph/graph_hub.c index 88c35d596..01acbd6f3 100644 --- a/src/graph/graph_hub.c +++ b/src/graph/graph_hub.c @@ -332,7 +332,7 @@ void UpdateNodeLabels // sync matrix // make sure label matrix is of the right dimensions if(schema_created) { - RG_Matrix m = Graph_GetLabelMatrix(gc->g, schema_id); + Delta_Matrix m = Graph_GetLabelMatrix(gc->g, schema_id); } // append label id add_labels_ids[add_labels_index++] = schema_id; diff --git a/src/graph/rg_matrix/rg_matrix_iter.h b/src/graph/rg_matrix/rg_matrix_iter.h deleted file mode 100644 index 734afbbc3..000000000 --- a/src/graph/rg_matrix/rg_matrix_iter.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#pragma once - -#include -#include "rg_matrix.h" -#include "GraphBLAS.h" - -#define RG_ITER_MIN_ROW 0 -#define RG_ITER_MAX_ROW ULLONG_MAX - -// TuplesIter maintains information required -// to iterate over a RG_Matrix -struct Opaque_RG_MatrixTupleIter -{ - char _private[296]; -}; - -typedef struct Opaque_RG_MatrixTupleIter RG_MatrixTupleIter ; - -// attach iterator to matrix -GrB_Info RG_MatrixTupleIter_attach -( - RG_MatrixTupleIter *iter, // iterator to update - const RG_Matrix A // matrix to scan -); - -// attach iterator to matrix governing the specified range -GrB_Info RG_MatrixTupleIter_AttachRange -( - RG_MatrixTupleIter *iter, // iterator to update - const RG_Matrix A, // matrix to scan - GrB_Index min_row, // minimum row for iteration - GrB_Index max_row // maximum row for iteration -); - -// free iterator internals, keeping the iterator intact -GrB_Info RG_MatrixTupleIter_detach -( - RG_MatrixTupleIter *iter // iterator to free -); - -// returns true if iterator is attached to given matrix false otherwise -bool RG_MatrixTupleIter_is_attached -( - const RG_MatrixTupleIter *iter, // iterator to check - const RG_Matrix M // matrix attached to -); - -GrB_Info RG_MatrixTupleIter_iterate_row -( - RG_MatrixTupleIter *iter, // iterator to use - GrB_Index rowIdx // row to iterate -); - -GrB_Info RG_MatrixTupleIter_iterate_range -( - RG_MatrixTupleIter *iter, // iterator to use - GrB_Index startRowIdx, // row index to start with - GrB_Index endRowIdx // row index to finish with -); - -// advance iterator -GrB_Info RG_MatrixTupleIter_next_BOOL -( - RG_MatrixTupleIter *iter, // iterator to consume - GrB_Index *row, // optional output row index - GrB_Index *col, // optional output column index - bool *val // optional value at A[row, col] -); - -// reset iterator -GrB_Info RG_MatrixTupleIter_reset -( - RG_MatrixTupleIter *iter // iterator to reset -); - diff --git a/src/index/index_construct.c b/src/index/index_construct.c index bd8b144ca..7ba4d5edd 100644 --- a/src/index/index_construct.c +++ b/src/index/index_construct.c @@ -6,7 +6,7 @@ #include "RG.h" #include "index.h" -#include "../graph/rg_matrix/rg_matrix_iter.h" +#include "../graph/delta_matrix/delta_matrix_iter.h" #include @@ -30,7 +30,7 @@ static void _Index_PopulateNodeIndex GrB_Index rowIdx = 0; int indexed = 0; // #entities in current batch int batch_size = 10000; // max #entities to index in one go - RG_MatrixTupleIter it = {0}; + Delta_MatrixTupleIter it = {0}; while(true) { // lock graph for reading @@ -48,7 +48,7 @@ static void _Index_PopulateNodeIndex indexed = 0; // fetch label matrix - const RG_Matrix m = Graph_GetLabelMatrix(g, Index_GetLabelID(idx)); + const Delta_Matrix m = Graph_GetLabelMatrix(g, Index_GetLabelID(idx)); ASSERT(m != NULL); //---------------------------------------------------------------------- @@ -56,9 +56,9 @@ static void _Index_PopulateNodeIndex //---------------------------------------------------------------------- GrB_Info info; - info = RG_MatrixTupleIter_attach(&it, m); + info = Delta_MatrixTupleIter_attach(&it, m); ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_iterate_range(&it, rowIdx, UINT64_MAX); + info = Delta_MatrixTupleIter_iterate_range(&it, rowIdx, UINT64_MAX); ASSERT(info == GrB_SUCCESS); //---------------------------------------------------------------------- @@ -67,7 +67,7 @@ static void _Index_PopulateNodeIndex EntityID id; while(indexed < batch_size && - RG_MatrixTupleIter_next_BOOL(&it, &id, NULL, NULL) == GrB_SUCCESS) + Delta_MatrixTupleIter_next_BOOL(&it, &id, NULL, NULL) == GrB_SUCCESS) { Node n; Graph_GetNode(g, id, &n); @@ -87,7 +87,7 @@ static void _Index_PopulateNodeIndex Graph_ReleaseLock(g); // finished current batch - RG_MatrixTupleIter_detach(&it); + Delta_MatrixTupleIter_detach(&it); // continue next batch from row id+1 // this is true because we're iterating over a diagonal matrix @@ -97,7 +97,7 @@ static void _Index_PopulateNodeIndex // release read lock Graph_ReleaseLock(g); - RG_MatrixTupleIter_detach(&it); + Delta_MatrixTupleIter_detach(&it); } // index edges in an asynchronous manner @@ -118,14 +118,14 @@ static void _Index_PopulateEdgeIndex ASSERT(idx != NULL); GrB_Info info; - EntityID src_id = 0; // current processed row idx - EntityID dest_id = 0; // current processed column idx - EntityID edge_id = 0; // current processed edge id - EntityID prev_src_id = 0; // last processed row idx - EntityID prev_edge_id = 0; // last processed column idx - int indexed = 0; // number of entities indexed in current batch - int batch_size = 1000; // max number of entities to index in one go - RG_MatrixTupleIter it = {0}; + EntityID src_id = 0; // current processed row idx + EntityID dest_id = 0; // current processed column idx + EntityID edge_id = 0; // current processed edge id + EntityID prev_src_id = 0; // last processed row idx + EntityID prev_edge_id = 0; // last processed column idx + int indexed = 0; // number of entities indexed in current batch + int batch_size = 1000; // max number of entities to index in one go + Delta_MatrixTupleIter it = {0}; while(true) { // lock graph for reading @@ -146,22 +146,22 @@ static void _Index_PopulateEdgeIndex // fetch relation matrix int label_id = Index_GetLabelID(idx); - RG_Matrix S = Graph_GetSourceRelationMatrix(g, label_id, false); + Delta_Matrix S = Graph_GetSourceRelationMatrix(g, label_id, false); ASSERT(S != NULL); - RG_Matrix T = Graph_GetTargetRelationMatrix(g, label_id, false); + Delta_Matrix T = Graph_GetTargetRelationMatrix(g, label_id, false); ASSERT(T != NULL); - RG_MatrixTupleIter it_dst = {0}; - RG_MatrixTupleIter_attach(&it_dst, T); + Delta_MatrixTupleIter it_dst = {0}; + Delta_MatrixTupleIter_attach(&it_dst, T); //---------------------------------------------------------------------- // resume scanning from previous row/col indices //---------------------------------------------------------------------- - info = RG_MatrixTupleIter_AttachRange(&it, S, src_id, UINT64_MAX); + info = Delta_MatrixTupleIter_AttachRange(&it, S, src_id, UINT64_MAX); ASSERT(info == GrB_SUCCESS); // skip previously indexed edges - while((info = RG_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, + while((info = Delta_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, NULL)) == GrB_SUCCESS && src_id == prev_src_id && edge_id < prev_edge_id); @@ -176,8 +176,8 @@ static void _Index_PopulateEdgeIndex //---------------------------------------------------------------------- do { - RG_MatrixTupleIter_iterate_row(&it_dst, edge_id); - RG_MatrixTupleIter_next_BOOL(&it_dst, NULL, &dest_id, NULL); + Delta_MatrixTupleIter_iterate_row(&it_dst, edge_id); + Delta_MatrixTupleIter_next_BOOL(&it_dst, NULL, &dest_id, NULL); Edge e; e.src_id = src_id; @@ -188,7 +188,7 @@ static void _Index_PopulateEdgeIndex indexed++; } while(indexed < batch_size && - RG_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, NULL) + Delta_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, NULL) == GrB_SUCCESS); //---------------------------------------------------------------------- @@ -202,13 +202,13 @@ static void _Index_PopulateEdgeIndex // finished current batch // release read lock Graph_ReleaseLock(g); - RG_MatrixTupleIter_detach(&it); + Delta_MatrixTupleIter_detach(&it); } } // release read lock Graph_ReleaseLock(g); - RG_MatrixTupleIter_detach(&it); + Delta_MatrixTupleIter_detach(&it); } // constructs index diff --git a/src/index/index_edge.c b/src/index/index_edge.c index 75baf895c..9c974c6b0 100644 --- a/src/index/index_edge.c +++ b/src/index/index_edge.c @@ -9,7 +9,7 @@ #include "../query_ctx.h" #include "../graph/graphcontext.h" #include "../graph/entities/edge.h" -#include "../graph/rg_matrix/rg_matrix_iter.h" +#include "../graph/delta_matrix/delta_matrix_iter.h" extern RSDoc *Index_IndexGraphEntity(Index idx,const GraphEntity *e, const void *key, size_t key_len, uint *doc_field_count); diff --git a/src/index/index_node.c b/src/index/index_node.c index 6daeeccd6..393fe7c41 100644 --- a/src/index/index_node.c +++ b/src/index/index_node.c @@ -9,7 +9,7 @@ #include "../value.h" #include "../query_ctx.h" #include "../graph/graphcontext.h" -#include "../graph/rg_matrix/rg_matrix_iter.h" +#include "../graph/delta_matrix/delta_matrix_iter.h" extern RSDoc *Index_IndexGraphEntity(Index idx, const GraphEntity *e, const void *key, size_t key_len, uint *doc_field_count); diff --git a/src/procedures/proc_bfs.c b/src/procedures/proc_bfs.c index a8fcd2bc9..6e555fb4e 100644 --- a/src/procedures/proc_bfs.c +++ b/src/procedures/proc_bfs.c @@ -97,14 +97,14 @@ static ProcedureResult Proc_BFS_Invoke GraphContext *gc = QueryCtx_GetGraphCtx(); if(reltype == NULL) { - RG_Matrix_export(&R, Graph_GetAdjacencyMatrix(gc->g, false)); + Delta_Matrix_export(&R, Graph_GetAdjacencyMatrix(gc->g, false)); } else { Schema *s = GraphContext_GetSchema(gc, reltype, SCHEMA_EDGE); // failed to find schema, first step will return NULL if(!s) return PROCEDURE_OK; bfs_ctx->reltype_id = s->id; - RG_Matrix_export(&R, Graph_GetRelationMatrix(gc->g, s->id, false)); + Delta_Matrix_export(&R, Graph_GetRelationMatrix(gc->g, s->id, false)); } // if we're not collecting edges, pass a NULL parent pointer diff --git a/src/procedures/proc_pagerank.c b/src/procedures/proc_pagerank.c index 92c0406ec..13d21f150 100644 --- a/src/procedures/proc_pagerank.c +++ b/src/procedures/proc_pagerank.c @@ -109,7 +109,7 @@ ProcedureResult Proc_PagerankInvoke s = GraphContext_GetSchema(gc, label, SCHEMA_NODE); // unknown label, quickly return if(!s) return PROCEDURE_OK; - RG_Matrix_export(&l, Graph_GetLabelMatrix(g, s->id)); + Delta_Matrix_export(&l, Graph_GetLabelMatrix(g, s->id)); } // get relation matrix @@ -117,14 +117,14 @@ ProcedureResult Proc_PagerankInvoke s = GraphContext_GetSchema(gc, relation, SCHEMA_EDGE); // unknown relation, quickly return if(!s) return PROCEDURE_OK; - RG_Matrix_export(&r, Graph_GetRelationMatrix(g, s->id, false)); + Delta_Matrix_export(&r, Graph_GetRelationMatrix(g, s->id, false)); // convert the values to true info = GrB_Matrix_apply(r, NULL, NULL, GxB_ONE_BOOL, r, GrB_DESC_R); ASSERT(info == GrB_SUCCESS); } else { // relation isn't specified, 'r' is the adjacency matrix - RG_Matrix_export(&r, Graph_GetAdjacencyMatrix(g, false)); + Delta_Matrix_export(&r, Graph_GetAdjacencyMatrix(g, false)); } // if label is specified: // filter 'r' to contain only rows and columns associated with diff --git a/src/serializers/encode_context.c b/src/serializers/encode_context.c index 4dd7684d3..c2e7bbdb2 100644 --- a/src/serializers/encode_context.c +++ b/src/serializers/encode_context.c @@ -54,7 +54,7 @@ void GraphEncodeContext_Reset(GraphEncodeContext *ctx) { } // Avoid leaks in case or reset during encodeing. - RG_MatrixTupleIter_detach(&ctx->matrix_tuple_iterator); + Delta_MatrixTupleIter_detach(&ctx->matrix_tuple_iterator); } void GraphEncodeContext_InitHeader @@ -159,7 +159,7 @@ void GraphEncodeContext_SetCurrentRelationID(GraphEncodeContext *ctx, ctx->current_relation_matrix_id = current_relation_matrix_id; } -RG_MatrixTupleIter *GraphEncodeContext_GetMatrixTupleIterator( +Delta_MatrixTupleIter *GraphEncodeContext_GetMatrixTupleIterator( GraphEncodeContext *ctx) { ASSERT(ctx); return &ctx->matrix_tuple_iterator; diff --git a/src/serializers/encode_context.h b/src/serializers/encode_context.h index 3233e95ff..474eb9315 100644 --- a/src/serializers/encode_context.h +++ b/src/serializers/encode_context.h @@ -11,7 +11,7 @@ #include "stdbool.h" #include "../graph/graph.h" #include "../util/datablock/datablock.h" -#include "../graph/rg_matrix/rg_matrix_iter.h" +#include "../graph/delta_matrix/delta_matrix_iter.h" #include "../graph/entities/graph_entity.h" #include "rax.h" @@ -49,7 +49,7 @@ typedef struct { uint64_t vkey_entity_count; // Number of entities in a single virtual key. uint current_relation_matrix_id; // Current encoded relationship matrix. DataBlockIterator *datablock_iterator; // Datablock iterator to be saved in the context. - RG_MatrixTupleIter matrix_tuple_iterator; // Matrix tuple iterator to be saved in the context. + Delta_MatrixTupleIter matrix_tuple_iterator;// Matrix tuple iterator to be saved in the context. } GraphEncodeContext; // Creates a new graph encoding context. @@ -102,7 +102,7 @@ void GraphEncodeContext_SetCurrentRelationID(GraphEncodeContext *ctx, uint current_relation_matrix_id); // Retrieve stored matrix tuple iterator. -RG_MatrixTupleIter *GraphEncodeContext_GetMatrixTupleIterator(GraphEncodeContext *ctx); +Delta_MatrixTupleIter *GraphEncodeContext_GetMatrixTupleIterator(GraphEncodeContext *ctx); // Returns if the the number of processed keys is equal to the total number of graph keys. bool GraphEncodeContext_Finished(const GraphEncodeContext *ctx); diff --git a/src/serializers/encoder/v14/encode_graph_entities.c b/src/serializers/encoder/v14/encode_graph_entities.c index 0d6404f2c..454663cd0 100644 --- a/src/serializers/encoder/v14/encode_graph_entities.c +++ b/src/serializers/encoder/v14/encode_graph_entities.c @@ -303,19 +303,19 @@ void RdbSaveEdges_v14 // get current relation matrix uint r = GraphEncodeContext_GetCurrentRelationID(gc->encoding_context); - RG_Matrix S = Graph_GetSourceRelationMatrix(gc->g, r, false); + Delta_Matrix S = Graph_GetSourceRelationMatrix(gc->g, r, false); ASSERT(S != NULL); - RG_Matrix T = Graph_GetTargetRelationMatrix(gc->g, r, false); + Delta_Matrix T = Graph_GetTargetRelationMatrix(gc->g, r, false); ASSERT(T != NULL); - RG_MatrixTupleIter iter_t = {0}; - RG_MatrixTupleIter_attach(&iter_t, T); + Delta_MatrixTupleIter iter_t = {0}; + Delta_MatrixTupleIter_attach(&iter_t, T); // get matrix tuple iterator from context // already set to the next entry to fetch // for previous edge encide or create new one - RG_MatrixTupleIter *iter = GraphEncodeContext_GetMatrixTupleIterator(gc->encoding_context); - if(!RG_MatrixTupleIter_is_attached(iter, S)) { - info = RG_MatrixTupleIter_attach(iter, S); + Delta_MatrixTupleIter *iter = GraphEncodeContext_GetMatrixTupleIterator(gc->encoding_context); + if(!Delta_MatrixTupleIter_is_attached(iter, S)) { + info = Delta_MatrixTupleIter_attach(iter, S); ASSERT(info == GrB_SUCCESS); } @@ -330,7 +330,7 @@ void RdbSaveEdges_v14 Edge e; // try to get next tuple - info = RG_MatrixTupleIter_next_BOOL(iter, &src_id, &edge_id, NULL); + info = Delta_MatrixTupleIter_next_BOOL(iter, &src_id, &edge_id, NULL); // if iterator is depleted // get new tuple from different matrix or finish encode @@ -345,18 +345,18 @@ void RdbSaveEdges_v14 S = Graph_GetSourceRelationMatrix(gc->g, r, false); ASSERT(S != NULL); T = Graph_GetTargetRelationMatrix(gc->g, r, false); - info = RG_MatrixTupleIter_attach(iter, S); + info = Delta_MatrixTupleIter_attach(iter, S); ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_attach(&iter_t, T); + info = Delta_MatrixTupleIter_attach(&iter_t, T); ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_next_BOOL(iter, &src_id, &edge_id, NULL); + info = Delta_MatrixTupleIter_next_BOOL(iter, &src_id, &edge_id, NULL); } ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_iterate_row(&iter_t, edge_id); + info = Delta_MatrixTupleIter_iterate_row(&iter_t, edge_id); ASSERT(info == GrB_SUCCESS); - info = RG_MatrixTupleIter_next_BOOL(&iter_t, NULL, &dest_id, NULL); + info = Delta_MatrixTupleIter_next_BOOL(&iter_t, NULL, &dest_id, NULL); ASSERT(info == GrB_SUCCESS); e.src_id = src_id; @@ -369,7 +369,7 @@ void RdbSaveEdges_v14 finish: // check if done encoding edges if(offset + edges_to_encode == graph_edges) { - RG_MatrixTupleIter_detach(iter); + Delta_MatrixTupleIter_detach(iter); } // update context diff --git a/src/serializers/graph_extensions.c b/src/serializers/graph_extensions.c index c70ef8d8c..955da9844 100644 --- a/src/serializers/graph_extensions.c +++ b/src/serializers/graph_extensions.c @@ -20,24 +20,24 @@ void Graph_EnsureNodeCap uint n; GrB_Index dim = Graph_RequiredMatrixDim(g); - RG_Matrix M = NULL; + Delta_Matrix M = NULL; M = Graph_GetAdjacencyMatrix(g, false); - RG_Matrix_resize(M, dim, dim); + Delta_Matrix_resize(M, dim, dim); M = Graph_GetNodeLabelMatrix(g); - RG_Matrix_resize(M, dim, dim); + Delta_Matrix_resize(M, dim, dim); n = array_len(g->labels); for(int i = 0; i < n; i ++) { M = Graph_GetLabelMatrix(g, i); - RG_Matrix_resize(M, dim, dim); + Delta_Matrix_resize(M, dim, dim); } n = array_len(g->relations); for(int i = 0; i < n; i ++) { M = Graph_GetRelationMatrix(g, i, false); - RG_Matrix_resize(M, dim, dim); + Delta_Matrix_resize(M, dim, dim); } } @@ -78,8 +78,8 @@ void Serializer_Graph_SetNode for(uint i = 0; i < label_count; i ++) { LabelID label = labels[i]; // set label matrix at position [id, id] - RG_Matrix M = Graph_GetLabelMatrix(g, label); - GrB_Matrix m = RG_Matrix_M(M); + Delta_Matrix M = Graph_GetLabelMatrix(g, label); + GrB_Matrix m = Delta_Matrix_M(M); info = GrB_Matrix_setElement_BOOL(m, true, id, id); if(info == GrB_INVALID_INDEX) { RedisModule_Log(NULL, "notice", "RESIZE LABEL MATRIX"); @@ -102,20 +102,20 @@ void Serializer_Graph_SetNodeLabels GrB_Vector v; int node_count = Graph_RequiredMatrixDim(g); int label_count = Graph_LabelTypeCount(g); - RG_Matrix node_labels = Graph_GetNodeLabelMatrix(g); - GrB_Matrix node_labels_m = RG_Matrix_M(node_labels); + Delta_Matrix node_labels = Graph_GetNodeLabelMatrix(g); + GrB_Matrix node_labels_m = Delta_Matrix_M(node_labels); #if RG_DEBUG GrB_Index nvals; - RG_Matrix_nvals(&nvals, node_labels); + Delta_Matrix_nvals(&nvals, node_labels); ASSERT(nvals == 0); #endif GrB_Vector_new(&v, GrB_BOOL, node_count); for(int i = 0; i < label_count; i++) { - RG_Matrix M = Graph_GetLabelMatrix(g, i); - GrB_Matrix m = RG_Matrix_M(M); + Delta_Matrix M = Graph_GetLabelMatrix(g, i); + GrB_Matrix m = Delta_Matrix_M(M); GxB_Vector_diag(v, m, 0, NULL); @@ -138,18 +138,18 @@ static void _OptimizedSingleEdgeFormConnection int r ) { GrB_Info info; - RG_Matrix M = Graph_GetRelationMatrix(g, r, false); - RG_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); - RG_Matrix T = Graph_GetTargetRelationMatrix(g, r, false); - RG_Matrix adj = Graph_GetAdjacencyMatrix(g, false); - GrB_Matrix m = RG_Matrix_M(M); - GrB_Matrix tm = RG_Matrix_M(RG_Matrix_getTranspose(M)); - GrB_Matrix s = RG_Matrix_M(S); - GrB_Matrix ts = RG_Matrix_M(RG_Matrix_getTranspose(S)); - GrB_Matrix t = RG_Matrix_M(T); - GrB_Matrix tt = RG_Matrix_M(RG_Matrix_getTranspose(T)); - GrB_Matrix adj_m = RG_Matrix_M(adj); - GrB_Matrix adj_tm = RG_Matrix_M(RG_Matrix_getTranspose(adj)); + Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); + Delta_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); + Delta_Matrix T = Graph_GetTargetRelationMatrix(g, r, false); + Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); + GrB_Matrix m = Delta_Matrix_M(M); + GrB_Matrix tm = Delta_Matrix_M(Delta_Matrix_getTranspose(M)); + GrB_Matrix s = Delta_Matrix_M(S); + GrB_Matrix ts = Delta_Matrix_M(Delta_Matrix_getTranspose(S)); + GrB_Matrix t = Delta_Matrix_M(T); + GrB_Matrix tt = Delta_Matrix_M(Delta_Matrix_getTranspose(T)); + GrB_Matrix adj_m = Delta_Matrix_M(adj); + GrB_Matrix adj_tm = Delta_Matrix_M(Delta_Matrix_getTranspose(adj)); UNUSED(info); diff --git a/tests/flow/test_graph_deletion.py b/tests/flow/test_graph_deletion.py index 74986e07c..ae4b8e0ad 100644 --- a/tests/flow/test_graph_deletion.py +++ b/tests/flow/test_graph_deletion.py @@ -348,7 +348,7 @@ def test18_delete_self_edge(self): def test19_random_delete(self): # test random graph deletion added as a result of a crash found in Graph_GetNodeEdges - # when iterating RG_Matrix of type BOOL with RG_MatrixTupleIter_next_UINT64 + # when iterating Delta_Matrix of type BOOL with Delta_MatrixTupleIter_next_UINT64 for i in range(1, 10): self.graph.delete() diff --git a/tests/unit/test_algebraic_expression.c b/tests/unit/test_algebraic_expression.c index 92c7f49c6..050076462 100644 --- a/tests/unit/test_algebraic_expression.c +++ b/tests/unit/test_algebraic_expression.c @@ -36,16 +36,16 @@ extern AR_ExpNode **_BuildReturnExpressions(const cypher_astnode_t *ret_clause, QueryGraph *qg; // Matrices. -RG_Matrix mat_p; -RG_Matrix mat_ef; -RG_Matrix mat_tef; -RG_Matrix mat_f; -RG_Matrix mat_ev; -RG_Matrix mat_tev; -RG_Matrix mat_c; -RG_Matrix mat_ew; -RG_Matrix mat_tew; -RG_Matrix mat_e; +Delta_Matrix mat_p; +Delta_Matrix mat_ef; +Delta_Matrix mat_tef; +Delta_Matrix mat_f; +Delta_Matrix mat_ev; +Delta_Matrix mat_tev; +Delta_Matrix mat_c; +Delta_Matrix mat_ew; +Delta_Matrix mat_tew; +Delta_Matrix mat_e; rax *_matrices; const char *query_no_intermidate_return_nodes = @@ -220,10 +220,10 @@ void _print_matrix(GrB_Matrix mat) { } } -bool _compare_matrices(GrB_Matrix expected, RG_Matrix actual) { +bool _compare_matrices(GrB_Matrix expected, Delta_Matrix actual) { GrB_Matrix a = expected; GrB_Matrix b = NULL; - RG_Matrix_export(&b, actual); + Delta_Matrix_export(&b, actual); GrB_Index acols, arows, avals; GrB_Index bcols, brows, bvals; @@ -340,7 +340,7 @@ void tearDown() { } void test_algebraicExpression() { - RG_Matrix matrix = NULL; + Delta_Matrix matrix = NULL; bool diagonal = false; const char *src = "src"; const char *dest = "dest"; @@ -596,25 +596,25 @@ void test_algebraicExpression_Transpose() { void test_Exp_OP_ADD() { // Exp = A + B - RG_Matrix A; - RG_Matrix B; - RG_Matrix res; + Delta_Matrix A; + Delta_Matrix B; + Delta_Matrix res; GrB_Matrix expected; // A // 1 1 // 0 0 - RG_Matrix_new(&A, GrB_BOOL, 2, 2, false); - RG_Matrix_setElement_BOOL(A, 0, 0); - RG_Matrix_setElement_BOOL(A, 0, 1); + Delta_Matrix_new(&A, GrB_BOOL, 2, 2, false); + Delta_Matrix_setElement_BOOL(A, 0, 0); + Delta_Matrix_setElement_BOOL(A, 0, 1); // B // 0 1 // 1 1 - RG_Matrix_new(&B, GrB_BOOL, 2, 2, false); - RG_Matrix_setElement_BOOL(B, 0, 1); - RG_Matrix_setElement_BOOL(B, 1, 0); - RG_Matrix_setElement_BOOL(B, 1, 1); + Delta_Matrix_new(&B, GrB_BOOL, 2, 2, false); + Delta_Matrix_setElement_BOOL(B, 0, 1); + Delta_Matrix_setElement_BOOL(B, 1, 0); + Delta_Matrix_setElement_BOOL(B, 1, 1); // expected // 1 1 @@ -632,7 +632,7 @@ void test_Exp_OP_ADD() { // Matrix used for intermidate computations of AlgebraicExpression_Eval // but also contains the result of expression evaluation. - RG_Matrix_new(&res, GrB_BOOL, 2, 2, false); + Delta_Matrix_new(&res, GrB_BOOL, 2, 2, false); AlgebraicExpression_Eval(exp, res); // Using the A matrix described above, @@ -640,33 +640,33 @@ void test_Exp_OP_ADD() { TEST_ASSERT(_compare_matrices(expected, res)); raxFree(matrices); - RG_Matrix_free(&A); - RG_Matrix_free(&B); - RG_Matrix_free(&res); + Delta_Matrix_free(&A); + Delta_Matrix_free(&B); + Delta_Matrix_free(&res); GrB_Matrix_free(&expected); AlgebraicExpression_Free(exp); } void test_Exp_OP_MUL() { // Exp = A * I - RG_Matrix A; - RG_Matrix i; - RG_Matrix res; + Delta_Matrix A; + Delta_Matrix i; + Delta_Matrix res; // A // 1 1 // 0 0 - RG_Matrix_new(&A, GrB_BOOL, 2, 2, false); - RG_Matrix_setElement_BOOL(A, 0, 0); - RG_Matrix_setElement_BOOL(A, 0, 1); - RG_Matrix_wait(A, true); // force flush + Delta_Matrix_new(&A, GrB_BOOL, 2, 2, false); + Delta_Matrix_setElement_BOOL(A, 0, 0); + Delta_Matrix_setElement_BOOL(A, 0, 1); + Delta_Matrix_wait(A, true); // force flush // I // 1 0 // 0 1 - RG_Matrix_new(&i, GrB_BOOL, 2, 2, false); - RG_Matrix_setElement_BOOL(i, 0, 0); - RG_Matrix_setElement_BOOL(i, 1, 1); + Delta_Matrix_new(&i, GrB_BOOL, 2, 2, false); + Delta_Matrix_setElement_BOOL(i, 0, 0); + Delta_Matrix_setElement_BOOL(i, 1, 1); rax *matrices = raxNew(); raxInsert(matrices, (unsigned char *)"A", strlen("A"), A, NULL); @@ -675,26 +675,26 @@ void test_Exp_OP_MUL() { // Matrix used for intermidate computations of AlgebraicExpression_Eval // but also contains the result of expression evaluation. - RG_Matrix_new(&res, GrB_BOOL, 2, 2, false); + Delta_Matrix_new(&res, GrB_BOOL, 2, 2, false); AlgebraicExpression_Eval(exp, res); // Using the A matrix described above, // A * I = A. GrB_Matrix expected; - RG_Matrix_export(&expected, A); + Delta_Matrix_export(&expected, A); TEST_ASSERT(_compare_matrices(expected, res)); raxFree(matrices); - RG_Matrix_free(&A); - RG_Matrix_free(&i); - RG_Matrix_free(&res); + Delta_Matrix_free(&A); + Delta_Matrix_free(&i); + Delta_Matrix_free(&res); GrB_Matrix_free(&expected); AlgebraicExpression_Free(exp); } void test_Exp_OP_ADD_Transpose() { // Exp = A + Transpose(A) - RG_Matrix res; + Delta_Matrix res; GrB_Matrix expected; /* We must use matrices that we've added to the graph, or else * the transpose optimization will erroneously use the adjacency matrix @@ -732,7 +732,7 @@ void test_Exp_OP_ADD_Transpose() { GrB_Matrix_setElement_BOOL(expected, true, 3, 0); // Matrix used for intermidate computations of AlgebraicExpression_Eval // but also contains the result of expression evaluation. - RG_Matrix_new(&res, GrB_BOOL, n, n, false); + Delta_Matrix_new(&res, GrB_BOOL, n, n, false); AlgebraicExpression *exp = AlgebraicExpression_FromString("V+tV", _matrices); AlgebraicExpression_Eval(exp, res); @@ -740,7 +740,7 @@ void test_Exp_OP_ADD_Transpose() { // A + Transpose(A) = B. TEST_ASSERT(_compare_matrices(expected, res)); - RG_Matrix_free(&res); + Delta_Matrix_free(&res); GrB_Matrix_free(&expected); AlgebraicExpression_Free(exp); } @@ -748,7 +748,7 @@ void test_Exp_OP_ADD_Transpose() { void test_Exp_OP_MUL_Transpose() { // Exp = Transpose(A) * A GrB_Matrix B; - RG_Matrix res; + Delta_Matrix res; /* We must use matrices that we've added to the graph, or else * the transpose optimization will erroneously use the adjacency matrix @@ -784,7 +784,7 @@ void test_Exp_OP_MUL_Transpose() { // Matrix used for intermidate computations of AlgebraicExpression_Eval // but also contains the result of expression evaluation. - RG_Matrix_new(&res, GrB_BOOL, n, n, false); + Delta_Matrix_new(&res, GrB_BOOL, n, n, false); // Transpose(A) * A AlgebraicExpression *exp = AlgebraicExpression_FromString("V*tV", _matrices); @@ -795,42 +795,42 @@ void test_Exp_OP_MUL_Transpose() { TEST_ASSERT(_compare_matrices(B, res)); GrB_Matrix_free(&B); - RG_Matrix_free(&res); + Delta_Matrix_free(&res); AlgebraicExpression_Free(exp); } void test_Exp_OP_A_MUL_B_Plus_C() { // Exp = A*(B+C) = A*B + A*C - RG_Matrix A; - RG_Matrix B; - RG_Matrix C; - RG_Matrix res; + Delta_Matrix A; + Delta_Matrix B; + Delta_Matrix C; + Delta_Matrix res; GrB_Matrix expected; // A // 1 1 // 0 0 - RG_Matrix_new(&A, GrB_BOOL, 2, 2, false); - RG_Matrix_setElement_BOOL(A, 0, 0); - RG_Matrix_setElement_BOOL(A, 0, 1); - RG_Matrix_wait(A, true); // force flush + Delta_Matrix_new(&A, GrB_BOOL, 2, 2, false); + Delta_Matrix_setElement_BOOL(A, 0, 0); + Delta_Matrix_setElement_BOOL(A, 0, 1); + Delta_Matrix_wait(A, true); // force flush // B // 1 0 // 0 0 - RG_Matrix_new(&B, GrB_BOOL, 2, 2, false); - RG_Matrix_setElement_BOOL(B, 0, 0); + Delta_Matrix_new(&B, GrB_BOOL, 2, 2, false); + Delta_Matrix_setElement_BOOL(B, 0, 0); // C // 0 0 // 0 1 - RG_Matrix_new(&C, GrB_BOOL, 2, 2, false); - RG_Matrix_setElement_BOOL(C, 1, 1); + Delta_Matrix_new(&C, GrB_BOOL, 2, 2, false); + Delta_Matrix_setElement_BOOL(C, 1, 1); // Matrix used for intermidate computations of AlgebraicExpression_Eval // but also contains the result of expression evaluation. - RG_Matrix_new(&res, GrB_BOOL, 2, 2, false); + Delta_Matrix_new(&res, GrB_BOOL, 2, 2, false); // A * (B+C) = A.rax *matrices = raxNew(); rax *matrices = raxNew(); @@ -849,10 +849,10 @@ void test_Exp_OP_A_MUL_B_Plus_C() { TEST_ASSERT(_compare_matrices(expected, res)); raxFree(matrices); - RG_Matrix_free(&A); - RG_Matrix_free(&B); - RG_Matrix_free(&C); - RG_Matrix_free(&res); + Delta_Matrix_free(&A); + Delta_Matrix_free(&B); + Delta_Matrix_free(&C); + Delta_Matrix_free(&res); GrB_Matrix_free(&expected); AlgebraicExpression_Free(exp); } @@ -860,13 +860,13 @@ void test_Exp_OP_A_MUL_B_Plus_C() { void test_ExpTransform_A_Times_B_Plus_C() { // Test Mul / Add transformation: // A*(B+C) -> A*B + A*C - RG_Matrix A; - RG_Matrix B; - RG_Matrix C; + Delta_Matrix A; + Delta_Matrix B; + Delta_Matrix C; - RG_Matrix_new(&A, GrB_BOOL, 2, 2, false); - RG_Matrix_new(&B, GrB_BOOL, 2, 2, false); - RG_Matrix_new(&C, GrB_BOOL, 2, 2, false); + Delta_Matrix_new(&A, GrB_BOOL, 2, 2, false); + Delta_Matrix_new(&B, GrB_BOOL, 2, 2, false); + Delta_Matrix_new(&C, GrB_BOOL, 2, 2, false); rax *matrices = raxNew(); raxInsert(matrices, (unsigned char *)"A", strlen("A"), A, NULL); @@ -899,24 +899,24 @@ void test_ExpTransform_A_Times_B_Plus_C() { TEST_ASSERT(rightRight->type == AL_OPERAND && rightRight->operand.matrix == B); raxFree(matrices); - RG_Matrix_free(&A); - RG_Matrix_free(&B); - RG_Matrix_free(&C); + Delta_Matrix_free(&A); + Delta_Matrix_free(&B); + Delta_Matrix_free(&C); AlgebraicExpression_Free(exp); } void test_ExpTransform_AB_Times_C_Plus_D() { // Test Mul / Add transformation: // A*B*(C+D) -> A*B*C + A*B*D - RG_Matrix A; - RG_Matrix B; - RG_Matrix C; - RG_Matrix D; + Delta_Matrix A; + Delta_Matrix B; + Delta_Matrix C; + Delta_Matrix D; - RG_Matrix_new(&A, GrB_BOOL, 2, 2, false); - RG_Matrix_new(&B, GrB_BOOL, 2, 2, false); - RG_Matrix_new(&C, GrB_BOOL, 2, 2, false); - RG_Matrix_new(&D, GrB_BOOL, 2, 2, false); + Delta_Matrix_new(&A, GrB_BOOL, 2, 2, false); + Delta_Matrix_new(&B, GrB_BOOL, 2, 2, false); + Delta_Matrix_new(&C, GrB_BOOL, 2, 2, false); + Delta_Matrix_new(&D, GrB_BOOL, 2, 2, false); // A*B*(C+D) -> A*B*C + A*B*D AlgebraicExpression *exp = AlgebraicExpression_NewOperand(C, false, NULL, @@ -959,24 +959,24 @@ void test_ExpTransform_AB_Times_C_Plus_D() { TEST_ASSERT(rightchild_2->type == AL_OPERAND && rightchild_2->operand.matrix == D); - RG_Matrix_free(&A); - RG_Matrix_free(&B); - RG_Matrix_free(&C); - RG_Matrix_free(&D); + Delta_Matrix_free(&A); + Delta_Matrix_free(&B); + Delta_Matrix_free(&C); + Delta_Matrix_free(&D); AlgebraicExpression_Free(exp); } void test_ExpTransform_A_Plus_B_Times_C_Plus_D() { // Test Mul / Add transformation: // (A+B)*(C+D) -> A*C + A*D + B*C + B*D - RG_Matrix A; - RG_Matrix B; - RG_Matrix C; - RG_Matrix D; - RG_Matrix_new(&A, GrB_BOOL, 2, 2, false); - RG_Matrix_new(&B, GrB_BOOL, 2, 2, false); - RG_Matrix_new(&C, GrB_BOOL, 2, 2, false); - RG_Matrix_new(&D, GrB_BOOL, 2, 2, false); + Delta_Matrix A; + Delta_Matrix B; + Delta_Matrix C; + Delta_Matrix D; + Delta_Matrix_new(&A, GrB_BOOL, 2, 2, false); + Delta_Matrix_new(&B, GrB_BOOL, 2, 2, false); + Delta_Matrix_new(&C, GrB_BOOL, 2, 2, false); + Delta_Matrix_new(&D, GrB_BOOL, 2, 2, false); rax *matrices = raxNew(); raxInsert(matrices, (unsigned char *)"A", strlen("A"), A, NULL); @@ -1009,10 +1009,10 @@ void test_ExpTransform_A_Plus_B_Times_C_Plus_D() { TEST_ASSERT(strcmp("(((A * C + A * D) + B * C) + B * D)", exp_str) == 0); rm_free(exp_str); raxFree(matrices); - RG_Matrix_free(&A); - RG_Matrix_free(&B); - RG_Matrix_free(&C); - RG_Matrix_free(&D); + Delta_Matrix_free(&A); + Delta_Matrix_free(&B); + Delta_Matrix_free(&C); + Delta_Matrix_free(&D); AlgebraicExpression_Free(exp); } @@ -1514,15 +1514,15 @@ void test_ExpressionExecute() { TEST_ASSERT(strcmp(AlgebraicExpression_Src(exp), "p") == 0); TEST_ASSERT(strcmp(AlgebraicExpression_Dest(exp), "e") == 0); - RG_Matrix res; - RG_Matrix_new(&res, GrB_BOOL, Graph_RequiredMatrixDim(g), + Delta_Matrix res; + Delta_Matrix_new(&res, GrB_BOOL, Graph_RequiredMatrixDim(g), Graph_RequiredMatrixDim(g), false); AlgebraicExpression_Eval(exp, res); // Validate result matrix. GrB_Index ncols, nrows; - RG_Matrix_ncols(&ncols, res); - RG_Matrix_nrows(&nrows, res); + Delta_Matrix_ncols(&ncols, res); + Delta_Matrix_nrows(&nrows, res); assert(ncols == Graph_RequiredMatrixDim(g)); assert(nrows == Graph_RequiredMatrixDim(g)); @@ -1537,7 +1537,7 @@ void test_ExpressionExecute() { assert(_compare_matrices(expected, res)); // Clean up - RG_Matrix_free(&res); + Delta_Matrix_free(&res); GrB_Matrix_free(&expected); free_algebraic_expressions(ae, exp_count); array_free(ae); @@ -1754,7 +1754,7 @@ void test_RemoveOperand() { void test_LocateOperand() { // construct algebraic expression bool located = false; - RG_Matrix mat = NULL; + Delta_Matrix mat = NULL; AlgebraicExpression *A = NULL; AlgebraicExpression *B = NULL; AlgebraicExpression *r = NULL; diff --git a/tests/unit/test_rg_matrix.c b/tests/unit/test_delta_matrix.c similarity index 61% rename from tests/unit/test_rg_matrix.c rename to tests/unit/test_delta_matrix.c index fdadfbfc1..52439d22b 100644 --- a/tests/unit/test_rg_matrix.c +++ b/tests/unit/test_delta_matrix.c @@ -6,7 +6,7 @@ #include "src/util/rmalloc.h" #include "src/configuration/config.h" -#include "src/graph/rg_matrix/rg_matrix.h" +#include "src/graph/delta_matrix/delta_matrix.h" #include @@ -131,83 +131,83 @@ void ASSERT_GrB_Matrices_EQ(const GrB_Matrix A, const GrB_Matrix B) TEST_ASSERT(info == GrB_SUCCESS); } -// test RGMatrix initialization -void test_RGMatrix_new() { - RG_Matrix A = NULL; - GrB_Matrix M = NULL; - GrB_Matrix DP = NULL; - GrB_Matrix DM = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nvals = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; +// test DeltaMatrix initialization +void test_DeltaMatrix_new() { + Delta_Matrix A = NULL; + GrB_Matrix M = NULL; + GrB_Matrix DP = NULL; + GrB_Matrix DM = NULL; + GrB_Type t = GrB_BOOL; + GrB_Info info = GrB_SUCCESS; + GrB_Index nvals = 0; + GrB_Index nrows = 100; + GrB_Index ncols = 100; - info = RG_Matrix_new(&A, t, nrows, ncols, false); + info = Delta_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_Matrix_M(A); - DP = RG_Matrix_DP(A); - DM = RG_Matrix_DM(A); + M = Delta_Matrix_M(A); + DP = Delta_Matrix_DP(A); + DM = Delta_Matrix_DM(A); // bool matrix do not maintain transpose - TEST_ASSERT(RG_Matrix_getTranspose(A) == NULL); + TEST_ASSERT(Delta_Matrix_getTranspose(A) == NULL); // a new empty matrix should be synced // no data in either DP or DM - TEST_ASSERT(!RG_Matrix_isDirty(A)); + TEST_ASSERT(!Delta_Matrix_isDirty(A)); // matrix should be empty M_EMPTY(); DP_EMPTY(); DM_EMPTY(); - RG_Matrix_nvals(&nvals, A); + Delta_Matrix_nvals(&nvals, A); TEST_ASSERT(nvals == 0); - RG_Matrix_free(&A); + Delta_Matrix_free(&A); TEST_ASSERT(A == NULL); } -void test_RGMatrix_set() { - GrB_Type t = GrB_BOOL; - RG_Matrix A = NULL; - GrB_Matrix M = NULL; - GrB_Matrix DP = NULL; - GrB_Matrix DM = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nvals = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - GrB_Index i = 0; - GrB_Index j = 1; +void test_DeltaMatrix_set() { + GrB_Type t = GrB_BOOL; + Delta_Matrix A = NULL; + GrB_Matrix M = NULL; + GrB_Matrix DP = NULL; + GrB_Matrix DM = NULL; + GrB_Info info = GrB_SUCCESS; + GrB_Index nvals = 0; + GrB_Index nrows = 100; + GrB_Index ncols = 100; + GrB_Index i = 0; + GrB_Index j = 1; - info = RG_Matrix_new(&A, t, nrows, ncols, false); + info = Delta_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_Matrix_M(A); - DP = RG_Matrix_DP(A); - DM = RG_Matrix_DM(A); + M = Delta_Matrix_M(A); + DP = Delta_Matrix_DP(A); + DM = Delta_Matrix_DM(A); //-------------------------------------------------------------------------- // Set element that marked for deletion //-------------------------------------------------------------------------- // set element at position i,j - info = RG_Matrix_setElement_BOOL(A, i, j); + info = Delta_Matrix_setElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); // force sync // entry should migrated from 'delta-plus' to 'M' - RG_Matrix_wait(A, true); + Delta_Matrix_wait(A, true); // set element at position i,j - info = RG_Matrix_removeElement_BOOL(A, i, j); + info = Delta_Matrix_removeElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); // set element at position i,j - info = RG_Matrix_setElement_BOOL(A, i, j); + info = Delta_Matrix_setElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- @@ -215,7 +215,7 @@ void test_RGMatrix_set() { //-------------------------------------------------------------------------- // A should be empty - RG_Matrix_nvals(&nvals, A); + Delta_Matrix_nvals(&nvals, A); TEST_ASSERT(nvals == 1); // M should contain a single element @@ -232,36 +232,36 @@ void test_RGMatrix_set() { // clean up //-------------------------------------------------------------------------- - RG_Matrix_free(&A); + Delta_Matrix_free(&A); TEST_ASSERT(A == NULL); } // flush simple addition -void test_RGMatrix_flush() { - GrB_Type t = GrB_BOOL; - RG_Matrix A = NULL; - GrB_Matrix M = NULL; - GrB_Matrix DP = NULL; - GrB_Matrix DM = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nvals = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - GrB_Index i = 0; - GrB_Index j = 1; - bool sync = false; - - info = RG_Matrix_new(&A, t, nrows, ncols, false); +void test_DeltaMatrix_flush() { + GrB_Type t = GrB_BOOL; + Delta_Matrix A = NULL; + GrB_Matrix M = NULL; + GrB_Matrix DP = NULL; + GrB_Matrix DM = NULL; + GrB_Info info = GrB_SUCCESS; + GrB_Index nvals = 0; + GrB_Index nrows = 100; + GrB_Index ncols = 100; + GrB_Index i = 0; + GrB_Index j = 1; + bool sync = false; + + info = Delta_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // set element at position i,j - info = RG_Matrix_setElement_BOOL(A, i, j); + info = Delta_Matrix_setElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_Matrix_M(A); - DP = RG_Matrix_DP(A); - DM = RG_Matrix_DM(A); + M = Delta_Matrix_M(A); + DP = Delta_Matrix_DP(A); + DM = Delta_Matrix_DM(A); //-------------------------------------------------------------------------- // flush matrix, no sync @@ -269,7 +269,7 @@ void test_RGMatrix_flush() { // wait, don't force sync sync = false; - RG_Matrix_wait(A, sync); + Delta_Matrix_wait(A, sync); // M should be empty M_EMPTY(); @@ -286,9 +286,9 @@ void test_RGMatrix_flush() { // wait, force sync sync = true; - RG_Matrix_wait(A, sync); + Delta_Matrix_wait(A, sync); - RG_Matrix_nvals(&nvals, A); + Delta_Matrix_nvals(&nvals, A); TEST_ASSERT(nvals == 1); // M should be empty @@ -301,33 +301,33 @@ void test_RGMatrix_flush() { DP_EMPTY(); // clean up - RG_Matrix_free(&A); + Delta_Matrix_free(&A); TEST_ASSERT(A == NULL); } //------------------------------------------------------------------------------ -// fuzzy test compare RG_Matrix to GrB_Matrix +// fuzzy test compare Delta_Matrix to GrB_Matrix //------------------------------------------------------------------------------ -void test_RGMatrix_fuzzy() { - GrB_Type t = GrB_BOOL; - RG_Matrix A = NULL; - RG_Matrix T = NULL; // A transposed - GrB_Matrix M = NULL; // primary internal matrix - GrB_Matrix MT = NULL; - GrB_Matrix N = NULL; - GrB_Matrix NT = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - GrB_Index i = 0; - GrB_Index j = 1; - GrB_Index* II = NULL; - GrB_Index* J = NULL; - uint32_t operations = 10000; +void test_DeltaMatrix_fuzzy() { + GrB_Type t = GrB_BOOL; + Delta_Matrix A = NULL; + Delta_Matrix T = NULL; // A transposed + GrB_Matrix M = NULL; // primary internal matrix + GrB_Matrix MT = NULL; + GrB_Matrix N = NULL; + GrB_Matrix NT = NULL; + GrB_Info info = GrB_SUCCESS; + GrB_Index nrows = 100; + GrB_Index ncols = 100; + GrB_Index i = 0; + GrB_Index j = 1; + GrB_Index* II = NULL; + GrB_Index* J = NULL; + uint32_t operations = 10000; //-------------------------------------------------------------------------- - // create RGMatrix + // create DeltaMatrix //-------------------------------------------------------------------------- srand(time(0)); @@ -335,17 +335,17 @@ void test_RGMatrix_fuzzy() { II = (GrB_Index*) malloc(sizeof(GrB_Index) * operations); J = (GrB_Index*) malloc(sizeof(GrB_Index) * operations); - info = RG_Matrix_new(&A, t, nrows, ncols, true); + info = Delta_Matrix_new(&A, t, nrows, ncols, true); TEST_ASSERT(info == GrB_SUCCESS); // make sure transposed was created - T = RG_Matrix_getTranspose(A); + T = Delta_Matrix_getTranspose(A); TEST_ASSERT(T != A); TEST_ASSERT(T != NULL); // get internal matrices - M = RG_Matrix_M(A); - MT = RG_Matrix_M(T); + M = Delta_Matrix_M(A); + MT = Delta_Matrix_M(T); info = GrB_Matrix_new(&N, t, nrows, ncols); TEST_ASSERT(info == GrB_SUCCESS); @@ -365,7 +365,7 @@ void test_RGMatrix_fuzzy() { // set element at position i,j //------------------------------------------------------------------ - info = RG_Matrix_setElement_BOOL(A, i, j); + info = Delta_Matrix_setElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); info = GrB_Matrix_setElement_BOOL(N, true, i, j); @@ -385,7 +385,7 @@ void test_RGMatrix_fuzzy() { // delete element at position i,j //------------------------------------------------------------------ - RG_Matrix_removeElement_BOOL(A, i, j); + Delta_Matrix_removeElement_BOOL(A, i, j); GrB_Matrix_removeElement(N, i, j); } @@ -395,7 +395,7 @@ void test_RGMatrix_fuzzy() { // flush matrix //-------------------------------------------------------------------------- - RG_Matrix_wait(A, true); + Delta_Matrix_wait(A, true); //-------------------------------------------------------------------------- // validation @@ -411,7 +411,7 @@ void test_RGMatrix_fuzzy() { // clean up //-------------------------------------------------------------------------- - RG_Matrix_free(&A); + Delta_Matrix_free(&A); TEST_ASSERT(A == NULL); info = GrB_Matrix_free(&N); @@ -424,31 +424,31 @@ void test_RGMatrix_fuzzy() { free(J); } -// test exporting RG_Matrix to GrB_Matrix when there are no pending changes +// test exporting Delta_Matrix to GrB_Matrix when there are no pending changes // by exporting the matrix after flushing -void test_RGMatrix_export_no_changes() { - GrB_Type t = GrB_BOOL; - RG_Matrix A = NULL; - GrB_Matrix M = NULL; - GrB_Matrix N = NULL; // exported matrix - GrB_Info info = GrB_SUCCESS; - GrB_Index i = 0; - GrB_Index j = 1; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool sync = false; +void test_DeltaMatrix_export_no_changes() { + GrB_Type t = GrB_BOOL; + Delta_Matrix A = NULL; + GrB_Matrix M = NULL; + GrB_Matrix N = NULL; // exported matrix + GrB_Info info = GrB_SUCCESS; + GrB_Index i = 0; + GrB_Index j = 1; + GrB_Index nrows = 100; + GrB_Index ncols = 100; + bool sync = false; - info = RG_Matrix_new(&A, t, nrows, ncols, false); + info = Delta_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_Matrix_M(A); + M = Delta_Matrix_M(A); //-------------------------------------------------------------------------- // export empty matrix //-------------------------------------------------------------------------- - info = RG_Matrix_export(&N, A); + info = Delta_Matrix_export(&N, A); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- @@ -463,7 +463,7 @@ void test_RGMatrix_export_no_changes() { //-------------------------------------------------------------------------- // set element at position i,j - info = RG_Matrix_setElement_BOOL(A, i, j); + info = Delta_Matrix_setElement_BOOL(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- @@ -472,13 +472,13 @@ void test_RGMatrix_export_no_changes() { // wait, force sync sync = true; - RG_Matrix_wait(A, sync); + Delta_Matrix_wait(A, sync); //-------------------------------------------------------------------------- // validation //-------------------------------------------------------------------------- - info = RG_Matrix_export(&N, A); + info = Delta_Matrix_export(&N, A); TEST_ASSERT(info == GrB_SUCCESS); ASSERT_GrB_Matrices_EQ(M, N); @@ -487,33 +487,33 @@ void test_RGMatrix_export_no_changes() { // clean up //-------------------------------------------------------------------------- - RG_Matrix_free(&A); + Delta_Matrix_free(&A); GrB_Matrix_free(&N); } -// test exporting RG_Matrix to GrB_Matrix when there are pending changes +// test exporting Delta_Matrix to GrB_Matrix when there are pending changes // by exporting the matrix after making changes // then flush the matrix and compare the internal matrix to the exported matrix -void test_RGMatrix_export_pending_changes() { - GrB_Type t = GrB_BOOL; - RG_Matrix A = NULL; - GrB_Matrix M = NULL; - GrB_Matrix N = NULL; // exported matrix - GrB_Info info = GrB_SUCCESS; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool sync = false; +void test_DeltaMatrix_export_pending_changes() { + GrB_Type t = GrB_BOOL; + Delta_Matrix A = NULL; + GrB_Matrix M = NULL; + GrB_Matrix N = NULL; // exported matrix + GrB_Info info = GrB_SUCCESS; + GrB_Index nrows = 100; + GrB_Index ncols = 100; + bool sync = false; - info = RG_Matrix_new(&A, t, nrows, ncols, false); + info = Delta_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // get internal matrices - M = RG_Matrix_M(A); + M = Delta_Matrix_M(A); // set elements - info = RG_Matrix_setElement_BOOL(A, 0, 0); + info = Delta_Matrix_setElement_BOOL(A, 0, 0); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_setElement_BOOL(A, 1, 1); + info = Delta_Matrix_setElement_BOOL(A, 1, 1); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- @@ -522,25 +522,25 @@ void test_RGMatrix_export_pending_changes() { // wait, force sync sync = true; - RG_Matrix_wait(A, sync); + Delta_Matrix_wait(A, sync); //-------------------------------------------------------------------------- // set pending changes //-------------------------------------------------------------------------- // remove element at position 0,0 - info = RG_Matrix_removeElement_BOOL(A, 0, 0); + info = Delta_Matrix_removeElement_BOOL(A, 0, 0); TEST_ASSERT(info == GrB_SUCCESS); // set element at position 2,2 - info = RG_Matrix_setElement_BOOL(A, 2, 2); + info = Delta_Matrix_setElement_BOOL(A, 2, 2); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- // export matrix //-------------------------------------------------------------------------- - info = RG_Matrix_export(&N, A); + info = Delta_Matrix_export(&N, A); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- @@ -549,7 +549,7 @@ void test_RGMatrix_export_pending_changes() { // wait, force sync sync = true; - RG_Matrix_wait(A, sync); + Delta_Matrix_wait(A, sync); //-------------------------------------------------------------------------- // validation @@ -559,35 +559,35 @@ void test_RGMatrix_export_pending_changes() { // clean up GrB_Matrix_free(&N); - RG_Matrix_free(&A); + Delta_Matrix_free(&A); TEST_ASSERT(A == NULL); } -void test_RGMatrix_copy() { - GrB_Type t = GrB_BOOL; - RG_Matrix A = NULL; - RG_Matrix B = NULL; - GrB_Matrix A_M = NULL; - GrB_Matrix B_M = NULL; - GrB_Matrix A_DP = NULL; - GrB_Matrix B_DP = NULL; - GrB_Matrix A_DM = NULL; - GrB_Matrix B_DM = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool sync = false; +void test_DeltaMatrix_copy() { + GrB_Type t = GrB_BOOL; + Delta_Matrix A = NULL; + Delta_Matrix B = NULL; + GrB_Matrix A_M = NULL; + GrB_Matrix B_M = NULL; + GrB_Matrix A_DP = NULL; + GrB_Matrix B_DP = NULL; + GrB_Matrix A_DM = NULL; + GrB_Matrix B_DM = NULL; + GrB_Info info = GrB_SUCCESS; + GrB_Index nrows = 100; + GrB_Index ncols = 100; + bool sync = false; - info = RG_Matrix_new(&A, t, nrows, ncols, false); + info = Delta_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_new(&B, t, nrows, ncols, false); + info = Delta_Matrix_new(&B, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // set elements - info = RG_Matrix_setElement_BOOL(A, 0, 0); + info = Delta_Matrix_setElement_BOOL(A, 0, 0); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_setElement_BOOL(A, 1, 1); + info = Delta_Matrix_setElement_BOOL(A, 1, 1); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- @@ -596,82 +596,82 @@ void test_RGMatrix_copy() { // wait, force sync sync = true; - RG_Matrix_wait(A, sync); + Delta_Matrix_wait(A, sync); //-------------------------------------------------------------------------- // set pending changes //-------------------------------------------------------------------------- // remove element at position 0,0 - info = RG_Matrix_removeElement_BOOL(A, 0, 0); + info = Delta_Matrix_removeElement_BOOL(A, 0, 0); TEST_ASSERT(info == GrB_SUCCESS); // set element at position 2,2 - info = RG_Matrix_setElement_BOOL(A, 2, 2); + info = Delta_Matrix_setElement_BOOL(A, 2, 2); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- // copy matrix //-------------------------------------------------------------------------- - info = RG_Matrix_copy(B, A); + info = Delta_Matrix_copy(B, A); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- // validation //-------------------------------------------------------------------------- - A_M = RG_Matrix_M(A); - B_M = RG_Matrix_M(B); - A_DP = RG_Matrix_DP(A); - B_DP = RG_Matrix_DP(B); - A_DM = RG_Matrix_DM(A); - B_DM = RG_Matrix_DM(B); + A_M = Delta_Matrix_M(A); + B_M = Delta_Matrix_M(B); + A_DP = Delta_Matrix_DP(A); + B_DP = Delta_Matrix_DP(B); + A_DM = Delta_Matrix_DM(A); + B_DM = Delta_Matrix_DM(B); ASSERT_GrB_Matrices_EQ(A_M, B_M); ASSERT_GrB_Matrices_EQ(A_DP, B_DP); ASSERT_GrB_Matrices_EQ(A_DM, B_DM); // clean up - RG_Matrix_free(&A); + Delta_Matrix_free(&A); TEST_ASSERT(A == NULL); - RG_Matrix_free(&B); + Delta_Matrix_free(&B); TEST_ASSERT(B == NULL); } -void test_RGMatrix_mxm() { - GrB_Type t = GrB_BOOL; - RG_Matrix A = NULL; - RG_Matrix B = NULL; - RG_Matrix C = NULL; - RG_Matrix D = NULL; - GrB_Matrix C_M = NULL; - GrB_Matrix D_M = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool sync = false; +void test_DeltaMatrix_mxm() { + GrB_Type t = GrB_BOOL; + Delta_Matrix A = NULL; + Delta_Matrix B = NULL; + Delta_Matrix C = NULL; + Delta_Matrix D = NULL; + GrB_Matrix C_M = NULL; + GrB_Matrix D_M = NULL; + GrB_Info info = GrB_SUCCESS; + GrB_Index nrows = 100; + GrB_Index ncols = 100; + bool sync = false; - info = RG_Matrix_new(&A, t, nrows, ncols, false); + info = Delta_Matrix_new(&A, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_new(&B, t, nrows, ncols, false); + info = Delta_Matrix_new(&B, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_new(&C, t, nrows, ncols, false); + info = Delta_Matrix_new(&C, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_new(&D, t, nrows, ncols, false); + info = Delta_Matrix_new(&D, t, nrows, ncols, false); TEST_ASSERT(info == GrB_SUCCESS); // set elements - info = RG_Matrix_setElement_BOOL(A, 0, 1); + info = Delta_Matrix_setElement_BOOL(A, 0, 1); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_setElement_BOOL(A, 2, 3); + info = Delta_Matrix_setElement_BOOL(A, 2, 3); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_setElement_BOOL(B, 1, 2); + info = Delta_Matrix_setElement_BOOL(B, 1, 2); TEST_ASSERT(info == GrB_SUCCESS); - info = RG_Matrix_setElement_BOOL(B, 3, 4); + info = Delta_Matrix_setElement_BOOL(B, 3, 4); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- @@ -680,61 +680,61 @@ void test_RGMatrix_mxm() { // wait, force sync sync = true; - RG_Matrix_wait(A, sync); - RG_Matrix_wait(B, sync); + Delta_Matrix_wait(A, sync); + Delta_Matrix_wait(B, sync); //-------------------------------------------------------------------------- // set pending changes //-------------------------------------------------------------------------- // remove element at position 0,0 - info = RG_Matrix_removeElement_BOOL(B, 1, 2); + info = Delta_Matrix_removeElement_BOOL(B, 1, 2); TEST_ASSERT(info == GrB_SUCCESS); // set element at position 1,3 - info = RG_Matrix_setElement_BOOL(B, 1, 3); + info = Delta_Matrix_setElement_BOOL(B, 1, 3); TEST_ASSERT(info == GrB_SUCCESS); //-------------------------------------------------------------------------- // mxm matrix //-------------------------------------------------------------------------- - info = RG_mxm(C, GxB_ANY_PAIR_BOOL, A, B); + info = Delta_mxm(C, GxB_ANY_PAIR_BOOL, A, B); TEST_ASSERT(info == GrB_SUCCESS); - RG_Matrix_wait(B, sync); + Delta_Matrix_wait(B, sync); - info = RG_mxm(D, GxB_ANY_PAIR_BOOL, A, B); + info = Delta_mxm(D, GxB_ANY_PAIR_BOOL, A, B); //-------------------------------------------------------------------------- // validation //-------------------------------------------------------------------------- - C_M = RG_Matrix_M(C); - D_M = RG_Matrix_M(D); + C_M = Delta_Matrix_M(C); + D_M = Delta_Matrix_M(D); ASSERT_GrB_Matrices_EQ(C_M, D_M); // clean up - RG_Matrix_free(&A); + Delta_Matrix_free(&A); TEST_ASSERT(A == NULL); - RG_Matrix_free(&B); + Delta_Matrix_free(&B); TEST_ASSERT(B == NULL); - RG_Matrix_free(&C); + Delta_Matrix_free(&C); TEST_ASSERT(C == NULL); - RG_Matrix_free(&D); + Delta_Matrix_free(&D); TEST_ASSERT(C == NULL); } -void test_RGMatrix_resize() { - RG_Matrix A = NULL; - RG_Matrix T = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Type t = GrB_BOOL; - GrB_Index nrows = 10; - GrB_Index ncols = 20; +void test_DeltaMatrix_resize() { + Delta_Matrix A = NULL; + Delta_Matrix T = NULL; + GrB_Info info = GrB_SUCCESS; + GrB_Type t = GrB_BOOL; + GrB_Index nrows = 10; + GrB_Index ncols = 20; - info = RG_Matrix_new(&A, t, nrows, ncols, true); - T = RG_Matrix_getTranspose(A); + info = Delta_Matrix_new(&A, t, nrows, ncols, true); + T = Delta_Matrix_getTranspose(A); GrB_Index A_nrows; GrB_Index A_ncols; @@ -742,17 +742,17 @@ void test_RGMatrix_resize() { GrB_Index T_ncols; // verify A and T dimensions - RG_Matrix_nrows(&A_nrows, A); + Delta_Matrix_nrows(&A_nrows, A); TEST_ASSERT(info == GrB_SUCCESS); - RG_Matrix_ncols(&A_ncols, A); + Delta_Matrix_ncols(&A_ncols, A); TEST_ASSERT(info == GrB_SUCCESS); TEST_ASSERT(A_nrows == nrows); TEST_ASSERT(A_ncols == ncols); - RG_Matrix_nrows(&T_nrows, T); + Delta_Matrix_nrows(&T_nrows, T); TEST_ASSERT(info == GrB_SUCCESS); - RG_Matrix_ncols(&T_ncols, T); + Delta_Matrix_ncols(&T_ncols, T); TEST_ASSERT(info == GrB_SUCCESS); TEST_ASSERT(T_nrows == ncols); @@ -762,21 +762,21 @@ void test_RGMatrix_resize() { nrows *= 2; ncols *= 2; - info = RG_Matrix_resize(A, nrows, ncols); + info = Delta_Matrix_resize(A, nrows, ncols); TEST_ASSERT(info == GrB_SUCCESS); // verify A and T dimensions - RG_Matrix_nrows(&A_nrows, A); + Delta_Matrix_nrows(&A_nrows, A); TEST_ASSERT(info == GrB_SUCCESS); - RG_Matrix_ncols(&A_ncols, A); + Delta_Matrix_ncols(&A_ncols, A); TEST_ASSERT(info == GrB_SUCCESS); TEST_ASSERT(A_nrows == nrows); TEST_ASSERT(A_ncols == ncols); - RG_Matrix_nrows(&T_nrows, T); + Delta_Matrix_nrows(&T_nrows, T); TEST_ASSERT(info == GrB_SUCCESS); - RG_Matrix_ncols(&T_ncols, T); + Delta_Matrix_ncols(&T_ncols, T); TEST_ASSERT(info == GrB_SUCCESS); TEST_ASSERT(T_nrows == ncols); @@ -786,113 +786,113 @@ void test_RGMatrix_resize() { nrows /= 2; ncols /= 2; - info = RG_Matrix_resize(A, nrows, ncols); + info = Delta_Matrix_resize(A, nrows, ncols); TEST_ASSERT(info == GrB_SUCCESS); // verify A and T dimensions - RG_Matrix_nrows(&A_nrows, A); + Delta_Matrix_nrows(&A_nrows, A); TEST_ASSERT(info == GrB_SUCCESS); - RG_Matrix_ncols(&A_ncols, A); + Delta_Matrix_ncols(&A_ncols, A); TEST_ASSERT(info == GrB_SUCCESS); TEST_ASSERT(A_nrows == nrows); TEST_ASSERT(A_ncols == ncols); - RG_Matrix_nrows(&T_nrows, T); + Delta_Matrix_nrows(&T_nrows, T); TEST_ASSERT(info == GrB_SUCCESS); - RG_Matrix_ncols(&T_ncols, T); + Delta_Matrix_ncols(&T_ncols, T); TEST_ASSERT(info == GrB_SUCCESS); TEST_ASSERT(T_nrows == ncols); TEST_ASSERT(T_ncols == nrows); - RG_Matrix_free(&A); + Delta_Matrix_free(&A); } TEST_LIST = { - {"RGMatrix_new", test_RGMatrix_new}, - {"RGMatrix_set", test_RGMatrix_set}, - {"RGMatrix_flush", test_RGMatrix_flush}, - {"RGMatrix_fuzzy", test_RGMatrix_fuzzy}, - {"RGMatrix_export_no_changes", test_RGMatrix_export_no_changes}, - {"RGMatrix_export_pending_changes", test_RGMatrix_export_pending_changes}, - {"RGMatrix_copy", test_RGMatrix_copy}, - {"RGMatrix_mxm", test_RGMatrix_mxm}, - {"RGMatrix_resize", test_RGMatrix_resize}, + {"DeltaMatrix_new", test_DeltaMatrix_new}, + {"DeltaMatrix_set", test_DeltaMatrix_set}, + {"DeltaMatrix_flush", test_DeltaMatrix_flush}, + {"DeltaMatrix_fuzzy", test_DeltaMatrix_fuzzy}, + {"DeltaMatrix_export_no_changes", test_DeltaMatrix_export_no_changes}, + {"DeltaMatrix_export_pending_changes", test_DeltaMatrix_export_pending_changes}, + {"DeltaMatrix_copy", test_DeltaMatrix_copy}, + {"DeltaMatrix_mxm", test_DeltaMatrix_mxm}, + {"DeltaMatrix_resize", test_DeltaMatrix_resize}, {NULL, NULL} }; //#ifndef RG_DEBUG -//// test RGMatrix_pending +//// test DeltaMatrix_pending //// if RG_DEBUG is defined, each call to setElement will flush all 3 matrices //// causing this test to fail -//TEST_F(RGMatrixTest, RGMatrix_pending) { -// RG_Matrix A = NULL; -// GrB_Info info = GrB_SUCCESS; -// GrB_Type t = GrB_UINT64; -// GrB_Index nrows = 100; -// GrB_Index ncols = 100; -// bool pending = false; +//TEST_F(DeltaMatrixTest, DeltaMatrix_pending) { +// Delta_Matrix A = NULL; +// GrB_Info info = GrB_SUCCESS; +// GrB_Type t = GrB_UINT64; +// GrB_Index nrows = 100; +// GrB_Index ncols = 100; +// bool pending = false; // -// info = RG_Matrix_new(&A, t, nrows, ncols); +// info = Delta_Matrix_new(&A, t, nrows, ncols); // ASSERT_EQ(info, GrB_SUCCESS); // -// // new RG_Matrix shouldn't have any pending operations -// info = RG_Matrix_pending(A, &pending); +// // new Delta_Matrix shouldn't have any pending operations +// info = Delta_Matrix_pending(A, &pending); // ASSERT_EQ(info, GrB_SUCCESS); // ASSERT_FALSE(pending); // // // set element, modifies delta-plus -// info = RG_Matrix_setElement_UINT64(A, 2, 2, 2); +// info = Delta_Matrix_setElement_UINT64(A, 2, 2, 2); // ASSERT_EQ(info, GrB_SUCCESS); // // // expecting pending changes -// info = RG_Matrix_pending(A, &pending); +// info = Delta_Matrix_pending(A, &pending); // ASSERT_EQ(info, GrB_SUCCESS); // ASSERT_TRUE(pending); // // // flush pending changes on both DP and DM -// info = RG_Matrix_wait(A, false); +// info = Delta_Matrix_wait(A, false); // ASSERT_EQ(info, GrB_SUCCESS); // // // expecting no pending changes -// info = RG_Matrix_pending(A, &pending); +// info = Delta_Matrix_pending(A, &pending); // ASSERT_EQ(info, GrB_SUCCESS); // ASSERT_FALSE(pending); // // // remove entry, DP entry is now a zombie -// info = RG_Matrix_removeElement_UINT64(A, 2, 2); +// info = Delta_Matrix_removeElement_UINT64(A, 2, 2); // ASSERT_EQ(info, GrB_SUCCESS); // // // expecting pending changes -// info = RG_Matrix_pending(A, &pending); +// info = Delta_Matrix_pending(A, &pending); // ASSERT_EQ(info, GrB_SUCCESS); // ASSERT_TRUE(pending); // // // flush pending changes on both DP and DM -// info = RG_Matrix_wait(A, false); +// info = Delta_Matrix_wait(A, false); // ASSERT_EQ(info, GrB_SUCCESS); // // // expecting no pending changes -// info = RG_Matrix_pending(A, &pending); +// info = Delta_Matrix_pending(A, &pending); // ASSERT_EQ(info, GrB_SUCCESS); // ASSERT_FALSE(pending); // // // set element, modifies delta-plus -// info = RG_Matrix_setElement_UINT64(A, 2, 2, 2); +// info = Delta_Matrix_setElement_UINT64(A, 2, 2, 2); // ASSERT_EQ(info, GrB_SUCCESS); // // // flush pending changes on M, DM and DP -// info = RG_Matrix_wait(A, true); +// info = Delta_Matrix_wait(A, true); // ASSERT_EQ(info, GrB_SUCCESS); // // // expecting no pending changes -// info = RG_Matrix_pending(A, &pending); +// info = Delta_Matrix_pending(A, &pending); // ASSERT_EQ(info, GrB_SUCCESS); // ASSERT_FALSE(pending); // // // clean up -// RG_Matrix_free(&A); +// Delta_Matrix_free(&A); // ASSERT_TRUE(A == NULL); //} //#endif diff --git a/tests/unit/test_delta_matrix_iter.c b/tests/unit/test_delta_matrix_iter.c new file mode 100644 index 000000000..8481b6044 --- /dev/null +++ b/tests/unit/test_delta_matrix_iter.c @@ -0,0 +1,393 @@ +/* + * Copyright Redis Ltd. 2018 - present + * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or + * the Server Side Public License v1 (SSPLv1). + */ + +#include "src/util/rmalloc.h" +#include "src/configuration/config.h" +#include "src/graph/delta_matrix/delta_matrix.h" +#include "src/graph/delta_matrix/delta_matrix_iter.h" + +void setup() { + Alloc_Reset(); + + // initialize GraphBLAS + GrB_init(GrB_NONBLOCKING); + + // all matrices in CSR format + GxB_Global_Option_set(GxB_FORMAT, GxB_BY_ROW); + + // set delta matrix flush threshold + Config_Option_set(Config_DELTA_MAX_PENDING_CHANGES, "10000", NULL); +} + +void tearDown() { + GrB_finalize(); +} + +#define TEST_INIT setup(); +#define TEST_FINI tearDown(); +#include "acutest.h" + +// test DeltaMatrixTupleIter initialization +void test_DeltaMatrixTupleIter_attach() { + Delta_Matrix A = NULL; + GrB_Type t = GrB_BOOL; + GrB_Info info = GrB_SUCCESS; + GrB_Index nrows = 100; + GrB_Index ncols = 100; + Delta_MatrixTupleIter iter; + memset(&iter, 0, sizeof(Delta_MatrixTupleIter)); + + info = Delta_Matrix_new(&A, t, nrows, ncols, false); + TEST_ASSERT(info == GrB_SUCCESS); + + info = Delta_MatrixTupleIter_attach(&iter, A); + TEST_ASSERT(Delta_MatrixTupleIter_is_attached(&iter, A)); + + Delta_MatrixTupleIter_detach(&iter); + // TEST_ASSERT(iter.A == NULL); + + Delta_Matrix_free(&A); + TEST_ASSERT(A == NULL); +} + +// test DeltaMatrixTupleIter iteration +void test_DeltaMatrixTupleIter_next() { + Delta_Matrix A = NULL; + GrB_Type t = GrB_BOOL; + GrB_Info info = GrB_SUCCESS; + GrB_Index i = 1; + GrB_Index j = 2; + GrB_Index row = 0; + GrB_Index col = 0; + GrB_Index nrows = 100; + GrB_Index ncols = 100; + bool val = 0; + bool sync = false; + Delta_MatrixTupleIter iter; + memset(&iter, 0, sizeof(Delta_MatrixTupleIter)); + + info = Delta_Matrix_new(&A, t, nrows, ncols, false); + TEST_ASSERT(info == GrB_SUCCESS); + + // set element at position i,j + info = Delta_Matrix_setElement_BOOL(A, i, j); + TEST_ASSERT(info == GrB_SUCCESS); + + //-------------------------------------------------------------------------- + // flush matrix, sync + //-------------------------------------------------------------------------- + + // wait, force sync + sync = true; + Delta_Matrix_wait(A, sync); + + //-------------------------------------------------------------------------- + // set pending changes + //-------------------------------------------------------------------------- + + // remove element at position i,j + info = Delta_Matrix_removeElement_BOOL(A, i, j); + TEST_ASSERT(info == GrB_SUCCESS); + + // set element at position i+1,j+1 + info = Delta_Matrix_setElement_BOOL(A, i+1, j+1); + TEST_ASSERT(info == GrB_SUCCESS); + + info = Delta_MatrixTupleIter_attach(&iter, A); + TEST_ASSERT(Delta_MatrixTupleIter_is_attached(&iter, A)); + + info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); + TEST_ASSERT(info == GrB_SUCCESS); + + TEST_ASSERT(row == i+1); + TEST_ASSERT(col == j+1); + TEST_ASSERT(val == 1); + + info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); + + TEST_ASSERT(info == GxB_EXHAUSTED); + + Delta_Matrix_free(&A); + TEST_ASSERT(A == NULL); + Delta_MatrixTupleIter_detach(&iter); + // TEST_ASSERT(iter.A == NULL); +} + +// test DeltaMatrixTupleIter iteration for sparse matrix +void test_DeltaMatrixTupleIter_next_sparse() { + Delta_Matrix A = NULL; + GrB_Type t = GrB_BOOL; + GrB_Info info = GrB_SUCCESS; + GrB_Index row = 0; + GrB_Index col = 0; + GrB_Index nrows = 100; + GrB_Index ncols = 100; + bool val = 0; + bool sync = false; + Delta_MatrixTupleIter iter; + memset(&iter, 0, sizeof(Delta_MatrixTupleIter)); + + info = Delta_Matrix_new(&A, t, nrows, ncols, false); + TEST_ASSERT(info == GrB_SUCCESS); + + for (GrB_Index i = 25; i < 100; i++) { + for (GrB_Index j = 25; j < 100; j++) { + // set element at position i,j + info = Delta_Matrix_setElement_BOOL(A, i, j); + TEST_ASSERT(info == GrB_SUCCESS); + } + } + + //-------------------------------------------------------------------------- + // flush matrix, sync + //-------------------------------------------------------------------------- + + // wait, force sync + sync = true; + Delta_Matrix_wait(A, sync); + + //-------------------------------------------------------------------------- + // check M is sparse + //-------------------------------------------------------------------------- + + GrB_Matrix M = Delta_Matrix_M(A); + + int sparsity; + GxB_Matrix_Option_get(M, GxB_SPARSITY_STATUS, &sparsity); + TEST_ASSERT(sparsity == GxB_SPARSE); + + //-------------------------------------------------------------------------- + // check iter start from correct row + //-------------------------------------------------------------------------- + + info = Delta_MatrixTupleIter_attach(&iter, A); + TEST_ASSERT(Delta_MatrixTupleIter_is_attached(&iter, A)); + + info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); + TEST_ASSERT(info == GrB_SUCCESS); + + TEST_ASSERT(row == 25); + TEST_ASSERT(col == 25); + TEST_ASSERT(val); + + Delta_Matrix_free(&A); + TEST_ASSERT(A == NULL); + Delta_MatrixTupleIter_detach(&iter); + // TEST_ASSERT(iter.A == NULL); +} + +// test DeltaMatrixTupleIter iteration +void test_DeltaMatrixTupleIter_reuse() { + Delta_Matrix A = NULL; + Delta_Matrix B = NULL; + GrB_Type t = GrB_BOOL; + GrB_Info info = GrB_SUCCESS; + GrB_Index i = 1; + GrB_Index j = 2; + GrB_Index row = 0; + GrB_Index col = 0; + GrB_Index nrows = 100; + GrB_Index ncols = 100; + bool val = 0; + bool sync = false; + Delta_MatrixTupleIter iter; + memset(&iter, 0, sizeof(Delta_MatrixTupleIter)); + + info = Delta_Matrix_new(&A, t, nrows, ncols, false); + TEST_ASSERT(info == GrB_SUCCESS); + + info = Delta_Matrix_new(&B, t, nrows, ncols, false); + TEST_ASSERT(info == GrB_SUCCESS); + + // set element at position i,j + info = Delta_Matrix_setElement_BOOL(A, i, j); + TEST_ASSERT(info == GrB_SUCCESS); + + //-------------------------------------------------------------------------- + // flush matrix, sync + //-------------------------------------------------------------------------- + + // wait, force sync + sync = true; + Delta_Matrix_wait(A, sync); + + info = Delta_MatrixTupleIter_attach(&iter, B); + TEST_ASSERT(Delta_MatrixTupleIter_is_attached(&iter, B)); + + info = Delta_MatrixTupleIter_attach(&iter, A); + TEST_ASSERT(Delta_MatrixTupleIter_is_attached(&iter, A)); + + info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); + + TEST_ASSERT(info == GrB_SUCCESS); + TEST_ASSERT(row == i); + TEST_ASSERT(col == j); + TEST_ASSERT(val); + + info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); + + TEST_ASSERT(info == GxB_EXHAUSTED); + + Delta_Matrix_free(&A); + TEST_ASSERT(A == NULL); + Delta_Matrix_free(&B); + TEST_ASSERT(A == NULL); + Delta_MatrixTupleIter_detach(&iter); + // TEST_ASSERT(iter.A == NULL); +} + +// test DeltaMatrixTupleIter_iterate_row +void test_DeltaMatrixTupleIter_iterate_row() { + Delta_Matrix A = NULL; + GrB_Type t = GrB_BOOL; + GrB_Info info = GrB_SUCCESS; + GrB_Index i = 1; + GrB_Index j = 2; + GrB_Index row = 0; + GrB_Index col = 0; + GrB_Index nrows = 100; + GrB_Index ncols = 100; + bool val = 0; + bool sync = false; + Delta_MatrixTupleIter iter; + memset(&iter, 0, sizeof(Delta_MatrixTupleIter)); + + info = Delta_Matrix_new(&A, t, nrows, ncols, false); + TEST_ASSERT(info == GrB_SUCCESS); + + // set element at position i,j + info = Delta_Matrix_setElement_BOOL(A, i, j); + TEST_ASSERT(info == GrB_SUCCESS); + + //-------------------------------------------------------------------------- + // flush matrix, sync + //-------------------------------------------------------------------------- + + // wait, force sync + sync = true; + Delta_Matrix_wait(A, sync); + + //-------------------------------------------------------------------------- + // set pending changes + //-------------------------------------------------------------------------- + + // remove element at position i,j + info = Delta_Matrix_removeElement_BOOL(A, i, j); + TEST_ASSERT(info == GrB_SUCCESS); + + // wait, DM can't have pendding changes + sync = false; + Delta_Matrix_wait(A, sync); + + // set element at position i+1,j+1 + info = Delta_Matrix_setElement_BOOL(A, i+1, j+1); + TEST_ASSERT(info == GrB_SUCCESS); + + info = Delta_MatrixTupleIter_attach(&iter, A); + // TEST_ASSERT(iter.A == A); + + info = Delta_MatrixTupleIter_iterate_row(&iter, i); + TEST_ASSERT(info == GrB_SUCCESS); + + info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); + TEST_ASSERT(info == GxB_EXHAUSTED); + + info = Delta_MatrixTupleIter_reset(&iter); + TEST_ASSERT(info == GrB_SUCCESS); + + info = Delta_MatrixTupleIter_iterate_row(&iter, i+1); + TEST_ASSERT(info == GrB_SUCCESS); + + info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); + + TEST_ASSERT(info == GrB_SUCCESS); + TEST_ASSERT(row == i+1); + TEST_ASSERT(col == j+1); + TEST_ASSERT(val); + + info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); + TEST_ASSERT(info == GxB_EXHAUSTED); + + Delta_Matrix_free(&A); + TEST_ASSERT(A == NULL); + Delta_MatrixTupleIter_detach(&iter); + // TEST_ASSERT(iter.A == NULL); +} + +// test DeltaMatrixTupleiIter_iterate_range +void test_DeltaMatrixTupleIter_iterate_range() { + Delta_Matrix A = NULL; + GrB_Type t = GrB_BOOL; + GrB_Info info = GrB_SUCCESS; + GrB_Index i = 1; + GrB_Index j = 2; + GrB_Index row = 0; + GrB_Index col = 0; + GrB_Index nrows = 100; + GrB_Index ncols = 100; + bool val = 0; + bool sync = false; + Delta_MatrixTupleIter iter; + memset(&iter, 0, sizeof(Delta_MatrixTupleIter)); + + info = Delta_Matrix_new(&A, t, nrows, ncols, false); + TEST_ASSERT(info == GrB_SUCCESS); + + // set element at position i,j + info = Delta_Matrix_setElement_BOOL(A, i, j); + TEST_ASSERT(info == GrB_SUCCESS); + + //-------------------------------------------------------------------------- + // flush matrix, sync + //-------------------------------------------------------------------------- + + // wait, force sync + sync = true; + Delta_Matrix_wait(A, sync); + + //-------------------------------------------------------------------------- + // set pending changes + //-------------------------------------------------------------------------- + + // remove element at position i,j + info = Delta_Matrix_removeElement_BOOL(A, i, j); + TEST_ASSERT(info == GrB_SUCCESS); + + // set element at position i+1,j+1 + info = Delta_Matrix_setElement_BOOL(A, i+1, j+1); + TEST_ASSERT(info == GrB_SUCCESS); + + info = Delta_MatrixTupleIter_attach(&iter, A); + TEST_ASSERT(Delta_MatrixTupleIter_is_attached(&iter, A)); + + info = Delta_MatrixTupleIter_iterate_range(&iter, i+1, i+1); + TEST_ASSERT(info == GrB_SUCCESS); + + info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); + + TEST_ASSERT(info == GrB_SUCCESS); + TEST_ASSERT(row == i+1); + TEST_ASSERT(col == j+1); + TEST_ASSERT(val == 1); + + info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); + TEST_ASSERT(info == GxB_EXHAUSTED); + + Delta_Matrix_free(&A); + TEST_ASSERT(A == NULL); + Delta_MatrixTupleIter_detach(&iter); + // TEST_ASSERT(iter.A == NULL); +} + +TEST_LIST = { + {"DeltaMatrixTupleIter_attach", test_DeltaMatrixTupleIter_attach}, + {"DeltaMatrixTupleIter_next", test_DeltaMatrixTupleIter_next}, + {"DeltaMatrixTupleIter_next_sparse", test_DeltaMatrixTupleIter_next_sparse}, + {"DeltaMatrixTupleIter_reuse", test_DeltaMatrixTupleIter_reuse}, + {"DeltaMatrixTupleIter_iterate_row", test_DeltaMatrixTupleIter_iterate_row}, + {"DeltaMatrixTupleIter_iterate_range", test_DeltaMatrixTupleIter_iterate_range}, + {NULL, NULL} +}; diff --git a/tests/unit/test_graph.c b/tests/unit/test_graph.c index e79c7d81f..b9e0c3896 100644 --- a/tests/unit/test_graph.c +++ b/tests/unit/test_graph.c @@ -45,10 +45,10 @@ void _test_node_creation(Graph *g, size_t node_count) { } // Validate nodes creation. - RG_Matrix adj = Graph_GetAdjacencyMatrix(g, false); - TEST_ASSERT(RG_Matrix_nrows(&nrows, adj) == GrB_SUCCESS); - TEST_ASSERT(RG_Matrix_ncols(&ncols, adj) == GrB_SUCCESS); - TEST_ASSERT(RG_Matrix_nvals(&nvals, adj) == GrB_SUCCESS); + Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); + TEST_ASSERT(Delta_Matrix_nrows(&nrows, adj) == GrB_SUCCESS); + TEST_ASSERT(Delta_Matrix_ncols(&ncols, adj) == GrB_SUCCESS); + TEST_ASSERT(Delta_Matrix_nvals(&nvals, adj) == GrB_SUCCESS); TEST_ASSERT(nvals == 0); // No connection were formed. TEST_ASSERT(ncols >= Graph_NodeCount(g)); // Graph's adjacency matrix dimensions. @@ -226,10 +226,10 @@ void test_newGraph() { GrB_Index ncols, nrows, nvals; Graph *g = Graph_New(GRAPH_DEFAULT_NODE_CAP, GRAPH_DEFAULT_EDGE_CAP); Graph_AcquireWriteLock(g); - RG_Matrix adj_matrix = g->adjacency_matrix; - TEST_ASSERT(RG_Matrix_ncols(&ncols, adj_matrix) == GrB_SUCCESS); - TEST_ASSERT(RG_Matrix_nrows(&nrows, adj_matrix) == GrB_SUCCESS); - TEST_ASSERT(RG_Matrix_nvals(&nvals, adj_matrix) == GrB_SUCCESS); + Delta_Matrix adj_matrix = g->adjacency_matrix; + TEST_ASSERT(Delta_Matrix_ncols(&ncols, adj_matrix) == GrB_SUCCESS); + TEST_ASSERT(Delta_Matrix_nrows(&nrows, adj_matrix) == GrB_SUCCESS); + TEST_ASSERT(Delta_Matrix_nvals(&nvals, adj_matrix) == GrB_SUCCESS); TEST_ASSERT(g->nodes != NULL); TEST_ASSERT(g->relations != NULL); @@ -258,7 +258,7 @@ void test_graphConstruction() { void test_removeNodes() { // Construct graph. - RG_Matrix M; + Delta_Matrix M; GrB_Index nnz; Graph *g = Graph_New(32, 32); Graph_AcquireWriteLock(g); @@ -290,11 +290,11 @@ void test_removeNodes() { // Validate graph creation. TEST_ASSERT(Graph_NodeCount(g) == 3); M = Graph_GetRelationMatrix(g, r, false); - RG_Matrix_nvals(&nnz, M); + Delta_Matrix_nvals(&nnz, M); TEST_ASSERT(nnz == 3); M = Graph_GetAdjacencyMatrix(g, false); - RG_Matrix_nvals(&nnz, M); + Delta_Matrix_nvals(&nnz, M); TEST_ASSERT(nnz == 3); Edge *edges = (Edge *)array_new(Edge, 3); diff --git a/tests/unit/test_rg_matrix_iter.c b/tests/unit/test_rg_matrix_iter.c deleted file mode 100644 index d07d42590..000000000 --- a/tests/unit/test_rg_matrix_iter.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "src/util/rmalloc.h" -#include "src/configuration/config.h" -#include "src/graph/rg_matrix/rg_matrix.h" -#include "src/graph/rg_matrix/rg_matrix_iter.h" - -void setup() { - Alloc_Reset(); - - // initialize GraphBLAS - GrB_init(GrB_NONBLOCKING); - - // all matrices in CSR format - GxB_Global_Option_set(GxB_FORMAT, GxB_BY_ROW); - - // set delta matrix flush threshold - Config_Option_set(Config_DELTA_MAX_PENDING_CHANGES, "10000", NULL); -} - -void tearDown() { - GrB_finalize(); -} - -#define TEST_INIT setup(); -#define TEST_FINI tearDown(); -#include "acutest.h" - -// test RGMatrixTupleIter initialization -void test_RGMatrixTupleIter_attach() { - RG_Matrix A = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - RG_MatrixTupleIter iter; - memset(&iter, 0, sizeof(RG_MatrixTupleIter)); - - info = RG_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - info = RG_MatrixTupleIter_attach(&iter, A); - TEST_ASSERT(RG_MatrixTupleIter_is_attached(&iter, A)); - - RG_MatrixTupleIter_detach(&iter); - // TEST_ASSERT(iter.A == NULL); - - RG_Matrix_free(&A); - TEST_ASSERT(A == NULL); -} - -// test RGMatrixTupleIter iteration -void test_RGMatrixTupleIter_next() { - RG_Matrix A = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index i = 1; - GrB_Index j = 2; - GrB_Index row = 0; - GrB_Index col = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool val = 0; - bool sync = false; - RG_MatrixTupleIter iter; - memset(&iter, 0, sizeof(RG_MatrixTupleIter)); - - info = RG_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i,j - info = RG_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - RG_Matrix_wait(A, sync); - - //-------------------------------------------------------------------------- - // set pending changes - //-------------------------------------------------------------------------- - - // remove element at position i,j - info = RG_Matrix_removeElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i+1,j+1 - info = RG_Matrix_setElement_BOOL(A, i+1, j+1); - TEST_ASSERT(info == GrB_SUCCESS); - - info = RG_MatrixTupleIter_attach(&iter, A); - TEST_ASSERT(RG_MatrixTupleIter_is_attached(&iter, A)); - - info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - TEST_ASSERT(info == GrB_SUCCESS); - - TEST_ASSERT(row == i+1); - TEST_ASSERT(col == j+1); - TEST_ASSERT(val == 1); - - info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - - TEST_ASSERT(info == GxB_EXHAUSTED); - - RG_Matrix_free(&A); - TEST_ASSERT(A == NULL); - RG_MatrixTupleIter_detach(&iter); - // TEST_ASSERT(iter.A == NULL); -} - -// test RGMatrixTupleIter iteration for sparse matrix -void test_RGMatrixTupleIter_next_sparse() { - RG_Matrix A = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index row = 0; - GrB_Index col = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool val = 0; - bool sync = false; - RG_MatrixTupleIter iter; - memset(&iter, 0, sizeof(RG_MatrixTupleIter)); - - info = RG_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - for (GrB_Index i = 25; i < 100; i++) { - for (GrB_Index j = 25; j < 100; j++) { - // set element at position i,j - info = RG_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - } - } - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - RG_Matrix_wait(A, sync); - - //-------------------------------------------------------------------------- - // check M is sparse - //-------------------------------------------------------------------------- - - GrB_Matrix M = RG_Matrix_M(A); - - int sparsity; - GxB_Matrix_Option_get(M, GxB_SPARSITY_STATUS, &sparsity); - TEST_ASSERT(sparsity == GxB_SPARSE); - - //-------------------------------------------------------------------------- - // check iter start from correct row - //-------------------------------------------------------------------------- - - info = RG_MatrixTupleIter_attach(&iter, A); - TEST_ASSERT(RG_MatrixTupleIter_is_attached(&iter, A)); - - info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - TEST_ASSERT(info == GrB_SUCCESS); - - TEST_ASSERT(row == 25); - TEST_ASSERT(col == 25); - TEST_ASSERT(val); - - RG_Matrix_free(&A); - TEST_ASSERT(A == NULL); - RG_MatrixTupleIter_detach(&iter); - // TEST_ASSERT(iter.A == NULL); -} - -// test RGMatrixTupleIter iteration -void test_RGMatrixTupleIter_reuse() { - RG_Matrix A = NULL; - RG_Matrix B = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index i = 1; - GrB_Index j = 2; - GrB_Index row = 0; - GrB_Index col = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool val = 0; - bool sync = false; - RG_MatrixTupleIter iter; - memset(&iter, 0, sizeof(RG_MatrixTupleIter)); - - info = RG_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - info = RG_Matrix_new(&B, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i,j - info = RG_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - RG_Matrix_wait(A, sync); - - info = RG_MatrixTupleIter_attach(&iter, B); - TEST_ASSERT(RG_MatrixTupleIter_is_attached(&iter, B)); - - info = RG_MatrixTupleIter_attach(&iter, A); - TEST_ASSERT(RG_MatrixTupleIter_is_attached(&iter, A)); - - info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - - TEST_ASSERT(info == GrB_SUCCESS); - TEST_ASSERT(row == i); - TEST_ASSERT(col == j); - TEST_ASSERT(val); - - info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - - TEST_ASSERT(info == GxB_EXHAUSTED); - - RG_Matrix_free(&A); - TEST_ASSERT(A == NULL); - RG_Matrix_free(&B); - TEST_ASSERT(A == NULL); - RG_MatrixTupleIter_detach(&iter); - // TEST_ASSERT(iter.A == NULL); -} - -// test RGMatrixTupleIter_iterate_row -void test_RGMatrixTupleIter_iterate_row() { - RG_Matrix A = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index i = 1; - GrB_Index j = 2; - GrB_Index row = 0; - GrB_Index col = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool val = 0; - bool sync = false; - RG_MatrixTupleIter iter; - memset(&iter, 0, sizeof(RG_MatrixTupleIter)); - - info = RG_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i,j - info = RG_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - RG_Matrix_wait(A, sync); - - //-------------------------------------------------------------------------- - // set pending changes - //-------------------------------------------------------------------------- - - // remove element at position i,j - info = RG_Matrix_removeElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // wait, DM can't have pendding changes - sync = false; - RG_Matrix_wait(A, sync); - - // set element at position i+1,j+1 - info = RG_Matrix_setElement_BOOL(A, i+1, j+1); - TEST_ASSERT(info == GrB_SUCCESS); - - info = RG_MatrixTupleIter_attach(&iter, A); - // TEST_ASSERT(iter.A == A); - - info = RG_MatrixTupleIter_iterate_row(&iter, i); - TEST_ASSERT(info == GrB_SUCCESS); - - info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - TEST_ASSERT(info == GxB_EXHAUSTED); - - info = RG_MatrixTupleIter_reset(&iter); - TEST_ASSERT(info == GrB_SUCCESS); - - info = RG_MatrixTupleIter_iterate_row(&iter, i+1); - TEST_ASSERT(info == GrB_SUCCESS); - - info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - - TEST_ASSERT(info == GrB_SUCCESS); - TEST_ASSERT(row == i+1); - TEST_ASSERT(col == j+1); - TEST_ASSERT(val); - - info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - TEST_ASSERT(info == GxB_EXHAUSTED); - - RG_Matrix_free(&A); - TEST_ASSERT(A == NULL); - RG_MatrixTupleIter_detach(&iter); - // TEST_ASSERT(iter.A == NULL); -} - -// test RGMatrixTupleiIter_iterate_range -void test_RGMatrixTupleIter_iterate_range() { - RG_Matrix A = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index i = 1; - GrB_Index j = 2; - GrB_Index row = 0; - GrB_Index col = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool val = 0; - bool sync = false; - RG_MatrixTupleIter iter; - memset(&iter, 0, sizeof(RG_MatrixTupleIter)); - - info = RG_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i,j - info = RG_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - RG_Matrix_wait(A, sync); - - //-------------------------------------------------------------------------- - // set pending changes - //-------------------------------------------------------------------------- - - // remove element at position i,j - info = RG_Matrix_removeElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i+1,j+1 - info = RG_Matrix_setElement_BOOL(A, i+1, j+1); - TEST_ASSERT(info == GrB_SUCCESS); - - info = RG_MatrixTupleIter_attach(&iter, A); - TEST_ASSERT(RG_MatrixTupleIter_is_attached(&iter, A)); - - info = RG_MatrixTupleIter_iterate_range(&iter, i+1, i+1); - TEST_ASSERT(info == GrB_SUCCESS); - - info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - - TEST_ASSERT(info == GrB_SUCCESS); - TEST_ASSERT(row == i+1); - TEST_ASSERT(col == j+1); - TEST_ASSERT(val == 1); - - info = RG_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - TEST_ASSERT(info == GxB_EXHAUSTED); - - RG_Matrix_free(&A); - TEST_ASSERT(A == NULL); - RG_MatrixTupleIter_detach(&iter); - // TEST_ASSERT(iter.A == NULL); -} - -TEST_LIST = { - {"RGMatrixTupleIter_attach", test_RGMatrixTupleIter_attach}, - {"RGMatrixTupleIter_next", test_RGMatrixTupleIter_next}, - {"RGMatrixTupleIter_next_sparse", test_RGMatrixTupleIter_next_sparse}, - {"RGMatrixTupleIter_reuse", test_RGMatrixTupleIter_reuse}, - {"RGMatrixTupleIter_iterate_row", test_RGMatrixTupleIter_iterate_row}, - {"RGMatrixTupleIter_iterate_range", test_RGMatrixTupleIter_iterate_range}, - {NULL, NULL} -}; From 7111fc45d24e78f95da7a646b81c4e43fbb91307 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Sun, 5 May 2024 10:51:37 +0300 Subject: [PATCH 11/57] address review --- deps/FalkorDB-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index f93be5173..972320294 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit f93be5173f6dc7cde35f57745a3f1089b473bab9 +Subproject commit 97232029453840fca37929d53471f77f46a7193a From 70e02f07723b0e95949895f35c32616a97c06823 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Sun, 5 May 2024 11:08:38 +0300 Subject: [PATCH 12/57] address review --- deps/FalkorDB-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 972320294..45e2176f7 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 97232029453840fca37929d53471f77f46a7193a +Subproject commit 45e2176f7034b87f8b0884fd3ee99e5b3b7cdaa3 From b53a7760543c25631a1e1b6b9a906df749c40126 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Sun, 5 May 2024 11:23:27 +0300 Subject: [PATCH 13/57] fix merge --- src/execution_plan/ops/op_node_by_label_scan.c | 6 +++--- src/execution_plan/ops/op_node_by_label_scan.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/execution_plan/ops/op_node_by_label_scan.c b/src/execution_plan/ops/op_node_by_label_scan.c index cdb3ed624..06f361c62 100644 --- a/src/execution_plan/ops/op_node_by_label_scan.c +++ b/src/execution_plan/ops/op_node_by_label_scan.c @@ -197,7 +197,7 @@ static Record NodeByLabelScanConsume NodeByLabelScan *op = (NodeByLabelScan *)opBase; GrB_Index id; - GrB_Info info = RG_MatrixTupleIter_next_BOOL(&op->iter, &id, NULL, NULL); + GrB_Info info = Delta_MatrixTupleIter_next_BOOL(&op->iter, &id, NULL, NULL); if(info == GxB_EXHAUSTED) return NULL; ASSERT(info == GrB_SUCCESS); @@ -224,7 +224,7 @@ static Record NodeByLabelAndIDScanConsume id = roaring64_iterator_value(op->ID_it); roaring64_iterator_advance(op->ID_it); bool x; - if(RG_Matrix_extractElement_BOOL(&x, op->L, id, id) == GrB_SUCCESS) { + if(Delta_Matrix_extractElement_BOOL(&x, op->L, id, id) == GrB_SUCCESS) { Record r = OpBase_CreateRecord((OpBase *)op); // Populate the Record with the actual node. @@ -311,7 +311,7 @@ static Record NodeByLabelAndIDScanConsumeFromChild roaring64_iterator_advance(op->ID_it); // make sure ID is labeled as L - if(RG_Matrix_extractElement_BOOL(&x, op->L, id, id) == GrB_SUCCESS) { + if(Delta_Matrix_extractElement_BOOL(&x, op->L, id, id) == GrB_SUCCESS) { emited = true; break; } diff --git a/src/execution_plan/ops/op_node_by_label_scan.h b/src/execution_plan/ops/op_node_by_label_scan.h index 72c848766..d1b3b4a54 100644 --- a/src/execution_plan/ops/op_node_by_label_scan.h +++ b/src/execution_plan/ops/op_node_by_label_scan.h @@ -12,7 +12,7 @@ #include "../../util/roaring.h" #include "shared/scan_functions.h" #include "../../util/range/range.h" -#include "../../graph/rg_matrix/delta_matrix_iter.h" +#include "../../graph/delta_matrix/delta_matrix_iter.h" // NodeByLabelScan, scans entire label typedef struct { @@ -23,7 +23,7 @@ typedef struct { RangeExpression *ranges; // array of ID range expressions roaring64_bitmap_t *ids; // resolved ids by filters roaring64_iterator_t *ID_it; // ID iterator - RG_Matrix L; // label matrix + Delta_Matrix L; // label matrix Delta_MatrixTupleIter iter; // iterator over label matrix Record child_record; // the record this op acts on if it is not a tap } NodeByLabelScan; From eeb387b55b99f1e1cc8d2d1c7dbaaf5d8ae7b795 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Sun, 5 May 2024 16:59:08 +0300 Subject: [PATCH 14/57] address review --- deps/FalkorDB-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 45e2176f7..1d9a8c798 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 45e2176f7034b87f8b0884fd3ee99e5b3b7cdaa3 +Subproject commit 1d9a8c79815099acfd93804b9c5ab970e9ff8cf2 From d6332b1c6c2be07643b37f179745c1fe8365e196 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Sun, 5 May 2024 17:35:05 +0300 Subject: [PATCH 15/57] address review --- deps/FalkorDB-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 1d9a8c798..bd1692d95 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 1d9a8c79815099acfd93804b9c5ab970e9ff8cf2 +Subproject commit bd1692d955fb99e2cd2e3cbc215033b6d30cc9ca From 5ab1b5aa2e01781555017cc95edfea39328302ae Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Wed, 8 May 2024 11:30:42 +0300 Subject: [PATCH 16/57] implement new incident matrix approach --- deps/FalkorDB-rs | 2 +- src/bulk_insert/bulk_insert.c | 4 +- src/constraint/constraint.c | 6 +- .../ops/shared/create_functions.c | 4 +- src/graph/delta_matrix/delta_matrix.h | 23 +++- src/graph/delta_matrix/delta_matrix_iter.h | 9 ++ src/graph/graph.c | 115 +++++++----------- src/graph/graph.h | 6 +- src/graph/graph_delete_nodes.c | 2 +- src/index/index_construct.c | 15 +-- .../encoder/v14/encode_graph_entities.c | 20 +-- src/serializers/graph_extensions.c | 14 +-- tests/unit/test_delta_matrix.c | 14 +-- tests/unit/test_delta_matrix_iter.c | 6 +- 14 files changed, 100 insertions(+), 140 deletions(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index bd1692d95..e486249d0 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit bd1692d955fb99e2cd2e3cbc215033b6d30cc9ca +Subproject commit e486249d058e26445f4d504f33a18f3bbc1d55da diff --git a/src/bulk_insert/bulk_insert.c b/src/bulk_insert/bulk_insert.c index 6ac8a945c..8024a0f92 100644 --- a/src/bulk_insert/bulk_insert.c +++ b/src/bulk_insert/bulk_insert.c @@ -272,8 +272,8 @@ static int _BulkInsert_ProcessEdgeFile // sync matrix once ASSERT(Graph_GetMatrixPolicy(gc->g) == SYNC_POLICY_RESIZE); Graph_GetRelationMatrix(gc->g, type_id, false); - Graph_GetSourceRelationMatrix(gc->g, type_id, false); - Graph_GetTargetRelationMatrix(gc->g, type_id, false); + Graph_GetSourceRelationMatrix(gc->g, type_id); + Graph_GetTargetRelationMatrix(gc->g, type_id); Graph_GetAdjacencyMatrix(gc->g, false); Graph_SetMatrixPolicy(gc->g, SYNC_POLICY_NOP); diff --git a/src/constraint/constraint.c b/src/constraint/constraint.c index 5712d25e8..3983c9f9b 100644 --- a/src/constraint/constraint.c +++ b/src/constraint/constraint.c @@ -527,7 +527,7 @@ void Constraint_EnforceEdges // fetch relation matrix ASSERT(Graph_GetMatrixPolicy(g) == SYNC_POLICY_FLUSH_RESIZE); - const Delta_Matrix m = Graph_GetSourceRelationMatrix(g, schema_id, false); + const Delta_Matrix m = Graph_GetSourceRelationMatrix(g, schema_id); ASSERT(m != NULL); //---------------------------------------------------------------------- @@ -538,8 +538,8 @@ void Constraint_EnforceEdges ASSERT(info == GrB_SUCCESS); // skip previously enforced edges - while((info = Delta_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, - NULL)) == GrB_SUCCESS && + while((info = Delta_MatrixTupleIter_next_UINT64(&it, &src_id, &edge_id, + &dest_id)) == GrB_SUCCESS && src_id == prev_src_id && edge_id != prev_edge_id); diff --git a/src/execution_plan/ops/shared/create_functions.c b/src/execution_plan/ops/shared/create_functions.c index efda72c9d..66ed14ec6 100644 --- a/src/execution_plan/ops/shared/create_functions.c +++ b/src/execution_plan/ops/shared/create_functions.c @@ -123,8 +123,8 @@ static void _CommitEdgesBlueprint // calling Graph_GetRelationMatrix will make sure relationship matrix // is of the right dimensions Graph_GetRelationMatrix(g, Schema_GetID(s), false); - Graph_GetSourceRelationMatrix(g, Schema_GetID(s), false); - Graph_GetTargetRelationMatrix(g, Schema_GetID(s), false); + Graph_GetSourceRelationMatrix(g, Schema_GetID(s)); + Graph_GetTargetRelationMatrix(g, Schema_GetID(s)); } // call Graph_GetAdjacencyMatrix will make sure the adjacency matrix diff --git a/src/graph/delta_matrix/delta_matrix.h b/src/graph/delta_matrix/delta_matrix.h index 09a5038af..1885f7f72 100644 --- a/src/graph/delta_matrix/delta_matrix.h +++ b/src/graph/delta_matrix/delta_matrix.h @@ -112,11 +112,6 @@ Delta_Matrix Delta_Matrix_getTranspose const Delta_Matrix C ); -bool Delta_Matrix_isDirty -( - const Delta_Matrix C -); - GrB_Matrix Delta_Matrix_M ( const Delta_Matrix C @@ -164,6 +159,14 @@ GrB_Info Delta_Matrix_setElement_BOOL // C (i,j) = x GrB_Index j // column index ); +GrB_Info Delta_Matrix_setElement_UINT64 // C (i,j) = x +( + Delta_Matrix C, // matrix to modify + uint64_t x, // value + GrB_Index i, // row index + GrB_Index j // column index +); + GrB_Info Delta_Matrix_extractElement_BOOL // x = A(i,j) ( bool *x, // extracted scalar @@ -172,6 +175,14 @@ GrB_Info Delta_Matrix_extractElement_BOOL // x = A(i,j) GrB_Index j // column index ) ; +GrB_Info Delta_Matrix_extractElement_UINT64 // x = A(i,j) +( + uint64_t *x, // extracted scalar + const Delta_Matrix A, // matrix to extract a scalar from + GrB_Index i, // row index + GrB_Index j // column index +) ; + GrB_Info Delta_Matrix_extract_row ( const Delta_Matrix A, // matrix to extract a vector from @@ -180,7 +191,7 @@ GrB_Info Delta_Matrix_extract_row ) ; // remove entry at position C[i,j] -GrB_Info Delta_Matrix_removeElement_BOOL +GrB_Info Delta_Matrix_removeElement ( Delta_Matrix C, // matrix to remove entry from GrB_Index i, // row index diff --git a/src/graph/delta_matrix/delta_matrix_iter.h b/src/graph/delta_matrix/delta_matrix_iter.h index 734b6854e..fb86b1c8b 100644 --- a/src/graph/delta_matrix/delta_matrix_iter.h +++ b/src/graph/delta_matrix/delta_matrix_iter.h @@ -73,6 +73,15 @@ GrB_Info Delta_MatrixTupleIter_next_BOOL bool *val // optional value at A[row, col] ); +// advance iterator +GrB_Info Delta_MatrixTupleIter_next_UINT64 +( + Delta_MatrixTupleIter *iter, // iterator to consume + GrB_Index *row, // optional output row index + GrB_Index *col, // optional output column index + uint64_t *val // optional value at A[row, col] +); + // reset iterator GrB_Info Delta_MatrixTupleIter_reset ( diff --git a/src/graph/graph.c b/src/graph/graph.c index 8b847e7d1..2c9bae1ac 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -112,16 +112,16 @@ void _Graph_GetEdgesConnectingNodes // no entry at [dest, src], src is not connected to dest with relation R if(res == GrB_NO_VALUE) return; - Edge e = {.src_id = src, .dest_id = dest, .relationID = r}; - Delta_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); - Delta_Matrix T = Graph_GetTargetRelationMatrix(g, r, true); GrB_Vector src_vec; GrB_Vector dst_vec; - GrB_Info info; + GrB_Info info; info = GrB_Vector_new(&src_vec, GrB_BOOL, g->edges->itemCap); ASSERT(info == GrB_SUCCESS); info = GrB_Vector_new(&dst_vec, GrB_BOOL, g->edges->itemCap); ASSERT(info == GrB_SUCCESS); + Edge e = {.src_id = src, .dest_id = dest, .relationID = r}; + Delta_Matrix S = Graph_GetSourceRelationMatrix(g, r); + Delta_Matrix T = Graph_GetTargetRelationMatrix(g, r); info = Delta_Matrix_extract_row(S, src_vec, src); ASSERT(info == GrB_SUCCESS); info = Delta_Matrix_extract_row(T, dst_vec, dest); @@ -292,9 +292,9 @@ void Graph_ApplyAllPending for(int i = 0; i < n; i ++) { M = Graph_GetRelationMatrix(g, i, false); Delta_Matrix_wait(M, force_flush); - M = Graph_GetSourceRelationMatrix(g, i, false); + M = Graph_GetSourceRelationMatrix(g, i); Delta_Matrix_wait(M, force_flush); - M = Graph_GetTargetRelationMatrix(g, i, false); + M = Graph_GetTargetRelationMatrix(g, i); Delta_Matrix_wait(M, force_flush); } @@ -461,7 +461,7 @@ uint64_t Graph_RelationEdgeCount ) { ASSERT(g); - Delta_Matrix S = Graph_GetSourceRelationMatrix(g, relation, false); + Delta_Matrix S = Graph_GetSourceRelationMatrix(g, relation); ASSERT(S != NULL); GrB_Index nvals; GrB_Info info = Delta_Matrix_nvals(&nvals, S); @@ -539,17 +539,15 @@ RelationID Graph_GetEdgeRelation // search for relation mapping matrix M, where M[dest,src] == edge ID uint n = array_len(g->relations); + GrB_Index dst; for(uint i = 0; i < n; i++) { EdgeID edgeId = 0; Delta_Matrix M = Graph_GetRelationMatrix(g, i, false); - Delta_Matrix S = Graph_GetSourceRelationMatrix(g, i, false); - Delta_Matrix T = Graph_GetTargetRelationMatrix(g, i, false); + Delta_Matrix S = Graph_GetSourceRelationMatrix(g, i); info = Delta_Matrix_extractElement_BOOL(NULL, M, src_id, dest_id); if(info != GrB_SUCCESS) continue; - info = Delta_Matrix_extractElement_BOOL(NULL, S, src_id, id); - if(info != GrB_SUCCESS) continue; - info = Delta_Matrix_extractElement_BOOL(NULL, T, id, dest_id); - if(info != GrB_SUCCESS) continue; + info = Delta_Matrix_extractElement_UINT64(&dst, S, src_id, id); + if(info != GrB_SUCCESS || dst != dest_id) continue; Edge_SetRelationID(e, i); rel = i; break; @@ -720,11 +718,11 @@ void Graph_RemoveNodeLabels Delta_Matrix M = Graph_GetLabelMatrix(g, l); // remove matrix at position [id, id] - info = Delta_Matrix_removeElement_BOOL(M, id, id); + info = Delta_Matrix_removeElement(M, id, id); ASSERT(info == GrB_SUCCESS); // remove this label from node's set of labels - info = Delta_Matrix_removeElement_BOOL(nl, id, l); + info = Delta_Matrix_removeElement(nl, id, l); ASSERT(info == GrB_SUCCESS); } } @@ -742,8 +740,8 @@ bool Graph_FormConnection GrB_Info info; UNUSED(info); Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); - Delta_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); - Delta_Matrix T = Graph_GetTargetRelationMatrix(g, r, false); + Delta_Matrix S = Graph_GetSourceRelationMatrix(g, r); + Delta_Matrix T = Graph_GetTargetRelationMatrix(g, r); Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); // rows represent source nodes, columns represent destination nodes @@ -755,10 +753,10 @@ bool Graph_FormConnection info = Delta_Matrix_setElement_BOOL(M, src, dest); if(info != GrB_SUCCESS) return false; - info = Delta_Matrix_setElement_BOOL(S, src, edge_id); + info = Delta_Matrix_setElement_UINT64(S, dest, src, edge_id); if(info != GrB_SUCCESS) return false; - info = Delta_Matrix_setElement_BOOL(T, edge_id, dest); + info = Delta_Matrix_setElement_UINT64(T, src, dest, edge_id); return info == GrB_SUCCESS; } @@ -807,8 +805,7 @@ void _GetOutgoingNodeEdges ASSERT(edgeType != GRAPH_NO_RELATION && edgeType != GRAPH_UNKNOWN_RELATION); GrB_Info info; - Delta_MatrixTupleIter it_s = {0}; - Delta_MatrixTupleIter it_t = {0}; + Delta_MatrixTupleIter it = {0}; Delta_Matrix S = NULL; Delta_Matrix T = NULL; NodeID src_id = ENTITY_GET_ID(n); @@ -816,20 +813,12 @@ void _GetOutgoingNodeEdges EdgeID edge_id = INVALID_ENTITY_ID; UNUSED(info); - S = Graph_GetSourceRelationMatrix(g, edgeType, false); - T = Graph_GetTargetRelationMatrix(g, edgeType, false); + S = Graph_GetSourceRelationMatrix(g, edgeType); - info = Delta_MatrixTupleIter_AttachRange(&it_s, S, src_id, src_id); - ASSERT(info == GrB_SUCCESS); - info = Delta_MatrixTupleIter_attach(&it_t, T); + info = Delta_MatrixTupleIter_AttachRange(&it, S, src_id, src_id); ASSERT(info == GrB_SUCCESS); - while(Delta_MatrixTupleIter_next_BOOL(&it_s, NULL, &edge_id, NULL) == GrB_SUCCESS) { - info = Delta_MatrixTupleIter_iterate_row(&it_t, edge_id); - ASSERT(info == GrB_SUCCESS); - info = Delta_MatrixTupleIter_next_BOOL(&it_t, NULL, &dest_id, NULL); - ASSERT(info == GrB_SUCCESS); - + while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &edge_id, &dest_id) == GrB_SUCCESS) { Edge e = {0}; e.src_id = src_id; e.dest_id = dest_id; @@ -839,9 +828,7 @@ void _GetOutgoingNodeEdges ASSERT(e.attributes); array_append(*edges, e); } - info = Delta_MatrixTupleIter_detach(&it_s); - ASSERT(info == GrB_SUCCESS); - info = Delta_MatrixTupleIter_detach(&it_t); + info = Delta_MatrixTupleIter_detach(&it); ASSERT(info == GrB_SUCCESS); } @@ -859,8 +846,7 @@ void _GetIncomingNodeEdges ASSERT(edgeType != GRAPH_NO_RELATION && edgeType != GRAPH_UNKNOWN_RELATION); GrB_Info info; - Delta_MatrixTupleIter it_s = {0}; - Delta_MatrixTupleIter it_t = {0}; + Delta_MatrixTupleIter it = {0}; Delta_Matrix S = NULL; Delta_Matrix T = NULL; NodeID src_id = ENTITY_GET_ID(n); @@ -868,18 +854,11 @@ void _GetIncomingNodeEdges EdgeID edge_id = INVALID_ENTITY_ID; UNUSED(info); - S = Graph_GetSourceRelationMatrix(g, edgeType, true); - T = Graph_GetTargetRelationMatrix(g, edgeType, true); + T = Graph_GetTargetRelationMatrix(g, edgeType); - info = Delta_MatrixTupleIter_AttachRange(&it_t, T, src_id, src_id); - ASSERT(info == GrB_SUCCESS); - info = Delta_MatrixTupleIter_attach(&it_s, S); + info = Delta_MatrixTupleIter_AttachRange(&it, T, src_id, src_id); ASSERT(info == GrB_SUCCESS); - while(Delta_MatrixTupleIter_next_BOOL(&it_t, NULL, &edge_id, NULL) == GrB_SUCCESS) { - info = Delta_MatrixTupleIter_iterate_row(&it_s, edge_id); - ASSERT(info == GrB_SUCCESS); - info = Delta_MatrixTupleIter_next_BOOL(&it_s, NULL, &dest_id, NULL); - ASSERT(info == GrB_SUCCESS); + while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &edge_id, &dest_id) == GrB_SUCCESS) { if(dir == GRAPH_EDGE_DIR_BOTH && src_id == dest_id) continue; Edge e = {0}; e.src_id = dest_id; @@ -890,9 +869,7 @@ void _GetIncomingNodeEdges ASSERT(e.attributes); array_append(*edges, e); } - info = Delta_MatrixTupleIter_detach(&it_s); - ASSERT(info == GrB_SUCCESS); - info = Delta_MatrixTupleIter_detach(&it_t); + info = Delta_MatrixTupleIter_detach(&it); ASSERT(info == GrB_SUCCESS); } @@ -988,7 +965,7 @@ uint64_t Graph_GetNodeDegree // for each relationship type to consider for(edgeType = start_rel; edgeType < end_rel; edgeType++) { - M = Graph_GetSourceRelationMatrix(g, edgeType, false); + M = Graph_GetSourceRelationMatrix(g, edgeType); //---------------------------------------------------------------------- // outgoing edges @@ -999,7 +976,7 @@ uint64_t Graph_GetNodeDegree // containing all outgoing edges Delta_MatrixTupleIter_AttachRange(&it, M, srcID, srcID); // scan row - while(Delta_MatrixTupleIter_next_BOOL(&it, NULL, NULL, NULL) + while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, NULL) == GrB_SUCCESS) { edge_count++; } @@ -1012,12 +989,12 @@ uint64_t Graph_GetNodeDegree if(incoming) { // transposed relation matrix - TM = Graph_GetTargetRelationMatrix(g, edgeType, true); + TM = Graph_GetTargetRelationMatrix(g, edgeType); // construct an iterator to traverse over the source node row, // containing all incoming edges Delta_MatrixTupleIter_AttachRange(&it, TM, srcID, srcID); - while(Delta_MatrixTupleIter_next_BOOL(&it, NULL, NULL, NULL) + while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, NULL) == GrB_SUCCESS) { edge_count++; } @@ -1096,12 +1073,12 @@ void Graph_DeleteEdges ASSERT(!DataBlock_ItemIsDeleted((void *)e->attributes)); R = Graph_GetRelationMatrix(g, r, false); - S = Graph_GetSourceRelationMatrix(g, r, false); - T = Graph_GetTargetRelationMatrix(g, r, false); + S = Graph_GetSourceRelationMatrix(g, r); + T = Graph_GetTargetRelationMatrix(g, r); - info = Delta_Matrix_removeElement_BOOL(S, src_id, ENTITY_GET_ID(e)); + info = Delta_Matrix_removeElement(S, src_id, ENTITY_GET_ID(e)); ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_removeElement_BOOL(T, ENTITY_GET_ID(e), dest_id); + info = Delta_Matrix_removeElement(T, dest_id, ENTITY_GET_ID(e)); ASSERT(info == GrB_SUCCESS); GrB_Vector src_vec; @@ -1112,7 +1089,7 @@ void Graph_DeleteEdges ASSERT(info == GrB_SUCCESS); info = Delta_Matrix_extract_row(S, src_vec, src_id); ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_extract_row(Delta_Matrix_getTranspose(T), dst_vec, dest_id); + info = Delta_Matrix_extract_row(T, dst_vec, dest_id); ASSERT(info == GrB_SUCCESS); info = GrB_Vector_eWiseMult_Semiring(src_vec, NULL, NULL, GxB_ANY_PAIR_BOOL, src_vec, dst_vec, GrB_DESC_R); GrB_Vector_nvals(&x, src_vec); @@ -1124,7 +1101,7 @@ void Graph_DeleteEdges if(x == 0) { // no more edges connecting src to other nodes // remove src from relation matrix - info = Delta_Matrix_removeElement_BOOL(R, src_id, dest_id); + info = Delta_Matrix_removeElement(R, src_id, dest_id); ASSERT(info == GrB_SUCCESS); // see if source is connected to destination with additional edges @@ -1144,7 +1121,7 @@ void Graph_DeleteEdges // remove edge from THE adjacency matrix if(!connected) { M = Graph_GetAdjacencyMatrix(g, false); - info = Delta_Matrix_removeElement_BOOL(M, src_id, dest_id); + info = Delta_Matrix_removeElement(M, src_id, dest_id); ASSERT(info == GrB_SUCCESS); } } @@ -1238,8 +1215,8 @@ RelationID Graph_AddRelationType size_t edge_cap = g->edges->itemCap; Delta_Matrix_new(&r.R, GrB_BOOL, n, n, true); - Delta_Matrix_new(&r.S, GrB_BOOL, n, edge_cap, true); - Delta_Matrix_new(&r.T, GrB_BOOL, edge_cap, n, true); + Delta_Matrix_new(&r.S, GrB_UINT64, n, edge_cap, false); + Delta_Matrix_new(&r.T, GrB_UINT64, n, edge_cap, false); array_append(g->relations, r); @@ -1313,8 +1290,7 @@ Delta_Matrix Graph_GetRelationMatrix Delta_Matrix Graph_GetSourceRelationMatrix ( const Graph *g, - RelationID relation_idx, - bool transposed + RelationID relation_idx ) { ASSERT(relation_idx != GRAPH_NO_RELATION); @@ -1324,16 +1300,13 @@ Delta_Matrix Graph_GetSourceRelationMatrix size_t edge_cap = g->edges->itemCap; g->SynchronizeMatrix(g, m, n, edge_cap); - if(transposed) m = Delta_Matrix_getTranspose(m); - return m; } Delta_Matrix Graph_GetTargetRelationMatrix ( const Graph *g, - RelationID relation_idx, - bool transposed + RelationID relation_idx ) { ASSERT(relation_idx != GRAPH_NO_RELATION); @@ -1341,9 +1314,7 @@ Delta_Matrix Graph_GetTargetRelationMatrix size_t n = Graph_RequiredMatrixDim(g); size_t edge_cap = g->edges->itemCap; - g->SynchronizeMatrix(g, m, edge_cap, n); - - if(transposed) m = Delta_Matrix_getTranspose(m); + g->SynchronizeMatrix(g, m, n, edge_cap); return m; } diff --git a/src/graph/graph.h b/src/graph/graph.h index 5a6aae1b1..ce9573589 100644 --- a/src/graph/graph.h +++ b/src/graph/graph.h @@ -419,8 +419,7 @@ Delta_Matrix Graph_GetRelationMatrix Delta_Matrix Graph_GetSourceRelationMatrix ( const Graph *g, // graph from which to get adjacency matrix - RelationID relation_idx, // relation described by matrix - bool transposed + RelationID relation_idx // relation described by matrix ); // retrieves a relation edge target matrix @@ -428,8 +427,7 @@ Delta_Matrix Graph_GetSourceRelationMatrix Delta_Matrix Graph_GetTargetRelationMatrix ( const Graph *g, // graph from which to get adjacency matrix - RelationID relation_idx, // relation described by matrix - bool transposed + RelationID relation_idx // relation described by matrix ); // retrieves the node-label mapping matrix, diff --git a/src/graph/graph_delete_nodes.c b/src/graph/graph_delete_nodes.c index 091635f01..c2a506542 100644 --- a/src/graph/graph_delete_nodes.c +++ b/src/graph/graph_delete_nodes.c @@ -100,7 +100,7 @@ void Graph_DeleteNodes // clear label matrix j at position [id,id] Delta_Matrix L = Graph_GetLabelMatrix(g, j); - info = Delta_Matrix_removeElement_BOOL(L, id, id); + info = Delta_Matrix_removeElement(L, id, id); ASSERT(info == GrB_SUCCESS); } diff --git a/src/index/index_construct.c b/src/index/index_construct.c index 7ba4d5edd..47c25e178 100644 --- a/src/index/index_construct.c +++ b/src/index/index_construct.c @@ -146,12 +146,8 @@ static void _Index_PopulateEdgeIndex // fetch relation matrix int label_id = Index_GetLabelID(idx); - Delta_Matrix S = Graph_GetSourceRelationMatrix(g, label_id, false); + Delta_Matrix S = Graph_GetSourceRelationMatrix(g, label_id); ASSERT(S != NULL); - Delta_Matrix T = Graph_GetTargetRelationMatrix(g, label_id, false); - ASSERT(T != NULL); - Delta_MatrixTupleIter it_dst = {0}; - Delta_MatrixTupleIter_attach(&it_dst, T); //---------------------------------------------------------------------- // resume scanning from previous row/col indices @@ -161,8 +157,8 @@ static void _Index_PopulateEdgeIndex ASSERT(info == GrB_SUCCESS); // skip previously indexed edges - while((info = Delta_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, - NULL)) == GrB_SUCCESS && + while((info = Delta_MatrixTupleIter_next_UINT64(&it, &src_id, &edge_id, + &dest_id)) == GrB_SUCCESS && src_id == prev_src_id && edge_id < prev_edge_id); @@ -176,9 +172,6 @@ static void _Index_PopulateEdgeIndex //---------------------------------------------------------------------- do { - Delta_MatrixTupleIter_iterate_row(&it_dst, edge_id); - Delta_MatrixTupleIter_next_BOOL(&it_dst, NULL, &dest_id, NULL); - Edge e; e.src_id = src_id; e.dest_id = dest_id; @@ -188,7 +181,7 @@ static void _Index_PopulateEdgeIndex indexed++; } while(indexed < batch_size && - Delta_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, NULL) + Delta_MatrixTupleIter_next_UINT64(&it, &src_id, &edge_id, &dest_id) == GrB_SUCCESS); //---------------------------------------------------------------------- diff --git a/src/serializers/encoder/v14/encode_graph_entities.c b/src/serializers/encoder/v14/encode_graph_entities.c index 454663cd0..cb0aa0493 100644 --- a/src/serializers/encoder/v14/encode_graph_entities.c +++ b/src/serializers/encoder/v14/encode_graph_entities.c @@ -303,12 +303,8 @@ void RdbSaveEdges_v14 // get current relation matrix uint r = GraphEncodeContext_GetCurrentRelationID(gc->encoding_context); - Delta_Matrix S = Graph_GetSourceRelationMatrix(gc->g, r, false); + Delta_Matrix S = Graph_GetSourceRelationMatrix(gc->g, r); ASSERT(S != NULL); - Delta_Matrix T = Graph_GetTargetRelationMatrix(gc->g, r, false); - ASSERT(T != NULL); - Delta_MatrixTupleIter iter_t = {0}; - Delta_MatrixTupleIter_attach(&iter_t, T); // get matrix tuple iterator from context // already set to the next entry to fetch @@ -330,7 +326,7 @@ void RdbSaveEdges_v14 Edge e; // try to get next tuple - info = Delta_MatrixTupleIter_next_BOOL(iter, &src_id, &edge_id, NULL); + info = Delta_MatrixTupleIter_next_UINT64(iter, &src_id, &edge_id, &dest_id); // if iterator is depleted // get new tuple from different matrix or finish encode @@ -342,23 +338,15 @@ void RdbSaveEdges_v14 if(r == relation_count) goto finish; // get matrix and set iterator - S = Graph_GetSourceRelationMatrix(gc->g, r, false); + S = Graph_GetSourceRelationMatrix(gc->g, r); ASSERT(S != NULL); - T = Graph_GetTargetRelationMatrix(gc->g, r, false); info = Delta_MatrixTupleIter_attach(iter, S); ASSERT(info == GrB_SUCCESS); - info = Delta_MatrixTupleIter_attach(&iter_t, T); - ASSERT(info == GrB_SUCCESS); - info = Delta_MatrixTupleIter_next_BOOL(iter, &src_id, &edge_id, NULL); + info = Delta_MatrixTupleIter_next_UINT64(iter, &src_id, &edge_id, &dest_id); } ASSERT(info == GrB_SUCCESS); - info = Delta_MatrixTupleIter_iterate_row(&iter_t, edge_id); - ASSERT(info == GrB_SUCCESS); - info = Delta_MatrixTupleIter_next_BOOL(&iter_t, NULL, &dest_id, NULL); - ASSERT(info == GrB_SUCCESS); - e.src_id = src_id; e.dest_id = dest_id; Graph_GetEdge(gc->g, edge_id, &e); diff --git a/src/serializers/graph_extensions.c b/src/serializers/graph_extensions.c index 955da9844..51d67b7ea 100644 --- a/src/serializers/graph_extensions.c +++ b/src/serializers/graph_extensions.c @@ -139,15 +139,13 @@ static void _OptimizedSingleEdgeFormConnection ) { GrB_Info info; Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); - Delta_Matrix S = Graph_GetSourceRelationMatrix(g, r, false); - Delta_Matrix T = Graph_GetTargetRelationMatrix(g, r, false); + Delta_Matrix S = Graph_GetSourceRelationMatrix(g, r); + Delta_Matrix T = Graph_GetTargetRelationMatrix(g, r); Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); GrB_Matrix m = Delta_Matrix_M(M); GrB_Matrix tm = Delta_Matrix_M(Delta_Matrix_getTranspose(M)); GrB_Matrix s = Delta_Matrix_M(S); - GrB_Matrix ts = Delta_Matrix_M(Delta_Matrix_getTranspose(S)); GrB_Matrix t = Delta_Matrix_M(T); - GrB_Matrix tt = Delta_Matrix_M(Delta_Matrix_getTranspose(T)); GrB_Matrix adj_m = Delta_Matrix_M(adj); GrB_Matrix adj_tm = Delta_Matrix_M(Delta_Matrix_getTranspose(adj)); @@ -180,13 +178,9 @@ static void _OptimizedSingleEdgeFormConnection ASSERT(info == GrB_SUCCESS); info = GrB_Matrix_setElement_BOOL(tm, true, dest, src); ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_setElement_BOOL(s, true, src, edge_id); + info = GrB_Matrix_setElement_UINT64(s, dest, src, edge_id); ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_setElement_BOOL(ts, true, edge_id, src); - ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_setElement_BOOL(t, true, edge_id, dest); - ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_setElement_BOOL(tt, true, dest, edge_id); + info = GrB_Matrix_setElement_UINT64(t, src, dest, edge_id); ASSERT(info == GrB_SUCCESS); } diff --git a/tests/unit/test_delta_matrix.c b/tests/unit/test_delta_matrix.c index 52439d22b..e6051e22f 100644 --- a/tests/unit/test_delta_matrix.c +++ b/tests/unit/test_delta_matrix.c @@ -154,10 +154,6 @@ void test_DeltaMatrix_new() { // bool matrix do not maintain transpose TEST_ASSERT(Delta_Matrix_getTranspose(A) == NULL); - // a new empty matrix should be synced - // no data in either DP or DM - TEST_ASSERT(!Delta_Matrix_isDirty(A)); - // matrix should be empty M_EMPTY(); DP_EMPTY(); @@ -203,7 +199,7 @@ void test_DeltaMatrix_set() { Delta_Matrix_wait(A, true); // set element at position i,j - info = Delta_Matrix_removeElement_BOOL(A, i, j); + info = Delta_Matrix_removeElement(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); // set element at position i,j @@ -385,7 +381,7 @@ void test_DeltaMatrix_fuzzy() { // delete element at position i,j //------------------------------------------------------------------ - Delta_Matrix_removeElement_BOOL(A, i, j); + Delta_Matrix_removeElement(A, i, j); GrB_Matrix_removeElement(N, i, j); } @@ -529,7 +525,7 @@ void test_DeltaMatrix_export_pending_changes() { //-------------------------------------------------------------------------- // remove element at position 0,0 - info = Delta_Matrix_removeElement_BOOL(A, 0, 0); + info = Delta_Matrix_removeElement(A, 0, 0); TEST_ASSERT(info == GrB_SUCCESS); // set element at position 2,2 @@ -603,7 +599,7 @@ void test_DeltaMatrix_copy() { //-------------------------------------------------------------------------- // remove element at position 0,0 - info = Delta_Matrix_removeElement_BOOL(A, 0, 0); + info = Delta_Matrix_removeElement(A, 0, 0); TEST_ASSERT(info == GrB_SUCCESS); // set element at position 2,2 @@ -688,7 +684,7 @@ void test_DeltaMatrix_mxm() { //-------------------------------------------------------------------------- // remove element at position 0,0 - info = Delta_Matrix_removeElement_BOOL(B, 1, 2); + info = Delta_Matrix_removeElement(B, 1, 2); TEST_ASSERT(info == GrB_SUCCESS); // set element at position 1,3 diff --git a/tests/unit/test_delta_matrix_iter.c b/tests/unit/test_delta_matrix_iter.c index 8481b6044..a79311b6e 100644 --- a/tests/unit/test_delta_matrix_iter.c +++ b/tests/unit/test_delta_matrix_iter.c @@ -89,7 +89,7 @@ void test_DeltaMatrixTupleIter_next() { //-------------------------------------------------------------------------- // remove element at position i,j - info = Delta_Matrix_removeElement_BOOL(A, i, j); + info = Delta_Matrix_removeElement(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); // set element at position i+1,j+1 @@ -275,7 +275,7 @@ void test_DeltaMatrixTupleIter_iterate_row() { //-------------------------------------------------------------------------- // remove element at position i,j - info = Delta_Matrix_removeElement_BOOL(A, i, j); + info = Delta_Matrix_removeElement(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); // wait, DM can't have pendding changes @@ -353,7 +353,7 @@ void test_DeltaMatrixTupleIter_iterate_range() { //-------------------------------------------------------------------------- // remove element at position i,j - info = Delta_Matrix_removeElement_BOOL(A, i, j); + info = Delta_Matrix_removeElement(A, i, j); TEST_ASSERT(info == GrB_SUCCESS); // set element at position i+1,j+1 From 2ae6ed89195ea9898c2ff42d9a06bed725df6977 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Wed, 15 May 2024 10:56:49 +0300 Subject: [PATCH 17/57] address review --- .../algebraic_expression/algebraic_expression_mul.c | 4 ++-- src/serializers/decode_context.c | 11 ----------- src/serializers/decode_context.h | 1 - src/serializers/decoders/current/v14/decode_graph.c | 11 +---------- .../decoders/current/v14/decode_graph_entities.c | 4 +--- src/serializers/decoders/prev/v10/decode_graph.c | 11 +---------- .../decoders/prev/v10/decode_graph_entities.c | 4 +--- src/serializers/decoders/prev/v11/decode_graph.c | 8 -------- .../decoders/prev/v11/decode_graph_entities.c | 4 +--- src/serializers/decoders/prev/v12/decode_graph.c | 11 +---------- .../decoders/prev/v12/decode_graph_entities.c | 4 +--- src/serializers/decoders/prev/v13/decode_graph.c | 11 +---------- .../decoders/prev/v13/decode_graph_entities.c | 4 +--- src/serializers/decoders/prev/v9/decode_graph.c | 11 +---------- .../decoders/prev/v9/decode_graph_entities.c | 4 +--- src/serializers/graph_extensions.c | 6 ++---- src/serializers/graph_extensions.h | 1 - 17 files changed, 15 insertions(+), 95 deletions(-) diff --git a/src/arithmetic/algebraic_expression/algebraic_expression_mul.c b/src/arithmetic/algebraic_expression/algebraic_expression_mul.c index fece5a380..572a12bca 100644 --- a/src/arithmetic/algebraic_expression/algebraic_expression_mul.c +++ b/src/arithmetic/algebraic_expression/algebraic_expression_mul.c @@ -22,13 +22,13 @@ Delta_Matrix _Eval_Mul ASSERT(AlgebraicExpression_OperationCount(exp, AL_EXP_MUL) == 1) ; GrB_Info info ; - Delta_Matrix M ; // current operand + Delta_Matrix M ; // current operand GrB_Index nvals ; // NNZ in res AlgebraicExpression *c ; // current child node UNUSED(info) ; - Delta_Matrix A = NULL ; + Delta_Matrix A = NULL ; bool res_modified = false ; GrB_Semiring semiring = GxB_ANY_PAIR_BOOL ; uint child_count = AlgebraicExpression_ChildCount(exp) ; diff --git a/src/serializers/decode_context.c b/src/serializers/decode_context.c index d40ede899..ae167ea6c 100644 --- a/src/serializers/decode_context.c +++ b/src/serializers/decode_context.c @@ -15,7 +15,6 @@ GraphDecodeContext *GraphDecodeContext_New() { ctx->keys_processed = 0; ctx->graph_keys_count = 1; ctx->meta_keys = raxNew(); - ctx->multi_edge = NULL; return ctx; } @@ -24,11 +23,6 @@ void GraphDecodeContext_Reset(GraphDecodeContext *ctx) { ctx->keys_processed = 0; ctx->graph_keys_count = 1; - - if(ctx->multi_edge) { - array_free(ctx->multi_edge); - ctx->multi_edge = NULL; - } } void GraphDecodeContext_SetKeyCount(GraphDecodeContext *ctx, uint64_t key_count) { @@ -77,11 +71,6 @@ void GraphDecodeContext_Free(GraphDecodeContext *ctx) { if(ctx) { raxFree(ctx->meta_keys); - if(ctx->multi_edge) { - array_free(ctx->multi_edge); - ctx->multi_edge = NULL; - } - rm_free(ctx); } } diff --git a/src/serializers/decode_context.h b/src/serializers/decode_context.h index 202e2b1d9..a99e7012c 100644 --- a/src/serializers/decode_context.h +++ b/src/serializers/decode_context.h @@ -16,7 +16,6 @@ typedef struct { uint64_t keys_processed; // Count the number of procssed graph keys. uint64_t graph_keys_count; // The number of keys representing the graph. rax *meta_keys; // The meta keys encountered so far in the decode process. - uint64_t *multi_edge; // Is relation contains multi edge values. } GraphDecodeContext; // Creates a new graph decoding context. diff --git a/src/serializers/decoders/current/v14/decode_graph.c b/src/serializers/decoders/current/v14/decode_graph.c index c31780617..806ecdef4 100644 --- a/src/serializers/decoders/current/v14/decode_graph.c +++ b/src/serializers/decoders/current/v14/decode_graph.c @@ -76,10 +76,9 @@ static GraphContext *_DecodeHeader uint64_t deleted_edge_count = SerializerIO_ReadUnsigned(rdb); uint64_t label_count = SerializerIO_ReadUnsigned(rdb); uint64_t relation_count = SerializerIO_ReadUnsigned(rdb); - uint64_t multi_edge[relation_count]; for(uint i = 0; i < relation_count; i++) { - multi_edge[i] = SerializerIO_ReadUnsigned(rdb); + SerializerIO_ReadUnsigned(rdb); } // total keys representing the graph @@ -97,14 +96,6 @@ static GraphContext *_DecodeHeader _InitGraphDataStructure(gc->g, node_count, edge_count, deleted_node_count, deleted_edge_count, label_count, relation_count); - gc->decoding_context->multi_edge = array_new(uint64_t, relation_count); - for(uint i = 0; i < relation_count; i++) { - // enable/Disable support for multi-edge - // we will enable support for multi-edge on all relationship - // matrices once we finish loading the graph - array_append(gc->decoding_context->multi_edge, multi_edge[i]); - } - GraphDecodeContext_SetKeyCount(gc->decoding_context, key_number); } diff --git a/src/serializers/decoders/current/v14/decode_graph_entities.c b/src/serializers/decoders/current/v14/decode_graph_entities.c index 2c2cd6bf1..b30c2fc06 100644 --- a/src/serializers/decoders/current/v14/decode_graph_entities.c +++ b/src/serializers/decoders/current/v14/decode_graph_entities.c @@ -201,9 +201,7 @@ void RdbLoadEdges_v14 NodeID destId = SerializerIO_ReadUnsigned(rdb); uint64_t relation = SerializerIO_ReadUnsigned(rdb); - Serializer_Graph_SetEdge(gc->g, - gc->decoding_context->multi_edge[relation], edgeId, srcId, - destId, relation, &e); + Serializer_Graph_SetEdge(gc->g, edgeId, srcId, destId, relation, &e); _RdbLoadEntity(rdb, gc, (GraphEntity *)&e); // index edge diff --git a/src/serializers/decoders/prev/v10/decode_graph.c b/src/serializers/decoders/prev/v10/decode_graph.c index 11750ea2f..545887a76 100644 --- a/src/serializers/decoders/prev/v10/decode_graph.c +++ b/src/serializers/decoders/prev/v10/decode_graph.c @@ -57,10 +57,9 @@ static GraphContext *_DecodeHeader(RedisModuleIO *rdb) { uint64_t edge_count = RedisModule_LoadUnsigned(rdb); uint64_t label_count = RedisModule_LoadUnsigned(rdb); uint64_t relation_count = RedisModule_LoadUnsigned(rdb); - uint64_t multi_edge[relation_count]; for(uint i = 0; i < relation_count; i++) { - multi_edge[i] = RedisModule_LoadUnsigned(rdb); + RedisModule_LoadUnsigned(rdb); } // Total keys representing the graph. @@ -74,14 +73,6 @@ static GraphContext *_DecodeHeader(RedisModuleIO *rdb) { if(GraphDecodeContext_GetProcessedKeyCount(gc->decoding_context) == 0) { _InitGraphDataStructure(g, node_count, edge_count, label_count, relation_count); - gc->decoding_context->multi_edge = array_new(uint64_t, relation_count); - for(uint i = 0; i < relation_count; i++) { - // Enable/Disable support for multi-edge - // we will enable support for multi-edge on all relationship - // matrices once we finish loading the graph - array_append(gc->decoding_context->multi_edge, multi_edge[i]); - } - GraphDecodeContext_SetKeyCount(gc->decoding_context, key_number); } diff --git a/src/serializers/decoders/prev/v10/decode_graph_entities.c b/src/serializers/decoders/prev/v10/decode_graph_entities.c index 2100b194d..c0c03649c 100644 --- a/src/serializers/decoders/prev/v10/decode_graph_entities.c +++ b/src/serializers/decoders/prev/v10/decode_graph_entities.c @@ -142,9 +142,7 @@ void RdbLoadEdges_v10(RedisModuleIO *rdb, GraphContext *gc, uint64_t edge_count) NodeID srcId = RedisModule_LoadUnsigned(rdb); NodeID destId = RedisModule_LoadUnsigned(rdb); uint64_t relation = RedisModule_LoadUnsigned(rdb); - Serializer_Graph_SetEdge(gc->g, - gc->decoding_context->multi_edge[relation], edgeId, srcId, - destId, relation, &e); + Serializer_Graph_SetEdge(gc->g, edgeId, srcId, destId, relation, &e); _RdbLoadEntity(rdb, gc, (GraphEntity *)&e); // index edge diff --git a/src/serializers/decoders/prev/v11/decode_graph.c b/src/serializers/decoders/prev/v11/decode_graph.c index b5f83cf34..ddfe73a6e 100644 --- a/src/serializers/decoders/prev/v11/decode_graph.c +++ b/src/serializers/decoders/prev/v11/decode_graph.c @@ -85,14 +85,6 @@ static GraphContext *_DecodeHeader if(GraphDecodeContext_GetProcessedKeyCount(gc->decoding_context) == 0) { _InitGraphDataStructure(gc->g, node_count, edge_count, label_count, relation_count); - gc->decoding_context->multi_edge = array_new(uint64_t, relation_count); - for(uint i = 0; i < relation_count; i++) { - // enable/Disable support for multi-edge - // we will enable support for multi-edge on all relationship - // matrices once we finish loading the graph - array_append(gc->decoding_context->multi_edge, multi_edge[i]); - } - GraphDecodeContext_SetKeyCount(gc->decoding_context, key_number); } diff --git a/src/serializers/decoders/prev/v11/decode_graph_entities.c b/src/serializers/decoders/prev/v11/decode_graph_entities.c index df20581d0..fa604edcf 100644 --- a/src/serializers/decoders/prev/v11/decode_graph_entities.c +++ b/src/serializers/decoders/prev/v11/decode_graph_entities.c @@ -167,9 +167,7 @@ void RdbLoadEdges_v11 NodeID srcId = RedisModule_LoadUnsigned(rdb); NodeID destId = RedisModule_LoadUnsigned(rdb); uint64_t relation = RedisModule_LoadUnsigned(rdb); - Serializer_Graph_SetEdge(gc->g, - gc->decoding_context->multi_edge[relation], edgeId, srcId, - destId, relation, &e); + Serializer_Graph_SetEdge(gc->g, edgeId, srcId, destId, relation, &e); _RdbLoadEntity(rdb, gc, (GraphEntity *)&e); // index edge diff --git a/src/serializers/decoders/prev/v12/decode_graph.c b/src/serializers/decoders/prev/v12/decode_graph.c index 4b060d71b..cbc6c1a2e 100644 --- a/src/serializers/decoders/prev/v12/decode_graph.c +++ b/src/serializers/decoders/prev/v12/decode_graph.c @@ -74,10 +74,9 @@ static GraphContext *_DecodeHeader uint64_t deleted_edge_count = RedisModule_LoadUnsigned(rdb); uint64_t label_count = RedisModule_LoadUnsigned(rdb); uint64_t relation_count = RedisModule_LoadUnsigned(rdb); - uint64_t multi_edge[relation_count]; for(uint i = 0; i < relation_count; i++) { - multi_edge[i] = RedisModule_LoadUnsigned(rdb); + RedisModule_LoadUnsigned(rdb); } // total keys representing the graph @@ -92,14 +91,6 @@ static GraphContext *_DecodeHeader _InitGraphDataStructure(gc->g, node_count, edge_count, deleted_node_count, deleted_edge_count, label_count, relation_count); - gc->decoding_context->multi_edge = array_new(uint64_t, relation_count); - for(uint i = 0; i < relation_count; i++) { - // enable/Disable support for multi-edge - // we will enable support for multi-edge on all relationship - // matrices once we finish loading the graph - array_append(gc->decoding_context->multi_edge, multi_edge[i]); - } - GraphDecodeContext_SetKeyCount(gc->decoding_context, key_number); } diff --git a/src/serializers/decoders/prev/v12/decode_graph_entities.c b/src/serializers/decoders/prev/v12/decode_graph_entities.c index 4d8bd3136..51037f19f 100644 --- a/src/serializers/decoders/prev/v12/decode_graph_entities.c +++ b/src/serializers/decoders/prev/v12/decode_graph_entities.c @@ -167,9 +167,7 @@ void RdbLoadEdges_v12 NodeID srcId = RedisModule_LoadUnsigned(rdb); NodeID destId = RedisModule_LoadUnsigned(rdb); uint64_t relation = RedisModule_LoadUnsigned(rdb); - Serializer_Graph_SetEdge(gc->g, - gc->decoding_context->multi_edge[relation], edgeId, srcId, - destId, relation, &e); + Serializer_Graph_SetEdge(gc->g, edgeId, srcId, destId, relation, &e); _RdbLoadEntity(rdb, gc, (GraphEntity *)&e); // index edge diff --git a/src/serializers/decoders/prev/v13/decode_graph.c b/src/serializers/decoders/prev/v13/decode_graph.c index 1e546c8a2..f39736e2b 100644 --- a/src/serializers/decoders/prev/v13/decode_graph.c +++ b/src/serializers/decoders/prev/v13/decode_graph.c @@ -76,10 +76,9 @@ static GraphContext *_DecodeHeader uint64_t deleted_edge_count = RedisModule_LoadUnsigned(rdb); uint64_t label_count = RedisModule_LoadUnsigned(rdb); uint64_t relation_count = RedisModule_LoadUnsigned(rdb); - uint64_t multi_edge[relation_count]; for(uint i = 0; i < relation_count; i++) { - multi_edge[i] = RedisModule_LoadUnsigned(rdb); + RedisModule_LoadUnsigned(rdb); } // total keys representing the graph @@ -97,14 +96,6 @@ static GraphContext *_DecodeHeader _InitGraphDataStructure(gc->g, node_count, edge_count, deleted_node_count, deleted_edge_count, label_count, relation_count); - gc->decoding_context->multi_edge = array_new(uint64_t, relation_count); - for(uint i = 0; i < relation_count; i++) { - // enable/Disable support for multi-edge - // we will enable support for multi-edge on all relationship - // matrices once we finish loading the graph - array_append(gc->decoding_context->multi_edge, multi_edge[i]); - } - GraphDecodeContext_SetKeyCount(gc->decoding_context, key_number); } diff --git a/src/serializers/decoders/prev/v13/decode_graph_entities.c b/src/serializers/decoders/prev/v13/decode_graph_entities.c index d53c4a6c9..5ebe09f99 100644 --- a/src/serializers/decoders/prev/v13/decode_graph_entities.c +++ b/src/serializers/decoders/prev/v13/decode_graph_entities.c @@ -169,9 +169,7 @@ void RdbLoadEdges_v13 NodeID destId = RedisModule_LoadUnsigned(rdb); uint64_t relation = RedisModule_LoadUnsigned(rdb); - Serializer_Graph_SetEdge(gc->g, - gc->decoding_context->multi_edge[relation], edgeId, srcId, - destId, relation, &e); + Serializer_Graph_SetEdge(gc->g, edgeId, srcId, destId, relation, &e); _RdbLoadEntity(rdb, gc, (GraphEntity *)&e); // index edge diff --git a/src/serializers/decoders/prev/v9/decode_graph.c b/src/serializers/decoders/prev/v9/decode_graph.c index 5cbb22324..9bdd90346 100644 --- a/src/serializers/decoders/prev/v9/decode_graph.c +++ b/src/serializers/decoders/prev/v9/decode_graph.c @@ -53,10 +53,9 @@ static GraphContext *_DecodeHeader(RedisModuleIO *rdb) { uint64_t edge_count = RedisModule_LoadUnsigned(rdb); uint64_t label_count = RedisModule_LoadUnsigned(rdb); uint64_t relation_count = RedisModule_LoadUnsigned(rdb); - uint64_t multi_edge[relation_count]; for(uint i = 0; i < relation_count; i++) { - multi_edge[i] = RedisModule_LoadUnsigned(rdb); + RedisModule_LoadUnsigned(rdb); } // Total keys representing the graph. @@ -70,14 +69,6 @@ static GraphContext *_DecodeHeader(RedisModuleIO *rdb) { if(GraphDecodeContext_GetProcessedKeyCount(gc->decoding_context) == 0) { _InitGraphDataStructure(g, node_count, edge_count, label_count, relation_count); - gc->decoding_context->multi_edge = array_new(uint64_t, relation_count); - for(uint i = 0; i < relation_count; i++) { - // Enable/Disable support for multi-edge - // we will enable support for multi-edge on all relationship - // matrices once we finish loading the graph - array_append(gc->decoding_context->multi_edge, multi_edge[i]); - } - GraphDecodeContext_SetKeyCount(gc->decoding_context, key_number); } diff --git a/src/serializers/decoders/prev/v9/decode_graph_entities.c b/src/serializers/decoders/prev/v9/decode_graph_entities.c index 43f715c0b..876ca68b6 100644 --- a/src/serializers/decoders/prev/v9/decode_graph_entities.c +++ b/src/serializers/decoders/prev/v9/decode_graph_entities.c @@ -137,9 +137,7 @@ void RdbLoadEdges_v9(RedisModuleIO *rdb, GraphContext *gc, uint64_t edge_count) NodeID srcId = RedisModule_LoadUnsigned(rdb); NodeID destId = RedisModule_LoadUnsigned(rdb); uint64_t relation = RedisModule_LoadUnsigned(rdb); - Serializer_Graph_SetEdge(gc->g, - gc->decoding_context->multi_edge[relation], edgeId, srcId, - destId, relation, &e); + Serializer_Graph_SetEdge(gc->g, edgeId, srcId, destId, relation, &e); _RdbLoadEntity(rdb, gc, (GraphEntity *)&e); } } diff --git a/src/serializers/graph_extensions.c b/src/serializers/graph_extensions.c index 51d67b7ea..34935a141 100644 --- a/src/serializers/graph_extensions.c +++ b/src/serializers/graph_extensions.c @@ -128,8 +128,7 @@ void Serializer_Graph_SetNodeLabels } // optimized version of Graph_FormConnection -// used only when matrix doesn't contains multi edge values -static void _OptimizedSingleEdgeFormConnection +static void _OptimizedFormConnection ( Graph *g, NodeID src, @@ -188,7 +187,6 @@ static void _OptimizedSingleEdgeFormConnection void Serializer_Graph_SetEdge ( Graph *g, - bool multi_edge, EdgeID edge_id, NodeID src, NodeID dest, @@ -206,7 +204,7 @@ void Serializer_Graph_SetEdge e->attributes = set; e->relationID = r; - _OptimizedSingleEdgeFormConnection(g, src, dest, edge_id, r); + _OptimizedFormConnection(g, src, dest, edge_id, r); } // returns the graph deleted nodes list diff --git a/src/serializers/graph_extensions.h b/src/serializers/graph_extensions.h index 2f6efbd07..c3588d780 100644 --- a/src/serializers/graph_extensions.h +++ b/src/serializers/graph_extensions.h @@ -28,7 +28,6 @@ void Serializer_Graph_SetNodeLabels void Serializer_Graph_SetEdge ( Graph *g, // graph to add edge to - bool multi_edge, // true if graph supports multi-edge EdgeID edge_id, // edge ID NodeID src, // edge source NodeID dest, // edge destination From def1a16b6a824d445c24a0257b402fd3c3a28f17 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Thu, 16 May 2024 17:09:23 +0300 Subject: [PATCH 18/57] address review --- src/bulk_insert/bulk_insert.c | 4 +- src/constraint/constraint.c | 2 +- src/cron/tasks/stream_finished_queries.c | 1 + .../ops/shared/create_functions.c | 4 +- src/globals.c | 1 + src/graph/graph.c | 133 +++++++++--------- src/graph/graph.h | 26 ++-- src/graph/graph_delete_nodes.c | 1 + src/index/index_construct.c | 6 +- src/index/indexer.c | 1 + .../encoder/v14/encode_graph_entities.c | 14 +- src/serializers/graph_extensions.c | 15 +- 12 files changed, 106 insertions(+), 102 deletions(-) diff --git a/src/bulk_insert/bulk_insert.c b/src/bulk_insert/bulk_insert.c index 8024a0f92..3611228f6 100644 --- a/src/bulk_insert/bulk_insert.c +++ b/src/bulk_insert/bulk_insert.c @@ -272,8 +272,8 @@ static int _BulkInsert_ProcessEdgeFile // sync matrix once ASSERT(Graph_GetMatrixPolicy(gc->g) == SYNC_POLICY_RESIZE); Graph_GetRelationMatrix(gc->g, type_id, false); - Graph_GetSourceRelationMatrix(gc->g, type_id); - Graph_GetTargetRelationMatrix(gc->g, type_id); + Graph_OutgoingRelationMatrix(gc->g, type_id); + Graph_IncomingRelationMatrix(gc->g, type_id); Graph_GetAdjacencyMatrix(gc->g, false); Graph_SetMatrixPolicy(gc->g, SYNC_POLICY_NOP); diff --git a/src/constraint/constraint.c b/src/constraint/constraint.c index 3983c9f9b..e59f849d6 100644 --- a/src/constraint/constraint.c +++ b/src/constraint/constraint.c @@ -527,7 +527,7 @@ void Constraint_EnforceEdges // fetch relation matrix ASSERT(Graph_GetMatrixPolicy(g) == SYNC_POLICY_FLUSH_RESIZE); - const Delta_Matrix m = Graph_GetSourceRelationMatrix(g, schema_id); + const Delta_Matrix m = Graph_OutgoingRelationMatrix(g, schema_id); ASSERT(m != NULL); //---------------------------------------------------------------------- diff --git a/src/cron/tasks/stream_finished_queries.c b/src/cron/tasks/stream_finished_queries.c index 6359cd756..b6f513ed8 100644 --- a/src/cron/tasks/stream_finished_queries.c +++ b/src/cron/tasks/stream_finished_queries.c @@ -7,6 +7,7 @@ #include "globals.h" #include "cron/cron.h" #include "redismodule.h" +#include "../../util/rmalloc.h" #include "graph/graphcontext.h" #include "configuration/config.h" #include "util/circular_buffer.h" diff --git a/src/execution_plan/ops/shared/create_functions.c b/src/execution_plan/ops/shared/create_functions.c index 66ed14ec6..fc37ce75f 100644 --- a/src/execution_plan/ops/shared/create_functions.c +++ b/src/execution_plan/ops/shared/create_functions.c @@ -123,8 +123,8 @@ static void _CommitEdgesBlueprint // calling Graph_GetRelationMatrix will make sure relationship matrix // is of the right dimensions Graph_GetRelationMatrix(g, Schema_GetID(s), false); - Graph_GetSourceRelationMatrix(g, Schema_GetID(s)); - Graph_GetTargetRelationMatrix(g, Schema_GetID(s)); + Graph_OutgoingRelationMatrix(g, Schema_GetID(s)); + Graph_IncomingRelationMatrix(g, Schema_GetID(s)); } // call Graph_GetAdjacencyMatrix will make sure the adjacency matrix diff --git a/src/globals.c b/src/globals.c index 5d64a88f6..9120cfeb4 100644 --- a/src/globals.c +++ b/src/globals.c @@ -5,6 +5,7 @@ */ #include "globals.h" +#include "util/arr.h" #include "util/thpool/pools.h" struct Globals { diff --git a/src/graph/graph.c b/src/graph/graph.c index 2c9bae1ac..8488942c1 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -102,29 +102,29 @@ void _Graph_GetEdgesConnectingNodes ASSERT(g); ASSERT(r != GRAPH_NO_RELATION); ASSERT(r < Graph_RelationTypeCount(g)); - ASSERT(src < Graph_RequiredMatrixDim(g)); - ASSERT(dest < Graph_RequiredMatrixDim(g)); + ASSERT(src < Graph_NodeCount(g)); + ASSERT(dest < Graph_NodeCount(g)); // relation map, maps (src, dest, r) to edge IDs. - Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); - GrB_Info res = Delta_Matrix_extractElement_BOOL(NULL, M, src, dest); + Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); + GrB_Info res = Delta_Matrix_extractElement_BOOL(NULL, M, src, dest); // no entry at [dest, src], src is not connected to dest with relation R if(res == GrB_NO_VALUE) return; + GrB_Info info; GrB_Vector src_vec; GrB_Vector dst_vec; - GrB_Info info; info = GrB_Vector_new(&src_vec, GrB_BOOL, g->edges->itemCap); ASSERT(info == GrB_SUCCESS); info = GrB_Vector_new(&dst_vec, GrB_BOOL, g->edges->itemCap); ASSERT(info == GrB_SUCCESS); Edge e = {.src_id = src, .dest_id = dest, .relationID = r}; - Delta_Matrix S = Graph_GetSourceRelationMatrix(g, r); - Delta_Matrix T = Graph_GetTargetRelationMatrix(g, r); - info = Delta_Matrix_extract_row(S, src_vec, src); + Delta_Matrix out = Graph_OutgoingRelationMatrix(g, r); + Delta_Matrix in = Graph_IncomingRelationMatrix(g, r); + info = Delta_Matrix_extract_row(out, src_vec, src); ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_extract_row(T, dst_vec, dest); + info = Delta_Matrix_extract_row(in, dst_vec, dest); ASSERT(info == GrB_SUCCESS); info = GrB_Vector_eWiseMult_Semiring(src_vec, NULL, NULL, GxB_ANY_PAIR_BOOL, src_vec, dst_vec, GrB_DESC_R); ASSERT(info == GrB_SUCCESS); @@ -292,9 +292,9 @@ void Graph_ApplyAllPending for(int i = 0; i < n; i ++) { M = Graph_GetRelationMatrix(g, i, false); Delta_Matrix_wait(M, force_flush); - M = Graph_GetSourceRelationMatrix(g, i); + M = Graph_OutgoingRelationMatrix(g, i); Delta_Matrix_wait(M, force_flush); - M = Graph_GetTargetRelationMatrix(g, i); + M = Graph_IncomingRelationMatrix(g, i); Delta_Matrix_wait(M, force_flush); } @@ -311,9 +311,9 @@ bool Graph_Pending GrB_Info info; UNUSED(info); - uint n = 0; + uint n = 0; Delta_Matrix M = NULL; - bool pending = false; + bool pending = false; //-------------------------------------------------------------------------- // see if ADJ matrix contains pending changes @@ -461,10 +461,10 @@ uint64_t Graph_RelationEdgeCount ) { ASSERT(g); - Delta_Matrix S = Graph_GetSourceRelationMatrix(g, relation); - ASSERT(S != NULL); + Delta_Matrix out = Graph_OutgoingRelationMatrix(g, relation); + ASSERT(out != NULL); GrB_Index nvals; - GrB_Info info = Delta_Matrix_nvals(&nvals, S); + GrB_Info info = Delta_Matrix_nvals(&nvals, out); ASSERT(info == GrB_SUCCESS); return nvals; } @@ -543,10 +543,10 @@ RelationID Graph_GetEdgeRelation for(uint i = 0; i < n; i++) { EdgeID edgeId = 0; Delta_Matrix M = Graph_GetRelationMatrix(g, i, false); - Delta_Matrix S = Graph_GetSourceRelationMatrix(g, i); info = Delta_Matrix_extractElement_BOOL(NULL, M, src_id, dest_id); if(info != GrB_SUCCESS) continue; - info = Delta_Matrix_extractElement_UINT64(&dst, S, src_id, id); + Delta_Matrix out = Graph_OutgoingRelationMatrix(g, i); + info = Delta_Matrix_extractElement_UINT64(&dst, out, src_id, id); if(info != GrB_SUCCESS || dst != dest_id) continue; Edge_SetRelationID(e, i); rel = i; @@ -740,8 +740,8 @@ bool Graph_FormConnection GrB_Info info; UNUSED(info); Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); - Delta_Matrix S = Graph_GetSourceRelationMatrix(g, r); - Delta_Matrix T = Graph_GetTargetRelationMatrix(g, r); + Delta_Matrix out = Graph_OutgoingRelationMatrix(g, r); + Delta_Matrix in = Graph_IncomingRelationMatrix(g, r); Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); // rows represent source nodes, columns represent destination nodes @@ -753,10 +753,10 @@ bool Graph_FormConnection info = Delta_Matrix_setElement_BOOL(M, src, dest); if(info != GrB_SUCCESS) return false; - info = Delta_Matrix_setElement_UINT64(S, dest, src, edge_id); + info = Delta_Matrix_setElement_UINT64(out, dest, src, edge_id); if(info != GrB_SUCCESS) return false; - info = Delta_Matrix_setElement_UINT64(T, src, dest, edge_id); + info = Delta_Matrix_setElement_UINT64(in, src, dest, edge_id); return info == GrB_SUCCESS; } @@ -795,7 +795,6 @@ void _GetOutgoingNodeEdges ( const Graph *g, // graph to collect edges from const Node *n, // either source or destination node - GRAPH_EDGE_DIR dir, // edge direction ->, <-, <-> RelationID edgeType, // relationship type Edge **edges // [output] array of edges ) { @@ -806,16 +805,15 @@ void _GetOutgoingNodeEdges GrB_Info info; Delta_MatrixTupleIter it = {0}; - Delta_Matrix S = NULL; - Delta_Matrix T = NULL; + Delta_Matrix out = NULL; NodeID src_id = ENTITY_GET_ID(n); NodeID dest_id = INVALID_ENTITY_ID; EdgeID edge_id = INVALID_ENTITY_ID; UNUSED(info); - S = Graph_GetSourceRelationMatrix(g, edgeType); + out = Graph_OutgoingRelationMatrix(g, edgeType); - info = Delta_MatrixTupleIter_AttachRange(&it, S, src_id, src_id); + info = Delta_MatrixTupleIter_AttachRange(&it, out, src_id, src_id); ASSERT(info == GrB_SUCCESS); while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &edge_id, &dest_id) == GrB_SUCCESS) { @@ -847,16 +845,15 @@ void _GetIncomingNodeEdges GrB_Info info; Delta_MatrixTupleIter it = {0}; - Delta_Matrix S = NULL; - Delta_Matrix T = NULL; + Delta_Matrix in = NULL; NodeID src_id = ENTITY_GET_ID(n); NodeID dest_id = INVALID_ENTITY_ID; EdgeID edge_id = INVALID_ENTITY_ID; UNUSED(info); - T = Graph_GetTargetRelationMatrix(g, edgeType); + in = Graph_IncomingRelationMatrix(g, edgeType); - info = Delta_MatrixTupleIter_AttachRange(&it, T, src_id, src_id); + info = Delta_MatrixTupleIter_AttachRange(&it, in, src_id, src_id); ASSERT(info == GrB_SUCCESS); while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &edge_id, &dest_id) == GrB_SUCCESS) { if(dir == GRAPH_EDGE_DIR_BOTH && src_id == dest_id) continue; @@ -897,12 +894,12 @@ void Graph_GetNodeEdges if(outgoing) { if(edgeType != GRAPH_NO_RELATION) { - _GetOutgoingNodeEdges(g, n, dir, edgeType, edges); + _GetOutgoingNodeEdges(g, n, edgeType, edges); } else { // relation type missing, scan through each edge type int relationCount = Graph_RelationTypeCount(g); for(int i = 0; i < relationCount; i++) { - _GetOutgoingNodeEdges(g, n, dir, i, edges); + _GetOutgoingNodeEdges(g, n, i, edges); } } } @@ -935,8 +932,8 @@ uint64_t Graph_GetNodeDegree NodeID destID = INVALID_ENTITY_ID; EdgeID edgeID = INVALID_ENTITY_ID; uint64_t edge_count = 0; - Delta_Matrix M = NULL; - Delta_Matrix TM = NULL; + Delta_Matrix out = NULL; + Delta_Matrix in = NULL; Delta_MatrixTupleIter it = {0}; if(edgeType == GRAPH_UNKNOWN_RELATION) { @@ -965,7 +962,7 @@ uint64_t Graph_GetNodeDegree // for each relationship type to consider for(edgeType = start_rel; edgeType < end_rel; edgeType++) { - M = Graph_GetSourceRelationMatrix(g, edgeType); + out = Graph_OutgoingRelationMatrix(g, edgeType); //---------------------------------------------------------------------- // outgoing edges @@ -974,7 +971,7 @@ uint64_t Graph_GetNodeDegree if(outgoing) { // construct an iterator to traverse over the source node row, // containing all outgoing edges - Delta_MatrixTupleIter_AttachRange(&it, M, srcID, srcID); + Delta_MatrixTupleIter_AttachRange(&it, out, srcID, srcID); // scan row while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, NULL) == GrB_SUCCESS) { @@ -989,11 +986,11 @@ uint64_t Graph_GetNodeDegree if(incoming) { // transposed relation matrix - TM = Graph_GetTargetRelationMatrix(g, edgeType); + in = Graph_IncomingRelationMatrix(g, edgeType); // construct an iterator to traverse over the source node row, // containing all incoming edges - Delta_MatrixTupleIter_AttachRange(&it, TM, srcID, srcID); + Delta_MatrixTupleIter_AttachRange(&it, in, srcID, srcID); while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, NULL) == GrB_SUCCESS) { edge_count++; @@ -1054,13 +1051,11 @@ void Graph_DeleteEdges ASSERT(n > 0); ASSERT(edges != NULL); - uint64_t x; + uint64_t x; + GrB_Info info; Delta_Matrix R; - Delta_Matrix S; - Delta_Matrix T; - Delta_Matrix TT; - Delta_Matrix M; - GrB_Info info; + Delta_Matrix out; + Delta_Matrix in; MATRIX_POLICY policy = Graph_SetMatrixPolicy(g, SYNC_POLICY_NOP); @@ -1073,12 +1068,12 @@ void Graph_DeleteEdges ASSERT(!DataBlock_ItemIsDeleted((void *)e->attributes)); R = Graph_GetRelationMatrix(g, r, false); - S = Graph_GetSourceRelationMatrix(g, r); - T = Graph_GetTargetRelationMatrix(g, r); + out = Graph_OutgoingRelationMatrix(g, r); + in = Graph_IncomingRelationMatrix(g, r); - info = Delta_Matrix_removeElement(S, src_id, ENTITY_GET_ID(e)); + info = Delta_Matrix_removeElement(out, src_id, ENTITY_GET_ID(e)); ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_removeElement(T, dest_id, ENTITY_GET_ID(e)); + info = Delta_Matrix_removeElement(in, dest_id, ENTITY_GET_ID(e)); ASSERT(info == GrB_SUCCESS); GrB_Vector src_vec; @@ -1087,9 +1082,9 @@ void Graph_DeleteEdges ASSERT(info == GrB_SUCCESS); info = GrB_Vector_new(&dst_vec, GrB_BOOL, g->edges->itemCap); ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_extract_row(S, src_vec, src_id); + info = Delta_Matrix_extract_row(out, src_vec, src_id); ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_extract_row(T, dst_vec, dest_id); + info = Delta_Matrix_extract_row(in, dst_vec, dest_id); ASSERT(info == GrB_SUCCESS); info = GrB_Vector_eWiseMult_Semiring(src_vec, NULL, NULL, GxB_ANY_PAIR_BOOL, src_vec, dst_vec, GrB_DESC_R); GrB_Vector_nvals(&x, src_vec); @@ -1109,8 +1104,8 @@ void Graph_DeleteEdges int relationCount = Graph_RelationTypeCount(g); for(int j = 0; j < relationCount; j++) { if(j == r) continue; - M = Graph_GetRelationMatrix(g, j, false); - info = Delta_Matrix_extractElement_BOOL(NULL, M, src_id, dest_id); + Delta_Matrix r = Graph_GetRelationMatrix(g, j, false); + info = Delta_Matrix_extractElement_BOOL(NULL, r, src_id, dest_id); if(info == GrB_SUCCESS) { connected = true; break; @@ -1120,8 +1115,8 @@ void Graph_DeleteEdges // there are no additional edges connecting source to destination // remove edge from THE adjacency matrix if(!connected) { - M = Graph_GetAdjacencyMatrix(g, false); - info = Delta_Matrix_removeElement(M, src_id, dest_id); + Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); + info = Delta_Matrix_removeElement(adj, src_id, dest_id); ASSERT(info == GrB_SUCCESS); } } @@ -1153,8 +1148,8 @@ static void _Graph_FreeRelationMatrices for(uint i = 0; i < relationCount; i++) { RelationMatrices *r = g->relations + i; Delta_Matrix_free(&r->R); - Delta_Matrix_free(&r->S); - Delta_Matrix_free(&r->T); + Delta_Matrix_free(&r->Out); + Delta_Matrix_free(&r->In); } } @@ -1215,8 +1210,8 @@ RelationID Graph_AddRelationType size_t edge_cap = g->edges->itemCap; Delta_Matrix_new(&r.R, GrB_BOOL, n, n, true); - Delta_Matrix_new(&r.S, GrB_UINT64, n, edge_cap, false); - Delta_Matrix_new(&r.T, GrB_UINT64, n, edge_cap, false); + Delta_Matrix_new(&r.Out, GrB_UINT64, n, edge_cap, false); + Delta_Matrix_new(&r.In, GrB_UINT64, n, edge_cap, false); array_append(g->relations, r); @@ -1238,8 +1233,8 @@ void Graph_RemoveRelation ASSERT(nvals == 0); #endif Delta_Matrix_free(&g->relations[relation_id].R); - Delta_Matrix_free(&g->relations[relation_id].S); - Delta_Matrix_free(&g->relations[relation_id].T); + Delta_Matrix_free(&g->relations[relation_id].Out); + Delta_Matrix_free(&g->relations[relation_id].In); g->relations = array_del(g->relations, relation_id); } @@ -1287,34 +1282,34 @@ Delta_Matrix Graph_GetRelationMatrix return m; } -Delta_Matrix Graph_GetSourceRelationMatrix +Delta_Matrix Graph_OutgoingRelationMatrix ( const Graph *g, RelationID relation_idx ) { ASSERT(relation_idx != GRAPH_NO_RELATION); - Delta_Matrix m = g->relations[relation_idx].S; + Delta_Matrix m = g->relations[relation_idx].Out; - size_t n = Graph_RequiredMatrixDim(g); + size_t node_cap = g->nodes->itemCap; size_t edge_cap = g->edges->itemCap; - g->SynchronizeMatrix(g, m, n, edge_cap); + g->SynchronizeMatrix(g, m, node_cap, edge_cap); return m; } -Delta_Matrix Graph_GetTargetRelationMatrix +Delta_Matrix Graph_IncomingRelationMatrix ( const Graph *g, RelationID relation_idx ) { ASSERT(relation_idx != GRAPH_NO_RELATION); - Delta_Matrix m = g->relations[relation_idx].T; + Delta_Matrix m = g->relations[relation_idx].In; - size_t n = Graph_RequiredMatrixDim(g); + size_t node_cap = g->nodes->itemCap; size_t edge_cap = g->edges->itemCap; - g->SynchronizeMatrix(g, m, n, edge_cap); + g->SynchronizeMatrix(g, m, node_cap, edge_cap); return m; } diff --git a/src/graph/graph.h b/src/graph/graph.h index ce9573589..02ac002bb 100644 --- a/src/graph/graph.h +++ b/src/graph/graph.h @@ -8,9 +8,7 @@ #include -#include "RG.h" #include "rax.h" -#include "../util/arr.h" #include "entities/node.h" #include "entities/edge.h" #include "../redismodule.h" @@ -44,10 +42,14 @@ typedef struct Graph Graph; // typedef for synchronization function pointer typedef void (*SyncMatrixFunc)(const Graph *, Delta_Matrix, GrB_Index, GrB_Index); +// A relation type is defined via three matrices: +// 1. boolean connecting source nodes to destination nodes +// 2. Outgoing, O[s,e] = d indicating an outgoing edge e from s to d +// 3. Incoming, I[d,e] = s indicating an incoming edge e from s to d typedef struct { - Delta_Matrix R; // relation matrix - Delta_Matrix S; // sources matrix - Delta_Matrix T; // targets matrix + Delta_Matrix R; // relation matrix + Delta_Matrix Out; // Outgoing matrix + Delta_Matrix In; // Incoming matrix } RelationMatrices; struct Graph { @@ -414,17 +416,19 @@ Delta_Matrix Graph_GetRelationMatrix bool transposed ); -// retrieves a relation edge source matrix -// matrix is resized if its dimensions doesn't match graph's node count & graph's edge count -Delta_Matrix Graph_GetSourceRelationMatrix +// retrieves a relation specific outgoing edges matrix O[s,e] = d +// where s is a source node, e is an edge ID d is a destination node (s)-[e]->(d) +// this function will sync the matrix according to the set synchronisation policy +Delta_Matrix Graph_OutgoingRelationMatrix ( const Graph *g, // graph from which to get adjacency matrix RelationID relation_idx // relation described by matrix ); -// retrieves a relation edge target matrix -// matrix is resized if its dimensions doesn't match graph's edge count & graph's node count -Delta_Matrix Graph_GetTargetRelationMatrix +// retrieves a relation specific incoming edges matrix O[d,e] = s +// where s is a source node, e is an edge ID d is a destination node (s)-[e]->(d) +// this function will sync the matrix according to the set synchronisation policy +Delta_Matrix Graph_IncomingRelationMatrix ( const Graph *g, // graph from which to get adjacency matrix RelationID relation_idx // relation described by matrix diff --git a/src/graph/graph_delete_nodes.c b/src/graph/graph_delete_nodes.c index c2a506542..310668b52 100644 --- a/src/graph/graph_delete_nodes.c +++ b/src/graph/graph_delete_nodes.c @@ -6,6 +6,7 @@ #include "RG.h" #include "graph.h" +#include "../util/arr.h" #include "delta_matrix/delta_matrix_iter.h" // deletes nodes from the graph diff --git a/src/index/index_construct.c b/src/index/index_construct.c index 47c25e178..8d667dcd6 100644 --- a/src/index/index_construct.c +++ b/src/index/index_construct.c @@ -146,14 +146,14 @@ static void _Index_PopulateEdgeIndex // fetch relation matrix int label_id = Index_GetLabelID(idx); - Delta_Matrix S = Graph_GetSourceRelationMatrix(g, label_id); - ASSERT(S != NULL); + Delta_Matrix out = Graph_OutgoingRelationMatrix(g, label_id); + ASSERT(out != NULL); //---------------------------------------------------------------------- // resume scanning from previous row/col indices //---------------------------------------------------------------------- - info = Delta_MatrixTupleIter_AttachRange(&it, S, src_id, UINT64_MAX); + info = Delta_MatrixTupleIter_AttachRange(&it, out, src_id, UINT64_MAX); ASSERT(info == GrB_SUCCESS); // skip previously indexed edges diff --git a/src/index/indexer.c b/src/index/indexer.c index 55b7f44b2..d37beb398 100644 --- a/src/index/indexer.c +++ b/src/index/indexer.c @@ -6,6 +6,7 @@ #include "indexer.h" #include "../redismodule.h" +#include "../util/rmalloc.h" #include "../util/circular_buffer.h" #include #include diff --git a/src/serializers/encoder/v14/encode_graph_entities.c b/src/serializers/encoder/v14/encode_graph_entities.c index cb0aa0493..550a8f1b0 100644 --- a/src/serializers/encoder/v14/encode_graph_entities.c +++ b/src/serializers/encoder/v14/encode_graph_entities.c @@ -303,15 +303,15 @@ void RdbSaveEdges_v14 // get current relation matrix uint r = GraphEncodeContext_GetCurrentRelationID(gc->encoding_context); - Delta_Matrix S = Graph_GetSourceRelationMatrix(gc->g, r); - ASSERT(S != NULL); + Delta_Matrix out = Graph_OutgoingRelationMatrix(gc->g, r); + ASSERT(out != NULL); // get matrix tuple iterator from context // already set to the next entry to fetch // for previous edge encide or create new one Delta_MatrixTupleIter *iter = GraphEncodeContext_GetMatrixTupleIterator(gc->encoding_context); - if(!Delta_MatrixTupleIter_is_attached(iter, S)) { - info = Delta_MatrixTupleIter_attach(iter, S); + if(!Delta_MatrixTupleIter_is_attached(iter, out)) { + info = Delta_MatrixTupleIter_attach(iter, out); ASSERT(info == GrB_SUCCESS); } @@ -338,9 +338,9 @@ void RdbSaveEdges_v14 if(r == relation_count) goto finish; // get matrix and set iterator - S = Graph_GetSourceRelationMatrix(gc->g, r); - ASSERT(S != NULL); - info = Delta_MatrixTupleIter_attach(iter, S); + out = Graph_OutgoingRelationMatrix(gc->g, r); + ASSERT(out != NULL); + info = Delta_MatrixTupleIter_attach(iter, out); ASSERT(info == GrB_SUCCESS); info = Delta_MatrixTupleIter_next_UINT64(iter, &src_id, &edge_id, &dest_id); } diff --git a/src/serializers/graph_extensions.c b/src/serializers/graph_extensions.c index 34935a141..63d9207ba 100644 --- a/src/serializers/graph_extensions.c +++ b/src/serializers/graph_extensions.c @@ -4,8 +4,9 @@ * the Server Side Public License v1 (SSPLv1). */ -#include "graph_extensions.h" #include "../RG.h" +#include "../util/arr.h" +#include "graph_extensions.h" #include "../util/datablock/oo_datablock.h" // functions declerations - implemented in graph.c @@ -138,13 +139,13 @@ static void _OptimizedFormConnection ) { GrB_Info info; Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); - Delta_Matrix S = Graph_GetSourceRelationMatrix(g, r); - Delta_Matrix T = Graph_GetTargetRelationMatrix(g, r); + Delta_Matrix out = Graph_OutgoingRelationMatrix(g, r); + Delta_Matrix in = Graph_IncomingRelationMatrix(g, r); Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); GrB_Matrix m = Delta_Matrix_M(M); GrB_Matrix tm = Delta_Matrix_M(Delta_Matrix_getTranspose(M)); - GrB_Matrix s = Delta_Matrix_M(S); - GrB_Matrix t = Delta_Matrix_M(T); + GrB_Matrix out_m = Delta_Matrix_M(out); + GrB_Matrix in_m = Delta_Matrix_M(in); GrB_Matrix adj_m = Delta_Matrix_M(adj); GrB_Matrix adj_tm = Delta_Matrix_M(Delta_Matrix_getTranspose(adj)); @@ -177,9 +178,9 @@ static void _OptimizedFormConnection ASSERT(info == GrB_SUCCESS); info = GrB_Matrix_setElement_BOOL(tm, true, dest, src); ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_setElement_UINT64(s, dest, src, edge_id); + info = GrB_Matrix_setElement_UINT64(out_m, dest, src, edge_id); ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_setElement_UINT64(t, src, dest, edge_id); + info = GrB_Matrix_setElement_UINT64(in_m, src, dest, edge_id); ASSERT(info == GrB_SUCCESS); } From ebfe445c79fdf52b2b025f64eb98d32d122bc822 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Thu, 16 May 2024 17:13:11 +0300 Subject: [PATCH 19/57] address review --- src/graph/graph.c | 12 +++++------- src/serializers/graph_extensions.c | 3 --- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index 8488942c1..a8ef8809e 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -727,7 +727,7 @@ void Graph_RemoveNodeLabels } } -bool Graph_FormConnection +void Graph_FormConnection ( Graph *g, NodeID src, @@ -746,18 +746,16 @@ bool Graph_FormConnection // rows represent source nodes, columns represent destination nodes info = Delta_Matrix_setElement_BOOL(adj, src, dest); - // incase of decoding it is possible to write outside of matrix bounds - // exit early - if(info != GrB_SUCCESS) return false; + ASSERT(info == GrB_SUCCESS); info = Delta_Matrix_setElement_BOOL(M, src, dest); - if(info != GrB_SUCCESS) return false; + ASSERT(info == GrB_SUCCESS); info = Delta_Matrix_setElement_UINT64(out, dest, src, edge_id); - if(info != GrB_SUCCESS) return false; + ASSERT(info == GrB_SUCCESS); info = Delta_Matrix_setElement_UINT64(in, src, dest, edge_id); - return info == GrB_SUCCESS; + ASSERT(info == GrB_SUCCESS); } void Graph_CreateEdge diff --git a/src/serializers/graph_extensions.c b/src/serializers/graph_extensions.c index 63d9207ba..896439431 100644 --- a/src/serializers/graph_extensions.c +++ b/src/serializers/graph_extensions.c @@ -9,9 +9,6 @@ #include "graph_extensions.h" #include "../util/datablock/oo_datablock.h" -// functions declerations - implemented in graph.c -bool Graph_FormConnection(Graph *g, NodeID src, NodeID dest, EdgeID edge_id, int r); - void Graph_EnsureNodeCap ( Graph *g, From 09d1b7ac933c0d324f884d69381666c04342d27d Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Thu, 16 May 2024 17:43:24 +0300 Subject: [PATCH 20/57] fix --- src/graph/graph.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index a8ef8809e..8eb2cb45b 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -102,8 +102,8 @@ void _Graph_GetEdgesConnectingNodes ASSERT(g); ASSERT(r != GRAPH_NO_RELATION); ASSERT(r < Graph_RelationTypeCount(g)); - ASSERT(src < Graph_NodeCount(g)); - ASSERT(dest < Graph_NodeCount(g)); + ASSERT(src < _Graph_NodeCap(g)); + ASSERT(dest < _Graph_NodeCap(g)); // relation map, maps (src, dest, r) to edge IDs. Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); From 903c00ade3f7f77ad93c7ccc6338b297c4b41da2 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Sun, 19 May 2024 10:13:18 +0300 Subject: [PATCH 21/57] address review --- src/graph/graph.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index 8eb2cb45b..0c79bfe32 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -132,16 +132,16 @@ void _Graph_GetEdgesConnectingNodes info = GxB_Vector_Iterator_attach(&it, src_vec, NULL); ASSERT(info == GrB_SUCCESS); info = GxB_Vector_Iterator_seek((&it), 0); - while (info != GxB_EXHAUSTED) { - GrB_Index edgeId = GxB_Vector_Iterator_getIndex((&it)); + while (info != GxB_EXHAUSTED) { + GrB_Index edgeId = GxB_Vector_Iterator_getIndex((&it)); e.id = edgeId; e.relationID = r; e.attributes = DataBlock_GetItem(g->edges, edgeId); ASSERT(e.attributes); array_append(*edges, e); - info = GxB_Vector_Iterator_next((&it)); - } + info = GxB_Vector_Iterator_next((&it)); + } GrB_Vector_free(&src_vec); GrB_Vector_free(&dst_vec); } @@ -542,9 +542,6 @@ RelationID Graph_GetEdgeRelation GrB_Index dst; for(uint i = 0; i < n; i++) { EdgeID edgeId = 0; - Delta_Matrix M = Graph_GetRelationMatrix(g, i, false); - info = Delta_Matrix_extractElement_BOOL(NULL, M, src_id, dest_id); - if(info != GrB_SUCCESS) continue; Delta_Matrix out = Graph_OutgoingRelationMatrix(g, i); info = Delta_Matrix_extractElement_UINT64(&dst, out, src_id, id); if(info != GrB_SUCCESS || dst != dest_id) continue; From a5580201084aaafc8a4cc73ca10509d22b97d535 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Sun, 19 May 2024 15:14:30 +0300 Subject: [PATCH 22/57] address review --- src/graph/graph.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index 0c79bfe32..dfa0747c5 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -374,6 +374,18 @@ bool Graph_Pending if(pending) { return true; } + M = g->relations[i].Out; + info = Delta_Matrix_pending(M, &pending); + ASSERT(info == GrB_SUCCESS); + if(pending) { + return true; + } + M = g->relations[i].In; + info = Delta_Matrix_pending(M, &pending); + ASSERT(info == GrB_SUCCESS); + if(pending) { + return true; + } } return false; @@ -544,7 +556,8 @@ RelationID Graph_GetEdgeRelation EdgeID edgeId = 0; Delta_Matrix out = Graph_OutgoingRelationMatrix(g, i); info = Delta_Matrix_extractElement_UINT64(&dst, out, src_id, id); - if(info != GrB_SUCCESS || dst != dest_id) continue; + if(info != GrB_SUCCESS) continue; + ASSERT(dst == dest_id); Edge_SetRelationID(e, i); rel = i; break; @@ -841,20 +854,20 @@ void _GetIncomingNodeEdges GrB_Info info; Delta_MatrixTupleIter it = {0}; Delta_Matrix in = NULL; - NodeID src_id = ENTITY_GET_ID(n); - NodeID dest_id = INVALID_ENTITY_ID; + NodeID src_id = INVALID_ENTITY_ID; + NodeID dest_id = ENTITY_GET_ID(n); EdgeID edge_id = INVALID_ENTITY_ID; UNUSED(info); in = Graph_IncomingRelationMatrix(g, edgeType); - info = Delta_MatrixTupleIter_AttachRange(&it, in, src_id, src_id); + info = Delta_MatrixTupleIter_AttachRange(&it, in, dest_id, dest_id); ASSERT(info == GrB_SUCCESS); - while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &edge_id, &dest_id) == GrB_SUCCESS) { + while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &edge_id, &src_id) == GrB_SUCCESS) { if(dir == GRAPH_EDGE_DIR_BOTH && src_id == dest_id) continue; Edge e = {0}; - e.src_id = dest_id; - e.dest_id = src_id; + e.src_id = src_id; + e.dest_id = dest_id; e.id = edge_id; e.relationID = edgeType; e.attributes = DataBlock_GetItem(g->edges, edge_id); @@ -1059,6 +1072,7 @@ void Graph_DeleteEdges int r = Edge_GetRelationID(e); NodeID src_id = Edge_GetSrcNodeID(e); NodeID dest_id = Edge_GetDestNodeID(e); + EdgeID edge_id = ENTITY_GET_ID(e); ASSERT(!DataBlock_ItemIsDeleted((void *)e->attributes)); @@ -1066,9 +1080,9 @@ void Graph_DeleteEdges out = Graph_OutgoingRelationMatrix(g, r); in = Graph_IncomingRelationMatrix(g, r); - info = Delta_Matrix_removeElement(out, src_id, ENTITY_GET_ID(e)); + info = Delta_Matrix_removeElement(out, src_id, edge_id); ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_removeElement(in, dest_id, ENTITY_GET_ID(e)); + info = Delta_Matrix_removeElement(in, dest_id, edge_id); ASSERT(info == GrB_SUCCESS); GrB_Vector src_vec; @@ -1117,7 +1131,7 @@ void Graph_DeleteEdges } // free and remove edges from datablock. - DataBlock_DeleteItem(g->edges, ENTITY_GET_ID(e)); + DataBlock_DeleteItem(g->edges, edge_id); } Graph_SetMatrixPolicy(g, policy); From 7ebafebaa83e2a000369a7d693dc46ab2da00b09 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 20 May 2024 09:50:16 +0300 Subject: [PATCH 23/57] address review --- src/graph/graph.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index dfa0747c5..f69b9f36f 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -1059,7 +1059,6 @@ void Graph_DeleteEdges ASSERT(n > 0); ASSERT(edges != NULL); - uint64_t x; GrB_Info info; Delta_Matrix R; Delta_Matrix out; @@ -1085,31 +1084,25 @@ void Graph_DeleteEdges info = Delta_Matrix_removeElement(in, dest_id, edge_id); ASSERT(info == GrB_SUCCESS); - GrB_Vector src_vec; - GrB_Vector dst_vec; - info = GrB_Vector_new(&src_vec, GrB_BOOL, g->edges->itemCap); - ASSERT(info == GrB_SUCCESS); - info = GrB_Vector_new(&dst_vec, GrB_BOOL, g->edges->itemCap); - ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_extract_row(out, src_vec, src_id); - ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_extract_row(in, dst_vec, dest_id); - ASSERT(info == GrB_SUCCESS); - info = GrB_Vector_eWiseMult_Semiring(src_vec, NULL, NULL, GxB_ANY_PAIR_BOOL, src_vec, dst_vec, GrB_DESC_R); - GrB_Vector_nvals(&x, src_vec); - info = GrB_free(&src_vec); - ASSERT(info == GrB_SUCCESS); - info = GrB_free(&dst_vec); - ASSERT(info == GrB_SUCCESS); + Delta_MatrixTupleIter it = {0}; + Delta_MatrixTupleIter_AttachRange(&it, out, src_id, src_id); + GrB_Index dst; + bool connected = false; + while (Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, &dst) == GrB_SUCCESS) { + if(dst == dest_id) { + connected = true; + break; + } + } - if(x == 0) { + if(!connected) { // no more edges connecting src to other nodes // remove src from relation matrix info = Delta_Matrix_removeElement(R, src_id, dest_id); ASSERT(info == GrB_SUCCESS); // see if source is connected to destination with additional edges - bool connected = false; + connected = false; int relationCount = Graph_RelationTypeCount(g); for(int j = 0; j < relationCount; j++) { if(j == r) continue; From b5d14f705d84043d3c062908595b3ecc82d6d2b9 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 20 May 2024 10:00:43 +0300 Subject: [PATCH 24/57] address review --- src/graph/graph.c | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index f69b9f36f..4e0048d57 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -113,37 +113,22 @@ void _Graph_GetEdgesConnectingNodes if(res == GrB_NO_VALUE) return; GrB_Info info; - GrB_Vector src_vec; - GrB_Vector dst_vec; - info = GrB_Vector_new(&src_vec, GrB_BOOL, g->edges->itemCap); - ASSERT(info == GrB_SUCCESS); - info = GrB_Vector_new(&dst_vec, GrB_BOOL, g->edges->itemCap); - ASSERT(info == GrB_SUCCESS); - Edge e = {.src_id = src, .dest_id = dest, .relationID = r}; + Edge e = {.src_id = src, .dest_id = dest, .relationID = r}; Delta_Matrix out = Graph_OutgoingRelationMatrix(g, r); - Delta_Matrix in = Graph_IncomingRelationMatrix(g, r); - info = Delta_Matrix_extract_row(out, src_vec, src); - ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_extract_row(in, dst_vec, dest); - ASSERT(info == GrB_SUCCESS); - info = GrB_Vector_eWiseMult_Semiring(src_vec, NULL, NULL, GxB_ANY_PAIR_BOOL, src_vec, dst_vec, GrB_DESC_R); - ASSERT(info == GrB_SUCCESS); - struct GB_Iterator_opaque it; - info = GxB_Vector_Iterator_attach(&it, src_vec, NULL); - ASSERT(info == GrB_SUCCESS); - info = GxB_Vector_Iterator_seek((&it), 0); - while (info != GxB_EXHAUSTED) { - GrB_Index edgeId = GxB_Vector_Iterator_getIndex((&it)); + + Delta_MatrixTupleIter it = {0}; + Delta_MatrixTupleIter_AttachRange(&it, out, src, src); + + GrB_Index dst; + GrB_Index edgeId; + while (Delta_MatrixTupleIter_next_UINT64(&it, NULL, &edgeId, &dst) == GrB_SUCCESS) { + if(dst != dest) continue; e.id = edgeId; e.relationID = r; e.attributes = DataBlock_GetItem(g->edges, edgeId); ASSERT(e.attributes); array_append(*edges, e); - - info = GxB_Vector_Iterator_next((&it)); } - GrB_Vector_free(&src_vec); - GrB_Vector_free(&dst_vec); } static inline AttributeSet *_Graph_GetEntity(const DataBlock *entities, EntityID id) { From a58a62416aeb8df49970c6717e3181ea5ed85a61 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 20 May 2024 10:11:31 +0300 Subject: [PATCH 25/57] address review --- src/graph/graph.c | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index 4e0048d57..1d2ebbd23 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -927,7 +927,6 @@ uint64_t Graph_GetNodeDegree uint64_t edge_count = 0; Delta_Matrix out = NULL; Delta_Matrix in = NULL; - Delta_MatrixTupleIter it = {0}; if(edgeType == GRAPH_UNKNOWN_RELATION) { return 0; // no edges @@ -953,24 +952,21 @@ uint64_t Graph_GetNodeDegree end_rel = Graph_RelationTypeCount(g); } + GrB_Index nvals; + GrB_Vector v; + GrB_Vector_new(&v, GrB_BOOL, g->edges->itemCap); + // for each relationship type to consider for(edgeType = start_rel; edgeType < end_rel; edgeType++) { - out = Graph_OutgoingRelationMatrix(g, edgeType); - //---------------------------------------------------------------------- // outgoing edges //---------------------------------------------------------------------- if(outgoing) { - // construct an iterator to traverse over the source node row, - // containing all outgoing edges - Delta_MatrixTupleIter_AttachRange(&it, out, srcID, srcID); - // scan row - while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, NULL) - == GrB_SUCCESS) { - edge_count++; - } - Delta_MatrixTupleIter_detach(&it); + out = Graph_OutgoingRelationMatrix(g, edgeType); + Delta_Matrix_extract_row(out, v, srcID); + GrB_Vector_nvals(&nvals, v); + edge_count += nvals; } //---------------------------------------------------------------------- @@ -978,20 +974,15 @@ uint64_t Graph_GetNodeDegree //---------------------------------------------------------------------- if(incoming) { - // transposed relation matrix in = Graph_IncomingRelationMatrix(g, edgeType); - - // construct an iterator to traverse over the source node row, - // containing all incoming edges - Delta_MatrixTupleIter_AttachRange(&it, in, srcID, srcID); - while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, NULL) - == GrB_SUCCESS) { - edge_count++; - } - Delta_MatrixTupleIter_detach(&it); + Delta_Matrix_extract_row(in, v, srcID); + GrB_Vector_nvals(&nvals, v); + edge_count += nvals; } } + GrB_free(&v); + return edge_count; } From 41ec2d2ceb8fe8eb0388841c295c58286de21060 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 20 May 2024 14:14:17 +0300 Subject: [PATCH 26/57] address review --- src/configuration/config.c | 8 ++++---- src/graph/graph.c | 8 ++++---- src/graph/graph.h | 6 ------ 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/configuration/config.c b/src/configuration/config.c index ec5bb8cd9..afdd71360 100644 --- a/src/configuration/config.c +++ b/src/configuration/config.c @@ -49,7 +49,7 @@ // Max mem(bytes) that query/thread can utilize at any given time #define QUERY_MEM_CAPACITY "QUERY_MEM_CAPACITY" -// number of pending changed befor Delta_Matrix flushed +// number of pending changed before Delta_Matrix flushed #define DELTA_MAX_PENDING_CHANGES "DELTA_MAX_PENDING_CHANGES" // size of node creation buffer @@ -93,7 +93,7 @@ typedef struct { uint64_t max_queued_queries; // max number of queued queries int64_t query_mem_capacity; // Max mem(bytes) that query/thread can utilize at any given time uint64_t node_creation_buffer; // Number of extra node creations to buffer as margin in matrices - int64_t delta_max_pending_changes; // number of pending changed befor Delta_Matrix flushed + int64_t delta_max_pending_changes; // number of pending changed before Delta_Matrix flushed Config_on_change cb; // callback function which being called when config param changed bool cmd_info_on; // If true, the GRAPH.INFO is enabled. uint64_t effects_threshold; // replicate via effects when runtime exceeds threshold @@ -636,7 +636,7 @@ static void _Config_SetToDefaults(void) { // no limit on query memory capacity config.query_mem_capacity = QUERY_MEM_CAPACITY_UNLIMITED; - // number of pending changed befor Delta_Matrix flushed + // number of pending changed before Delta_Matrix flushed config.delta_max_pending_changes = DELTA_MAX_PENDING_CHANGES_DEFAULT; // the amount of empty space to reserve for node creations in matrices @@ -891,7 +891,7 @@ bool Config_Option_get break; //---------------------------------------------------------------------- - // number of pending changed befor Delta_Matrix flushed + // number of pending changed before Delta_Matrix flushed //---------------------------------------------------------------------- case Config_DELTA_MAX_PENDING_CHANGES: { diff --git a/src/graph/graph.c b/src/graph/graph.c index 1d2ebbd23..1d5d65172 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -734,10 +734,10 @@ void Graph_FormConnection GrB_Info info; UNUSED(info); - Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); + Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); Delta_Matrix out = Graph_OutgoingRelationMatrix(g, r); Delta_Matrix in = Graph_IncomingRelationMatrix(g, r); - Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); + Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); // rows represent source nodes, columns represent destination nodes info = Delta_Matrix_setElement_BOOL(adj, src, dest); @@ -1051,9 +1051,9 @@ void Graph_DeleteEdges ASSERT(!DataBlock_ItemIsDeleted((void *)e->attributes)); - R = Graph_GetRelationMatrix(g, r, false); + R = Graph_GetRelationMatrix(g, r, false); out = Graph_OutgoingRelationMatrix(g, r); - in = Graph_IncomingRelationMatrix(g, r); + in = Graph_IncomingRelationMatrix(g, r); info = Delta_Matrix_removeElement(out, src_id, edge_id); ASSERT(info == GrB_SUCCESS); diff --git a/src/graph/graph.h b/src/graph/graph.h index 02ac002bb..e70adffb7 100644 --- a/src/graph/graph.h +++ b/src/graph/graph.h @@ -449,12 +449,6 @@ Delta_Matrix Graph_GetZeroMatrix const Graph *g ); -Delta_Matrix Graph_GetLabelMatrix -( - const Graph *g, - int label_idx -); - // free partial graph void Graph_PartialFree ( From 2aa805fb7dacdd79344c045e1afb01e30e9ab4ca Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Tue, 21 May 2024 14:17:49 +0300 Subject: [PATCH 27/57] iterators mutch more efficient --- src/graph/graph.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index 1d5d65172..fa17ae24c 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -927,6 +927,7 @@ uint64_t Graph_GetNodeDegree uint64_t edge_count = 0; Delta_Matrix out = NULL; Delta_Matrix in = NULL; + Delta_MatrixTupleIter it = {0}; if(edgeType == GRAPH_UNKNOWN_RELATION) { return 0; // no edges @@ -952,10 +953,6 @@ uint64_t Graph_GetNodeDegree end_rel = Graph_RelationTypeCount(g); } - GrB_Index nvals; - GrB_Vector v; - GrB_Vector_new(&v, GrB_BOOL, g->edges->itemCap); - // for each relationship type to consider for(edgeType = start_rel; edgeType < end_rel; edgeType++) { //---------------------------------------------------------------------- @@ -964,9 +961,15 @@ uint64_t Graph_GetNodeDegree if(outgoing) { out = Graph_OutgoingRelationMatrix(g, edgeType); - Delta_Matrix_extract_row(out, v, srcID); - GrB_Vector_nvals(&nvals, v); - edge_count += nvals; + // construct an iterator to traverse over the source node row, + // containing all outgoing edges + Delta_MatrixTupleIter_AttachRange(&it, out, srcID, srcID); + // scan row + while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, NULL) + == GrB_SUCCESS) { + edge_count++; + } + Delta_MatrixTupleIter_detach(&it); } //---------------------------------------------------------------------- @@ -975,14 +978,18 @@ uint64_t Graph_GetNodeDegree if(incoming) { in = Graph_IncomingRelationMatrix(g, edgeType); - Delta_Matrix_extract_row(in, v, srcID); - GrB_Vector_nvals(&nvals, v); - edge_count += nvals; + // construct an iterator to traverse over the source node row, + // containing all incoming edges + Delta_MatrixTupleIter_AttachRange(&it, in, srcID, srcID); + // scan row + while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, NULL) + == GrB_SUCCESS) { + edge_count++; + } + Delta_MatrixTupleIter_detach(&it); } } - GrB_free(&v); - return edge_count; } From fec36c18221f7007ccba06cefaea7ac2078d7dd0 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Tue, 21 May 2024 16:27:19 +0300 Subject: [PATCH 28/57] run rust unit tests --- Makefile | 5 +++++ codecov.yml | 10 ++++++++-- deps/FalkorDB-rs | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 8010b59bf..44ffac6da 100644 --- a/Makefile +++ b/Makefile @@ -281,6 +281,10 @@ export RUSTFLAGS=-Zsanitizer=$(SAN) CARGO_FLAGS=--target x86_64-unknown-linux-gnu endif +ifneq ($(COV),) +export RUSTFLAGS=-C instrument-coverage +endif + falkordbrs: @echo Building $@ ... cd deps/FalkorDB-rs && cargo build $(CARGO_FLAGS) --features falkordb_allocator --target-dir $(FalkorDBRS_BINDIR) @@ -367,6 +371,7 @@ ifneq ($(BUILD),0) $(SHOW)$(MAKE) build FORCE=1 UNIT_TESTS=1 endif $(SHOW)BINROOT=$(BINROOT) ./tests/unit/tests.sh + RUSTFLAGS+='-L$(BINROOT)/GraphBLAS -lgraphblas -L$(LIBOMP_PREFIX)/lib -lomp' cargo test --lib flow-tests: $(TEST_DEPS) $(SHOW)MODULE=$(TARGET) BINROOT=$(BINROOT) PARALLEL=$(_RLTEST_PARALLEL) GEN=$(GEN) AOF=$(AOF) TCK=0 ./tests/flow/tests.sh diff --git a/codecov.yml b/codecov.yml index af9a01ad3..059981f2b 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,5 +1,11 @@ ignore: - - "deps" + - "deps/GraphBLAS" + - "deps/libcypher-parser" + - "deps/oniguruma" + - "deps/rax" + - "deps/RediSearch" + - "deps/utf8proc" + - "deps/utf8proc" - "src/util/sds" - "src/util/roaring.c" - - "tests" \ No newline at end of file + - "xxHash" \ No newline at end of file diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index e486249d0..b67615caa 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit e486249d058e26445f4d504f33a18f3bbc1d55da +Subproject commit b67615caa0e36a260e9a8a29815a3f852fb805f7 From 980eb5a157f72dc62e38cb64e2a7acb2900a2a82 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Tue, 21 May 2024 17:34:17 +0300 Subject: [PATCH 29/57] rewrite test --- Makefile | 10 +++- codecov.yml | 4 +- deps/FalkorDB-rs | 2 +- tests/unit/test_delta_matrix.c | 103 --------------------------------- 4 files changed, 11 insertions(+), 108 deletions(-) diff --git a/Makefile b/Makefile index 44ffac6da..dfdfdbb18 100644 --- a/Makefile +++ b/Makefile @@ -371,7 +371,7 @@ ifneq ($(BUILD),0) $(SHOW)$(MAKE) build FORCE=1 UNIT_TESTS=1 endif $(SHOW)BINROOT=$(BINROOT) ./tests/unit/tests.sh - RUSTFLAGS+='-L$(BINROOT)/GraphBLAS -lgraphblas -L$(LIBOMP_PREFIX)/lib -lomp' cargo test --lib + RUSTFLAGS+='-L$(BINROOT)/src -lfalkordb_static -L$(BINROOT)/GraphBLAS -lgraphblas -L$(LIBOMP_PREFIX)/lib -lomp' cargo test --lib flow-tests: $(TEST_DEPS) $(SHOW)MODULE=$(TARGET) BINROOT=$(BINROOT) PARALLEL=$(_RLTEST_PARALLEL) GEN=$(GEN) AOF=$(AOF) TCK=0 ./tests/flow/tests.sh @@ -413,7 +413,13 @@ benchmark: $(TARGET) #---------------------------------------------------------------------------------------------- COV_EXCLUDE_DIRS += \ - deps \ + deps/GraphBLAS \ + deps/libcypher-parser \ + deps/oniguruma \ + deps/rax \ + deps/RediSearch \ + deps/utf8proc \ + deps/xxHash \ src/util/sds \ tests diff --git a/codecov.yml b/codecov.yml index 059981f2b..b8b3d718e 100644 --- a/codecov.yml +++ b/codecov.yml @@ -5,7 +5,7 @@ ignore: - "deps/rax" - "deps/RediSearch" - "deps/utf8proc" - - "deps/utf8proc" + - "deps/xxHash" - "src/util/sds" - "src/util/roaring.c" - - "xxHash" \ No newline at end of file + - "tests" \ No newline at end of file diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index b67615caa..20ed7d66d 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit b67615caa0e36a260e9a8a29815a3f852fb805f7 +Subproject commit 20ed7d66d71b5ad9cc67a9e734c0fba29c0b1640 diff --git a/tests/unit/test_delta_matrix.c b/tests/unit/test_delta_matrix.c index e6051e22f..ce385f7d4 100644 --- a/tests/unit/test_delta_matrix.c +++ b/tests/unit/test_delta_matrix.c @@ -131,107 +131,6 @@ void ASSERT_GrB_Matrices_EQ(const GrB_Matrix A, const GrB_Matrix B) TEST_ASSERT(info == GrB_SUCCESS); } -// test DeltaMatrix initialization -void test_DeltaMatrix_new() { - Delta_Matrix A = NULL; - GrB_Matrix M = NULL; - GrB_Matrix DP = NULL; - GrB_Matrix DM = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nvals = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - - info = Delta_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // get internal matrices - M = Delta_Matrix_M(A); - DP = Delta_Matrix_DP(A); - DM = Delta_Matrix_DM(A); - - // bool matrix do not maintain transpose - TEST_ASSERT(Delta_Matrix_getTranspose(A) == NULL); - - // matrix should be empty - M_EMPTY(); - DP_EMPTY(); - DM_EMPTY(); - Delta_Matrix_nvals(&nvals, A); - TEST_ASSERT(nvals == 0); - - Delta_Matrix_free(&A); - TEST_ASSERT(A == NULL); -} - -void test_DeltaMatrix_set() { - GrB_Type t = GrB_BOOL; - Delta_Matrix A = NULL; - GrB_Matrix M = NULL; - GrB_Matrix DP = NULL; - GrB_Matrix DM = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nvals = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - GrB_Index i = 0; - GrB_Index j = 1; - - info = Delta_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // get internal matrices - M = Delta_Matrix_M(A); - DP = Delta_Matrix_DP(A); - DM = Delta_Matrix_DM(A); - - //-------------------------------------------------------------------------- - // Set element that marked for deletion - //-------------------------------------------------------------------------- - - // set element at position i,j - info = Delta_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // force sync - // entry should migrated from 'delta-plus' to 'M' - Delta_Matrix_wait(A, true); - - // set element at position i,j - info = Delta_Matrix_removeElement(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i,j - info = Delta_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // validations - //-------------------------------------------------------------------------- - - // A should be empty - Delta_Matrix_nvals(&nvals, A); - TEST_ASSERT(nvals == 1); - - // M should contain a single element - M_NOT_EMPTY(); - - // DM should contain a single element - DM_EMPTY(); - - // DP should be empty - DP_EMPTY(); - - - //-------------------------------------------------------------------------- - // clean up - //-------------------------------------------------------------------------- - - Delta_Matrix_free(&A); - TEST_ASSERT(A == NULL); -} - // flush simple addition void test_DeltaMatrix_flush() { GrB_Type t = GrB_BOOL; @@ -806,8 +705,6 @@ void test_DeltaMatrix_resize() { } TEST_LIST = { - {"DeltaMatrix_new", test_DeltaMatrix_new}, - {"DeltaMatrix_set", test_DeltaMatrix_set}, {"DeltaMatrix_flush", test_DeltaMatrix_flush}, {"DeltaMatrix_fuzzy", test_DeltaMatrix_fuzzy}, {"DeltaMatrix_export_no_changes", test_DeltaMatrix_export_no_changes}, From 3bcf342a9f194aedbe6c0a425b9f908b41c9cec3 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Wed, 22 May 2024 09:48:16 +0300 Subject: [PATCH 30/57] rewrite tests --- deps/FalkorDB-rs | 2 +- tests/unit/test_delta_matrix.c | 70 ---------------------------------- 2 files changed, 1 insertion(+), 71 deletions(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 20ed7d66d..b158e9f48 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 20ed7d66d71b5ad9cc67a9e734c0fba29c0b1640 +Subproject commit b158e9f484f6b09d83147d784518caa6e3fa30f3 diff --git a/tests/unit/test_delta_matrix.c b/tests/unit/test_delta_matrix.c index ce385f7d4..1b72d0d62 100644 --- a/tests/unit/test_delta_matrix.c +++ b/tests/unit/test_delta_matrix.c @@ -131,75 +131,6 @@ void ASSERT_GrB_Matrices_EQ(const GrB_Matrix A, const GrB_Matrix B) TEST_ASSERT(info == GrB_SUCCESS); } -// flush simple addition -void test_DeltaMatrix_flush() { - GrB_Type t = GrB_BOOL; - Delta_Matrix A = NULL; - GrB_Matrix M = NULL; - GrB_Matrix DP = NULL; - GrB_Matrix DM = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nvals = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - GrB_Index i = 0; - GrB_Index j = 1; - bool sync = false; - - info = Delta_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i,j - info = Delta_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // get internal matrices - M = Delta_Matrix_M(A); - DP = Delta_Matrix_DP(A); - DM = Delta_Matrix_DM(A); - - //-------------------------------------------------------------------------- - // flush matrix, no sync - //-------------------------------------------------------------------------- - - // wait, don't force sync - sync = false; - Delta_Matrix_wait(A, sync); - - // M should be empty - M_EMPTY(); - - // DM should be empty - DM_EMPTY(); - - // DP should contain a single element - DP_NOT_EMPTY(); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - Delta_Matrix_wait(A, sync); - - Delta_Matrix_nvals(&nvals, A); - TEST_ASSERT(nvals == 1); - - // M should be empty - M_NOT_EMPTY(); - - // DM should be empty - DM_EMPTY(); - - // DP should contain a single element - DP_EMPTY(); - - // clean up - Delta_Matrix_free(&A); - TEST_ASSERT(A == NULL); -} - //------------------------------------------------------------------------------ // fuzzy test compare Delta_Matrix to GrB_Matrix //------------------------------------------------------------------------------ @@ -705,7 +636,6 @@ void test_DeltaMatrix_resize() { } TEST_LIST = { - {"DeltaMatrix_flush", test_DeltaMatrix_flush}, {"DeltaMatrix_fuzzy", test_DeltaMatrix_fuzzy}, {"DeltaMatrix_export_no_changes", test_DeltaMatrix_export_no_changes}, {"DeltaMatrix_export_pending_changes", test_DeltaMatrix_export_pending_changes}, From b7b5dda66b50e5ea039bce04c5c494f409cf27c6 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Wed, 22 May 2024 14:57:13 +0300 Subject: [PATCH 31/57] address review --- deps/FalkorDB-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index b158e9f48..4a16874f0 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit b158e9f484f6b09d83147d784518caa6e3fa30f3 +Subproject commit 4a16874f0d23e3afce8c02756cb065893ba59a68 From 93088e6bdd5a1a5fdb12986abc7a58dcb7e655c6 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Sun, 26 May 2024 16:04:28 +0300 Subject: [PATCH 32/57] rewrite tests --- deps/FalkorDB-rs | 2 +- tests/unit/test_delta_matrix.c | 721 --------------------------------- 2 files changed, 1 insertion(+), 722 deletions(-) delete mode 100644 tests/unit/test_delta_matrix.c diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 4a16874f0..1c048081f 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 4a16874f0d23e3afce8c02756cb065893ba59a68 +Subproject commit 1c048081fc97c0b2a160da70091dd44c75c61194 diff --git a/tests/unit/test_delta_matrix.c b/tests/unit/test_delta_matrix.c deleted file mode 100644 index 1b72d0d62..000000000 --- a/tests/unit/test_delta_matrix.c +++ /dev/null @@ -1,721 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "src/util/rmalloc.h" -#include "src/configuration/config.h" -#include "src/graph/delta_matrix/delta_matrix.h" - -#include - -void setup(); -void tearDown(); - -#define TEST_INIT setup(); -#define TEST_FINI tearDown(); -#include "acutest.h" - -#define MATRIX_EMPTY(M) \ - ({ \ - GrB_Matrix_nvals(&nvals, M); \ - TEST_ASSERT(nvals == 0); \ - }) - -#define MATRIX_NOT_EMPTY(M) \ - ({ \ - GrB_Matrix_nvals(&nvals, M); \ - TEST_ASSERT(nvals != 0); \ - }) - -#define M_EMPTY() MATRIX_EMPTY(M) -#define DP_EMPTY() MATRIX_EMPTY(DP) -#define DM_EMPTY() MATRIX_EMPTY(DM) - -#define M_NOT_EMPTY() MATRIX_NOT_EMPTY(M) -#define DP_NOT_EMPTY() MATRIX_NOT_EMPTY(DP) -#define DM_NOT_EMPTY() MATRIX_NOT_EMPTY(DM) - -void setup() { - // use the malloc family for allocations - Alloc_Reset(); - - // initialize GraphBLAS - GrB_init(GrB_NONBLOCKING); - - // all matrices in CSR format - GxB_Global_Option_set(GxB_FORMAT, GxB_BY_ROW); - - // set delta matrix flush threshold - Config_Option_set(Config_DELTA_MAX_PENDING_CHANGES, "10000", NULL); -} - -void tearDown() { - GrB_finalize(); -} - -// nvals(A + B) == nvals(A) == nvals(B) -void ASSERT_GrB_Matrices_EQ(const GrB_Matrix A, const GrB_Matrix B) -{ - GrB_Type t_A = NULL; - GrB_Type t_B = NULL; - GrB_Matrix C = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nvals_A = 0; - GrB_Index nvals_B = 0; - GrB_Index nvals_C = 0; - GrB_Index nrows_A = 0; - GrB_Index ncols_A = 0; - GrB_Index nrows_B = 0; - GrB_Index ncols_B = 0; - - //-------------------------------------------------------------------------- - // type(A) == type(B) - //-------------------------------------------------------------------------- - - info = GxB_Matrix_type(&t_A, A); - TEST_ASSERT(info == GrB_SUCCESS); - - info = GxB_Matrix_type(&t_B, B); - TEST_ASSERT(info == GrB_SUCCESS); - - TEST_ASSERT(t_A == t_B); - - //-------------------------------------------------------------------------- - // dim(A) == dim(B) - //-------------------------------------------------------------------------- - - info = GrB_Matrix_nrows(&nrows_A, A); - TEST_ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_ncols(&ncols_A, A); - TEST_ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_nrows(&nrows_B, B); - TEST_ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_ncols(&ncols_B, B); - TEST_ASSERT(info == GrB_SUCCESS); - - TEST_ASSERT(nrows_A == nrows_B); - TEST_ASSERT(ncols_A == ncols_B); - - //-------------------------------------------------------------------------- - // NNZ(A) == NNZ(B) - //-------------------------------------------------------------------------- - - GrB_Matrix_nvals(&nvals_A, A); - TEST_ASSERT(info == GrB_SUCCESS); - - GrB_Matrix_nvals(&nvals_B, B); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // structure(A) == structure(B) - //-------------------------------------------------------------------------- - - info = GrB_Matrix_new(&C, t_A, nrows_A, ncols_A); - TEST_ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_eWiseMult_BinaryOp(C, NULL, NULL, GrB_LAND, A, B, NULL); - TEST_ASSERT(info == GrB_SUCCESS); - - GrB_Matrix_nvals(&nvals_C, C); - TEST_ASSERT(info == GrB_SUCCESS); - - TEST_ASSERT(nvals_C == nvals_A); - - // clean up - info = GrB_Matrix_free(&C); - TEST_ASSERT(info == GrB_SUCCESS); -} - -//------------------------------------------------------------------------------ -// fuzzy test compare Delta_Matrix to GrB_Matrix -//------------------------------------------------------------------------------ - -void test_DeltaMatrix_fuzzy() { - GrB_Type t = GrB_BOOL; - Delta_Matrix A = NULL; - Delta_Matrix T = NULL; // A transposed - GrB_Matrix M = NULL; // primary internal matrix - GrB_Matrix MT = NULL; - GrB_Matrix N = NULL; - GrB_Matrix NT = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - GrB_Index i = 0; - GrB_Index j = 1; - GrB_Index* II = NULL; - GrB_Index* J = NULL; - uint32_t operations = 10000; - - //-------------------------------------------------------------------------- - // create DeltaMatrix - //-------------------------------------------------------------------------- - - srand(time(0)); - - II = (GrB_Index*) malloc(sizeof(GrB_Index) * operations); - J = (GrB_Index*) malloc(sizeof(GrB_Index) * operations); - - info = Delta_Matrix_new(&A, t, nrows, ncols, true); - TEST_ASSERT(info == GrB_SUCCESS); - - // make sure transposed was created - T = Delta_Matrix_getTranspose(A); - TEST_ASSERT(T != A); - TEST_ASSERT(T != NULL); - - // get internal matrices - M = Delta_Matrix_M(A); - MT = Delta_Matrix_M(T); - - info = GrB_Matrix_new(&N, t, nrows, ncols); - TEST_ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_new(&NT, t, ncols, nrows); - TEST_ASSERT(info == GrB_SUCCESS); - - uint additions = 0; - for (size_t index = 0; index < operations; index++) - { - if (index < 10 || rand() % 100 > 20) - { - i = rand() % nrows; - j = rand() % ncols; - - //------------------------------------------------------------------ - // set element at position i,j - //------------------------------------------------------------------ - - info = Delta_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_setElement_BOOL(N, true, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - II[additions] = i; - J[additions] = j; - additions++; - } - else - { - uint32_t delete_pos = rand() % additions; - i = II[delete_pos]; - j = J[delete_pos]; - - //------------------------------------------------------------------ - // delete element at position i,j - //------------------------------------------------------------------ - - Delta_Matrix_removeElement(A, i, j); - - GrB_Matrix_removeElement(N, i, j); - } - } - - //-------------------------------------------------------------------------- - // flush matrix - //-------------------------------------------------------------------------- - - Delta_Matrix_wait(A, true); - - //-------------------------------------------------------------------------- - // validation - //-------------------------------------------------------------------------- - - info = GrB_transpose(NT, NULL, NULL, N, NULL); - TEST_ASSERT(info == GrB_SUCCESS); - - ASSERT_GrB_Matrices_EQ(M, N); - ASSERT_GrB_Matrices_EQ(MT, NT); - - //-------------------------------------------------------------------------- - // clean up - //-------------------------------------------------------------------------- - - Delta_Matrix_free(&A); - TEST_ASSERT(A == NULL); - - info = GrB_Matrix_free(&N); - TEST_ASSERT(info == GrB_SUCCESS); - - info = GrB_Matrix_free(&NT); - TEST_ASSERT(info == GrB_SUCCESS); - - free(II); - free(J); -} - -// test exporting Delta_Matrix to GrB_Matrix when there are no pending changes -// by exporting the matrix after flushing -void test_DeltaMatrix_export_no_changes() { - GrB_Type t = GrB_BOOL; - Delta_Matrix A = NULL; - GrB_Matrix M = NULL; - GrB_Matrix N = NULL; // exported matrix - GrB_Info info = GrB_SUCCESS; - GrB_Index i = 0; - GrB_Index j = 1; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool sync = false; - - info = Delta_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // get internal matrices - M = Delta_Matrix_M(A); - - //-------------------------------------------------------------------------- - // export empty matrix - //-------------------------------------------------------------------------- - - info = Delta_Matrix_export(&N, A); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // validation - //-------------------------------------------------------------------------- - - ASSERT_GrB_Matrices_EQ(M, N); - GrB_Matrix_free(&N); - - //-------------------------------------------------------------------------- - // export none empty matrix - //-------------------------------------------------------------------------- - - // set element at position i,j - info = Delta_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - Delta_Matrix_wait(A, sync); - - //-------------------------------------------------------------------------- - // validation - //-------------------------------------------------------------------------- - - info = Delta_Matrix_export(&N, A); - TEST_ASSERT(info == GrB_SUCCESS); - - ASSERT_GrB_Matrices_EQ(M, N); - - //-------------------------------------------------------------------------- - // clean up - //-------------------------------------------------------------------------- - - Delta_Matrix_free(&A); - GrB_Matrix_free(&N); -} - -// test exporting Delta_Matrix to GrB_Matrix when there are pending changes -// by exporting the matrix after making changes -// then flush the matrix and compare the internal matrix to the exported matrix -void test_DeltaMatrix_export_pending_changes() { - GrB_Type t = GrB_BOOL; - Delta_Matrix A = NULL; - GrB_Matrix M = NULL; - GrB_Matrix N = NULL; // exported matrix - GrB_Info info = GrB_SUCCESS; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool sync = false; - - info = Delta_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // get internal matrices - M = Delta_Matrix_M(A); - - // set elements - info = Delta_Matrix_setElement_BOOL(A, 0, 0); - TEST_ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_setElement_BOOL(A, 1, 1); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - Delta_Matrix_wait(A, sync); - - //-------------------------------------------------------------------------- - // set pending changes - //-------------------------------------------------------------------------- - - // remove element at position 0,0 - info = Delta_Matrix_removeElement(A, 0, 0); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position 2,2 - info = Delta_Matrix_setElement_BOOL(A, 2, 2); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // export matrix - //-------------------------------------------------------------------------- - - info = Delta_Matrix_export(&N, A); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - Delta_Matrix_wait(A, sync); - - //-------------------------------------------------------------------------- - // validation - //-------------------------------------------------------------------------- - - ASSERT_GrB_Matrices_EQ(M, N); - - // clean up - GrB_Matrix_free(&N); - Delta_Matrix_free(&A); - TEST_ASSERT(A == NULL); -} - -void test_DeltaMatrix_copy() { - GrB_Type t = GrB_BOOL; - Delta_Matrix A = NULL; - Delta_Matrix B = NULL; - GrB_Matrix A_M = NULL; - GrB_Matrix B_M = NULL; - GrB_Matrix A_DP = NULL; - GrB_Matrix B_DP = NULL; - GrB_Matrix A_DM = NULL; - GrB_Matrix B_DM = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool sync = false; - - info = Delta_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - info = Delta_Matrix_new(&B, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // set elements - info = Delta_Matrix_setElement_BOOL(A, 0, 0); - TEST_ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_setElement_BOOL(A, 1, 1); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - Delta_Matrix_wait(A, sync); - - //-------------------------------------------------------------------------- - // set pending changes - //-------------------------------------------------------------------------- - - // remove element at position 0,0 - info = Delta_Matrix_removeElement(A, 0, 0); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position 2,2 - info = Delta_Matrix_setElement_BOOL(A, 2, 2); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // copy matrix - //-------------------------------------------------------------------------- - - info = Delta_Matrix_copy(B, A); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // validation - //-------------------------------------------------------------------------- - - A_M = Delta_Matrix_M(A); - B_M = Delta_Matrix_M(B); - A_DP = Delta_Matrix_DP(A); - B_DP = Delta_Matrix_DP(B); - A_DM = Delta_Matrix_DM(A); - B_DM = Delta_Matrix_DM(B); - - ASSERT_GrB_Matrices_EQ(A_M, B_M); - ASSERT_GrB_Matrices_EQ(A_DP, B_DP); - ASSERT_GrB_Matrices_EQ(A_DM, B_DM); - - // clean up - Delta_Matrix_free(&A); - TEST_ASSERT(A == NULL); - Delta_Matrix_free(&B); - TEST_ASSERT(B == NULL); -} - -void test_DeltaMatrix_mxm() { - GrB_Type t = GrB_BOOL; - Delta_Matrix A = NULL; - Delta_Matrix B = NULL; - Delta_Matrix C = NULL; - Delta_Matrix D = NULL; - GrB_Matrix C_M = NULL; - GrB_Matrix D_M = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool sync = false; - - info = Delta_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - info = Delta_Matrix_new(&B, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - info = Delta_Matrix_new(&C, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - info = Delta_Matrix_new(&D, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // set elements - info = Delta_Matrix_setElement_BOOL(A, 0, 1); - TEST_ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_setElement_BOOL(A, 2, 3); - TEST_ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_setElement_BOOL(B, 1, 2); - TEST_ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_setElement_BOOL(B, 3, 4); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - Delta_Matrix_wait(A, sync); - Delta_Matrix_wait(B, sync); - - //-------------------------------------------------------------------------- - // set pending changes - //-------------------------------------------------------------------------- - - // remove element at position 0,0 - info = Delta_Matrix_removeElement(B, 1, 2); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position 1,3 - info = Delta_Matrix_setElement_BOOL(B, 1, 3); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // mxm matrix - //-------------------------------------------------------------------------- - - info = Delta_mxm(C, GxB_ANY_PAIR_BOOL, A, B); - TEST_ASSERT(info == GrB_SUCCESS); - - Delta_Matrix_wait(B, sync); - - info = Delta_mxm(D, GxB_ANY_PAIR_BOOL, A, B); - //-------------------------------------------------------------------------- - // validation - //-------------------------------------------------------------------------- - - C_M = Delta_Matrix_M(C); - D_M = Delta_Matrix_M(D); - - ASSERT_GrB_Matrices_EQ(C_M, D_M); - - // clean up - Delta_Matrix_free(&A); - TEST_ASSERT(A == NULL); - Delta_Matrix_free(&B); - TEST_ASSERT(B == NULL); - Delta_Matrix_free(&C); - TEST_ASSERT(C == NULL); - Delta_Matrix_free(&D); - TEST_ASSERT(C == NULL); -} - -void test_DeltaMatrix_resize() { - Delta_Matrix A = NULL; - Delta_Matrix T = NULL; - GrB_Info info = GrB_SUCCESS; - GrB_Type t = GrB_BOOL; - GrB_Index nrows = 10; - GrB_Index ncols = 20; - - info = Delta_Matrix_new(&A, t, nrows, ncols, true); - T = Delta_Matrix_getTranspose(A); - - GrB_Index A_nrows; - GrB_Index A_ncols; - GrB_Index T_nrows; - GrB_Index T_ncols; - - // verify A and T dimensions - Delta_Matrix_nrows(&A_nrows, A); - TEST_ASSERT(info == GrB_SUCCESS); - Delta_Matrix_ncols(&A_ncols, A); - TEST_ASSERT(info == GrB_SUCCESS); - - TEST_ASSERT(A_nrows == nrows); - TEST_ASSERT(A_ncols == ncols); - - Delta_Matrix_nrows(&T_nrows, T); - TEST_ASSERT(info == GrB_SUCCESS); - Delta_Matrix_ncols(&T_ncols, T); - TEST_ASSERT(info == GrB_SUCCESS); - - TEST_ASSERT(T_nrows == ncols); - TEST_ASSERT(T_ncols == nrows); - - // resize matrix, increase size by 2 - nrows *= 2; - ncols *= 2; - - info = Delta_Matrix_resize(A, nrows, ncols); - TEST_ASSERT(info == GrB_SUCCESS); - - // verify A and T dimensions - Delta_Matrix_nrows(&A_nrows, A); - TEST_ASSERT(info == GrB_SUCCESS); - Delta_Matrix_ncols(&A_ncols, A); - TEST_ASSERT(info == GrB_SUCCESS); - - TEST_ASSERT(A_nrows == nrows); - TEST_ASSERT(A_ncols == ncols); - - Delta_Matrix_nrows(&T_nrows, T); - TEST_ASSERT(info == GrB_SUCCESS); - Delta_Matrix_ncols(&T_ncols, T); - TEST_ASSERT(info == GrB_SUCCESS); - - TEST_ASSERT(T_nrows == ncols); - TEST_ASSERT(T_ncols == nrows); - - // resize matrix decrease size by 2 - nrows /= 2; - ncols /= 2; - - info = Delta_Matrix_resize(A, nrows, ncols); - TEST_ASSERT(info == GrB_SUCCESS); - - // verify A and T dimensions - Delta_Matrix_nrows(&A_nrows, A); - TEST_ASSERT(info == GrB_SUCCESS); - Delta_Matrix_ncols(&A_ncols, A); - TEST_ASSERT(info == GrB_SUCCESS); - - TEST_ASSERT(A_nrows == nrows); - TEST_ASSERT(A_ncols == ncols); - - Delta_Matrix_nrows(&T_nrows, T); - TEST_ASSERT(info == GrB_SUCCESS); - Delta_Matrix_ncols(&T_ncols, T); - TEST_ASSERT(info == GrB_SUCCESS); - - TEST_ASSERT(T_nrows == ncols); - TEST_ASSERT(T_ncols == nrows); - - Delta_Matrix_free(&A); -} - -TEST_LIST = { - {"DeltaMatrix_fuzzy", test_DeltaMatrix_fuzzy}, - {"DeltaMatrix_export_no_changes", test_DeltaMatrix_export_no_changes}, - {"DeltaMatrix_export_pending_changes", test_DeltaMatrix_export_pending_changes}, - {"DeltaMatrix_copy", test_DeltaMatrix_copy}, - {"DeltaMatrix_mxm", test_DeltaMatrix_mxm}, - {"DeltaMatrix_resize", test_DeltaMatrix_resize}, - {NULL, NULL} -}; - -//#ifndef RG_DEBUG -//// test DeltaMatrix_pending -//// if RG_DEBUG is defined, each call to setElement will flush all 3 matrices -//// causing this test to fail -//TEST_F(DeltaMatrixTest, DeltaMatrix_pending) { -// Delta_Matrix A = NULL; -// GrB_Info info = GrB_SUCCESS; -// GrB_Type t = GrB_UINT64; -// GrB_Index nrows = 100; -// GrB_Index ncols = 100; -// bool pending = false; -// -// info = Delta_Matrix_new(&A, t, nrows, ncols); -// ASSERT_EQ(info, GrB_SUCCESS); -// -// // new Delta_Matrix shouldn't have any pending operations -// info = Delta_Matrix_pending(A, &pending); -// ASSERT_EQ(info, GrB_SUCCESS); -// ASSERT_FALSE(pending); -// -// // set element, modifies delta-plus -// info = Delta_Matrix_setElement_UINT64(A, 2, 2, 2); -// ASSERT_EQ(info, GrB_SUCCESS); -// -// // expecting pending changes -// info = Delta_Matrix_pending(A, &pending); -// ASSERT_EQ(info, GrB_SUCCESS); -// ASSERT_TRUE(pending); -// -// // flush pending changes on both DP and DM -// info = Delta_Matrix_wait(A, false); -// ASSERT_EQ(info, GrB_SUCCESS); -// -// // expecting no pending changes -// info = Delta_Matrix_pending(A, &pending); -// ASSERT_EQ(info, GrB_SUCCESS); -// ASSERT_FALSE(pending); -// -// // remove entry, DP entry is now a zombie -// info = Delta_Matrix_removeElement_UINT64(A, 2, 2); -// ASSERT_EQ(info, GrB_SUCCESS); -// -// // expecting pending changes -// info = Delta_Matrix_pending(A, &pending); -// ASSERT_EQ(info, GrB_SUCCESS); -// ASSERT_TRUE(pending); -// -// // flush pending changes on both DP and DM -// info = Delta_Matrix_wait(A, false); -// ASSERT_EQ(info, GrB_SUCCESS); -// -// // expecting no pending changes -// info = Delta_Matrix_pending(A, &pending); -// ASSERT_EQ(info, GrB_SUCCESS); -// ASSERT_FALSE(pending); -// -// // set element, modifies delta-plus -// info = Delta_Matrix_setElement_UINT64(A, 2, 2, 2); -// ASSERT_EQ(info, GrB_SUCCESS); -// -// // flush pending changes on M, DM and DP -// info = Delta_Matrix_wait(A, true); -// ASSERT_EQ(info, GrB_SUCCESS); -// -// // expecting no pending changes -// info = Delta_Matrix_pending(A, &pending); -// ASSERT_EQ(info, GrB_SUCCESS); -// ASSERT_FALSE(pending); -// -// // clean up -// Delta_Matrix_free(&A); -// ASSERT_TRUE(A == NULL); -//} -//#endif From e7deba394680a606500174fd223d3ec5317cd39a Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Sun, 26 May 2024 16:24:00 +0300 Subject: [PATCH 33/57] fix make file --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index dfdfdbb18..e361cd398 100644 --- a/Makefile +++ b/Makefile @@ -371,7 +371,7 @@ ifneq ($(BUILD),0) $(SHOW)$(MAKE) build FORCE=1 UNIT_TESTS=1 endif $(SHOW)BINROOT=$(BINROOT) ./tests/unit/tests.sh - RUSTFLAGS+='-L$(BINROOT)/src -lfalkordb_static -L$(BINROOT)/GraphBLAS -lgraphblas -L$(LIBOMP_PREFIX)/lib -lomp' cargo test --lib + RUSTFLAGS+=' -L$(BINROOT)/src -lfalkordb_static -L$(BINROOT)/GraphBLAS -lgraphblas -L$(LIBOMP_PREFIX)/lib -lomp' cargo test --lib flow-tests: $(TEST_DEPS) $(SHOW)MODULE=$(TARGET) BINROOT=$(BINROOT) PARALLEL=$(_RLTEST_PARALLEL) GEN=$(GEN) AOF=$(AOF) TCK=0 ./tests/flow/tests.sh From 96508e82e3b48c2d01be7480b188a26e98cfe075 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Tue, 28 May 2024 10:31:39 +0300 Subject: [PATCH 34/57] rewrite tests --- deps/FalkorDB-rs | 2 +- tests/unit/test_delta_matrix_iter.c | 393 ---------------------------- 2 files changed, 1 insertion(+), 394 deletions(-) delete mode 100644 tests/unit/test_delta_matrix_iter.c diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 1c048081f..ad79af6f4 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 1c048081fc97c0b2a160da70091dd44c75c61194 +Subproject commit ad79af6f474f05b6498ed128d411e2fc4fc61321 diff --git a/tests/unit/test_delta_matrix_iter.c b/tests/unit/test_delta_matrix_iter.c deleted file mode 100644 index a79311b6e..000000000 --- a/tests/unit/test_delta_matrix_iter.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright Redis Ltd. 2018 - present - * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or - * the Server Side Public License v1 (SSPLv1). - */ - -#include "src/util/rmalloc.h" -#include "src/configuration/config.h" -#include "src/graph/delta_matrix/delta_matrix.h" -#include "src/graph/delta_matrix/delta_matrix_iter.h" - -void setup() { - Alloc_Reset(); - - // initialize GraphBLAS - GrB_init(GrB_NONBLOCKING); - - // all matrices in CSR format - GxB_Global_Option_set(GxB_FORMAT, GxB_BY_ROW); - - // set delta matrix flush threshold - Config_Option_set(Config_DELTA_MAX_PENDING_CHANGES, "10000", NULL); -} - -void tearDown() { - GrB_finalize(); -} - -#define TEST_INIT setup(); -#define TEST_FINI tearDown(); -#include "acutest.h" - -// test DeltaMatrixTupleIter initialization -void test_DeltaMatrixTupleIter_attach() { - Delta_Matrix A = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - Delta_MatrixTupleIter iter; - memset(&iter, 0, sizeof(Delta_MatrixTupleIter)); - - info = Delta_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - info = Delta_MatrixTupleIter_attach(&iter, A); - TEST_ASSERT(Delta_MatrixTupleIter_is_attached(&iter, A)); - - Delta_MatrixTupleIter_detach(&iter); - // TEST_ASSERT(iter.A == NULL); - - Delta_Matrix_free(&A); - TEST_ASSERT(A == NULL); -} - -// test DeltaMatrixTupleIter iteration -void test_DeltaMatrixTupleIter_next() { - Delta_Matrix A = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index i = 1; - GrB_Index j = 2; - GrB_Index row = 0; - GrB_Index col = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool val = 0; - bool sync = false; - Delta_MatrixTupleIter iter; - memset(&iter, 0, sizeof(Delta_MatrixTupleIter)); - - info = Delta_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i,j - info = Delta_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - Delta_Matrix_wait(A, sync); - - //-------------------------------------------------------------------------- - // set pending changes - //-------------------------------------------------------------------------- - - // remove element at position i,j - info = Delta_Matrix_removeElement(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i+1,j+1 - info = Delta_Matrix_setElement_BOOL(A, i+1, j+1); - TEST_ASSERT(info == GrB_SUCCESS); - - info = Delta_MatrixTupleIter_attach(&iter, A); - TEST_ASSERT(Delta_MatrixTupleIter_is_attached(&iter, A)); - - info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - TEST_ASSERT(info == GrB_SUCCESS); - - TEST_ASSERT(row == i+1); - TEST_ASSERT(col == j+1); - TEST_ASSERT(val == 1); - - info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - - TEST_ASSERT(info == GxB_EXHAUSTED); - - Delta_Matrix_free(&A); - TEST_ASSERT(A == NULL); - Delta_MatrixTupleIter_detach(&iter); - // TEST_ASSERT(iter.A == NULL); -} - -// test DeltaMatrixTupleIter iteration for sparse matrix -void test_DeltaMatrixTupleIter_next_sparse() { - Delta_Matrix A = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index row = 0; - GrB_Index col = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool val = 0; - bool sync = false; - Delta_MatrixTupleIter iter; - memset(&iter, 0, sizeof(Delta_MatrixTupleIter)); - - info = Delta_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - for (GrB_Index i = 25; i < 100; i++) { - for (GrB_Index j = 25; j < 100; j++) { - // set element at position i,j - info = Delta_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - } - } - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - Delta_Matrix_wait(A, sync); - - //-------------------------------------------------------------------------- - // check M is sparse - //-------------------------------------------------------------------------- - - GrB_Matrix M = Delta_Matrix_M(A); - - int sparsity; - GxB_Matrix_Option_get(M, GxB_SPARSITY_STATUS, &sparsity); - TEST_ASSERT(sparsity == GxB_SPARSE); - - //-------------------------------------------------------------------------- - // check iter start from correct row - //-------------------------------------------------------------------------- - - info = Delta_MatrixTupleIter_attach(&iter, A); - TEST_ASSERT(Delta_MatrixTupleIter_is_attached(&iter, A)); - - info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - TEST_ASSERT(info == GrB_SUCCESS); - - TEST_ASSERT(row == 25); - TEST_ASSERT(col == 25); - TEST_ASSERT(val); - - Delta_Matrix_free(&A); - TEST_ASSERT(A == NULL); - Delta_MatrixTupleIter_detach(&iter); - // TEST_ASSERT(iter.A == NULL); -} - -// test DeltaMatrixTupleIter iteration -void test_DeltaMatrixTupleIter_reuse() { - Delta_Matrix A = NULL; - Delta_Matrix B = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index i = 1; - GrB_Index j = 2; - GrB_Index row = 0; - GrB_Index col = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool val = 0; - bool sync = false; - Delta_MatrixTupleIter iter; - memset(&iter, 0, sizeof(Delta_MatrixTupleIter)); - - info = Delta_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - info = Delta_Matrix_new(&B, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i,j - info = Delta_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - Delta_Matrix_wait(A, sync); - - info = Delta_MatrixTupleIter_attach(&iter, B); - TEST_ASSERT(Delta_MatrixTupleIter_is_attached(&iter, B)); - - info = Delta_MatrixTupleIter_attach(&iter, A); - TEST_ASSERT(Delta_MatrixTupleIter_is_attached(&iter, A)); - - info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - - TEST_ASSERT(info == GrB_SUCCESS); - TEST_ASSERT(row == i); - TEST_ASSERT(col == j); - TEST_ASSERT(val); - - info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - - TEST_ASSERT(info == GxB_EXHAUSTED); - - Delta_Matrix_free(&A); - TEST_ASSERT(A == NULL); - Delta_Matrix_free(&B); - TEST_ASSERT(A == NULL); - Delta_MatrixTupleIter_detach(&iter); - // TEST_ASSERT(iter.A == NULL); -} - -// test DeltaMatrixTupleIter_iterate_row -void test_DeltaMatrixTupleIter_iterate_row() { - Delta_Matrix A = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index i = 1; - GrB_Index j = 2; - GrB_Index row = 0; - GrB_Index col = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool val = 0; - bool sync = false; - Delta_MatrixTupleIter iter; - memset(&iter, 0, sizeof(Delta_MatrixTupleIter)); - - info = Delta_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i,j - info = Delta_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - Delta_Matrix_wait(A, sync); - - //-------------------------------------------------------------------------- - // set pending changes - //-------------------------------------------------------------------------- - - // remove element at position i,j - info = Delta_Matrix_removeElement(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // wait, DM can't have pendding changes - sync = false; - Delta_Matrix_wait(A, sync); - - // set element at position i+1,j+1 - info = Delta_Matrix_setElement_BOOL(A, i+1, j+1); - TEST_ASSERT(info == GrB_SUCCESS); - - info = Delta_MatrixTupleIter_attach(&iter, A); - // TEST_ASSERT(iter.A == A); - - info = Delta_MatrixTupleIter_iterate_row(&iter, i); - TEST_ASSERT(info == GrB_SUCCESS); - - info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - TEST_ASSERT(info == GxB_EXHAUSTED); - - info = Delta_MatrixTupleIter_reset(&iter); - TEST_ASSERT(info == GrB_SUCCESS); - - info = Delta_MatrixTupleIter_iterate_row(&iter, i+1); - TEST_ASSERT(info == GrB_SUCCESS); - - info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - - TEST_ASSERT(info == GrB_SUCCESS); - TEST_ASSERT(row == i+1); - TEST_ASSERT(col == j+1); - TEST_ASSERT(val); - - info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - TEST_ASSERT(info == GxB_EXHAUSTED); - - Delta_Matrix_free(&A); - TEST_ASSERT(A == NULL); - Delta_MatrixTupleIter_detach(&iter); - // TEST_ASSERT(iter.A == NULL); -} - -// test DeltaMatrixTupleiIter_iterate_range -void test_DeltaMatrixTupleIter_iterate_range() { - Delta_Matrix A = NULL; - GrB_Type t = GrB_BOOL; - GrB_Info info = GrB_SUCCESS; - GrB_Index i = 1; - GrB_Index j = 2; - GrB_Index row = 0; - GrB_Index col = 0; - GrB_Index nrows = 100; - GrB_Index ncols = 100; - bool val = 0; - bool sync = false; - Delta_MatrixTupleIter iter; - memset(&iter, 0, sizeof(Delta_MatrixTupleIter)); - - info = Delta_Matrix_new(&A, t, nrows, ncols, false); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i,j - info = Delta_Matrix_setElement_BOOL(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - //-------------------------------------------------------------------------- - // flush matrix, sync - //-------------------------------------------------------------------------- - - // wait, force sync - sync = true; - Delta_Matrix_wait(A, sync); - - //-------------------------------------------------------------------------- - // set pending changes - //-------------------------------------------------------------------------- - - // remove element at position i,j - info = Delta_Matrix_removeElement(A, i, j); - TEST_ASSERT(info == GrB_SUCCESS); - - // set element at position i+1,j+1 - info = Delta_Matrix_setElement_BOOL(A, i+1, j+1); - TEST_ASSERT(info == GrB_SUCCESS); - - info = Delta_MatrixTupleIter_attach(&iter, A); - TEST_ASSERT(Delta_MatrixTupleIter_is_attached(&iter, A)); - - info = Delta_MatrixTupleIter_iterate_range(&iter, i+1, i+1); - TEST_ASSERT(info == GrB_SUCCESS); - - info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - - TEST_ASSERT(info == GrB_SUCCESS); - TEST_ASSERT(row == i+1); - TEST_ASSERT(col == j+1); - TEST_ASSERT(val == 1); - - info = Delta_MatrixTupleIter_next_BOOL(&iter, &row, &col, &val); - TEST_ASSERT(info == GxB_EXHAUSTED); - - Delta_Matrix_free(&A); - TEST_ASSERT(A == NULL); - Delta_MatrixTupleIter_detach(&iter); - // TEST_ASSERT(iter.A == NULL); -} - -TEST_LIST = { - {"DeltaMatrixTupleIter_attach", test_DeltaMatrixTupleIter_attach}, - {"DeltaMatrixTupleIter_next", test_DeltaMatrixTupleIter_next}, - {"DeltaMatrixTupleIter_next_sparse", test_DeltaMatrixTupleIter_next_sparse}, - {"DeltaMatrixTupleIter_reuse", test_DeltaMatrixTupleIter_reuse}, - {"DeltaMatrixTupleIter_iterate_row", test_DeltaMatrixTupleIter_iterate_row}, - {"DeltaMatrixTupleIter_iterate_range", test_DeltaMatrixTupleIter_iterate_range}, - {NULL, NULL} -}; From 144d5467cce6bab666f1132ca1b5d08d5f047b61 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Wed, 29 May 2024 10:01:57 +0300 Subject: [PATCH 35/57] update --- deps/FalkorDB-rs | 2 +- src/graph/delta_matrix/delta_matrix.h | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index ad79af6f4..0acc3ed52 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit ad79af6f474f05b6498ed128d411e2fc4fc61321 +Subproject commit 0acc3ed52b6190815f21aae7e40cfdb64c93295b diff --git a/src/graph/delta_matrix/delta_matrix.h b/src/graph/delta_matrix/delta_matrix.h index 1885f7f72..194cdaef5 100644 --- a/src/graph/delta_matrix/delta_matrix.h +++ b/src/graph/delta_matrix/delta_matrix.h @@ -117,16 +117,6 @@ GrB_Matrix Delta_Matrix_M const Delta_Matrix C ); -GrB_Matrix Delta_Matrix_DP -( - const Delta_Matrix C -); - -GrB_Matrix Delta_Matrix_DM -( - const Delta_Matrix C -); - GrB_Info Delta_Matrix_nrows ( GrB_Index *nrows, From d04f36ee5311bd9224a8e93734710f23c9f0e0d3 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Wed, 29 May 2024 11:06:23 +0300 Subject: [PATCH 36/57] address review --- deps/FalkorDB-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 0acc3ed52..0e8393d8f 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 0acc3ed52b6190815f21aae7e40cfdb64c93295b +Subproject commit 0e8393d8f450718af3af1283feb9991d74cc2798 From 81e21f698d3ae4ccfebbf7b5f30b6820b34e3fb9 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Wed, 29 May 2024 11:15:23 +0300 Subject: [PATCH 37/57] address review --- deps/FalkorDB-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 0e8393d8f..8fb8b0f80 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 0e8393d8f450718af3af1283feb9991d74cc2798 +Subproject commit 8fb8b0f80ad2684ca072eef3980f4f91b4f5c2ca From 7e1dbab9fc12c48b8f98fb9d040b4580e60ba08b Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Wed, 29 May 2024 11:20:24 +0300 Subject: [PATCH 38/57] fix --- deps/FalkorDB-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/FalkorDB-rs b/deps/FalkorDB-rs index 8fb8b0f80..6ec65fe46 160000 --- a/deps/FalkorDB-rs +++ b/deps/FalkorDB-rs @@ -1 +1 @@ -Subproject commit 8fb8b0f80ad2684ca072eef3980f4f91b4f5c2ca +Subproject commit 6ec65fe460a4841ae1b327b8b9f92921ad09222e From eb460328f4e7de9aa8b9ba232e818ac26795afd7 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Sun, 16 Jun 2024 12:34:37 +0300 Subject: [PATCH 39/57] address review --- src/graph/graph.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index fa17ae24c..3f1544334 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -1067,6 +1067,22 @@ void Graph_DeleteEdges info = Delta_Matrix_removeElement(in, dest_id, edge_id); ASSERT(info == GrB_SUCCESS); + // free and remove edges from datablock. + DataBlock_DeleteItem(g->edges, edge_id); + } + + for (uint i = 0; i < n; i++) { + Edge *e = edges + i; + int r = Edge_GetRelationID(e); + NodeID src_id = Edge_GetSrcNodeID(e); + NodeID dest_id = Edge_GetDestNodeID(e); + EdgeID edge_id = ENTITY_GET_ID(e); + + ASSERT(!DataBlock_ItemIsDeleted((void *)e->attributes)); + + R = Graph_GetRelationMatrix(g, r, false); + out = Graph_OutgoingRelationMatrix(g, r); + Delta_MatrixTupleIter it = {0}; Delta_MatrixTupleIter_AttachRange(&it, out, src_id, src_id); GrB_Index dst; @@ -1105,9 +1121,6 @@ void Graph_DeleteEdges ASSERT(info == GrB_SUCCESS); } } - - // free and remove edges from datablock. - DataBlock_DeleteItem(g->edges, edge_id); } Graph_SetMatrixPolicy(g, policy); From 929bf8406aa6f2986505b486748d329d63412b13 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 17 Jun 2024 10:44:47 +0300 Subject: [PATCH 40/57] improve perf --- deps/FalkorDB-core-rs | 2 +- src/graph/delta_matrix/delta_matrix_iter.h | 2 +- src/graph/graph.c | 5 +---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/deps/FalkorDB-core-rs b/deps/FalkorDB-core-rs index 6ec65fe46..d45245efa 160000 --- a/deps/FalkorDB-core-rs +++ b/deps/FalkorDB-core-rs @@ -1 +1 @@ -Subproject commit 6ec65fe460a4841ae1b327b8b9f92921ad09222e +Subproject commit d45245efab51ed84c4dc86308578745f08dab687 diff --git a/src/graph/delta_matrix/delta_matrix_iter.h b/src/graph/delta_matrix/delta_matrix_iter.h index fb86b1c8b..b37304d12 100644 --- a/src/graph/delta_matrix/delta_matrix_iter.h +++ b/src/graph/delta_matrix/delta_matrix_iter.h @@ -17,7 +17,7 @@ // to iterate over a Delta_Matrix struct Opaque_Delta_MatrixTupleIter { - char _private[296]; + char _private[432]; }; typedef struct Opaque_Delta_MatrixTupleIter Delta_MatrixTupleIter ; diff --git a/src/graph/graph.c b/src/graph/graph.c index 3f1544334..b94b73c2b 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -1058,7 +1058,6 @@ void Graph_DeleteEdges ASSERT(!DataBlock_ItemIsDeleted((void *)e->attributes)); - R = Graph_GetRelationMatrix(g, r, false); out = Graph_OutgoingRelationMatrix(g, r); in = Graph_IncomingRelationMatrix(g, r); @@ -1078,9 +1077,6 @@ void Graph_DeleteEdges NodeID dest_id = Edge_GetDestNodeID(e); EdgeID edge_id = ENTITY_GET_ID(e); - ASSERT(!DataBlock_ItemIsDeleted((void *)e->attributes)); - - R = Graph_GetRelationMatrix(g, r, false); out = Graph_OutgoingRelationMatrix(g, r); Delta_MatrixTupleIter it = {0}; @@ -1095,6 +1091,7 @@ void Graph_DeleteEdges } if(!connected) { + R = Graph_GetRelationMatrix(g, r, false); // no more edges connecting src to other nodes // remove src from relation matrix info = Delta_Matrix_removeElement(R, src_id, dest_id); From 43308cfa232c746881a6471d3374e2c2b1abb86c Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 17 Jun 2024 11:29:09 +0300 Subject: [PATCH 41/57] fix --- deps/FalkorDB-core-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/FalkorDB-core-rs b/deps/FalkorDB-core-rs index d45245efa..e45ce63ad 160000 --- a/deps/FalkorDB-core-rs +++ b/deps/FalkorDB-core-rs @@ -1 +1 @@ -Subproject commit d45245efab51ed84c4dc86308578745f08dab687 +Subproject commit e45ce63ad42b83ef0e7927e0f997a3192e1aac7d From 7be62f07d87e35c173e5d37f2baf4e15b8cb6400 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 17 Jun 2024 15:38:25 +0300 Subject: [PATCH 42/57] fix cond --- deps/FalkorDB-core-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/FalkorDB-core-rs b/deps/FalkorDB-core-rs index e45ce63ad..8dfc1c005 160000 --- a/deps/FalkorDB-core-rs +++ b/deps/FalkorDB-core-rs @@ -1 +1 @@ -Subproject commit e45ce63ad42b83ef0e7927e0f997a3192e1aac7d +Subproject commit 8dfc1c00561d8e7ef33365937d18380dcf05c683 From 4173e3ccc2e25c989ac3291d24ce43182cbe8e41 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 24 Jun 2024 13:34:36 +0300 Subject: [PATCH 43/57] address review --- deps/FalkorDB-core-rs | 2 +- src/bulk_insert/bulk_insert.c | 3 +- src/constraint/constraint.c | 53 ++- .../ops/shared/create_functions.c | 3 +- src/graph/delta_matrix/delta_matrix.h | 5 +- src/graph/graph.c | 349 ++++++++++-------- src/graph/graph.h | 28 +- src/graph/graph_statistics.c | 72 ++++ src/graph/graph_statistics.h | 101 +++++ src/index/index_construct.c | 47 ++- src/index/index_edge.c | 1 - src/index/index_node.c | 1 - src/serializers/decode_context.c | 11 + src/serializers/decode_context.h | 1 + .../decoders/current/v14/decode_graph.c | 19 +- .../current/v14/decode_graph_entities.c | 3 +- .../decoders/prev/v10/decode_graph.c | 18 +- .../decoders/prev/v10/decode_graph_entities.c | 3 +- .../decoders/prev/v11/decode_graph.c | 15 +- .../decoders/prev/v11/decode_graph_entities.c | 3 +- .../decoders/prev/v12/decode_graph.c | 18 +- .../decoders/prev/v12/decode_graph_entities.c | 3 +- .../decoders/prev/v13/decode_graph.c | 18 +- .../decoders/prev/v13/decode_graph_entities.c | 3 +- .../decoders/prev/v9/decode_graph.c | 27 +- .../decoders/prev/v9/decode_graph_entities.c | 3 +- src/serializers/encode_context.c | 25 +- src/serializers/encode_context.h | 34 +- .../encoder/v14/encode_graph_entities.c | 96 ++++- src/serializers/graph_extensions.c | 26 +- src/serializers/graph_extensions.h | 1 + 31 files changed, 721 insertions(+), 271 deletions(-) create mode 100644 src/graph/graph_statistics.c create mode 100644 src/graph/graph_statistics.h diff --git a/deps/FalkorDB-core-rs b/deps/FalkorDB-core-rs index 8dfc1c005..c83945a78 160000 --- a/deps/FalkorDB-core-rs +++ b/deps/FalkorDB-core-rs @@ -1 +1 @@ -Subproject commit 8dfc1c00561d8e7ef33365937d18380dcf05c683 +Subproject commit c83945a7866ede517141b1b1ca37d2a66147e8c7 diff --git a/src/bulk_insert/bulk_insert.c b/src/bulk_insert/bulk_insert.c index 3611228f6..b9a705a2d 100644 --- a/src/bulk_insert/bulk_insert.c +++ b/src/bulk_insert/bulk_insert.c @@ -272,8 +272,7 @@ static int _BulkInsert_ProcessEdgeFile // sync matrix once ASSERT(Graph_GetMatrixPolicy(gc->g) == SYNC_POLICY_RESIZE); Graph_GetRelationMatrix(gc->g, type_id, false); - Graph_OutgoingRelationMatrix(gc->g, type_id); - Graph_IncomingRelationMatrix(gc->g, type_id); + Graph_MultiEdgeRelationMatrix(gc->g, type_id); Graph_GetAdjacencyMatrix(gc->g, false); Graph_SetMatrixPolicy(gc->g, SYNC_POLICY_NOP); diff --git a/src/constraint/constraint.c b/src/constraint/constraint.c index e59f849d6..50f01631d 100644 --- a/src/constraint/constraint.c +++ b/src/constraint/constraint.c @@ -409,11 +409,11 @@ void Constraint_EnforceNodes ASSERT(g != NULL); Delta_MatrixTupleIter it = {0}; // matrix iterator - bool holds = true; // constraint holds - GrB_Index rowIdx = 0; // current row being scanned - int enforced = 0; // #entities in current batch - int schema_id = c->schema_id; // constraint schema ID - int batch_size = 10000; // #entities to enforce + bool holds = true; // constraint holds + GrB_Index rowIdx = 0; // current row being scanned + int enforced = 0; // #entities in current batch + int schema_id = c->schema_id; // constraint schema ID + int batch_size = 10000; // #entities to enforce while(holds) { // lock graph for reading @@ -503,7 +503,7 @@ void Constraint_EnforceEdges EntityID dest_id = 0; // current processed column idx EntityID edge_id = 0; // current processed edge id EntityID prev_src_id = 0; // last processed row idx - EntityID prev_edge_id = 0; // last processed column idx + EntityID prev_dest_id = 0; // last processed column idx int enforced = 0; // # entities enforced in batch int schema_id = c->schema_id; // edge relationship type ID int batch_size = 1000; // max number of entities to enforce @@ -523,11 +523,11 @@ void Constraint_EnforceEdges // reset number of enforced edges in batch enforced = 0; prev_src_id = src_id; - prev_edge_id = edge_id; + prev_dest_id = dest_id; // fetch relation matrix ASSERT(Graph_GetMatrixPolicy(g) == SYNC_POLICY_FLUSH_RESIZE); - const Delta_Matrix m = Graph_OutgoingRelationMatrix(g, schema_id); + const Delta_Matrix m = Graph_GetRelationMatrix(g, schema_id, false); ASSERT(m != NULL); //---------------------------------------------------------------------- @@ -538,10 +538,10 @@ void Constraint_EnforceEdges ASSERT(info == GrB_SUCCESS); // skip previously enforced edges - while((info = Delta_MatrixTupleIter_next_UINT64(&it, &src_id, &edge_id, - &dest_id)) == GrB_SUCCESS && + while((info = Delta_MatrixTupleIter_next_UINT64(&it, &src_id, &dest_id, + &edge_id)) == GrB_SUCCESS && src_id == prev_src_id && - edge_id != prev_edge_id); + dest_id < prev_dest_id); // process only if iterator is on an active entry if(info != GrB_SUCCESS) { @@ -558,15 +558,33 @@ void Constraint_EnforceEdges e.dest_id = dest_id; e.relationID = schema_id; - bool res = Graph_GetEdge(g, edge_id, &e); - assert(res == true); - if(!c->enforce(c, (GraphEntity*)&e, NULL)) { - holds = false; - break; + if(SINGLE_EDGE(edge_id)) { + bool res = Graph_GetEdge(g, edge_id, &e); + assert(res == true); + if(!c->enforce(c, (GraphEntity*)&e, NULL)) { + holds = false; + break; + } + } else { + GrB_Index me_ids = CLEAR_MSB(edge_id); + Delta_Matrix me = Graph_MultiEdgeRelationMatrix(g, schema_id); + Delta_MatrixTupleIter me_it; + Delta_MatrixTupleIter_AttachRange(&me_it, me, me_ids, me_ids); + + while(Delta_MatrixTupleIter_next_BOOL(&it, NULL, &edge_id, NULL) == GrB_SUCCESS) { + bool res = Graph_GetEdge(g, edge_id, &e); + assert(res == true); + if(!c->enforce(c, (GraphEntity*)&e, NULL)) { + holds = false; + break; + } + } + + Delta_MatrixTupleIter_detach(&me_it); } enforced++; // single/multi edge are counted similarly } while(enforced < batch_size && - Delta_MatrixTupleIter_next_BOOL(&it, &src_id, &edge_id, NULL) + Delta_MatrixTupleIter_next_UINT64(&it, &src_id, &dest_id, &edge_id) == GrB_SUCCESS && holds); //---------------------------------------------------------------------- @@ -623,4 +641,3 @@ void Constraint_Free *c = NULL; } - diff --git a/src/execution_plan/ops/shared/create_functions.c b/src/execution_plan/ops/shared/create_functions.c index fc37ce75f..f5c46d71c 100644 --- a/src/execution_plan/ops/shared/create_functions.c +++ b/src/execution_plan/ops/shared/create_functions.c @@ -123,8 +123,7 @@ static void _CommitEdgesBlueprint // calling Graph_GetRelationMatrix will make sure relationship matrix // is of the right dimensions Graph_GetRelationMatrix(g, Schema_GetID(s), false); - Graph_OutgoingRelationMatrix(g, Schema_GetID(s)); - Graph_IncomingRelationMatrix(g, Schema_GetID(s)); + Graph_MultiEdgeRelationMatrix(g, Schema_GetID(s)); } // call Graph_GetAdjacencyMatrix will make sure the adjacency matrix diff --git a/src/graph/delta_matrix/delta_matrix.h b/src/graph/delta_matrix/delta_matrix.h index 194cdaef5..2ac97f158 100644 --- a/src/graph/delta_matrix/delta_matrix.h +++ b/src/graph/delta_matrix/delta_matrix.h @@ -8,12 +8,13 @@ #include "RG.h" #include "GraphBLAS.h" -#include - // forward declaration of Delta_Matrix type typedef struct _Delta_Matrix _Delta_Matrix; typedef _Delta_Matrix *Delta_Matrix; +// Checks if X represents edge ID. +#define SINGLE_EDGE(x) !((x) & MSB_MASK) + //------------------------------------------------------------------------------ // diff --git a/src/graph/graph.c b/src/graph/graph.c index b94b73c2b..0c44de26d 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -106,28 +106,31 @@ void _Graph_GetEdgesConnectingNodes ASSERT(dest < _Graph_NodeCap(g)); // relation map, maps (src, dest, r) to edge IDs. + GrB_Index edge_id; Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); - GrB_Info res = Delta_Matrix_extractElement_BOOL(NULL, M, src, dest); + GrB_Info res = Delta_Matrix_extractElement_UINT64(&edge_id, M, src, dest); // no entry at [dest, src], src is not connected to dest with relation R if(res == GrB_NO_VALUE) return; - GrB_Info info; - Edge e = {.src_id = src, .dest_id = dest, .relationID = r}; - Delta_Matrix out = Graph_OutgoingRelationMatrix(g, r); - - Delta_MatrixTupleIter it = {0}; - Delta_MatrixTupleIter_AttachRange(&it, out, src, src); - - GrB_Index dst; - GrB_Index edgeId; - while (Delta_MatrixTupleIter_next_UINT64(&it, NULL, &edgeId, &dst) == GrB_SUCCESS) { - if(dst != dest) continue; - e.id = edgeId; - e.relationID = r; - e.attributes = DataBlock_GetItem(g->edges, edgeId); - ASSERT(e.attributes); + if(SINGLE_EDGE(edge_id)) { + Edge e = {.src_id = src, .dest_id = dest, .relationID = r, .id = edge_id, .attributes = DataBlock_GetItem(g->edges, edge_id)}; array_append(*edges, e); + } else { + GrB_Info info; + Edge e = {.src_id = src, .dest_id = dest, .relationID = r}; + Delta_Matrix me = Graph_MultiEdgeRelationMatrix(g, r); + + Delta_MatrixTupleIter it = {0}; + Delta_MatrixTupleIter_AttachRange(&it, me, CLEAR_MSB(edge_id), CLEAR_MSB(edge_id)); + + while (Delta_MatrixTupleIter_next_BOOL(&it, NULL, &edge_id, NULL) == GrB_SUCCESS) { + e.id = edge_id; + e.relationID = r; + e.attributes = DataBlock_GetItem(g->edges, edge_id); + ASSERT(e.attributes); + array_append(*edges, e); + } } } @@ -277,9 +280,7 @@ void Graph_ApplyAllPending for(int i = 0; i < n; i ++) { M = Graph_GetRelationMatrix(g, i, false); Delta_Matrix_wait(M, force_flush); - M = Graph_OutgoingRelationMatrix(g, i); - Delta_Matrix_wait(M, force_flush); - M = Graph_IncomingRelationMatrix(g, i); + M = Graph_MultiEdgeRelationMatrix(g, i); Delta_Matrix_wait(M, force_flush); } @@ -359,13 +360,7 @@ bool Graph_Pending if(pending) { return true; } - M = g->relations[i].Out; - info = Delta_Matrix_pending(M, &pending); - ASSERT(info == GrB_SUCCESS); - if(pending) { - return true; - } - M = g->relations[i].In; + M = g->relations[i].ME; info = Delta_Matrix_pending(M, &pending); ASSERT(info == GrB_SUCCESS); if(pending) { @@ -402,6 +397,9 @@ Graph *Graph_New Delta_Matrix_new(&g->adjacency_matrix, GrB_BOOL, n, n, true); Delta_Matrix_new(&g->_zero_matrix, GrB_BOOL, n, n, false); + // init graph statistics + GraphStatistics_init(&g->stats); + // initialize a read-write lock scoped to the individual graph _CreateRWLock(g); g->_writelocked = false; @@ -456,14 +454,7 @@ uint64_t Graph_RelationEdgeCount const Graph *g, RelationID relation ) { - ASSERT(g); - - Delta_Matrix out = Graph_OutgoingRelationMatrix(g, relation); - ASSERT(out != NULL); - GrB_Index nvals; - GrB_Info info = Delta_Matrix_nvals(&nvals, out); - ASSERT(info == GrB_SUCCESS); - return nvals; + return GraphStatistics_EdgeCount(&g->stats, relation); } uint Graph_DeletedEdgeCount(const Graph *g) { @@ -539,13 +530,26 @@ RelationID Graph_GetEdgeRelation GrB_Index dst; for(uint i = 0; i < n; i++) { EdgeID edgeId = 0; - Delta_Matrix out = Graph_OutgoingRelationMatrix(g, i); - info = Delta_Matrix_extractElement_UINT64(&dst, out, src_id, id); + Delta_Matrix M = Graph_GetRelationMatrix(g, i, false); + info = Delta_Matrix_extractElement_UINT64(&edgeId, M, src_id, dest_id); if(info != GrB_SUCCESS) continue; - ASSERT(dst == dest_id); - Edge_SetRelationID(e, i); - rel = i; - break; + + if(SINGLE_EDGE(edgeId)) { + EdgeID curEdgeID = edgeId; + if(curEdgeID == id) { + Edge_SetRelationID(e, i); + rel = i; + break; + } + } else { + Delta_Matrix me = Graph_MultiEdgeRelationMatrix(g, i); + GrB_Index me_id = CLEAR_MSB(edgeId); + if(Delta_Matrix_extractElement_BOOL(NULL, me, me_id, id) == GrB_SUCCESS) { + Edge_SetRelationID(e, i); + rel = i; + break; + } + } } // we must be able to find edge relation @@ -735,22 +739,30 @@ void Graph_FormConnection GrB_Info info; UNUSED(info); Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); - Delta_Matrix out = Graph_OutgoingRelationMatrix(g, r); - Delta_Matrix in = Graph_IncomingRelationMatrix(g, r); + Delta_Matrix me = Graph_MultiEdgeRelationMatrix(g, r); Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); // rows represent source nodes, columns represent destination nodes info = Delta_Matrix_setElement_BOOL(adj, src, dest); ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_setElement_BOOL(M, src, dest); - ASSERT(info == GrB_SUCCESS); - - info = Delta_Matrix_setElement_UINT64(out, dest, src, edge_id); - ASSERT(info == GrB_SUCCESS); - - info = Delta_Matrix_setElement_UINT64(in, src, dest, edge_id); - ASSERT(info == GrB_SUCCESS); + GrB_Index current_edge; + info = Delta_Matrix_extractElement_UINT64(¤t_edge, M, src, dest); + if(info == GrB_NO_VALUE) { + info = Delta_Matrix_setElement_UINT64(M, edge_id, src, dest); + ASSERT(info == GrB_SUCCESS); + } else if(SINGLE_EDGE(current_edge)) { + GrB_Index meid = g->relations[r].me_id++; + info = Delta_Matrix_setElement_UINT64(M, SET_MSB(meid), src, dest); + ASSERT(info == GrB_SUCCESS); + info = Delta_Matrix_setElement_BOOL(me, meid, current_edge); + ASSERT(info == GrB_SUCCESS); + info = Delta_Matrix_setElement_BOOL(me, meid, edge_id); + ASSERT(info == GrB_SUCCESS); + } else { + info = Delta_Matrix_setElement_BOOL(me, CLEAR_MSB(current_edge), edge_id); + ASSERT(info == GrB_SUCCESS); + } } void Graph_CreateEdge @@ -798,26 +810,40 @@ void _GetOutgoingNodeEdges GrB_Info info; Delta_MatrixTupleIter it = {0}; - Delta_Matrix out = NULL; + Delta_Matrix M = NULL; NodeID src_id = ENTITY_GET_ID(n); NodeID dest_id = INVALID_ENTITY_ID; EdgeID edge_id = INVALID_ENTITY_ID; UNUSED(info); - out = Graph_OutgoingRelationMatrix(g, edgeType); + M = Graph_GetRelationMatrix(g, edgeType, false); - info = Delta_MatrixTupleIter_AttachRange(&it, out, src_id, src_id); + info = Delta_MatrixTupleIter_AttachRange(&it, M, src_id, src_id); ASSERT(info == GrB_SUCCESS); - while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &edge_id, &dest_id) == GrB_SUCCESS) { + while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &dest_id, &edge_id) == GrB_SUCCESS) { Edge e = {0}; e.src_id = src_id; e.dest_id = dest_id; - e.id = edge_id; e.relationID = edgeType; - e.attributes = DataBlock_GetItem(g->edges, edge_id); - ASSERT(e.attributes); - array_append(*edges, e); + if(SINGLE_EDGE(edge_id)) { + e.id = edge_id; + e.attributes = DataBlock_GetItem(g->edges, edge_id); + ASSERT(e.attributes); + array_append(*edges, e); + } else { + Delta_Matrix me = Graph_MultiEdgeRelationMatrix(g, e.relationID); + GrB_Index me_id = CLEAR_MSB(edge_id); + Delta_MatrixTupleIter me_it; + Delta_MatrixTupleIter_AttachRange(&me_it, me, me_id, me_id); + + while(Delta_MatrixTupleIter_next_BOOL(&me_it, NULL, &edge_id, NULL) == GrB_SUCCESS) { + e.id = edge_id; + e.attributes = DataBlock_GetItem(g->edges, edge_id); + ASSERT(e.attributes); + array_append(*edges, e); + } + } } info = Delta_MatrixTupleIter_detach(&it); ASSERT(info == GrB_SUCCESS); @@ -838,26 +864,41 @@ void _GetIncomingNodeEdges GrB_Info info; Delta_MatrixTupleIter it = {0}; - Delta_Matrix in = NULL; + Delta_Matrix M = NULL; NodeID src_id = INVALID_ENTITY_ID; NodeID dest_id = ENTITY_GET_ID(n); EdgeID edge_id = INVALID_ENTITY_ID; UNUSED(info); - in = Graph_IncomingRelationMatrix(g, edgeType); + M = Graph_GetRelationMatrix(g, edgeType, true); - info = Delta_MatrixTupleIter_AttachRange(&it, in, dest_id, dest_id); + info = Delta_MatrixTupleIter_AttachRange(&it, M, dest_id, dest_id); ASSERT(info == GrB_SUCCESS); - while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &edge_id, &src_id) == GrB_SUCCESS) { - if(dir == GRAPH_EDGE_DIR_BOTH && src_id == dest_id) continue; + while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &src_id, &edge_id) == GrB_SUCCESS) { Edge e = {0}; e.src_id = src_id; e.dest_id = dest_id; - e.id = edge_id; e.relationID = edgeType; - e.attributes = DataBlock_GetItem(g->edges, edge_id); - ASSERT(e.attributes); - array_append(*edges, e); + if(SINGLE_EDGE(edge_id)) { + if(dir == GRAPH_EDGE_DIR_BOTH && src_id == dest_id) continue; + e.id = edge_id; + e.attributes = DataBlock_GetItem(g->edges, edge_id); + ASSERT(e.attributes); + array_append(*edges, e); + } else { + Delta_Matrix me = Graph_MultiEdgeRelationMatrix(g, e.relationID); + GrB_Index me_id = CLEAR_MSB(edge_id); + Delta_MatrixTupleIter me_it; + Delta_MatrixTupleIter_AttachRange(&me_it, me, me_id, me_id); + + while(Delta_MatrixTupleIter_next_BOOL(&me_it, NULL, &edge_id, NULL) == GrB_SUCCESS) { + if(dir == GRAPH_EDGE_DIR_BOTH && src_id == dest_id) continue; + e.id = edge_id; + e.attributes = DataBlock_GetItem(g->edges, edge_id); + ASSERT(e.attributes); + array_append(*edges, e); + } + } } info = Delta_MatrixTupleIter_detach(&it); ASSERT(info == GrB_SUCCESS); @@ -926,8 +967,10 @@ uint64_t Graph_GetNodeDegree EdgeID edgeID = INVALID_ENTITY_ID; uint64_t edge_count = 0; Delta_Matrix out = NULL; + Delta_Matrix me = NULL; Delta_Matrix in = NULL; Delta_MatrixTupleIter it = {0}; + Delta_MatrixTupleIter me_it = {0}; if(edgeType == GRAPH_UNKNOWN_RELATION) { return 0; // no edges @@ -960,14 +1003,26 @@ uint64_t Graph_GetNodeDegree //---------------------------------------------------------------------- if(outgoing) { - out = Graph_OutgoingRelationMatrix(g, edgeType); + out = Graph_GetRelationMatrix(g, edgeType, false); + me = Graph_MultiEdgeRelationMatrix(g, edgeType); // construct an iterator to traverse over the source node row, // containing all outgoing edges Delta_MatrixTupleIter_AttachRange(&it, out, srcID, srcID); // scan row - while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, NULL) + while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, &edgeID) == GrB_SUCCESS) { - edge_count++; + // check for edge type single/multi + if(SINGLE_EDGE(edgeID)) { + edge_count++; + } else { + EdgeID me_id = CLEAR_MSB(edgeID); + Delta_MatrixTupleIter me_it; + Delta_MatrixTupleIter_AttachRange(&me_it, me, me_id, me_id); + while(Delta_MatrixTupleIter_next_BOOL(&me_it, NULL, NULL, NULL) == GrB_SUCCESS) { + edge_count++; + } + Delta_MatrixTupleIter_detach(&me_it); + } } Delta_MatrixTupleIter_detach(&it); } @@ -977,14 +1032,26 @@ uint64_t Graph_GetNodeDegree //---------------------------------------------------------------------- if(incoming) { - in = Graph_IncomingRelationMatrix(g, edgeType); + in = Graph_GetRelationMatrix(g, edgeType, true); + me = Graph_MultiEdgeRelationMatrix(g, edgeType); // construct an iterator to traverse over the source node row, // containing all incoming edges Delta_MatrixTupleIter_AttachRange(&it, in, srcID, srcID); // scan row - while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, NULL) + while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, &edgeID) == GrB_SUCCESS) { - edge_count++; + // check for edge type single/multi + if(SINGLE_EDGE(edgeID)) { + edge_count++; + } else { + EdgeID me_id = CLEAR_MSB(edgeID); + Delta_MatrixTupleIter me_it; + Delta_MatrixTupleIter_AttachRange(&me_it, me, me_id, me_id); + while(Delta_MatrixTupleIter_next_BOOL(&me_it, NULL, NULL, NULL) == GrB_SUCCESS) { + edge_count++; + } + Delta_MatrixTupleIter_detach(&me_it); + } } Delta_MatrixTupleIter_detach(&it); } @@ -1043,9 +1110,8 @@ void Graph_DeleteEdges ASSERT(edges != NULL); GrB_Info info; - Delta_Matrix R; - Delta_Matrix out; - Delta_Matrix in; + Delta_Matrix M; + Delta_Matrix ME; MATRIX_POLICY policy = Graph_SetMatrixPolicy(g, SYNC_POLICY_NOP); @@ -1058,66 +1124,60 @@ void Graph_DeleteEdges ASSERT(!DataBlock_ItemIsDeleted((void *)e->attributes)); - out = Graph_OutgoingRelationMatrix(g, r); - in = Graph_IncomingRelationMatrix(g, r); + M = Graph_GetRelationMatrix(g, r, false); + ME = Graph_MultiEdgeRelationMatrix(g, r); - info = Delta_Matrix_removeElement(out, src_id, edge_id); - ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_removeElement(in, dest_id, edge_id); + GrB_Index me_id; + info = Delta_Matrix_extractElement_UINT64(&me_id, M, src_id, dest_id); ASSERT(info == GrB_SUCCESS); - // free and remove edges from datablock. - DataBlock_DeleteItem(g->edges, edge_id); - } - - for (uint i = 0; i < n; i++) { - Edge *e = edges + i; - int r = Edge_GetRelationID(e); - NodeID src_id = Edge_GetSrcNodeID(e); - NodeID dest_id = Edge_GetDestNodeID(e); - EdgeID edge_id = ENTITY_GET_ID(e); - - out = Graph_OutgoingRelationMatrix(g, r); + if(SINGLE_EDGE(me_id)) { + info = Delta_Matrix_removeElement(M, src_id, dest_id); + ASSERT(info == GrB_SUCCESS); + } else { + info = Delta_Matrix_removeElement(ME, CLEAR_MSB(me_id), edge_id); + ASSERT(info == GrB_SUCCESS); - Delta_MatrixTupleIter it = {0}; - Delta_MatrixTupleIter_AttachRange(&it, out, src_id, src_id); - GrB_Index dst; - bool connected = false; - while (Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, &dst) == GrB_SUCCESS) { - if(dst == dest_id) { + Delta_MatrixTupleIter it = {0}; + Delta_MatrixTupleIter_AttachRange(&it, ME, CLEAR_MSB(me_id), CLEAR_MSB(me_id)); + GrB_Index dst; + bool connected = false; + while (Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, &dst) == GrB_SUCCESS) { connected = true; break; } - } - if(!connected) { - R = Graph_GetRelationMatrix(g, r, false); - // no more edges connecting src to other nodes - // remove src from relation matrix - info = Delta_Matrix_removeElement(R, src_id, dest_id); - ASSERT(info == GrB_SUCCESS); + if(!connected) { + // no more edges connecting src to other nodes + // remove src from relation matrix + info = Delta_Matrix_removeElement(M, src_id, dest_id); + ASSERT(info == GrB_SUCCESS); - // see if source is connected to destination with additional edges - connected = false; - int relationCount = Graph_RelationTypeCount(g); - for(int j = 0; j < relationCount; j++) { - if(j == r) continue; - Delta_Matrix r = Graph_GetRelationMatrix(g, j, false); - info = Delta_Matrix_extractElement_BOOL(NULL, r, src_id, dest_id); - if(info == GrB_SUCCESS) { - connected = true; - break; + // see if source is connected to destination with additional edges + connected = false; + int relationCount = Graph_RelationTypeCount(g); + for(int j = 0; j < relationCount; j++) { + if(j == r) continue; + Delta_Matrix r = Graph_GetRelationMatrix(g, j, false); + info = Delta_Matrix_extractElement_BOOL(NULL, r, src_id, dest_id); + if(info == GrB_SUCCESS) { + connected = true; + break; + } } - } - // there are no additional edges connecting source to destination - // remove edge from THE adjacency matrix - if(!connected) { - Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); - info = Delta_Matrix_removeElement(adj, src_id, dest_id); - ASSERT(info == GrB_SUCCESS); + // there are no additional edges connecting source to destination + // remove edge from THE adjacency matrix + if(!connected) { + Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); + info = Delta_Matrix_removeElement(adj, src_id, dest_id); + ASSERT(info == GrB_SUCCESS); + } } } + + // free and remove edges from datablock. + DataBlock_DeleteItem(g->edges, edge_id); } Graph_SetMatrixPolicy(g, policy); @@ -1143,8 +1203,8 @@ static void _Graph_FreeRelationMatrices for(uint i = 0; i < relationCount; i++) { RelationMatrices *r = g->relations + i; Delta_Matrix_free(&r->R); - Delta_Matrix_free(&r->Out); - Delta_Matrix_free(&r->In); + Delta_Matrix_free(&r->ME); + array_free(&r->me_deleted_ids); } } @@ -1170,6 +1230,8 @@ LabelID Graph_AddLabel Delta_Matrix_new(&m, GrB_BOOL, n, n, false); array_append(g->labels, m); + // adding a new label, update the stats structures to support it + GraphStatistics_IntroduceLabel(&g->stats); LabelID l = Graph_LabelTypeCount(g) - 1; return l; @@ -1204,11 +1266,14 @@ RelationID Graph_AddRelationType size_t n = Graph_RequiredMatrixDim(g); size_t edge_cap = g->edges->itemCap; - Delta_Matrix_new(&r.R, GrB_BOOL, n, n, true); - Delta_Matrix_new(&r.Out, GrB_UINT64, n, edge_cap, false); - Delta_Matrix_new(&r.In, GrB_UINT64, n, edge_cap, false); + Delta_Matrix_new(&r.R, GrB_UINT64, n, n, true); + Delta_Matrix_new(&r.ME, GrB_BOOL, n, edge_cap, false); + r.me_id = 0; + r.me_deleted_ids = array_new(uint64_t, 0); array_append(g->relations, r); + // adding a new relationship type, update the stats structures to support it + GraphStatistics_IntroduceRelationship(&g->stats); RelationID relationID = Graph_RelationTypeCount(g) - 1; return relationID; @@ -1228,8 +1293,8 @@ void Graph_RemoveRelation ASSERT(nvals == 0); #endif Delta_Matrix_free(&g->relations[relation_id].R); - Delta_Matrix_free(&g->relations[relation_id].Out); - Delta_Matrix_free(&g->relations[relation_id].In); + Delta_Matrix_free(&g->relations[relation_id].ME); + array_free(&g->relations[relation_id].me_deleted_ids); g->relations = array_del(g->relations, relation_id); } @@ -1277,34 +1342,17 @@ Delta_Matrix Graph_GetRelationMatrix return m; } -Delta_Matrix Graph_OutgoingRelationMatrix -( - const Graph *g, - RelationID relation_idx -) { - ASSERT(relation_idx != GRAPH_NO_RELATION); - - Delta_Matrix m = g->relations[relation_idx].Out; - - size_t node_cap = g->nodes->itemCap; - size_t edge_cap = g->edges->itemCap; - g->SynchronizeMatrix(g, m, node_cap, edge_cap); - - return m; -} - -Delta_Matrix Graph_IncomingRelationMatrix +Delta_Matrix Graph_MultiEdgeRelationMatrix ( const Graph *g, RelationID relation_idx ) { ASSERT(relation_idx != GRAPH_NO_RELATION); - Delta_Matrix m = g->relations[relation_idx].In; + Delta_Matrix m = g->relations[relation_idx].ME; - size_t node_cap = g->nodes->itemCap; size_t edge_cap = g->edges->itemCap; - g->SynchronizeMatrix(g, m, node_cap, edge_cap); + g->SynchronizeMatrix(g, m, edge_cap, edge_cap); return m; } @@ -1381,6 +1429,7 @@ static void _Graph_Free _Graph_FreeRelationMatrices(g); array_free(g->relations); + GraphStatistics_FreeInternals(&g->stats); uint32_t labelCount = array_len(g->labels); for(int i = 0; i < labelCount; i++) Delta_Matrix_free(&g->labels[i]); diff --git a/src/graph/graph.h b/src/graph/graph.h index e70adffb7..8f71061f4 100644 --- a/src/graph/graph.h +++ b/src/graph/graph.h @@ -12,6 +12,7 @@ #include "entities/node.h" #include "entities/edge.h" #include "../redismodule.h" +#include "graph_statistics.h" #include "delta_matrix/delta_matrix.h" #include "../util/datablock/datablock.h" #include "../util/datablock/datablock_iterator.h" @@ -43,13 +44,13 @@ typedef struct Graph Graph; typedef void (*SyncMatrixFunc)(const Graph *, Delta_Matrix, GrB_Index, GrB_Index); // A relation type is defined via three matrices: -// 1. boolean connecting source nodes to destination nodes -// 2. Outgoing, O[s,e] = d indicating an outgoing edge e from s to d -// 3. Incoming, I[d,e] = s indicating an incoming edge e from s to d +// 1. uint64 connecting source nodes to destination nodes +// 2. multi-edge, O[meid,e] = true typedef struct { - Delta_Matrix R; // relation matrix - Delta_Matrix Out; // Outgoing matrix - Delta_Matrix In; // Incoming matrix + Delta_Matrix R; // relation matrix + Delta_Matrix ME; // multi-edge matrix + uint64_t me_id; // multi-edge id + uint64_t *me_deleted_ids; // multi-edge deleted ids } RelationMatrices; struct Graph { @@ -64,6 +65,7 @@ struct Graph { pthread_rwlock_t _rwlock; // read-write lock scoped to this specific graph bool _writelocked; // true if the read-write lock was acquired by a writer SyncMatrixFunc SynchronizeMatrix; // function pointer to matrix synchronization routine + GraphStatistics stats; // graph related statistics }; // graph synchronization functions @@ -416,24 +418,12 @@ Delta_Matrix Graph_GetRelationMatrix bool transposed ); -// retrieves a relation specific outgoing edges matrix O[s,e] = d -// where s is a source node, e is an edge ID d is a destination node (s)-[e]->(d) -// this function will sync the matrix according to the set synchronisation policy -Delta_Matrix Graph_OutgoingRelationMatrix +Delta_Matrix Graph_MultiEdgeRelationMatrix ( const Graph *g, // graph from which to get adjacency matrix RelationID relation_idx // relation described by matrix ); -// retrieves a relation specific incoming edges matrix O[d,e] = s -// where s is a source node, e is an edge ID d is a destination node (s)-[e]->(d) -// this function will sync the matrix according to the set synchronisation policy -Delta_Matrix Graph_IncomingRelationMatrix -( - const Graph *g, // graph from which to get adjacency matrix - RelationID relation_idx // relation described by matrix -); - // retrieves the node-label mapping matrix, // matrix is resized if its size doesn't match graph's node count. Delta_Matrix Graph_GetNodeLabelMatrix diff --git a/src/graph/graph_statistics.c b/src/graph/graph_statistics.c new file mode 100644 index 000000000..2ff0da68b --- /dev/null +++ b/src/graph/graph_statistics.c @@ -0,0 +1,72 @@ +/* + * Copyright Redis Ltd. 2018 - present + * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or + * the Server Side Public License v1 (SSPLv1). + */ + +#include "graph_statistics.h" + +// Initialize the node_count and edge_count arrays +void GraphStatistics_init +( + GraphStatistics *stats +) { + ASSERT(stats); + stats->node_count = array_new(uint64_t, 0); + stats->edge_count = array_new(uint64_t, 0); +} + +void GraphStatistics_IntroduceRelationship +( + GraphStatistics *stats +) { + ASSERT(stats && stats->edge_count); + array_append(stats->edge_count, 0); +} + +void GraphStatistics_IntroduceLabel +( + GraphStatistics *stats +) { + ASSERT(stats && stats->node_count); + array_append(stats->node_count, 0); +} + +uint64_t GraphStatistics_EdgeCount +( + const GraphStatistics *stats, + RelationID r +) { + ASSERT(stats != NULL); + ASSERT(r < ((RelationID)array_len(stats->edge_count))); + + if(r < 0) { + return 0; + } + + return stats->edge_count[r]; +} + +uint64_t GraphStatistics_NodeCount +( + const GraphStatistics *stats, + LabelID l +) { + ASSERT(stats != NULL); + ASSERT(l < ((LabelID)array_len(stats->node_count))); + + if(l < 0) { + return 0; + } + + return stats->node_count[l]; +} + +void GraphStatistics_FreeInternals +( + GraphStatistics *stats +) { + ASSERT(stats); + if(stats->node_count) array_free(stats->node_count); + if(stats->edge_count) array_free(stats->edge_count); +} diff --git a/src/graph/graph_statistics.h b/src/graph/graph_statistics.h new file mode 100644 index 000000000..061f9755f --- /dev/null +++ b/src/graph/graph_statistics.h @@ -0,0 +1,101 @@ +/* + * Copyright Redis Ltd. 2018 - present + * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or + * the Server Side Public License v1 (SSPLv1). + */ + +#pragma once + +#include +#include "../util/arr.h" +#include "entities/node.h" +#include "entities/edge.h" + +// graph related statistics + +typedef struct { + uint64_t *node_count; // array of node count per label matrix + uint64_t *edge_count; // array of edge count per relationship matrix +} GraphStatistics; + +// initialize the node_count and edge_count arrays +void GraphStatistics_init +( + GraphStatistics *stats +); + +// new relationship is added, resize the edge_count array +void GraphStatistics_IntroduceRelationship +( + GraphStatistics *stats +); + +// new label is added, resize the node_count array +void GraphStatistics_IntroduceLabel +( + GraphStatistics *stats +); + +// increment the edge counter by amount +static inline void GraphStatistics_IncEdgeCount +( + GraphStatistics *stats, + RelationID r, + uint64_t amount +) { + ASSERT(r < array_len(stats->edge_count)); + stats->edge_count[r] += amount; +} + +// decrement the edge counter by amount +static inline void GraphStatistics_DecEdgeCount +( + GraphStatistics *stats, + RelationID r, + uint64_t amount +) { + ASSERT(r < array_len(stats->edge_count) && stats->edge_count[r] >= amount); + stats->edge_count[r] -= amount; +} + +// increment the node counter by amount +static inline void GraphStatistics_IncNodeCount +( + GraphStatistics *stats, + LabelID l, + uint64_t amount +) { + ASSERT(l < array_len(stats->node_count)); + stats->node_count[l] += amount; +} + +// decrement the node counter by amount +static inline void GraphStatistics_DecNodeCount +( + GraphStatistics *stats, + int l, + uint64_t amount +) { + ASSERT(l < array_len(stats->node_count) && stats->node_count[l] >= amount); + stats->node_count[l] -= amount; +} + +// retrieves edge count for given relationship type +uint64_t GraphStatistics_EdgeCount +( + const GraphStatistics *stats, + RelationID r +); + +// retrieves node count for given label +uint64_t GraphStatistics_NodeCount +( + const GraphStatistics *stats, + LabelID l +); + +// free the internal structures +void GraphStatistics_FreeInternals +( + GraphStatistics *stats +); diff --git a/src/index/index_construct.c b/src/index/index_construct.c index 8d667dcd6..99360c574 100644 --- a/src/index/index_construct.c +++ b/src/index/index_construct.c @@ -122,7 +122,7 @@ static void _Index_PopulateEdgeIndex EntityID dest_id = 0; // current processed column idx EntityID edge_id = 0; // current processed edge id EntityID prev_src_id = 0; // last processed row idx - EntityID prev_edge_id = 0; // last processed column idx + EntityID prev_dest_id = 0; // last processed column idx int indexed = 0; // number of entities indexed in current batch int batch_size = 1000; // max number of entities to index in one go Delta_MatrixTupleIter it = {0}; @@ -142,25 +142,27 @@ static void _Index_PopulateEdgeIndex // reset number of indexed edges in batch indexed = 0; prev_src_id = src_id; - prev_edge_id = edge_id; + prev_dest_id = dest_id; // fetch relation matrix - int label_id = Index_GetLabelID(idx); - Delta_Matrix out = Graph_OutgoingRelationMatrix(g, label_id); - ASSERT(out != NULL); + const Delta_Matrix m = Graph_GetRelationMatrix(g, Index_GetLabelID(idx), + false); + ASSERT(m != NULL); //---------------------------------------------------------------------- // resume scanning from previous row/col indices //---------------------------------------------------------------------- - info = Delta_MatrixTupleIter_AttachRange(&it, out, src_id, UINT64_MAX); + info = Delta_MatrixTupleIter_attach(&it, m); + ASSERT(info == GrB_SUCCESS); + info = Delta_MatrixTupleIter_iterate_range(&it, src_id, UINT64_MAX); ASSERT(info == GrB_SUCCESS); // skip previously indexed edges - while((info = Delta_MatrixTupleIter_next_UINT64(&it, &src_id, &edge_id, - &dest_id)) == GrB_SUCCESS && + while((info = Delta_MatrixTupleIter_next_UINT64(&it, &src_id, &dest_id, + &edge_id)) == GrB_SUCCESS && src_id == prev_src_id && - edge_id < prev_edge_id); + dest_id < prev_dest_id); // process only if iterator is on an active entry if(info != GrB_SUCCESS) { @@ -175,13 +177,27 @@ static void _Index_PopulateEdgeIndex Edge e; e.src_id = src_id; e.dest_id = dest_id; - e.relationID = label_id; - Graph_GetEdge(g, edge_id, &e); - Index_IndexEdge(idx, &e); - - indexed++; + e.relationID = Index_GetLabelID(idx); + + if(SINGLE_EDGE(edge_id)) { + Graph_GetEdge(g, edge_id, &e); + Index_IndexEdge(idx, &e); + } else { + Delta_Matrix me = Graph_MultiEdgeRelationMatrix(g, e.relationID); + GrB_Index me_id = CLEAR_MSB(edge_id); + Delta_MatrixTupleIter me_it; + Delta_MatrixTupleIter_AttachRange(&me_it, me, me_id, me_id); + + while(Delta_MatrixTupleIter_next_BOOL(&me_it, NULL, &edge_id, NULL) == GrB_SUCCESS) { + Graph_GetEdge(g, edge_id, &e); + Index_IndexEdge(idx, &e); + } + + Delta_MatrixTupleIter_detach(&me_it); + } + indexed++; // single/multi edge are counted similarly } while(indexed < batch_size && - Delta_MatrixTupleIter_next_UINT64(&it, &src_id, &edge_id, &dest_id) + Delta_MatrixTupleIter_next_UINT64(&it, &src_id, &dest_id, &edge_id) == GrB_SUCCESS); //---------------------------------------------------------------------- @@ -224,4 +240,3 @@ void Index_Populate _Index_PopulateEdgeIndex(idx, g); } } - diff --git a/src/index/index_edge.c b/src/index/index_edge.c index 9c974c6b0..a15307ce9 100644 --- a/src/index/index_edge.c +++ b/src/index/index_edge.c @@ -9,7 +9,6 @@ #include "../query_ctx.h" #include "../graph/graphcontext.h" #include "../graph/entities/edge.h" -#include "../graph/delta_matrix/delta_matrix_iter.h" extern RSDoc *Index_IndexGraphEntity(Index idx,const GraphEntity *e, const void *key, size_t key_len, uint *doc_field_count); diff --git a/src/index/index_node.c b/src/index/index_node.c index 393fe7c41..9f8b07e0d 100644 --- a/src/index/index_node.c +++ b/src/index/index_node.c @@ -9,7 +9,6 @@ #include "../value.h" #include "../query_ctx.h" #include "../graph/graphcontext.h" -#include "../graph/delta_matrix/delta_matrix_iter.h" extern RSDoc *Index_IndexGraphEntity(Index idx, const GraphEntity *e, const void *key, size_t key_len, uint *doc_field_count); diff --git a/src/serializers/decode_context.c b/src/serializers/decode_context.c index ae167ea6c..d40ede899 100644 --- a/src/serializers/decode_context.c +++ b/src/serializers/decode_context.c @@ -15,6 +15,7 @@ GraphDecodeContext *GraphDecodeContext_New() { ctx->keys_processed = 0; ctx->graph_keys_count = 1; ctx->meta_keys = raxNew(); + ctx->multi_edge = NULL; return ctx; } @@ -23,6 +24,11 @@ void GraphDecodeContext_Reset(GraphDecodeContext *ctx) { ctx->keys_processed = 0; ctx->graph_keys_count = 1; + + if(ctx->multi_edge) { + array_free(ctx->multi_edge); + ctx->multi_edge = NULL; + } } void GraphDecodeContext_SetKeyCount(GraphDecodeContext *ctx, uint64_t key_count) { @@ -71,6 +77,11 @@ void GraphDecodeContext_Free(GraphDecodeContext *ctx) { if(ctx) { raxFree(ctx->meta_keys); + if(ctx->multi_edge) { + array_free(ctx->multi_edge); + ctx->multi_edge = NULL; + } + rm_free(ctx); } } diff --git a/src/serializers/decode_context.h b/src/serializers/decode_context.h index a99e7012c..202e2b1d9 100644 --- a/src/serializers/decode_context.h +++ b/src/serializers/decode_context.h @@ -16,6 +16,7 @@ typedef struct { uint64_t keys_processed; // Count the number of procssed graph keys. uint64_t graph_keys_count; // The number of keys representing the graph. rax *meta_keys; // The meta keys encountered so far in the decode process. + uint64_t *multi_edge; // Is relation contains multi edge values. } GraphDecodeContext; // Creates a new graph decoding context. diff --git a/src/serializers/decoders/current/v14/decode_graph.c b/src/serializers/decoders/current/v14/decode_graph.c index 806ecdef4..fe75ea175 100644 --- a/src/serializers/decoders/current/v14/decode_graph.c +++ b/src/serializers/decoders/current/v14/decode_graph.c @@ -76,9 +76,10 @@ static GraphContext *_DecodeHeader uint64_t deleted_edge_count = SerializerIO_ReadUnsigned(rdb); uint64_t label_count = SerializerIO_ReadUnsigned(rdb); uint64_t relation_count = SerializerIO_ReadUnsigned(rdb); + uint64_t multi_edge[relation_count]; for(uint i = 0; i < relation_count; i++) { - SerializerIO_ReadUnsigned(rdb); + multi_edge[i] = SerializerIO_ReadUnsigned(rdb); } // total keys representing the graph @@ -96,6 +97,14 @@ static GraphContext *_DecodeHeader _InitGraphDataStructure(gc->g, node_count, edge_count, deleted_node_count, deleted_edge_count, label_count, relation_count); + gc->decoding_context->multi_edge = array_new(uint64_t, relation_count); + for(uint i = 0; i < relation_count; i++) { + // enable/Disable support for multi-edge + // we will enable support for multi-edge on all relationship + // matrices once we finish loading the graph + array_append(gc->decoding_context->multi_edge, multi_edge[i]); + } + GraphDecodeContext_SetKeyCount(gc->decoding_context, key_number); } @@ -211,8 +220,13 @@ GraphContext *RdbLoadGraphContext_latest uint rel_count = Graph_RelationTypeCount(g); uint label_count = Graph_LabelTypeCount(g); - // enable node indices + // update the node statistics, enable node indices for(uint i = 0; i < label_count; i++) { + GrB_Index nvals; + Delta_Matrix L = Graph_GetLabelMatrix(g, i); + Delta_Matrix_nvals(&nvals, L); + GraphStatistics_IncNodeCount(&g->stats, i, nvals); + Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); idx = PENDING_IDX(s); @@ -241,4 +255,3 @@ GraphContext *RdbLoadGraphContext_latest return gc; } - diff --git a/src/serializers/decoders/current/v14/decode_graph_entities.c b/src/serializers/decoders/current/v14/decode_graph_entities.c index b30c2fc06..e70b44cf9 100644 --- a/src/serializers/decoders/current/v14/decode_graph_entities.c +++ b/src/serializers/decoders/current/v14/decode_graph_entities.c @@ -201,7 +201,8 @@ void RdbLoadEdges_v14 NodeID destId = SerializerIO_ReadUnsigned(rdb); uint64_t relation = SerializerIO_ReadUnsigned(rdb); - Serializer_Graph_SetEdge(gc->g, edgeId, srcId, destId, relation, &e); + Serializer_Graph_SetEdge(gc->g, gc->decoding_context->multi_edge[relation], + edgeId, srcId, destId, relation, &e); _RdbLoadEntity(rdb, gc, (GraphEntity *)&e); // index edge diff --git a/src/serializers/decoders/prev/v10/decode_graph.c b/src/serializers/decoders/prev/v10/decode_graph.c index 545887a76..787669209 100644 --- a/src/serializers/decoders/prev/v10/decode_graph.c +++ b/src/serializers/decoders/prev/v10/decode_graph.c @@ -57,9 +57,10 @@ static GraphContext *_DecodeHeader(RedisModuleIO *rdb) { uint64_t edge_count = RedisModule_LoadUnsigned(rdb); uint64_t label_count = RedisModule_LoadUnsigned(rdb); uint64_t relation_count = RedisModule_LoadUnsigned(rdb); + uint64_t multi_edge[relation_count]; for(uint i = 0; i < relation_count; i++) { - RedisModule_LoadUnsigned(rdb); + multi_edge[i] = RedisModule_LoadUnsigned(rdb); } // Total keys representing the graph. @@ -73,6 +74,14 @@ static GraphContext *_DecodeHeader(RedisModuleIO *rdb) { if(GraphDecodeContext_GetProcessedKeyCount(gc->decoding_context) == 0) { _InitGraphDataStructure(g, node_count, edge_count, label_count, relation_count); + gc->decoding_context->multi_edge = array_new(uint64_t, relation_count); + for(uint i = 0; i < relation_count; i++) { + // Enable/Disable support for multi-edge + // we will enable support for multi-edge on all relationship + // matrices once we finish loading the graph + array_append(gc->decoding_context->multi_edge, multi_edge[i]); + } + GraphDecodeContext_SetKeyCount(gc->decoding_context, key_number); } @@ -190,8 +199,13 @@ GraphContext *RdbLoadGraphContext_v10(RedisModuleIO *rdb) { uint rel_count = Graph_RelationTypeCount(g); uint label_count = Graph_LabelTypeCount(g); - // enable node indices + // update the node statistics, enable node indices for(uint i = 0; i < label_count; i++) { + GrB_Index nvals; + Delta_Matrix L = Graph_GetLabelMatrix(g, i); + Delta_Matrix_nvals(&nvals, L); + GraphStatistics_IncNodeCount(&g->stats, i, nvals); + Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); idx = PENDING_IDX(s); diff --git a/src/serializers/decoders/prev/v10/decode_graph_entities.c b/src/serializers/decoders/prev/v10/decode_graph_entities.c index c0c03649c..59b70e733 100644 --- a/src/serializers/decoders/prev/v10/decode_graph_entities.c +++ b/src/serializers/decoders/prev/v10/decode_graph_entities.c @@ -142,7 +142,8 @@ void RdbLoadEdges_v10(RedisModuleIO *rdb, GraphContext *gc, uint64_t edge_count) NodeID srcId = RedisModule_LoadUnsigned(rdb); NodeID destId = RedisModule_LoadUnsigned(rdb); uint64_t relation = RedisModule_LoadUnsigned(rdb); - Serializer_Graph_SetEdge(gc->g, edgeId, srcId, destId, relation, &e); + Serializer_Graph_SetEdge(gc->g, gc->decoding_context->multi_edge[relation], + edgeId, srcId, destId, relation, &e); _RdbLoadEntity(rdb, gc, (GraphEntity *)&e); // index edge diff --git a/src/serializers/decoders/prev/v11/decode_graph.c b/src/serializers/decoders/prev/v11/decode_graph.c index ddfe73a6e..9baa703e9 100644 --- a/src/serializers/decoders/prev/v11/decode_graph.c +++ b/src/serializers/decoders/prev/v11/decode_graph.c @@ -85,6 +85,14 @@ static GraphContext *_DecodeHeader if(GraphDecodeContext_GetProcessedKeyCount(gc->decoding_context) == 0) { _InitGraphDataStructure(gc->g, node_count, edge_count, label_count, relation_count); + gc->decoding_context->multi_edge = array_new(uint64_t, relation_count); + for(uint i = 0; i < relation_count; i++) { + // enable/Disable support for multi-edge + // we will enable support for multi-edge on all relationship + // matrices once we finish loading the graph + array_append(gc->decoding_context->multi_edge, multi_edge[i]); + } + GraphDecodeContext_SetKeyCount(gc->decoding_context, key_number); } @@ -198,8 +206,13 @@ GraphContext *RdbLoadGraphContext_v11 uint rel_count = Graph_RelationTypeCount(g); uint label_count = Graph_LabelTypeCount(g); - // enable node indices + // update the node statistics, enable node indices for(uint i = 0; i < label_count; i++) { + GrB_Index nvals; + Delta_Matrix L = Graph_GetLabelMatrix(g, i); + Delta_Matrix_nvals(&nvals, L); + GraphStatistics_IncNodeCount(&g->stats, i, nvals); + Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); idx = PENDING_IDX(s); diff --git a/src/serializers/decoders/prev/v11/decode_graph_entities.c b/src/serializers/decoders/prev/v11/decode_graph_entities.c index fa604edcf..140b6cc79 100644 --- a/src/serializers/decoders/prev/v11/decode_graph_entities.c +++ b/src/serializers/decoders/prev/v11/decode_graph_entities.c @@ -167,7 +167,8 @@ void RdbLoadEdges_v11 NodeID srcId = RedisModule_LoadUnsigned(rdb); NodeID destId = RedisModule_LoadUnsigned(rdb); uint64_t relation = RedisModule_LoadUnsigned(rdb); - Serializer_Graph_SetEdge(gc->g, edgeId, srcId, destId, relation, &e); + Serializer_Graph_SetEdge(gc->g, gc->decoding_context->multi_edge[relation], + edgeId, srcId, destId, relation, &e); _RdbLoadEntity(rdb, gc, (GraphEntity *)&e); // index edge diff --git a/src/serializers/decoders/prev/v12/decode_graph.c b/src/serializers/decoders/prev/v12/decode_graph.c index cbc6c1a2e..f7f164668 100644 --- a/src/serializers/decoders/prev/v12/decode_graph.c +++ b/src/serializers/decoders/prev/v12/decode_graph.c @@ -74,9 +74,10 @@ static GraphContext *_DecodeHeader uint64_t deleted_edge_count = RedisModule_LoadUnsigned(rdb); uint64_t label_count = RedisModule_LoadUnsigned(rdb); uint64_t relation_count = RedisModule_LoadUnsigned(rdb); + uint64_t multi_edge[relation_count]; for(uint i = 0; i < relation_count; i++) { - RedisModule_LoadUnsigned(rdb); + multi_edge[i] = RedisModule_LoadUnsigned(rdb); } // total keys representing the graph @@ -91,6 +92,14 @@ static GraphContext *_DecodeHeader _InitGraphDataStructure(gc->g, node_count, edge_count, deleted_node_count, deleted_edge_count, label_count, relation_count); + gc->decoding_context->multi_edge = array_new(uint64_t, relation_count); + for(uint i = 0; i < relation_count; i++) { + // enable/Disable support for multi-edge + // we will enable support for multi-edge on all relationship + // matrices once we finish loading the graph + array_append(gc->decoding_context->multi_edge, multi_edge[i]); + } + GraphDecodeContext_SetKeyCount(gc->decoding_context, key_number); } @@ -205,8 +214,13 @@ GraphContext *RdbLoadGraphContext_v12 uint rel_count = Graph_RelationTypeCount(g); uint label_count = Graph_LabelTypeCount(g); - // enable node indices + // update the node statistics, enable node indices for(uint i = 0; i < label_count; i++) { + GrB_Index nvals; + Delta_Matrix L = Graph_GetLabelMatrix(g, i); + Delta_Matrix_nvals(&nvals, L); + GraphStatistics_IncNodeCount(&g->stats, i, nvals); + Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); idx = PENDING_IDX(s); diff --git a/src/serializers/decoders/prev/v12/decode_graph_entities.c b/src/serializers/decoders/prev/v12/decode_graph_entities.c index 51037f19f..3d1f2feb9 100644 --- a/src/serializers/decoders/prev/v12/decode_graph_entities.c +++ b/src/serializers/decoders/prev/v12/decode_graph_entities.c @@ -167,7 +167,8 @@ void RdbLoadEdges_v12 NodeID srcId = RedisModule_LoadUnsigned(rdb); NodeID destId = RedisModule_LoadUnsigned(rdb); uint64_t relation = RedisModule_LoadUnsigned(rdb); - Serializer_Graph_SetEdge(gc->g, edgeId, srcId, destId, relation, &e); + Serializer_Graph_SetEdge(gc->g, gc->decoding_context->multi_edge[relation], + edgeId, srcId, destId, relation, &e); _RdbLoadEntity(rdb, gc, (GraphEntity *)&e); // index edge diff --git a/src/serializers/decoders/prev/v13/decode_graph.c b/src/serializers/decoders/prev/v13/decode_graph.c index f39736e2b..6790468a7 100644 --- a/src/serializers/decoders/prev/v13/decode_graph.c +++ b/src/serializers/decoders/prev/v13/decode_graph.c @@ -76,9 +76,10 @@ static GraphContext *_DecodeHeader uint64_t deleted_edge_count = RedisModule_LoadUnsigned(rdb); uint64_t label_count = RedisModule_LoadUnsigned(rdb); uint64_t relation_count = RedisModule_LoadUnsigned(rdb); + uint64_t multi_edge[relation_count]; for(uint i = 0; i < relation_count; i++) { - RedisModule_LoadUnsigned(rdb); + multi_edge[i] = RedisModule_LoadUnsigned(rdb); } // total keys representing the graph @@ -96,6 +97,14 @@ static GraphContext *_DecodeHeader _InitGraphDataStructure(gc->g, node_count, edge_count, deleted_node_count, deleted_edge_count, label_count, relation_count); + gc->decoding_context->multi_edge = array_new(uint64_t, relation_count); + for(uint i = 0; i < relation_count; i++) { + // enable/Disable support for multi-edge + // we will enable support for multi-edge on all relationship + // matrices once we finish loading the graph + array_append(gc->decoding_context->multi_edge, multi_edge[i]); + } + GraphDecodeContext_SetKeyCount(gc->decoding_context, key_number); } @@ -211,8 +220,13 @@ GraphContext *RdbLoadGraphContext_v13 uint rel_count = Graph_RelationTypeCount(g); uint label_count = Graph_LabelTypeCount(g); - // enable node indices + // update the node statistics, enable node indices for(uint i = 0; i < label_count; i++) { + GrB_Index nvals; + Delta_Matrix L = Graph_GetLabelMatrix(g, i); + Delta_Matrix_nvals(&nvals, L); + GraphStatistics_IncNodeCount(&g->stats, i, nvals); + Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); idx = PENDING_IDX(s); diff --git a/src/serializers/decoders/prev/v13/decode_graph_entities.c b/src/serializers/decoders/prev/v13/decode_graph_entities.c index 5ebe09f99..a1e23edd0 100644 --- a/src/serializers/decoders/prev/v13/decode_graph_entities.c +++ b/src/serializers/decoders/prev/v13/decode_graph_entities.c @@ -169,7 +169,8 @@ void RdbLoadEdges_v13 NodeID destId = RedisModule_LoadUnsigned(rdb); uint64_t relation = RedisModule_LoadUnsigned(rdb); - Serializer_Graph_SetEdge(gc->g, edgeId, srcId, destId, relation, &e); + Serializer_Graph_SetEdge(gc->g, gc->decoding_context->multi_edge[relation], + edgeId, srcId, destId, relation, &e); _RdbLoadEntity(rdb, gc, (GraphEntity *)&e); // index edge diff --git a/src/serializers/decoders/prev/v9/decode_graph.c b/src/serializers/decoders/prev/v9/decode_graph.c index 9bdd90346..3a90b8e15 100644 --- a/src/serializers/decoders/prev/v9/decode_graph.c +++ b/src/serializers/decoders/prev/v9/decode_graph.c @@ -53,9 +53,10 @@ static GraphContext *_DecodeHeader(RedisModuleIO *rdb) { uint64_t edge_count = RedisModule_LoadUnsigned(rdb); uint64_t label_count = RedisModule_LoadUnsigned(rdb); uint64_t relation_count = RedisModule_LoadUnsigned(rdb); + uint64_t multi_edge[relation_count]; for(uint i = 0; i < relation_count; i++) { - RedisModule_LoadUnsigned(rdb); + multi_edge[i] = RedisModule_LoadUnsigned(rdb); } // Total keys representing the graph. @@ -69,6 +70,14 @@ static GraphContext *_DecodeHeader(RedisModuleIO *rdb) { if(GraphDecodeContext_GetProcessedKeyCount(gc->decoding_context) == 0) { _InitGraphDataStructure(g, node_count, edge_count, label_count, relation_count); + gc->decoding_context->multi_edge = array_new(uint64_t, relation_count); + for(uint i = 0; i < relation_count; i++) { + // Enable/Disable support for multi-edge + // we will enable support for multi-edge on all relationship + // matrices once we finish loading the graph + array_append(gc->decoding_context->multi_edge, multi_edge[i]); + } + GraphDecodeContext_SetKeyCount(gc->decoding_context, key_number); } @@ -179,11 +188,25 @@ GraphContext *RdbLoadGraphContext_v9(RedisModuleIO *rdb) { // revert to default synchronization behavior Graph_SetMatrixPolicy(g, SYNC_POLICY_FLUSH_RESIZE); + uint node_schemas_count = array_len(gc->node_schemas); + // update the node statistics + for(uint i = 0; i < node_schemas_count; i++) { + GrB_Index nvals; + Delta_Matrix L = g->labels[i]; + Delta_Matrix_nvals(&nvals, L); + GraphStatistics_IncNodeCount(&g->stats, i, nvals); + } + uint rel_count = Graph_RelationTypeCount(g); uint label_count = Graph_LabelTypeCount(g); - // enable node indices + // update the node statistics, enable node indices for(uint i = 0; i < label_count; i++) { + GrB_Index nvals; + Delta_Matrix L = Graph_GetLabelMatrix(g, i); + Delta_Matrix_nvals(&nvals, L); + GraphStatistics_IncNodeCount(&g->stats, i, nvals); + Index idx; Schema *s = GraphContext_GetSchemaByID(gc, i, SCHEMA_NODE); idx = PENDING_IDX(s); diff --git a/src/serializers/decoders/prev/v9/decode_graph_entities.c b/src/serializers/decoders/prev/v9/decode_graph_entities.c index 876ca68b6..90641c0a2 100644 --- a/src/serializers/decoders/prev/v9/decode_graph_entities.c +++ b/src/serializers/decoders/prev/v9/decode_graph_entities.c @@ -137,7 +137,8 @@ void RdbLoadEdges_v9(RedisModuleIO *rdb, GraphContext *gc, uint64_t edge_count) NodeID srcId = RedisModule_LoadUnsigned(rdb); NodeID destId = RedisModule_LoadUnsigned(rdb); uint64_t relation = RedisModule_LoadUnsigned(rdb); - Serializer_Graph_SetEdge(gc->g, edgeId, srcId, destId, relation, &e); + Serializer_Graph_SetEdge(gc->g, gc->decoding_context->multi_edge[relation], + edgeId, srcId, destId, relation, &e); _RdbLoadEntity(rdb, gc, (GraphEntity *)&e); } } diff --git a/src/serializers/encode_context.c b/src/serializers/encode_context.c index c2e7bbdb2..4bd605f88 100644 --- a/src/serializers/encode_context.c +++ b/src/serializers/encode_context.c @@ -43,6 +43,9 @@ void GraphEncodeContext_Reset(GraphEncodeContext *ctx) { ctx->offset = 0; ctx->keys_processed = 0; ctx->state = ENCODE_STATE_INIT; + ctx->multiple_edges_src_id = 0; + ctx->multiple_edges_dest_id = 0; + ctx->multiple_edges_it = (Delta_MatrixTupleIter){0}; ctx->current_relation_matrix_id = 0; Config_Option_get(Config_VKEY_MAX_ENTITY_COUNT, &ctx->vkey_entity_count); @@ -165,6 +168,27 @@ Delta_MatrixTupleIter *GraphEncodeContext_GetMatrixTupleIterator( return &ctx->matrix_tuple_iterator; } +void GraphEncodeContext_SetMutipleEdges(GraphEncodeContext *ctx, NodeID src, NodeID dest) { + ASSERT(ctx); + ctx->multiple_edges_src_id = src; + ctx->multiple_edges_dest_id = dest; +} + +Delta_MatrixTupleIter *GraphEncodeContext_GetMultipleEdgesIterator(GraphEncodeContext *ctx) { + ASSERT(ctx); + return &ctx->multiple_edges_it; +} + +NodeID GraphEncodeContext_GetMultipleEdgesSourceNode(const GraphEncodeContext *ctx) { + ASSERT(ctx); + return ctx->multiple_edges_src_id; +} + +NodeID GraphEncodeContext_GetMultipleEdgesDestinationNode(const GraphEncodeContext *ctx) { + ASSERT(ctx); + return ctx->multiple_edges_dest_id; +} + bool GraphEncodeContext_Finished(const GraphEncodeContext *ctx) { ASSERT(ctx); return ctx->keys_processed == GraphEncodeContext_GetKeyCount(ctx); @@ -187,4 +211,3 @@ void GraphEncodeContext_Free(GraphEncodeContext *ctx) { rm_free(ctx); } } - diff --git a/src/serializers/encode_context.h b/src/serializers/encode_context.h index 474eb9315..41d42dc1c 100644 --- a/src/serializers/encode_context.h +++ b/src/serializers/encode_context.h @@ -41,15 +41,18 @@ typedef struct { // GraphEncodeContext maintains the state of a graph being encoded or decoded typedef struct { - rax *meta_keys; // The holds the names of meta keys representing the graph. - uint64_t offset; // Number of encoded entities in the current state. - EncodeState state; // Represents the current encoding state. - uint64_t keys_processed; // Count the number of procssed graph keys. - GraphEncodeHeader header; // Header replied for each vkey - uint64_t vkey_entity_count; // Number of entities in a single virtual key. - uint current_relation_matrix_id; // Current encoded relationship matrix. - DataBlockIterator *datablock_iterator; // Datablock iterator to be saved in the context. - Delta_MatrixTupleIter matrix_tuple_iterator;// Matrix tuple iterator to be saved in the context. + rax *meta_keys; // The holds the names of meta keys representing the graph. + uint64_t offset; // Number of encoded entities in the current state. + EncodeState state; // Represents the current encoding state. + uint64_t keys_processed; // Count the number of procssed graph keys. + GraphEncodeHeader header; // Header replied for each vkey + uint64_t vkey_entity_count; // Number of entities in a single virtual key. + NodeID multiple_edges_src_id; // The current edges array sourc node id. + NodeID multiple_edges_dest_id; // The current edges array destination node id. + Delta_MatrixTupleIter multiple_edges_it; // Multiple edges array, save in the context. + uint current_relation_matrix_id; // Current encoded relationship matrix. + DataBlockIterator *datablock_iterator; // Datablock iterator to be saved in the context. + Delta_MatrixTupleIter matrix_tuple_iterator; // Matrix tuple iterator to be saved in the context. } GraphEncodeContext; // Creates a new graph encoding context. @@ -104,6 +107,18 @@ void GraphEncodeContext_SetCurrentRelationID(GraphEncodeContext *ctx, // Retrieve stored matrix tuple iterator. Delta_MatrixTupleIter *GraphEncodeContext_GetMatrixTupleIterator(GraphEncodeContext *ctx); +// Sets a multiple edges array and the current index, for saving the state of multiple edges encoding. +void GraphEncodeContext_SetMutipleEdges(GraphEncodeContext *ctx, NodeID src, NodeID dest); + +// Retrive the multiple edges id, to continue array of multiple edge encoding. +Delta_MatrixTupleIter * GraphEncodeContext_GetMultipleEdgesIterator(GraphEncodeContext *ctx); + +// Retrive the multiple edges array source node. +NodeID GraphEncodeContext_GetMultipleEdgesSourceNode(const GraphEncodeContext *ctx); + +// Retrive the multiple edges array destination node. +NodeID GraphEncodeContext_GetMultipleEdgesDestinationNode(const GraphEncodeContext *ctx); + // Returns if the the number of processed keys is equal to the total number of graph keys. bool GraphEncodeContext_Finished(const GraphEncodeContext *ctx); @@ -112,4 +127,3 @@ void GraphEncodeContext_IncreaseProcessedKeyCount(GraphEncodeContext *ctx); // Free graph encoding context. void GraphEncodeContext_Free(GraphEncodeContext *ctx); - diff --git a/src/serializers/encoder/v14/encode_graph_entities.c b/src/serializers/encoder/v14/encode_graph_entities.c index 550a8f1b0..ed5c6a0a2 100644 --- a/src/serializers/encoder/v14/encode_graph_entities.c +++ b/src/serializers/encoder/v14/encode_graph_entities.c @@ -272,6 +272,39 @@ void RdbSaveNodes_v14 } } +// Auxilary function to encode a multiple edges array, +// while consdirating the allowed number of edges to encode +// returns true if the number of encoded edges has reached the capacity +static void _RdbSaveMultipleEdges +( + SerializerIO rdb, // RDB IO. + GraphContext *gc, // Graph context. + uint r, // Edges relation id. + Delta_MatrixTupleIter *me_it, // Multiple edges iter. + uint64_t *encoded_edges, // Number of encoded edges in this phase (passed by ref). + uint64_t edges_to_encode, // Allowed capacity for encoding edges. + NodeID src, // Edges source node id. + NodeID dest // Edges destination node id. +) { + // define function local variables from passed-by-reference parameters. + uint encoded_edges_count = *encoded_edges; + + // add edges as long the number of encoded edges is in the allowed range + // and the array is not depleted + EdgeID edgeID; + while(encoded_edges_count < edges_to_encode && Delta_MatrixTupleIter_next_BOOL(me_it, NULL, &edgeID, NULL) == GrB_SUCCESS) { + Edge e; + e.src_id = src; + e.dest_id = dest; + Graph_GetEdge(gc->g, edgeID, &e); + _RdbSaveEdge(rdb, gc->g, &e, r); + encoded_edges_count++; + } + + // update passed-by-reference parameters + *encoded_edges = encoded_edges_count; +} + void RdbSaveEdges_v14 ( SerializerIO rdb, @@ -303,30 +336,43 @@ void RdbSaveEdges_v14 // get current relation matrix uint r = GraphEncodeContext_GetCurrentRelationID(gc->encoding_context); - Delta_Matrix out = Graph_OutgoingRelationMatrix(gc->g, r); - ASSERT(out != NULL); + Delta_Matrix M = Graph_GetRelationMatrix(gc->g, r, false); + Delta_Matrix ME = Graph_MultiEdgeRelationMatrix(gc->g, r); // get matrix tuple iterator from context // already set to the next entry to fetch // for previous edge encide or create new one Delta_MatrixTupleIter *iter = GraphEncodeContext_GetMatrixTupleIterator(gc->encoding_context); - if(!Delta_MatrixTupleIter_is_attached(iter, out)) { - info = Delta_MatrixTupleIter_attach(iter, out); + if(!Delta_MatrixTupleIter_is_attached(iter, M)) { + info = Delta_MatrixTupleIter_attach(iter, M); ASSERT(info == GrB_SUCCESS); } // first, see if the last edges encoding stopped at multiple edges array - NodeID src_id; - NodeID dest_id; - EdgeID edge_id; + Delta_MatrixTupleIter *me_it = GraphEncodeContext_GetMultipleEdgesIterator(gc->encoding_context); + NodeID src = GraphEncodeContext_GetMultipleEdgesSourceNode(gc->encoding_context); + NodeID dest = GraphEncodeContext_GetMultipleEdgesDestinationNode(gc->encoding_context); + if(Delta_MatrixTupleIter_is_attached(me_it, ME)) { + _RdbSaveMultipleEdges(rdb, gc, r, me_it, + &encoded_edges, edges_to_encode, src, dest); + // if the multiple edges array filled the capacity of entities allowed + // to be encoded, finish encoding + if(encoded_edges == edges_to_encode) { + goto finish; + } else { + // reset the multiple edges context for re-use + Delta_MatrixTupleIter_detach(me_it); + } + } uint relation_count = Graph_RelationTypeCount(gc->g); // write the required number of edges while(encoded_edges < edges_to_encode) { Edge e; + EdgeID edgeID; // try to get next tuple - info = Delta_MatrixTupleIter_next_UINT64(iter, &src_id, &edge_id, &dest_id); + info = Delta_MatrixTupleIter_next_UINT64(iter, &src, &dest, &edgeID); // if iterator is depleted // get new tuple from different matrix or finish encode @@ -338,20 +384,33 @@ void RdbSaveEdges_v14 if(r == relation_count) goto finish; // get matrix and set iterator - out = Graph_OutgoingRelationMatrix(gc->g, r); - ASSERT(out != NULL); - info = Delta_MatrixTupleIter_attach(iter, out); + M = Graph_GetRelationMatrix(gc->g, r, false); + info = Delta_MatrixTupleIter_attach(iter, M); ASSERT(info == GrB_SUCCESS); - info = Delta_MatrixTupleIter_next_UINT64(iter, &src_id, &edge_id, &dest_id); + info = Delta_MatrixTupleIter_next_UINT64(iter, &src, &dest, &edgeID); } ASSERT(info == GrB_SUCCESS); - e.src_id = src_id; - e.dest_id = dest_id; - Graph_GetEdge(gc->g, edge_id, &e); - _RdbSaveEdge(rdb, gc->g, &e, r); - encoded_edges++; + e.src_id = src; + e.dest_id = dest; + if(SINGLE_EDGE(edgeID)) { + Graph_GetEdge(gc->g, edgeID, &e); + _RdbSaveEdge(rdb, gc->g, &e, r); + encoded_edges++; + } else { + Delta_MatrixTupleIter_AttachRange(me_it, ME, CLEAR_MSB(edgeID), CLEAR_MSB(edgeID)); + _RdbSaveMultipleEdges(rdb, gc, r, me_it, + &encoded_edges, edges_to_encode, src, dest); + // if the multiple edges array filled the capacity of entities + // allowed to be encoded, finish encoding + if(encoded_edges == edges_to_encode) { + goto finish; + } else { + // reset the multiple edges context for re-use + Delta_MatrixTupleIter_detach(me_it); + } + } } finish: @@ -362,4 +421,5 @@ void RdbSaveEdges_v14 // update context GraphEncodeContext_SetCurrentRelationID(gc->encoding_context, r); -} + GraphEncodeContext_SetMutipleEdges(gc->encoding_context, src, dest); +} \ No newline at end of file diff --git a/src/serializers/graph_extensions.c b/src/serializers/graph_extensions.c index 896439431..8f932f9f3 100644 --- a/src/serializers/graph_extensions.c +++ b/src/serializers/graph_extensions.c @@ -9,6 +9,9 @@ #include "graph_extensions.h" #include "../util/datablock/oo_datablock.h" +// functions declerations - implemented in graph.c +void Graph_FormConnection(Graph *g, NodeID src, NodeID dest, EdgeID edge_id, int r); + void Graph_EnsureNodeCap ( Graph *g, @@ -126,7 +129,7 @@ void Serializer_Graph_SetNodeLabels } // optimized version of Graph_FormConnection -static void _OptimizedFormConnection +static void _OptimizedSingleEdgeFormConnection ( Graph *g, NodeID src, @@ -136,13 +139,9 @@ static void _OptimizedFormConnection ) { GrB_Info info; Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); - Delta_Matrix out = Graph_OutgoingRelationMatrix(g, r); - Delta_Matrix in = Graph_IncomingRelationMatrix(g, r); Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); GrB_Matrix m = Delta_Matrix_M(M); GrB_Matrix tm = Delta_Matrix_M(Delta_Matrix_getTranspose(M)); - GrB_Matrix out_m = Delta_Matrix_M(out); - GrB_Matrix in_m = Delta_Matrix_M(in); GrB_Matrix adj_m = Delta_Matrix_M(adj); GrB_Matrix adj_tm = Delta_Matrix_M(Delta_Matrix_getTranspose(adj)); @@ -171,20 +170,19 @@ static void _OptimizedFormConnection // update relationship matrix //-------------------------------------------------------------------------- - info = GrB_Matrix_setElement_BOOL(m, true, src, dest); - ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_setElement_BOOL(tm, true, dest, src); - ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_setElement_UINT64(out_m, dest, src, edge_id); + info = GrB_Matrix_setElement_UINT64(m, edge_id, src, dest); ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_setElement_UINT64(in_m, src, dest, edge_id); + info = GrB_Matrix_setElement_UINT64(tm, edge_id, dest, src); ASSERT(info == GrB_SUCCESS); + + GraphStatistics_IncEdgeCount(&g->stats, r, 1); } // set a given edge in the graph - Used for deserialization of graph void Serializer_Graph_SetEdge ( Graph *g, + bool multi_edge, EdgeID edge_id, NodeID src, NodeID dest, @@ -202,7 +200,11 @@ void Serializer_Graph_SetEdge e->attributes = set; e->relationID = r; - _OptimizedFormConnection(g, src, dest, edge_id, r); + if(multi_edge) { + Graph_FormConnection(g, src, dest, edge_id, r); + } else { + _OptimizedSingleEdgeFormConnection(g, src, dest, edge_id, r); + } } // returns the graph deleted nodes list diff --git a/src/serializers/graph_extensions.h b/src/serializers/graph_extensions.h index c3588d780..2f6efbd07 100644 --- a/src/serializers/graph_extensions.h +++ b/src/serializers/graph_extensions.h @@ -28,6 +28,7 @@ void Serializer_Graph_SetNodeLabels void Serializer_Graph_SetEdge ( Graph *g, // graph to add edge to + bool multi_edge, // true if graph supports multi-edge EdgeID edge_id, // edge ID NodeID src, // edge source NodeID dest, // edge destination From 72966f8e944047f31b2f3d33609a4925b232addb Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 24 Jun 2024 13:44:17 +0300 Subject: [PATCH 44/57] fix --- src/graph/graph.c | 2 +- src/serializers/decoders/prev/v9/decode_graph.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index 0c44de26d..f57e39f8f 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -1204,7 +1204,7 @@ static void _Graph_FreeRelationMatrices RelationMatrices *r = g->relations + i; Delta_Matrix_free(&r->R); Delta_Matrix_free(&r->ME); - array_free(&r->me_deleted_ids); + array_free(r->me_deleted_ids); } } diff --git a/src/serializers/decoders/prev/v9/decode_graph.c b/src/serializers/decoders/prev/v9/decode_graph.c index 3a90b8e15..05883758f 100644 --- a/src/serializers/decoders/prev/v9/decode_graph.c +++ b/src/serializers/decoders/prev/v9/decode_graph.c @@ -187,7 +187,7 @@ GraphContext *RdbLoadGraphContext_v9(RedisModuleIO *rdb) { // revert to default synchronization behavior Graph_SetMatrixPolicy(g, SYNC_POLICY_FLUSH_RESIZE); - + uint node_schemas_count = array_len(gc->node_schemas); // update the node statistics for(uint i = 0; i < node_schemas_count; i++) { From 5834e29f11d769ce678327b407bb3d73a638e8bc Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 24 Jun 2024 13:49:05 +0300 Subject: [PATCH 45/57] fix --- src/serializers/graph_extensions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/serializers/graph_extensions.c b/src/serializers/graph_extensions.c index 8f932f9f3..9f62fe43b 100644 --- a/src/serializers/graph_extensions.c +++ b/src/serializers/graph_extensions.c @@ -172,7 +172,7 @@ static void _OptimizedSingleEdgeFormConnection info = GrB_Matrix_setElement_UINT64(m, edge_id, src, dest); ASSERT(info == GrB_SUCCESS); - info = GrB_Matrix_setElement_UINT64(tm, edge_id, dest, src); + info = GrB_Matrix_setElement_BOOL(tm, true, dest, src); ASSERT(info == GrB_SUCCESS); GraphStatistics_IncEdgeCount(&g->stats, r, 1); From 1be8df0865ce6855a7f45537bdd73bb176870225 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 24 Jun 2024 13:53:08 +0300 Subject: [PATCH 46/57] fix --- src/graph/graph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index f57e39f8f..5dda5374f 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -1294,7 +1294,7 @@ void Graph_RemoveRelation #endif Delta_Matrix_free(&g->relations[relation_id].R); Delta_Matrix_free(&g->relations[relation_id].ME); - array_free(&g->relations[relation_id].me_deleted_ids); + array_free(g->relations[relation_id].me_deleted_ids); g->relations = array_del(g->relations, relation_id); } From 0fe7f41bca93523ea44809d24440036ef0e5493c Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 24 Jun 2024 14:02:02 +0300 Subject: [PATCH 47/57] fix --- src/graph/graph.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index 5dda5374f..f83755d83 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -1140,9 +1140,8 @@ void Graph_DeleteEdges Delta_MatrixTupleIter it = {0}; Delta_MatrixTupleIter_AttachRange(&it, ME, CLEAR_MSB(me_id), CLEAR_MSB(me_id)); - GrB_Index dst; bool connected = false; - while (Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, &dst) == GrB_SUCCESS) { + while (Delta_MatrixTupleIter_next_BOOL(&it, NULL, NULL, NULL) == GrB_SUCCESS) { connected = true; break; } From ad90708e02662e40802e7b12fdb57ce8f9cbd15a Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Mon, 24 Jun 2024 14:15:24 +0300 Subject: [PATCH 48/57] fix --- src/graph/graph.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index f83755d83..a7bfb24fe 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -435,13 +435,7 @@ uint64_t Graph_LabeledNodeCount const Graph *g, LabelID label ) { - ASSERT(g); - - Delta_Matrix L = Graph_GetLabelMatrix(g, label); - GrB_Index nvals; - GrB_Info info = Delta_Matrix_nvals(&nvals, L); - ASSERT(info == GrB_SUCCESS); - return nvals; + return GraphStatistics_NodeCount(&g->stats, label); } size_t Graph_EdgeCount(const Graph *g) { @@ -674,6 +668,9 @@ void Graph_LabelNode // map this label in this node's set of labels info = Delta_Matrix_setElement_BOOL(nl, id, l); ASSERT(info == GrB_SUCCESS); + + // update labels statistics + GraphStatistics_IncNodeCount(&g->stats, l, 1); } } @@ -723,6 +720,9 @@ void Graph_RemoveNodeLabels // remove this label from node's set of labels info = Delta_Matrix_removeElement(nl, id, l); ASSERT(info == GrB_SUCCESS); + + // a label was removed from node, update statistics + GraphStatistics_DecNodeCount(&g->stats, l, 1); } } @@ -746,6 +746,9 @@ void Graph_FormConnection info = Delta_Matrix_setElement_BOOL(adj, src, dest); ASSERT(info == GrB_SUCCESS); + // an edge of type r has just been created, update statistics + GraphStatistics_IncEdgeCount(&g->stats, r, 1); + GrB_Index current_edge; info = Delta_Matrix_extractElement_UINT64(¤t_edge, M, src, dest); if(info == GrB_NO_VALUE) { @@ -1124,6 +1127,9 @@ void Graph_DeleteEdges ASSERT(!DataBlock_ItemIsDeleted((void *)e->attributes)); + // an edge of type r has just been deleted, update statistics + GraphStatistics_DecEdgeCount(&g->stats, r, 1); + M = Graph_GetRelationMatrix(g, r, false); ME = Graph_MultiEdgeRelationMatrix(g, r); From 621705a5c11e94b9092fa392f26f0f8f730aff6b Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Tue, 25 Jun 2024 12:34:21 +0300 Subject: [PATCH 49/57] fix --- deps/FalkorDB-core-rs | 2 +- src/graph/delta_matrix/delta_matrix.h | 7 -- src/graph/graph.c | 78 ++++++++++--------- .../encoder/v14/encode_graph_entities.c | 50 ++++++------ 4 files changed, 70 insertions(+), 67 deletions(-) diff --git a/deps/FalkorDB-core-rs b/deps/FalkorDB-core-rs index c83945a78..408715de8 160000 --- a/deps/FalkorDB-core-rs +++ b/deps/FalkorDB-core-rs @@ -1 +1 @@ -Subproject commit c83945a7866ede517141b1b1ca37d2a66147e8c7 +Subproject commit 408715de89e7e92794fb3ed2f47084602b3269fd diff --git a/src/graph/delta_matrix/delta_matrix.h b/src/graph/delta_matrix/delta_matrix.h index 2ac97f158..201ac6fd4 100644 --- a/src/graph/delta_matrix/delta_matrix.h +++ b/src/graph/delta_matrix/delta_matrix.h @@ -174,13 +174,6 @@ GrB_Info Delta_Matrix_extractElement_UINT64 // x = A(i,j) GrB_Index j // column index ) ; -GrB_Info Delta_Matrix_extract_row -( - const Delta_Matrix A, // matrix to extract a vector from - GrB_Vector v, // vector to extract - GrB_Index i // row index -) ; - // remove entry at position C[i,j] GrB_Info Delta_Matrix_removeElement ( diff --git a/src/graph/graph.c b/src/graph/graph.c index a7bfb24fe..55470cf94 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -669,7 +669,7 @@ void Graph_LabelNode info = Delta_Matrix_setElement_BOOL(nl, id, l); ASSERT(info == GrB_SUCCESS); - // update labels statistics + // update labels statistics GraphStatistics_IncNodeCount(&g->stats, l, 1); } } @@ -721,7 +721,7 @@ void Graph_RemoveNodeLabels info = Delta_Matrix_removeElement(nl, id, l); ASSERT(info == GrB_SUCCESS); - // a label was removed from node, update statistics + // a label was removed from node, update statistics GraphStatistics_DecNodeCount(&g->stats, l, 1); } } @@ -746,7 +746,7 @@ void Graph_FormConnection info = Delta_Matrix_setElement_BOOL(adj, src, dest); ASSERT(info == GrB_SUCCESS); - // an edge of type r has just been created, update statistics + // an edge of type r has just been created, update statistics GraphStatistics_IncEdgeCount(&g->stats, r, 1); GrB_Index current_edge; @@ -867,7 +867,7 @@ void _GetIncomingNodeEdges GrB_Info info; Delta_MatrixTupleIter it = {0}; - Delta_Matrix M = NULL; + Delta_Matrix M = NULL; NodeID src_id = INVALID_ENTITY_ID; NodeID dest_id = ENTITY_GET_ID(n); EdgeID edge_id = INVALID_ENTITY_ID; @@ -1140,45 +1140,47 @@ void Graph_DeleteEdges if(SINGLE_EDGE(me_id)) { info = Delta_Matrix_removeElement(M, src_id, dest_id); ASSERT(info == GrB_SUCCESS); - } else { - info = Delta_Matrix_removeElement(ME, CLEAR_MSB(me_id), edge_id); - ASSERT(info == GrB_SUCCESS); + ASSERT(me_id == edge_id); - Delta_MatrixTupleIter it = {0}; - Delta_MatrixTupleIter_AttachRange(&it, ME, CLEAR_MSB(me_id), CLEAR_MSB(me_id)); + // see if source is connected to destination with additional edges bool connected = false; - while (Delta_MatrixTupleIter_next_BOOL(&it, NULL, NULL, NULL) == GrB_SUCCESS) { - connected = true; - break; + int relationCount = Graph_RelationTypeCount(g); + for(int j = 0; j < relationCount; j++) { + if(j == r) continue; + Delta_Matrix r = Graph_GetRelationMatrix(g, j, false); + info = Delta_Matrix_extractElement_BOOL(NULL, r, src_id, dest_id); + if(info == GrB_SUCCESS) { + connected = true; + break; + } } + // there are no additional edges connecting source to destination + // remove edge from THE adjacency matrix if(!connected) { - // no more edges connecting src to other nodes - // remove src from relation matrix - info = Delta_Matrix_removeElement(M, src_id, dest_id); + Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); + info = Delta_Matrix_removeElement(adj, src_id, dest_id); ASSERT(info == GrB_SUCCESS); + } + } else { + me_id = CLEAR_MSB(me_id); + info = Delta_Matrix_removeElement(ME, me_id, edge_id); + ASSERT(info == GrB_SUCCESS); - // see if source is connected to destination with additional edges - connected = false; - int relationCount = Graph_RelationTypeCount(g); - for(int j = 0; j < relationCount; j++) { - if(j == r) continue; - Delta_Matrix r = Graph_GetRelationMatrix(g, j, false); - info = Delta_Matrix_extractElement_BOOL(NULL, r, src_id, dest_id); - if(info == GrB_SUCCESS) { - connected = true; - break; - } - } - - // there are no additional edges connecting source to destination - // remove edge from THE adjacency matrix - if(!connected) { - Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); - info = Delta_Matrix_removeElement(adj, src_id, dest_id); - ASSERT(info == GrB_SUCCESS); - } + Delta_MatrixTupleIter it = {0}; + Delta_MatrixTupleIter_AttachRange(&it, ME, me_id, me_id); + GrB_Index last_edge_id; + uint count = 0; + while (Delta_MatrixTupleIter_next_BOOL(&it, NULL, &last_edge_id, NULL) == GrB_SUCCESS) { + count++; + if(count == 2) break; } + + if(count == 1) { + Delta_Matrix_removeElement(ME, me_id, last_edge_id); + Delta_Matrix_setElement_UINT64(M, last_edge_id, src_id, dest_id); + array_append(g->relations[r].me_deleted_ids, me_id); + } } // free and remove edges from datablock. @@ -1272,7 +1274,7 @@ RelationID Graph_AddRelationType size_t edge_cap = g->edges->itemCap; Delta_Matrix_new(&r.R, GrB_UINT64, n, n, true); - Delta_Matrix_new(&r.ME, GrB_BOOL, n, edge_cap, false); + Delta_Matrix_new(&r.ME, GrB_BOOL, edge_cap, edge_cap, false); r.me_id = 0; r.me_deleted_ids = array_new(uint64_t, 0); @@ -1352,7 +1354,9 @@ Delta_Matrix Graph_MultiEdgeRelationMatrix const Graph *g, RelationID relation_idx ) { - ASSERT(relation_idx != GRAPH_NO_RELATION); + ASSERT(g); + ASSERT(relation_idx != GRAPH_NO_RELATION && + relation_idx < Graph_RelationTypeCount(g)); Delta_Matrix m = g->relations[relation_idx].ME; diff --git a/src/serializers/encoder/v14/encode_graph_entities.c b/src/serializers/encoder/v14/encode_graph_entities.c index ed5c6a0a2..24667a17a 100644 --- a/src/serializers/encoder/v14/encode_graph_entities.c +++ b/src/serializers/encoder/v14/encode_graph_entities.c @@ -336,36 +336,42 @@ void RdbSaveEdges_v14 // get current relation matrix uint r = GraphEncodeContext_GetCurrentRelationID(gc->encoding_context); - Delta_Matrix M = Graph_GetRelationMatrix(gc->g, r, false); - Delta_Matrix ME = Graph_MultiEdgeRelationMatrix(gc->g, r); - + NodeID src; + NodeID dest; + Delta_Matrix M = NULL; + Delta_Matrix ME = NULL; // get matrix tuple iterator from context // already set to the next entry to fetch // for previous edge encide or create new one + uint relation_count = Graph_RelationTypeCount(gc->g); Delta_MatrixTupleIter *iter = GraphEncodeContext_GetMatrixTupleIterator(gc->encoding_context); - if(!Delta_MatrixTupleIter_is_attached(iter, M)) { - info = Delta_MatrixTupleIter_attach(iter, M); - ASSERT(info == GrB_SUCCESS); - } - - // first, see if the last edges encoding stopped at multiple edges array Delta_MatrixTupleIter *me_it = GraphEncodeContext_GetMultipleEdgesIterator(gc->encoding_context); - NodeID src = GraphEncodeContext_GetMultipleEdgesSourceNode(gc->encoding_context); - NodeID dest = GraphEncodeContext_GetMultipleEdgesDestinationNode(gc->encoding_context); - if(Delta_MatrixTupleIter_is_attached(me_it, ME)) { - _RdbSaveMultipleEdges(rdb, gc, r, me_it, - &encoded_edges, edges_to_encode, src, dest); - // if the multiple edges array filled the capacity of entities allowed - // to be encoded, finish encoding - if(encoded_edges == edges_to_encode) { - goto finish; - } else { - // reset the multiple edges context for re-use - Delta_MatrixTupleIter_detach(me_it); + if(r < relation_count) { + M = Graph_GetRelationMatrix(gc->g, r, false); + ME = Graph_MultiEdgeRelationMatrix(gc->g, r); + + if(!Delta_MatrixTupleIter_is_attached(iter, M)) { + info = Delta_MatrixTupleIter_attach(iter, M); + ASSERT(info == GrB_SUCCESS); + } + + // first, see if the last edges encoding stopped at multiple edges array + src = GraphEncodeContext_GetMultipleEdgesSourceNode(gc->encoding_context); + dest = GraphEncodeContext_GetMultipleEdgesDestinationNode(gc->encoding_context); + if(Delta_MatrixTupleIter_is_attached(me_it, ME)) { + _RdbSaveMultipleEdges(rdb, gc, r, me_it, + &encoded_edges, edges_to_encode, src, dest); + // if the multiple edges array filled the capacity of entities allowed + // to be encoded, finish encoding + if(encoded_edges == edges_to_encode) { + goto finish; + } else { + // reset the multiple edges context for re-use + Delta_MatrixTupleIter_detach(me_it); + } } } - uint relation_count = Graph_RelationTypeCount(gc->g); // write the required number of edges while(encoded_edges < edges_to_encode) { Edge e; From b589b9ebb128bdb7122852f63f1b582de2971f5e Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Tue, 25 Jun 2024 12:41:21 +0300 Subject: [PATCH 50/57] fix --- src/graph/graph.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index 55470cf94..5a1342a38 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -868,20 +868,24 @@ void _GetIncomingNodeEdges GrB_Info info; Delta_MatrixTupleIter it = {0}; Delta_Matrix M = NULL; + Delta_Matrix TM = NULL; NodeID src_id = INVALID_ENTITY_ID; NodeID dest_id = ENTITY_GET_ID(n); EdgeID edge_id = INVALID_ENTITY_ID; UNUSED(info); - M = Graph_GetRelationMatrix(g, edgeType, true); + M = Graph_GetRelationMatrix(g, edgeType, false); + TM = Graph_GetRelationMatrix(g, edgeType, true); - info = Delta_MatrixTupleIter_AttachRange(&it, M, dest_id, dest_id); + info = Delta_MatrixTupleIter_AttachRange(&it, TM, dest_id, dest_id); ASSERT(info == GrB_SUCCESS); - while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &src_id, &edge_id) == GrB_SUCCESS) { + while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &src_id, NULL) == GrB_SUCCESS) { Edge e = {0}; e.src_id = src_id; e.dest_id = dest_id; e.relationID = edgeType; + info = Delta_Matrix_extractElement_UINT64(&edge_id, M, src_id, dest_id); + ASSERT(info == GrB_SUCCESS); if(SINGLE_EDGE(edge_id)) { if(dir == GRAPH_EDGE_DIR_BOTH && src_id == dest_id) continue; e.id = edge_id; From c84f9bfa500d8630d29751408caf3e3876b66bbf Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Tue, 25 Jun 2024 14:32:40 +0300 Subject: [PATCH 51/57] fix --- src/graph/graph.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index 5a1342a38..152973155 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -879,7 +879,7 @@ void _GetIncomingNodeEdges info = Delta_MatrixTupleIter_AttachRange(&it, TM, dest_id, dest_id); ASSERT(info == GrB_SUCCESS); - while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &src_id, NULL) == GrB_SUCCESS) { + while(Delta_MatrixTupleIter_next_BOOL(&it, NULL, &src_id, NULL) == GrB_SUCCESS) { Edge e = {0}; e.src_id = src_id; e.dest_id = dest_id; @@ -1009,9 +1009,10 @@ uint64_t Graph_GetNodeDegree // outgoing edges //---------------------------------------------------------------------- + out = Graph_GetRelationMatrix(g, edgeType, false); + me = Graph_MultiEdgeRelationMatrix(g, edgeType); + if(outgoing) { - out = Graph_GetRelationMatrix(g, edgeType, false); - me = Graph_MultiEdgeRelationMatrix(g, edgeType); // construct an iterator to traverse over the source node row, // containing all outgoing edges Delta_MatrixTupleIter_AttachRange(&it, out, srcID, srcID); @@ -1040,13 +1041,13 @@ uint64_t Graph_GetNodeDegree if(incoming) { in = Graph_GetRelationMatrix(g, edgeType, true); - me = Graph_MultiEdgeRelationMatrix(g, edgeType); // construct an iterator to traverse over the source node row, // containing all incoming edges Delta_MatrixTupleIter_AttachRange(&it, in, srcID, srcID); // scan row - while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, &edgeID) + while(Delta_MatrixTupleIter_next_BOOL(&it, NULL, &destID, NULL) == GrB_SUCCESS) { + Delta_Matrix_extractElement_UINT64(&edgeID, out, destID, srcID); // check for edge type single/multi if(SINGLE_EDGE(edgeID)) { edge_count++; From b7082bc12607570f5333d6fb543708107cbe5f37 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Wed, 26 Jun 2024 11:09:42 +0300 Subject: [PATCH 52/57] fix --- src/graph/graph.c | 38 +++++++++---------- .../encoder/v14/encode_graph_entities.c | 2 +- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index 152973155..8bae7ac57 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -824,18 +824,16 @@ void _GetOutgoingNodeEdges info = Delta_MatrixTupleIter_AttachRange(&it, M, src_id, src_id); ASSERT(info == GrB_SUCCESS); + Delta_Matrix me = Graph_MultiEdgeRelationMatrix(g, edgeType); + Edge e = {.src_id = src_id, .relationID = edgeType}; while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, &dest_id, &edge_id) == GrB_SUCCESS) { - Edge e = {0}; - e.src_id = src_id; - e.dest_id = dest_id; - e.relationID = edgeType; + e.dest_id = dest_id; if(SINGLE_EDGE(edge_id)) { e.id = edge_id; e.attributes = DataBlock_GetItem(g->edges, edge_id); ASSERT(e.attributes); array_append(*edges, e); } else { - Delta_Matrix me = Graph_MultiEdgeRelationMatrix(g, e.relationID); GrB_Index me_id = CLEAR_MSB(edge_id); Delta_MatrixTupleIter me_it; Delta_MatrixTupleIter_AttachRange(&me_it, me, me_id, me_id); @@ -879,11 +877,10 @@ void _GetIncomingNodeEdges info = Delta_MatrixTupleIter_AttachRange(&it, TM, dest_id, dest_id); ASSERT(info == GrB_SUCCESS); + Delta_Matrix me = Graph_MultiEdgeRelationMatrix(g, edgeType); + Edge e = {.dest_id = dest_id, .relationID = edgeType}; while(Delta_MatrixTupleIter_next_BOOL(&it, NULL, &src_id, NULL) == GrB_SUCCESS) { - Edge e = {0}; - e.src_id = src_id; - e.dest_id = dest_id; - e.relationID = edgeType; + e.src_id = src_id; info = Delta_Matrix_extractElement_UINT64(&edge_id, M, src_id, dest_id); ASSERT(info == GrB_SUCCESS); if(SINGLE_EDGE(edge_id)) { @@ -893,7 +890,6 @@ void _GetIncomingNodeEdges ASSERT(e.attributes); array_append(*edges, e); } else { - Delta_Matrix me = Graph_MultiEdgeRelationMatrix(g, e.relationID); GrB_Index me_id = CLEAR_MSB(edge_id); Delta_MatrixTupleIter me_it; Delta_MatrixTupleIter_AttachRange(&me_it, me, me_id, me_id); @@ -973,9 +969,9 @@ uint64_t Graph_GetNodeDegree NodeID destID = INVALID_ENTITY_ID; EdgeID edgeID = INVALID_ENTITY_ID; uint64_t edge_count = 0; - Delta_Matrix out = NULL; - Delta_Matrix me = NULL; - Delta_Matrix in = NULL; + Delta_Matrix M = NULL; + Delta_Matrix TM = NULL; + Delta_Matrix ME = NULL; Delta_MatrixTupleIter it = {0}; Delta_MatrixTupleIter me_it = {0}; @@ -1009,13 +1005,13 @@ uint64_t Graph_GetNodeDegree // outgoing edges //---------------------------------------------------------------------- - out = Graph_GetRelationMatrix(g, edgeType, false); - me = Graph_MultiEdgeRelationMatrix(g, edgeType); + M = Graph_GetRelationMatrix(g, edgeType, false); + ME = Graph_MultiEdgeRelationMatrix(g, edgeType); if(outgoing) { // construct an iterator to traverse over the source node row, // containing all outgoing edges - Delta_MatrixTupleIter_AttachRange(&it, out, srcID, srcID); + Delta_MatrixTupleIter_AttachRange(&it, M, srcID, srcID); // scan row while(Delta_MatrixTupleIter_next_UINT64(&it, NULL, NULL, &edgeID) == GrB_SUCCESS) { @@ -1025,7 +1021,7 @@ uint64_t Graph_GetNodeDegree } else { EdgeID me_id = CLEAR_MSB(edgeID); Delta_MatrixTupleIter me_it; - Delta_MatrixTupleIter_AttachRange(&me_it, me, me_id, me_id); + Delta_MatrixTupleIter_AttachRange(&me_it, ME, me_id, me_id); while(Delta_MatrixTupleIter_next_BOOL(&me_it, NULL, NULL, NULL) == GrB_SUCCESS) { edge_count++; } @@ -1040,21 +1036,21 @@ uint64_t Graph_GetNodeDegree //---------------------------------------------------------------------- if(incoming) { - in = Graph_GetRelationMatrix(g, edgeType, true); + TM = Graph_GetRelationMatrix(g, edgeType, true); // construct an iterator to traverse over the source node row, // containing all incoming edges - Delta_MatrixTupleIter_AttachRange(&it, in, srcID, srcID); + Delta_MatrixTupleIter_AttachRange(&it, TM, srcID, srcID); // scan row while(Delta_MatrixTupleIter_next_BOOL(&it, NULL, &destID, NULL) == GrB_SUCCESS) { - Delta_Matrix_extractElement_UINT64(&edgeID, out, destID, srcID); + Delta_Matrix_extractElement_UINT64(&edgeID, M, destID, srcID); // check for edge type single/multi if(SINGLE_EDGE(edgeID)) { edge_count++; } else { EdgeID me_id = CLEAR_MSB(edgeID); Delta_MatrixTupleIter me_it; - Delta_MatrixTupleIter_AttachRange(&me_it, me, me_id, me_id); + Delta_MatrixTupleIter_AttachRange(&me_it, ME, me_id, me_id); while(Delta_MatrixTupleIter_next_BOOL(&me_it, NULL, NULL, NULL) == GrB_SUCCESS) { edge_count++; } diff --git a/src/serializers/encoder/v14/encode_graph_entities.c b/src/serializers/encoder/v14/encode_graph_entities.c index 24667a17a..9dc4b4a92 100644 --- a/src/serializers/encoder/v14/encode_graph_entities.c +++ b/src/serializers/encoder/v14/encode_graph_entities.c @@ -387,7 +387,7 @@ void RdbSaveEdges_v14 r++; // if done iterating over all the matrices, jump to finish - if(r == relation_count) goto finish; + if(r >= relation_count) goto finish; // get matrix and set iterator M = Graph_GetRelationMatrix(gc->g, r, false); From f5f92bdb377783c0a14c6078b40c93994b631476 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Wed, 26 Jun 2024 12:18:12 +0300 Subject: [PATCH 53/57] fix --- src/graph/graph_delete_nodes.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/graph/graph_delete_nodes.c b/src/graph/graph_delete_nodes.c index 310668b52..dca8833b7 100644 --- a/src/graph/graph_delete_nodes.c +++ b/src/graph/graph_delete_nodes.c @@ -103,6 +103,9 @@ void Graph_DeleteNodes Delta_Matrix L = Graph_GetLabelMatrix(g, j); info = Delta_Matrix_removeElement(L, id, id); ASSERT(info == GrB_SUCCESS); + + // a label was removed from node, update statistics + GraphStatistics_DecNodeCount(&g->stats, j, 1); } // remove node from datablock From ed1d2fa71c72274d847c140084def2fc0612a234 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Thu, 27 Jun 2024 10:30:41 +0300 Subject: [PATCH 54/57] fix --- src/serializers/encoder/v14/encode_graph_entities.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/serializers/encoder/v14/encode_graph_entities.c b/src/serializers/encoder/v14/encode_graph_entities.c index 9dc4b4a92..24667a17a 100644 --- a/src/serializers/encoder/v14/encode_graph_entities.c +++ b/src/serializers/encoder/v14/encode_graph_entities.c @@ -387,7 +387,7 @@ void RdbSaveEdges_v14 r++; // if done iterating over all the matrices, jump to finish - if(r >= relation_count) goto finish; + if(r == relation_count) goto finish; // get matrix and set iterator M = Graph_GetRelationMatrix(gc->g, r, false); From e47b26b69b42a59bab509cd8165cd8b527a0bbf4 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Thu, 27 Jun 2024 12:38:20 +0300 Subject: [PATCH 55/57] fix --- src/graph/graph.c | 8 ++++---- src/serializers/encoder/v14/encode_graph_entities.c | 13 +++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index 8bae7ac57..da6a6447d 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -739,7 +739,7 @@ void Graph_FormConnection GrB_Info info; UNUSED(info); Delta_Matrix M = Graph_GetRelationMatrix(g, r, false); - Delta_Matrix me = Graph_MultiEdgeRelationMatrix(g, r); + Delta_Matrix ME = Graph_MultiEdgeRelationMatrix(g, r); Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); // rows represent source nodes, columns represent destination nodes @@ -758,12 +758,12 @@ void Graph_FormConnection GrB_Index meid = g->relations[r].me_id++; info = Delta_Matrix_setElement_UINT64(M, SET_MSB(meid), src, dest); ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_setElement_BOOL(me, meid, current_edge); + info = Delta_Matrix_setElement_BOOL(ME, meid, current_edge); ASSERT(info == GrB_SUCCESS); - info = Delta_Matrix_setElement_BOOL(me, meid, edge_id); + info = Delta_Matrix_setElement_BOOL(ME, meid, edge_id); ASSERT(info == GrB_SUCCESS); } else { - info = Delta_Matrix_setElement_BOOL(me, CLEAR_MSB(current_edge), edge_id); + info = Delta_Matrix_setElement_BOOL(ME, CLEAR_MSB(current_edge), edge_id); ASSERT(info == GrB_SUCCESS); } } diff --git a/src/serializers/encoder/v14/encode_graph_entities.c b/src/serializers/encoder/v14/encode_graph_entities.c index 24667a17a..23b94d219 100644 --- a/src/serializers/encoder/v14/encode_graph_entities.c +++ b/src/serializers/encoder/v14/encode_graph_entities.c @@ -287,7 +287,7 @@ static void _RdbSaveMultipleEdges NodeID dest // Edges destination node id. ) { // define function local variables from passed-by-reference parameters. - uint encoded_edges_count = *encoded_edges; + uint64_t encoded_edges_count = *encoded_edges; // add edges as long the number of encoded edges is in the allowed range // and the array is not depleted @@ -355,12 +355,12 @@ void RdbSaveEdges_v14 ASSERT(info == GrB_SUCCESS); } - // first, see if the last edges encoding stopped at multiple edges array - src = GraphEncodeContext_GetMultipleEdgesSourceNode(gc->encoding_context); - dest = GraphEncodeContext_GetMultipleEdgesDestinationNode(gc->encoding_context); if(Delta_MatrixTupleIter_is_attached(me_it, ME)) { + // first, see if the last edges encoding stopped at multiple edges array + src = GraphEncodeContext_GetMultipleEdgesSourceNode(gc->encoding_context); + dest = GraphEncodeContext_GetMultipleEdgesDestinationNode(gc->encoding_context); _RdbSaveMultipleEdges(rdb, gc, r, me_it, - &encoded_edges, edges_to_encode, src, dest); + &encoded_edges, edges_to_encode, src, dest); // if the multiple edges array filled the capacity of entities allowed // to be encoded, finish encoding if(encoded_edges == edges_to_encode) { @@ -391,6 +391,7 @@ void RdbSaveEdges_v14 // get matrix and set iterator M = Graph_GetRelationMatrix(gc->g, r, false); + ME = Graph_MultiEdgeRelationMatrix(gc->g, r); info = Delta_MatrixTupleIter_attach(iter, M); ASSERT(info == GrB_SUCCESS); info = Delta_MatrixTupleIter_next_UINT64(iter, &src, &dest, &edgeID); @@ -407,7 +408,7 @@ void RdbSaveEdges_v14 } else { Delta_MatrixTupleIter_AttachRange(me_it, ME, CLEAR_MSB(edgeID), CLEAR_MSB(edgeID)); _RdbSaveMultipleEdges(rdb, gc, r, me_it, - &encoded_edges, edges_to_encode, src, dest); + &encoded_edges, edges_to_encode, src, dest); // if the multiple edges array filled the capacity of entities // allowed to be encoded, finish encoding if(encoded_edges == edges_to_encode) { From 118b5569e3e4721acd785cd01c44fa8dcafb6148 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Thu, 27 Jun 2024 12:48:00 +0300 Subject: [PATCH 56/57] reuse multi edge ids --- src/graph/graph.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index da6a6447d..dea7204ea 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -755,7 +755,9 @@ void Graph_FormConnection info = Delta_Matrix_setElement_UINT64(M, edge_id, src, dest); ASSERT(info == GrB_SUCCESS); } else if(SINGLE_EDGE(current_edge)) { - GrB_Index meid = g->relations[r].me_id++; + GrB_Index meid = array_len(g->relations[r].me_deleted_ids) > 0 + ? array_pop(g->relations[r].me_deleted_ids) + : g->relations[r].me_id++; info = Delta_Matrix_setElement_UINT64(M, SET_MSB(meid), src, dest); ASSERT(info == GrB_SUCCESS); info = Delta_Matrix_setElement_BOOL(ME, meid, current_edge); From 37bf3fb6caa88ec74a91533fd612455f44487530 Mon Sep 17 00:00:00 2001 From: Avi Avni Date: Thu, 27 Jun 2024 13:45:30 +0300 Subject: [PATCH 57/57] fix performance --- src/graph/graph.c | 72 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/src/graph/graph.c b/src/graph/graph.c index dea7204ea..d7cf4578f 100644 --- a/src/graph/graph.c +++ b/src/graph/graph.c @@ -1134,7 +1134,6 @@ void Graph_DeleteEdges GraphStatistics_DecEdgeCount(&g->stats, r, 1); M = Graph_GetRelationMatrix(g, r, false); - ME = Graph_MultiEdgeRelationMatrix(g, r); GrB_Index me_id; info = Delta_Matrix_extractElement_UINT64(&me_id, M, src_id, dest_id); @@ -1166,30 +1165,71 @@ void Graph_DeleteEdges ASSERT(info == GrB_SUCCESS); } } else { + ME = Graph_MultiEdgeRelationMatrix(g, r); me_id = CLEAR_MSB(me_id); info = Delta_Matrix_removeElement(ME, me_id, edge_id); ASSERT(info == GrB_SUCCESS); - - Delta_MatrixTupleIter it = {0}; - Delta_MatrixTupleIter_AttachRange(&it, ME, me_id, me_id); - GrB_Index last_edge_id; - uint count = 0; - while (Delta_MatrixTupleIter_next_BOOL(&it, NULL, &last_edge_id, NULL) == GrB_SUCCESS) { - count++; - if(count == 2) break; - } - - if(count == 1) { - Delta_Matrix_removeElement(ME, me_id, last_edge_id); - Delta_Matrix_setElement_UINT64(M, last_edge_id, src_id, dest_id); - array_append(g->relations[r].me_deleted_ids, me_id); - } } // free and remove edges from datablock. DataBlock_DeleteItem(g->edges, edge_id); } + for (uint i = 0; i < n; i++) { + Edge *e = edges + i; + int r = Edge_GetRelationID(e); + NodeID src_id = Edge_GetSrcNodeID(e); + NodeID dest_id = Edge_GetDestNodeID(e); + EdgeID edge_id = ENTITY_GET_ID(e); + + M = Graph_GetRelationMatrix(g, r, false); + + GrB_Index me_id; + info = Delta_Matrix_extractElement_UINT64(&me_id, M, src_id, dest_id); + if(info != GrB_SUCCESS || SINGLE_EDGE(me_id)) continue; + + ME = Graph_MultiEdgeRelationMatrix(g, r); + me_id = CLEAR_MSB(me_id); + Delta_MatrixTupleIter it = {0}; + Delta_MatrixTupleIter_AttachRange(&it, ME, me_id, me_id); + GrB_Index last_edge_id; + uint count = 0; + while (Delta_MatrixTupleIter_next_BOOL(&it, NULL, &last_edge_id, NULL) == GrB_SUCCESS) { + count++; + if(count == 2) break; + } + + if(count == 0) { + info = Delta_Matrix_removeElement(M, src_id, dest_id); + ASSERT(info == GrB_SUCCESS); + + // see if source is connected to destination with additional edges + bool connected = false; + int relationCount = Graph_RelationTypeCount(g); + for(int j = 0; j < relationCount; j++) { + if(j == r) continue; + Delta_Matrix r = Graph_GetRelationMatrix(g, j, false); + info = Delta_Matrix_extractElement_BOOL(NULL, r, src_id, dest_id); + if(info == GrB_SUCCESS) { + connected = true; + break; + } + } + + // there are no additional edges connecting source to destination + // remove edge from THE adjacency matrix + if(!connected) { + Delta_Matrix adj = Graph_GetAdjacencyMatrix(g, false); + info = Delta_Matrix_removeElement(adj, src_id, dest_id); + ASSERT(info == GrB_SUCCESS); + } + } else if(count == 1) { + Delta_Matrix_removeElement(ME, me_id, last_edge_id); + Delta_Matrix_setElement_UINT64(M, last_edge_id, src_id, dest_id); + array_append(g->relations[r].me_deleted_ids, me_id); + } + } + Graph_SetMatrixPolicy(g, policy); }