Preencode attribute keys into utf8 bytes. (#3576)
* Use constants for AttributeKeys in JMH * Preencode attribute keys into utf8 bytes. * Spot * Ignore * Be lazy * Boil
This commit is contained in:
parent
060e50ed5f
commit
ece161f6e0
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
package io.opentelemetry.api.common;
|
||||
|
||||
import io.opentelemetry.api.internal.InternalAttributeKeyImpl;
|
||||
import java.util.List;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
|
|
@ -27,41 +28,41 @@ public interface AttributeKey<T> {
|
|||
|
||||
/** Returns a new AttributeKey for String valued attributes. */
|
||||
static AttributeKey<String> stringKey(String key) {
|
||||
return AttributeKeyImpl.create(key, AttributeType.STRING);
|
||||
return InternalAttributeKeyImpl.create(key, AttributeType.STRING);
|
||||
}
|
||||
|
||||
/** Returns a new AttributeKey for Boolean valued attributes. */
|
||||
static AttributeKey<Boolean> booleanKey(String key) {
|
||||
return AttributeKeyImpl.create(key, AttributeType.BOOLEAN);
|
||||
return InternalAttributeKeyImpl.create(key, AttributeType.BOOLEAN);
|
||||
}
|
||||
|
||||
/** Returns a new AttributeKey for Long valued attributes. */
|
||||
static AttributeKey<Long> longKey(String key) {
|
||||
return AttributeKeyImpl.create(key, AttributeType.LONG);
|
||||
return InternalAttributeKeyImpl.create(key, AttributeType.LONG);
|
||||
}
|
||||
|
||||
/** Returns a new AttributeKey for Double valued attributes. */
|
||||
static AttributeKey<Double> doubleKey(String key) {
|
||||
return AttributeKeyImpl.create(key, AttributeType.DOUBLE);
|
||||
return InternalAttributeKeyImpl.create(key, AttributeType.DOUBLE);
|
||||
}
|
||||
|
||||
/** Returns a new AttributeKey for List<String> valued attributes. */
|
||||
static AttributeKey<List<String>> stringArrayKey(String key) {
|
||||
return AttributeKeyImpl.create(key, AttributeType.STRING_ARRAY);
|
||||
return InternalAttributeKeyImpl.create(key, AttributeType.STRING_ARRAY);
|
||||
}
|
||||
|
||||
/** Returns a new AttributeKey for List<Boolean> valued attributes. */
|
||||
static AttributeKey<List<Boolean>> booleanArrayKey(String key) {
|
||||
return AttributeKeyImpl.create(key, AttributeType.BOOLEAN_ARRAY);
|
||||
return InternalAttributeKeyImpl.create(key, AttributeType.BOOLEAN_ARRAY);
|
||||
}
|
||||
|
||||
/** Returns a new AttributeKey for List<Long> valued attributes. */
|
||||
static AttributeKey<List<Long>> longArrayKey(String key) {
|
||||
return AttributeKeyImpl.create(key, AttributeType.LONG_ARRAY);
|
||||
return InternalAttributeKeyImpl.create(key, AttributeType.LONG_ARRAY);
|
||||
}
|
||||
|
||||
/** Returns a new AttributeKey for List<Double> valued attributes. */
|
||||
static AttributeKey<List<Double>> doubleArrayKey(String key) {
|
||||
return AttributeKeyImpl.create(key, AttributeType.DOUBLE_ARRAY);
|
||||
return InternalAttributeKeyImpl.create(key, AttributeType.DOUBLE_ARRAY);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,18 +3,28 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.api.common;
|
||||
package io.opentelemetry.api.internal;
|
||||
|
||||
import io.opentelemetry.api.common.AttributeKey;
|
||||
import io.opentelemetry.api.common.AttributeType;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
final class AttributeKeyImpl<T> implements AttributeKey<T> {
|
||||
/**
|
||||
* Default AttributeKey implementation which preencodes to UTF8 for OTLP export.
|
||||
*
|
||||
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
|
||||
* at any time.
|
||||
*/
|
||||
public final class InternalAttributeKeyImpl<T> implements AttributeKey<T> {
|
||||
|
||||
private final AttributeType type;
|
||||
private final String key;
|
||||
private final int hashCode;
|
||||
|
||||
private AttributeKeyImpl(AttributeType type, String key) {
|
||||
private byte[] keyUtf8;
|
||||
|
||||
private InternalAttributeKeyImpl(AttributeType type, String key) {
|
||||
if (type == null) {
|
||||
throw new NullPointerException("Null type");
|
||||
}
|
||||
|
|
@ -38,8 +48,8 @@ final class AttributeKeyImpl<T> implements AttributeKey<T> {
|
|||
// the class loader automatically resolves its super classes (interfaces), which in this case is
|
||||
// Context, which would be the same class (interface) being instrumented at that time,
|
||||
// which would lead to the JVM throwing a LinkageError "attempted duplicate interface definition"
|
||||
static <T> AttributeKey<T> create(@Nullable String key, AttributeType type) {
|
||||
return new AttributeKeyImpl<>(type, key != null ? key : "");
|
||||
public static <T> AttributeKey<T> create(@Nullable String key, AttributeType type) {
|
||||
return new InternalAttributeKeyImpl<>(type, key != null ? key : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -52,13 +62,23 @@ final class AttributeKeyImpl<T> implements AttributeKey<T> {
|
|||
return key;
|
||||
}
|
||||
|
||||
/** Returns the key, encoded as UTF-8 bytes. */
|
||||
public byte[] getKeyUtf8() {
|
||||
byte[] keyUtf8 = this.keyUtf8;
|
||||
if (keyUtf8 == null) {
|
||||
keyUtf8 = key.getBytes(StandardCharsets.UTF_8);
|
||||
this.keyUtf8 = keyUtf8;
|
||||
}
|
||||
return keyUtf8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (o instanceof AttributeKeyImpl) {
|
||||
AttributeKeyImpl<?> that = (AttributeKeyImpl<?>) o;
|
||||
if (o instanceof InternalAttributeKeyImpl) {
|
||||
InternalAttributeKeyImpl<?> that = (InternalAttributeKeyImpl<?>) o;
|
||||
return this.type.equals(that.getType()) && this.key.equals(that.getKey());
|
||||
}
|
||||
return false;
|
||||
|
|
@ -7,6 +7,7 @@ package io.opentelemetry.api.common;
|
|||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.opentelemetry.api.internal.InternalAttributeKeyImpl;
|
||||
import nl.jqno.equalsverifier.EqualsVerifier;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -14,9 +15,12 @@ class AttributeKeyTest {
|
|||
|
||||
@Test
|
||||
void equalsVerifier() {
|
||||
EqualsVerifier.forClass(AttributeKeyImpl.class)
|
||||
EqualsVerifier.forClass(InternalAttributeKeyImpl.class)
|
||||
.withIgnoredFields("keyUtf8")
|
||||
.withCachedHashCode(
|
||||
"hashCode", "buildHashCode", (AttributeKeyImpl<?>) AttributeKey.stringKey("test"))
|
||||
"hashCode",
|
||||
"buildHashCode",
|
||||
(InternalAttributeKeyImpl<?>) AttributeKey.stringKey("test"))
|
||||
.verify();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ package io.opentelemetry.exporter.otlp.internal;
|
|||
|
||||
import io.opentelemetry.api.common.AttributeKey;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.internal.InternalAttributeKeyImpl;
|
||||
import io.opentelemetry.proto.common.v1.internal.AnyValue;
|
||||
import io.opentelemetry.proto.common.v1.internal.ArrayValue;
|
||||
import io.opentelemetry.proto.common.v1.internal.KeyValue;
|
||||
|
|
@ -41,7 +42,14 @@ final class KeyValueMarshaler extends MarshalerWithSize {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
static KeyValueMarshaler create(AttributeKey<?> attributeKey, Object value) {
|
||||
byte[] keyUtf8 = MarshalerUtil.toBytes(attributeKey.getKey());
|
||||
final byte[] keyUtf8;
|
||||
if (attributeKey.getKey().isEmpty()) {
|
||||
keyUtf8 = MarshalerUtil.EMPTY_BYTES;
|
||||
} else if (attributeKey instanceof InternalAttributeKeyImpl) {
|
||||
keyUtf8 = ((InternalAttributeKeyImpl<?>) attributeKey).getKeyUtf8();
|
||||
} else {
|
||||
keyUtf8 = attributeKey.getKey().getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
switch (attributeKey.getType()) {
|
||||
case STRING:
|
||||
return new KeyValueMarshaler(
|
||||
|
|
|
|||
Loading…
Reference in New Issue