Skip to content

Commit bf566d5

Browse files
committed
wip
1 parent 6a1ac98 commit bf566d5

379 files changed

Lines changed: 97707 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Eclipse RDF4J contributors.
3+
*
4+
* All rights reserved. This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Distribution License v1.0
6+
* which accompanies this distribution, and is available at
7+
* http://www.eclipse.org/org/documents/edl-v10.php.
8+
*
9+
* SPDX-License-Identifier: BSD-3-Clause
10+
*******************************************************************************/
11+
// Some portions generated by Codex
12+
package org.eclipse.rdf4j.query.algebra.evaluation.impl;
13+
14+
import java.util.Objects;
15+
import java.util.concurrent.ConcurrentHashMap;
16+
import java.util.concurrent.atomic.LongAdder;
17+
18+
import org.eclipse.rdf4j.query.algebra.Filter;
19+
import org.eclipse.rdf4j.query.algebra.Join;
20+
import org.eclipse.rdf4j.query.algebra.LeftJoin;
21+
import org.eclipse.rdf4j.query.algebra.QueryModelNode;
22+
import org.eclipse.rdf4j.query.algebra.StatementPattern;
23+
import org.eclipse.rdf4j.query.algebra.TupleExpr;
24+
import org.eclipse.rdf4j.query.algebra.ValueExpr;
25+
import org.eclipse.rdf4j.query.algebra.Var;
26+
27+
/**
28+
* Process-local runtime telemetry history keyed by normalized statement-pattern signature.
29+
*/
30+
public final class QueryRuntimeTelemetryRegistry {
31+
32+
private static final ConcurrentHashMap<String, TelemetryAggregate> BY_PATTERN_KEY = new ConcurrentHashMap<>();
33+
34+
private QueryRuntimeTelemetryRegistry() {
35+
}
36+
37+
public static void clear() {
38+
BY_PATTERN_KEY.clear();
39+
}
40+
41+
public static void record(QueryModelNode node) {
42+
String key = keyFor(node);
43+
if (key == null) {
44+
return;
45+
}
46+
47+
long sourceRowsScannedActual = node.getSourceRowsScannedActual();
48+
long sourceRowsMatchedActual = node.getSourceRowsMatchedActual();
49+
long sourceRowsFilteredActual = node.getSourceRowsFilteredActual();
50+
long joinRightIteratorsCreatedActual = node.getJoinRightIteratorsCreatedActual();
51+
long joinLeftBindingsConsumedActual = node.getJoinLeftBindingsConsumedActual();
52+
long joinRightBindingsConsumedActual = node.getJoinRightBindingsConsumedActual();
53+
54+
if (sourceRowsScannedActual < 0 && sourceRowsMatchedActual < 0 && sourceRowsFilteredActual < 0
55+
&& joinRightIteratorsCreatedActual < 0 && joinLeftBindingsConsumedActual < 0
56+
&& joinRightBindingsConsumedActual < 0) {
57+
return;
58+
}
59+
60+
TelemetryAggregate aggregate = BY_PATTERN_KEY.computeIfAbsent(key, unused -> new TelemetryAggregate());
61+
aggregate.record(sourceRowsScannedActual, sourceRowsMatchedActual, sourceRowsFilteredActual,
62+
joinRightIteratorsCreatedActual, joinLeftBindingsConsumedActual, joinRightBindingsConsumedActual);
63+
64+
recordFilterDerivedStatementPatternTelemetry(node, joinRightIteratorsCreatedActual,
65+
joinLeftBindingsConsumedActual, joinRightBindingsConsumedActual);
66+
}
67+
68+
public static TelemetrySnapshot snapshotFor(TupleExpr tupleExpr) {
69+
String key = keyFor(tupleExpr);
70+
if (key == null) {
71+
return TelemetrySnapshot.empty();
72+
}
73+
TelemetryAggregate aggregate = BY_PATTERN_KEY.get(key);
74+
if (aggregate == null) {
75+
return TelemetrySnapshot.empty();
76+
}
77+
return aggregate.snapshot();
78+
}
79+
80+
private static String keyFor(QueryModelNode node) {
81+
if (!(node instanceof TupleExpr)) {
82+
return null;
83+
}
84+
85+
return tupleExprKey((TupleExpr) node);
86+
}
87+
88+
private static String tupleExprKey(TupleExpr tupleExpr) {
89+
if (tupleExpr == null) {
90+
return null;
91+
}
92+
if (tupleExpr instanceof StatementPattern) {
93+
return statementPatternKey((StatementPattern) tupleExpr);
94+
}
95+
if (tupleExpr instanceof Filter) {
96+
Filter filter = (Filter) tupleExpr;
97+
return "FILTER|arg=" + tupleExprKey(filter.getArg()) + "|condition=" + valueExprKey(filter.getCondition());
98+
}
99+
if (tupleExpr instanceof Join) {
100+
Join join = (Join) tupleExpr;
101+
return "JOIN|left=" + tupleExprKey(join.getLeftArg()) + "|right=" + tupleExprKey(join.getRightArg());
102+
}
103+
if (tupleExpr instanceof LeftJoin) {
104+
LeftJoin leftJoin = (LeftJoin) tupleExpr;
105+
return "LEFT_JOIN|left=" + tupleExprKey(leftJoin.getLeftArg()) + "|right="
106+
+ tupleExprKey(leftJoin.getRightArg())
107+
+ "|condition=" + valueExprKey(leftJoin.getCondition());
108+
}
109+
return tupleExpr.getClass().getSimpleName() + "|" + tupleExpr.getSignature();
110+
}
111+
112+
private static String statementPatternKey(StatementPattern statementPattern) {
113+
return "SP|s=" + varKey(statementPattern.getSubjectVar())
114+
+ "|p=" + varKey(statementPattern.getPredicateVar())
115+
+ "|o=" + varKey(statementPattern.getObjectVar())
116+
+ "|c=" + varKey(statementPattern.getContextVar());
117+
}
118+
119+
private static String valueExprKey(ValueExpr valueExpr) {
120+
if (valueExpr == null) {
121+
return "<null>";
122+
}
123+
return valueExpr.toString().replaceAll("\\s+", " ").trim();
124+
}
125+
126+
private static void recordFilterDerivedStatementPatternTelemetry(QueryModelNode node,
127+
long joinRightIteratorsCreatedActual, long joinLeftBindingsConsumedActual,
128+
long joinRightBindingsConsumedActual) {
129+
if (!(node instanceof Filter)) {
130+
return;
131+
}
132+
133+
TupleExpr filterArg = ((Filter) node).getArg();
134+
if (!(filterArg instanceof StatementPattern)) {
135+
return;
136+
}
137+
138+
long sourceRowsScannedActual = joinLeftBindingsConsumedActual;
139+
long sourceRowsMatchedActual = joinRightBindingsConsumedActual;
140+
long sourceRowsFilteredActual = -1;
141+
if (sourceRowsScannedActual >= 0 && sourceRowsMatchedActual >= 0) {
142+
sourceRowsFilteredActual = Math.max(0L, sourceRowsScannedActual - sourceRowsMatchedActual);
143+
}
144+
145+
long derivedJoinRightIteratorsCreatedActual = joinRightIteratorsCreatedActual >= 0
146+
? joinRightIteratorsCreatedActual
147+
: joinLeftBindingsConsumedActual;
148+
long derivedJoinLeftBindingsConsumedActual = joinLeftBindingsConsumedActual;
149+
long derivedJoinRightBindingsConsumedActual = joinRightBindingsConsumedActual;
150+
151+
String statementPatternKey = statementPatternKey((StatementPattern) filterArg);
152+
TelemetryAggregate aggregate = BY_PATTERN_KEY.computeIfAbsent(statementPatternKey,
153+
unused -> new TelemetryAggregate());
154+
aggregate.record(sourceRowsScannedActual, sourceRowsMatchedActual, sourceRowsFilteredActual,
155+
derivedJoinRightIteratorsCreatedActual, derivedJoinLeftBindingsConsumedActual,
156+
derivedJoinRightBindingsConsumedActual);
157+
}
158+
159+
private static String varKey(Var var) {
160+
if (var == null) {
161+
return "<null>";
162+
}
163+
164+
if (var.hasValue()) {
165+
return "const:" + var.getValue().stringValue();
166+
}
167+
168+
String name = var.getName();
169+
return "var:" + (name == null ? "<anon>" : name);
170+
}
171+
172+
private static final class TelemetryAggregate {
173+
private final LongAdder sourceRowsScannedSum = new LongAdder();
174+
private final LongAdder sourceRowsScannedCount = new LongAdder();
175+
private final LongAdder sourceRowsMatchedSum = new LongAdder();
176+
private final LongAdder sourceRowsMatchedCount = new LongAdder();
177+
private final LongAdder sourceRowsFilteredSum = new LongAdder();
178+
private final LongAdder sourceRowsFilteredCount = new LongAdder();
179+
private final LongAdder joinRightIteratorsCreatedSum = new LongAdder();
180+
private final LongAdder joinRightIteratorsCreatedCount = new LongAdder();
181+
private final LongAdder joinLeftBindingsConsumedSum = new LongAdder();
182+
private final LongAdder joinLeftBindingsConsumedCount = new LongAdder();
183+
private final LongAdder joinRightBindingsConsumedSum = new LongAdder();
184+
private final LongAdder joinRightBindingsConsumedCount = new LongAdder();
185+
186+
private void record(long sourceRowsScannedActual, long sourceRowsMatchedActual, long sourceRowsFilteredActual,
187+
long joinRightIteratorsCreatedActual, long joinLeftBindingsConsumedActual,
188+
long joinRightBindingsConsumedActual) {
189+
recordMetric(sourceRowsScannedActual, sourceRowsScannedSum, sourceRowsScannedCount);
190+
recordMetric(sourceRowsMatchedActual, sourceRowsMatchedSum, sourceRowsMatchedCount);
191+
recordMetric(sourceRowsFilteredActual, sourceRowsFilteredSum, sourceRowsFilteredCount);
192+
recordMetric(joinRightIteratorsCreatedActual, joinRightIteratorsCreatedSum, joinRightIteratorsCreatedCount);
193+
recordMetric(joinLeftBindingsConsumedActual, joinLeftBindingsConsumedSum, joinLeftBindingsConsumedCount);
194+
recordMetric(joinRightBindingsConsumedActual, joinRightBindingsConsumedSum, joinRightBindingsConsumedCount);
195+
}
196+
197+
private TelemetrySnapshot snapshot() {
198+
return new TelemetrySnapshot(average(sourceRowsScannedSum, sourceRowsScannedCount),
199+
average(sourceRowsMatchedSum, sourceRowsMatchedCount),
200+
average(sourceRowsFilteredSum, sourceRowsFilteredCount),
201+
average(joinRightIteratorsCreatedSum, joinRightIteratorsCreatedCount),
202+
average(joinLeftBindingsConsumedSum, joinLeftBindingsConsumedCount),
203+
average(joinRightBindingsConsumedSum, joinRightBindingsConsumedCount));
204+
}
205+
206+
private static void recordMetric(long value, LongAdder sum, LongAdder count) {
207+
if (value < 0) {
208+
return;
209+
}
210+
sum.add(value);
211+
count.increment();
212+
}
213+
214+
private static long average(LongAdder sum, LongAdder count) {
215+
long sampleCount = count.longValue();
216+
if (sampleCount <= 0) {
217+
return -1;
218+
}
219+
return Math.max(0L, Math.round(sum.doubleValue() / sampleCount));
220+
}
221+
}
222+
223+
public static final class TelemetrySnapshot {
224+
private static final TelemetrySnapshot EMPTY = new TelemetrySnapshot(-1, -1, -1, -1, -1, -1);
225+
226+
private final long sourceRowsScannedActual;
227+
private final long sourceRowsMatchedActual;
228+
private final long sourceRowsFilteredActual;
229+
private final long joinRightIteratorsCreatedActual;
230+
private final long joinLeftBindingsConsumedActual;
231+
private final long joinRightBindingsConsumedActual;
232+
233+
private TelemetrySnapshot(long sourceRowsScannedActual, long sourceRowsMatchedActual,
234+
long sourceRowsFilteredActual, long joinRightIteratorsCreatedActual,
235+
long joinLeftBindingsConsumedActual, long joinRightBindingsConsumedActual) {
236+
this.sourceRowsScannedActual = sourceRowsScannedActual;
237+
this.sourceRowsMatchedActual = sourceRowsMatchedActual;
238+
this.sourceRowsFilteredActual = sourceRowsFilteredActual;
239+
this.joinRightIteratorsCreatedActual = joinRightIteratorsCreatedActual;
240+
this.joinLeftBindingsConsumedActual = joinLeftBindingsConsumedActual;
241+
this.joinRightBindingsConsumedActual = joinRightBindingsConsumedActual;
242+
}
243+
244+
public static TelemetrySnapshot empty() {
245+
return EMPTY;
246+
}
247+
248+
public long sourceRowsScannedActual() {
249+
return sourceRowsScannedActual;
250+
}
251+
252+
public long sourceRowsMatchedActual() {
253+
return sourceRowsMatchedActual;
254+
}
255+
256+
public long sourceRowsFilteredActual() {
257+
return sourceRowsFilteredActual;
258+
}
259+
260+
public long joinRightIteratorsCreatedActual() {
261+
return joinRightIteratorsCreatedActual;
262+
}
263+
264+
public long joinLeftBindingsConsumedActual() {
265+
return joinLeftBindingsConsumedActual;
266+
}
267+
268+
public long joinRightBindingsConsumedActual() {
269+
return joinRightBindingsConsumedActual;
270+
}
271+
272+
@Override
273+
public boolean equals(Object o) {
274+
if (this == o) {
275+
return true;
276+
}
277+
if (!(o instanceof TelemetrySnapshot)) {
278+
return false;
279+
}
280+
TelemetrySnapshot that = (TelemetrySnapshot) o;
281+
return sourceRowsScannedActual == that.sourceRowsScannedActual
282+
&& sourceRowsMatchedActual == that.sourceRowsMatchedActual
283+
&& sourceRowsFilteredActual == that.sourceRowsFilteredActual
284+
&& joinRightIteratorsCreatedActual == that.joinRightIteratorsCreatedActual
285+
&& joinLeftBindingsConsumedActual == that.joinLeftBindingsConsumedActual
286+
&& joinRightBindingsConsumedActual == that.joinRightBindingsConsumedActual;
287+
}
288+
289+
@Override
290+
public int hashCode() {
291+
return Objects.hash(sourceRowsScannedActual, sourceRowsMatchedActual, sourceRowsFilteredActual,
292+
joinRightIteratorsCreatedActual, joinLeftBindingsConsumedActual, joinRightBindingsConsumedActual);
293+
}
294+
}
295+
}

0 commit comments

Comments
 (0)