Use constant for baggage validation bitsets (#3274)

* Use constant for baggage validation bitsets

* Spot

* Move to element

* private
This commit is contained in:
Anuraag Agrawal 2021-06-04 09:26:00 +09:00 committed by GitHub
parent d044890a7c
commit d6849219a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 66 additions and 32 deletions

View File

@ -8,8 +8,11 @@ package io.opentelemetry.api.baggage.propagation;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapGetter;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.annotation.Nullable;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
@ -25,24 +28,28 @@ import org.openjdk.jmh.annotations.Warmup;
@State(Scope.Thread)
public class W3CBaggagePropagatorBenchmark {
// pre-allocate the keys & values to remove one possible confounding factor
private static String header;
private static final Map<String, String> SMALL_BAGGAGE;
private static final Map<String, String> LARGE_BAGGAGE;
static {
for (int i = 0; i < 100; i++) {
header +=
"key"
+ i
+ " = value"
+ i
+ ";metaKey"
+ i
+ "=\tmetaVal"
+ i
+ ",broken)key"
+ i
+ "=value,";
}
List<String> baggages =
IntStream.range(0, 100)
.mapToObj(
i ->
"key"
+ i
+ " = value"
+ i
+ ";metaKey"
+ i
+ "=\tmetaVal"
+ i
+ ",broken)key"
+ i
+ "=value")
.collect(Collectors.toList());
SMALL_BAGGAGE = Collections.singletonMap("baggage", String.join(",", baggages.subList(0, 5)));
LARGE_BAGGAGE = Collections.singletonMap("baggage", String.join(",", baggages));
}
private static final TextMapGetter<Map<String, String>> getter =
@ -61,13 +68,23 @@ public class W3CBaggagePropagatorBenchmark {
@Benchmark
@BenchmarkMode({Mode.AverageTime})
@Fork(1)
@Fork(3)
@Measurement(iterations = 15, time = 1)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5, time = 1)
public Context defaultPropagatorExtractBenchmark() {
public Context smallBaggage() {
W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance();
return propagator.extract(Context.root(), SMALL_BAGGAGE, getter);
}
return propagator.extract(Context.root(), Collections.singletonMap("baggage", header), getter);
@Benchmark
@BenchmarkMode({Mode.AverageTime})
@Fork(3)
@Measurement(iterations = 15, time = 1)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5, time = 1)
public Context largeBaggage() {
W3CBaggagePropagator propagator = W3CBaggagePropagator.getInstance();
return propagator.extract(Context.root(), LARGE_BAGGAGE, getter);
}
}

View File

@ -14,7 +14,22 @@ import java.util.BitSet;
*/
class Element {
private final BitSet excluded = new BitSet(128);
private static final BitSet EXCLUDED_KEY_CHARS = new BitSet(128);
private static final BitSet EXCLUDED_VALUE_CHARS = new BitSet(128);
static {
for (char c :
new char[] {
'(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}'
}) {
EXCLUDED_KEY_CHARS.set(c);
}
for (char c : new char[] {'"', ',', ';', '\\'}) {
EXCLUDED_VALUE_CHARS.set(c);
}
}
private final BitSet excluded;
private boolean leadingSpace;
private boolean readingValue;
@ -23,15 +38,21 @@ class Element {
private int end;
private String value;
static Element createKeyElement() {
return new Element(EXCLUDED_KEY_CHARS);
}
static Element createValueElement() {
return new Element(EXCLUDED_VALUE_CHARS);
}
/**
* Constructs element instance.
*
* @param excludedChars characters that are not allowed for this type of an element
* @param excluded characters that are not allowed for this type of an element
*/
Element(char[] excludedChars) {
for (char excludedChar : excludedChars) {
excluded.set(excludedChar);
}
private Element(BitSet excluded) {
this.excluded = excluded;
reset(0);
}

View File

@ -26,12 +26,8 @@ class Parser {
private final String baggageHeader;
private final Element key =
new Element(
new char[] {
'(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}'
});
private final Element value = new Element(new char[] {'"', ',', ';', '\\'});
private final Element key = Element.createKeyElement();
private final Element value = Element.createValueElement();
private String meta;
private State state;