Skip to content

Commit 55a6e24

Browse files
committed
Finalize implementation
1 parent b75eaca commit 55a6e24

File tree

4 files changed

+68
-42
lines changed

4 files changed

+68
-42
lines changed

dd-trace-core/src/main/java/datadog/trace/common/metrics/MetricKey.java

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString;
66
import java.util.Collections;
77
import java.util.List;
8+
import java.util.Objects;
89

910
/** The aggregation key for tracked metrics. */
1011
public final class MetricKey {
1112
private final UTF8BytesString resource;
1213
private final UTF8BytesString service;
13-
// note: it won't participate to equals/hashcode since not part of aggregation
1414
private final UTF8BytesString serviceSource;
1515
private final UTF8BytesString operationName;
1616
private final UTF8BytesString type;
@@ -58,18 +58,34 @@ public MetricKey(
5858

5959
// Only include httpMethod and httpEndpoint in hash if they are not null
6060
// This ensures backward compatibility when the feature is disabled
61-
this.hash =
62-
-196_513_505 * Boolean.hashCode(this.isTraceRoot)
63-
+ -1_807_454_463 * this.spanKind.hashCode()
64-
+ 887_503_681 * this.peerTags.hashCode()
65-
+ (this.httpMethod != null ? 28_629_151 * this.httpMethod.hashCode() : 0)
66-
+ (this.httpEndpoint != null ? 923_521 * this.httpEndpoint.hashCode() : 0)
67-
+ 29_791 * this.resource.hashCode()
68-
+ 961 * this.service.hashCode()
69-
+ 31 * this.operationName.hashCode()
70-
+ this.type.hashCode()
71-
+ 31 * httpStatusCode
72-
+ (this.synthetics ? 1 : 0);
61+
62+
// Note: all the multiplication got constant folded at compile time (see javap -verbose ...)
63+
int tmpHash =
64+
(int) (31L * 31 * 31 * 31 * 31 * 31 * 31 * 31) * Boolean.hashCode(this.isTraceRoot) // 8
65+
+ (int) (31L * 31 * 31 * 31 * 31 * 31 * 31) * this.spanKind.hashCode() // 7
66+
+ 31 * 31 * 31 * 31 * 31 * 31 * this.peerTags.hashCode() // 6
67+
+ 31 * 31 * 31 * 31 * 31 * this.resource.hashCode() // 5
68+
+ 31 * 31 * 31 * 31 * this.service.hashCode() // 4
69+
+ 31 * 31 * 31 * this.operationName.hashCode() // 3
70+
+ 31 * 31 * this.type.hashCode() // 2
71+
+ 31 * this.httpStatusCode // 1
72+
+ (this.synthetics ? 1 : 0); // 0
73+
// optional fields
74+
if (this.serviceSource != null) {
75+
tmpHash +=
76+
(int) (31L * 31 * 31 * 31 * 31 * 31 * 31 * 31 * 31) * this.serviceSource.hashCode(); // 9
77+
}
78+
if (this.httpEndpoint != null) {
79+
tmpHash +=
80+
(int) (31L * 31 * 31 * 31 * 31 * 31 * 31 * 31 * 31 * 31)
81+
* this.httpEndpoint.hashCode(); // 10
82+
}
83+
if (this.httpMethod != null) {
84+
tmpHash +=
85+
(int) (31L * 31 * 31 * 31 * 31 * 31 * 31 * 31 * 31 * 31 * 31)
86+
* this.httpMethod.hashCode(); // 11
87+
}
88+
this.hash = tmpHash;
7389
}
7490

7591
public UTF8BytesString getResource() {
@@ -127,29 +143,19 @@ public boolean equals(Object o) {
127143
}
128144
if ((o instanceof MetricKey)) {
129145
MetricKey metricKey = (MetricKey) o;
130-
boolean basicEquals =
131-
hash == metricKey.hash
132-
&& synthetics == metricKey.synthetics
133-
&& httpStatusCode == metricKey.httpStatusCode
134-
&& resource.equals(metricKey.resource)
135-
&& service.equals(metricKey.service)
136-
&& operationName.equals(metricKey.operationName)
137-
&& type.equals(metricKey.type)
138-
&& isTraceRoot == metricKey.isTraceRoot
139-
&& spanKind.equals(metricKey.spanKind)
140-
&& peerTags.equals(metricKey.peerTags);
141-
142-
// Only compare httpMethod and httpEndpoint if at least one of them is not null
143-
// This ensures backward compatibility when the feature is disabled
144-
boolean thisHasEndpoint = httpMethod != null || httpEndpoint != null;
145-
boolean otherHasEndpoint = metricKey.httpMethod != null || metricKey.httpEndpoint != null;
146-
147-
if (thisHasEndpoint || otherHasEndpoint) {
148-
return basicEquals
149-
&& java.util.Objects.equals(httpMethod, metricKey.httpMethod)
150-
&& java.util.Objects.equals(httpEndpoint, metricKey.httpEndpoint);
151-
}
152-
return basicEquals;
146+
return hash == metricKey.hash
147+
&& synthetics == metricKey.synthetics
148+
&& httpStatusCode == metricKey.httpStatusCode
149+
&& resource.equals(metricKey.resource)
150+
&& service.equals(metricKey.service)
151+
&& operationName.equals(metricKey.operationName)
152+
&& type.equals(metricKey.type)
153+
&& isTraceRoot == metricKey.isTraceRoot
154+
&& spanKind.equals(metricKey.spanKind)
155+
&& peerTags.equals(metricKey.peerTags)
156+
&& Objects.equals(serviceSource, metricKey.serviceSource)
157+
&& Objects.equals(httpMethod, metricKey.httpMethod)
158+
&& Objects.equals(httpEndpoint, metricKey.httpEndpoint);
153159
}
154160
return false;
155161
}

dd-trace-core/src/main/java/datadog/trace/common/metrics/SerializingMetricWriter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public final class SerializingMetricWriter implements MetricWriter {
3737
private static final byte[] PEER_TAGS = "PeerTags".getBytes(ISO_8859_1);
3838
private static final byte[] HTTP_METHOD = "HTTPMethod".getBytes(ISO_8859_1);
3939
private static final byte[] HTTP_ENDPOINT = "HTTPEndpoint".getBytes(ISO_8859_1);
40-
private static final byte[] SERVICE_SOURCE = "ServiceSource".getBytes(ISO_8859_1);
40+
private static final byte[] SERVICE_SOURCE = "srv_src".getBytes(ISO_8859_1);
4141

4242
// Constant declared here for compile-time folding
4343
public static final int TRISTATE_TRUE = TriState.TRUE.serialValue;

dd-trace-core/src/test/groovy/datadog/trace/common/metrics/ConflatingMetricAggregatorTest.groovy

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -797,22 +797,26 @@ class ConflatingMetricAggregatorTest extends DDSpecification {
797797
features.supportsMetrics() >> true
798798
features.peerTags() >> []
799799
ConflatingMetricsAggregator aggregator = new ConflatingMetricsAggregator(empty,
800-
features, HealthMetrics.NO_OP, sink, writer, 10, queueSize, reportingInterval, SECONDS, true)
800+
features, HealthMetrics.NO_OP, sink, writer, 10, queueSize, reportingInterval, SECONDS, false)
801801
aggregator.start()
802802

803-
when: "publish span with a service name source"
803+
when: "publish spans with different service name source"
804804
CountDownLatch latch = new CountDownLatch(1)
805805
long duration = 100
806806
aggregator.publish([
807+
new SimpleSpan("service", "operation", "resource", "type", true, true, false, 0, duration, 200, false, 0, "source")
808+
.setTag(SPAN_KIND, "server"),
809+
new SimpleSpan("service", "operation", "resource", "type", true, true, false, 0, duration, 200, false, 0, null)
810+
.setTag(SPAN_KIND, "server"),
807811
new SimpleSpan("service", "operation", "resource", "type", true, true, false, 0, duration, 200, false, 0, "source")
808812
.setTag(SPAN_KIND, "server")
809813
])
810814
aggregator.report()
811815
def latchTriggered = latch.await(2, SECONDS)
812816

813-
then: "should create the same metric keys for spans with and without s"
817+
then: "should create the different metric keys for spans with and without sources"
814818
latchTriggered
815-
1 * writer.startBucket(1, _, _)
819+
1 * writer.startBucket(2, _, _)
816820
1 * writer.add(new MetricKey(
817821
"resource",
818822
"service",
@@ -826,6 +830,22 @@ class ConflatingMetricAggregatorTest extends DDSpecification {
826830
[],
827831
null,
828832
null
833+
), { AggregateMetric value ->
834+
value.getHitCount() == 2 && value.getDuration() == 2 * duration
835+
})
836+
1 * writer.add(new MetricKey(
837+
"resource",
838+
"service",
839+
"operation",
840+
null,
841+
"type",
842+
200,
843+
false,
844+
false,
845+
"server",
846+
[],
847+
null,
848+
null
829849
), { AggregateMetric value ->
830850
value.getHitCount() == 1 && value.getDuration() == duration
831851
})

dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SerializingMetricWriterTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ class SerializingMetricWriterTest extends DDSpecification {
230230
++elementCount
231231
// Service source is only present when the service name has been overridden by the tracer
232232
if (hasServiceSource) {
233-
assert unpacker.unpackString() == "ServiceSource"
233+
assert unpacker.unpackString() == "srv_src"
234234
assert unpacker.unpackString() == key.getServiceSource().toString()
235235
++elementCount
236236
}

0 commit comments

Comments
 (0)