MCPcopy Create free account
hub / github.com/RedisGraph/RedisGraph / _reduceEdgeCount

Function _reduceEdgeCount

src/execution_plan/optimizations/reduce_count.c:157–221  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

155}
156
157void _reduceEdgeCount(ExecutionPlan *plan) {
158 // we'll only modify execution plan if it is structured as follows:
159 // "Full Scan -> Conditional Traverse -> Aggregate -> Results"
160 OpBase *opScan;
161 OpBase *opTraverse;
162 OpResult *opResult;
163 OpAggregate *opAggregate;
164
165 // see if execution-plan matches the pattern:
166 // "Full Scan -> Conditional Traverse -> Aggregate -> Results"
167 // if that's not the case, simply return without making any modifications
168 if(!_identifyEdgeCountPattern(plan->root, &opResult, &opAggregate,
169 &opTraverse, &opScan)) return;
170
171 // user is trying to count edges (either in total or of specific types)
172 // in the graph. optimize by skipping Scan, Traverse and Aggregate
173 Graph *g = QueryCtx_GetGraph();
174 SIValue edgeCount = SI_LongVal(0);
175
176 // if type is specified, count only labeled entities
177 OpCondTraverse *condTraverse = (OpCondTraverse *)opTraverse;
178 // the traversal op doesn't contain information about the traversed edge,
179 // cannot apply optimization
180 if(!condTraverse->edge_ctx) return;
181
182 uint relationCount = array_len(condTraverse->edge_ctx->edgeRelationTypes);
183
184 uint64_t edges = 0;
185 for(uint i = 0; i < relationCount; i++) {
186 int relType = condTraverse->edge_ctx->edgeRelationTypes[i];
187 switch(relType) {
188 case GRAPH_NO_RELATION:
189 // should be the only relationship type mentioned, -[]->
190 edges = Graph_EdgeCount(g);
191 break;
192 case GRAPH_UNKNOWN_RELATION:
193 // no change to current count, -[:none_existing]->
194 break;
195 default:
196 edges += Graph_RelationEdgeCount(g, relType);
197 }
198 }
199 edgeCount = SI_LongVal(edges);
200
201 // construct a constant expression, used by a new projection operation
202 AR_ExpNode *exp = AR_EXP_NewConstOperandNode(edgeCount);
203 // the new expression must be aliased to populate the Record
204 exp->resolved_name = opAggregate->aggregate_exps[0]->resolved_name;
205 AR_ExpNode **exps = array_new(AR_ExpNode *, 1);
206 array_append(exps, exp);
207
208 OpBase *opProject = NewProjectOp(opAggregate->op.plan, exps);
209
210 // new execution plan: "Project -> Results"
211 ExecutionPlan_RemoveOp(plan, opScan);
212 OpBase_Free(opScan);
213
214 ExecutionPlan_RemoveOp(plan, (OpBase *)opTraverse);

Callers 1

reduceCountFunction · 0.85

Calls 11

QueryCtx_GetGraphFunction · 0.85
SI_LongValFunction · 0.85
array_lenFunction · 0.85
Graph_EdgeCountFunction · 0.85
Graph_RelationEdgeCountFunction · 0.85
NewProjectOpFunction · 0.85
ExecutionPlan_RemoveOpFunction · 0.85
OpBase_FreeFunction · 0.85
ExecutionPlan_AddOpFunction · 0.85

Tested by

no test coverage detected