mirror of https://github.com/grpc/grpc-java.git
core: allow attributes to be built multiple times
This commit is contained in:
parent
401066ada3
commit
291f17059e
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright 2017, gRPC Authors All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.grpc;
|
||||
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
|
||||
/**
|
||||
* Javadoc.
|
||||
*/
|
||||
@State(Scope.Benchmark)
|
||||
public class AttributesBenchmark {
|
||||
|
||||
public Attributes base = Attributes.EMPTY;
|
||||
|
||||
public Attributes.Key<Object>[] keys;
|
||||
public Attributes withValue = base;
|
||||
|
||||
/**
|
||||
* Javadoc.
|
||||
*/
|
||||
@Setup
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public void setUp() {
|
||||
keys = new Attributes.Key[iterations];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
keys[i] = Attributes.Key.of("any");
|
||||
withValue = Attributes.newBuilder(withValue).set(keys[i], "yes").build();
|
||||
}
|
||||
}
|
||||
|
||||
@Param({"1", "2", "10"})
|
||||
public int iterations;
|
||||
|
||||
/**
|
||||
* Javadoc.
|
||||
*/
|
||||
@Benchmark
|
||||
@BenchmarkMode(Mode.SampleTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
public Attributes chain() {
|
||||
Attributes attr = base;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
attr = Attributes.newBuilder(attr).set(keys[i], new Object()).build();
|
||||
}
|
||||
return attr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Javadoc.
|
||||
*/
|
||||
@Benchmark
|
||||
@BenchmarkMode(Mode.SampleTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
public Object lookup() {
|
||||
return withValue.get(keys[0]);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,10 +16,13 @@
|
|||
|
||||
package io.grpc;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
|
@ -31,11 +34,13 @@ import javax.annotation.concurrent.Immutable;
|
|||
@Immutable
|
||||
public final class Attributes {
|
||||
|
||||
private final HashMap<Key<?>, Object> data = new HashMap<Key<?>, Object>();
|
||||
private final Map<Key<?>, Object> data;
|
||||
|
||||
public static final Attributes EMPTY = new Attributes();
|
||||
public static final Attributes EMPTY = new Attributes(Collections.<Key<?>, Object>emptyMap());
|
||||
|
||||
private Attributes() {
|
||||
private Attributes(Map<Key<?>, Object> data) {
|
||||
assert data != null;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -60,14 +65,15 @@ public final class Attributes {
|
|||
* Create a new builder that is pre-populated with the content from a given container.
|
||||
*/
|
||||
public static Builder newBuilder(Attributes base) {
|
||||
return newBuilder().setAll(base);
|
||||
checkNotNull(base, "base");
|
||||
return new Builder(base);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new builder.
|
||||
*/
|
||||
public static Builder newBuilder() {
|
||||
return new Builder();
|
||||
return new Builder(EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -144,30 +150,45 @@ public final class Attributes {
|
|||
* The helper class to build an Attributes instance.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private Attributes product;
|
||||
private Attributes base;
|
||||
private Map<Key<?>, Object> newdata;
|
||||
|
||||
private Builder() {
|
||||
this.product = new Attributes();
|
||||
private Builder(Attributes base) {
|
||||
assert base != null;
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
private Map<Key<?>, Object> data(int size) {
|
||||
if (newdata == null) {
|
||||
newdata = new IdentityHashMap<Key<?>, Object>(size);
|
||||
}
|
||||
return newdata;
|
||||
}
|
||||
|
||||
public <T> Builder set(Key<T> key, T value) {
|
||||
product.data.put(key, value);
|
||||
data(1).put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public <T> Builder setAll(Attributes other) {
|
||||
product.data.putAll(other.data);
|
||||
data(other.data.size()).putAll(other.data);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the attributes. Can only be called once.
|
||||
* Build the attributes.
|
||||
*/
|
||||
public Attributes build() {
|
||||
Preconditions.checkState(product != null, "Already built");
|
||||
Attributes result = product;
|
||||
product = null;
|
||||
return result;
|
||||
if (newdata != null) {
|
||||
for (Entry<Key<?>, Object> entry : base.data.entrySet()) {
|
||||
if (!newdata.containsKey(entry.getKey())) {
|
||||
newdata.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
base = new Attributes(newdata);
|
||||
newdata = null;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue