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

Function reduce_scan_op

src/execution_plan/optimizations/utilize_indices.c:291–420  ·  view source on GitHub ↗

try to replace given Label Scan operation and a set of Filter operations with a single Index Scan operation

Source from the content-addressed store, hash-verified

289// try to replace given Label Scan operation and a set of Filter operations with
290// a single Index Scan operation
291void reduce_scan_op
292(
293 ExecutionPlan *plan,
294 NodeByLabelScan *scan
295) {
296 // in the multi-label case, we want to pick the label which will allow us to
297 // both utilize an index and iterate over the fewest values
298 GraphContext *gc = QueryCtx_GetGraphCtx();
299 Graph *g = QueryCtx_GetGraph();
300 QueryGraph *qg = scan->op.plan->query_graph;
301
302 // find label with filtered indexed properties
303 // that has the minimum NNZ entries
304 int min_label_id; // tracks min label ID
305 uint64_t min_nnz = UINT64_MAX; // tracks min entries
306 RSIndex *rs_idx = NULL; // the index to be applied
307 OpFilter **filters = NULL; // tracks indexed filters to apply
308 uint filters_count = 0; // number of matching filters
309 const char *min_label_str = NULL; // tracks min label name
310
311 // see if scanned node has multiple labels
312 const char *node_alias = scan->n->alias;
313 QGNode *qn = QueryGraph_GetNodeByAlias(qg, node_alias);
314 ASSERT(qn != NULL);
315
316 uint label_count = QGNode_LabelCount(qn);
317 for(uint i = 0; i < label_count; i++) {
318 Index idx;
319 uint64_t nnz;
320 int label_id = QGNode_GetLabelID(qn, i);
321 const char *label = QGNode_GetLabel(qn, i);
322
323 // unknown label
324 if(label_id == GRAPH_UNKNOWN_LABEL) continue;
325
326 idx = GraphContext_GetIndexByID(gc, label_id, NULL, 0, IDX_EXACT_MATCH,
327 GETYPE_NODE);
328
329 // no index for current label
330 if(idx == NULL) continue;
331
332 ASSERT(Index_Enabled(idx));
333
334 // TODO switch to reusable array
335 OpFilter **cur_filters = _applicableFilters((OpBase *)scan, scan->n->alias, idx);
336
337 // TODO consider heuristic which combines max
338 // number / restrictiveness of applicable filters
339 // vs. the label's NNZ?
340 uint cur_filters_count = array_len(cur_filters);
341 if(cur_filters_count == 0) {
342 // no filters
343 array_free(cur_filters);
344 continue;
345 }
346
347 // get all applicable filter for index
348 RSIndex *cur_idx = Index_RSIndex(idx);

Callers 1

utilizeIndicesFunction · 0.85

Calls 15

QueryCtx_GetGraphCtxFunction · 0.85
QueryCtx_GetGraphFunction · 0.85
QGNode_LabelCountFunction · 0.85
QGNode_GetLabelIDFunction · 0.85
QGNode_GetLabelFunction · 0.85
Index_EnabledFunction · 0.85
_applicableFiltersFunction · 0.85
array_lenFunction · 0.85
array_freeFunction · 0.85
Index_RSIndexFunction · 0.85

Tested by

no test coverage detected