io.servicetalk.client.api.partition.PartitionAttributes Maven / Gradle / Ivy
/*
* Copyright © 2018 Apple Inc. and the ServiceTalk project authors
*
* 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.servicetalk.client.api.partition;
import io.servicetalk.client.api.ClientGroup;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import javax.annotation.Nullable;
import static java.lang.Integer.compare;
import static java.lang.String.valueOf;
import static java.util.Objects.requireNonNull;
/**
* Provide a way to describe a partition using a collection of attributes. Typically only a single type of any
* particular {@link Key} exists in each {@link PartitionAttributes}. For example:
*
* { [Key(shard) = "shard X"], [Key(data center) = "data center X"], [Key(is main) = "false/true"] }
*
* This construct allows for the attributes to partially specify a partition and preform "wild card" type matching.
*
* @deprecated We are unaware of anyone using "partition" feature and plan to remove it in future releases.
* If you depend on it, consider using {@link ClientGroup} as an alternative or reach out to the maintainers describing
* the use-case.
*/
@Deprecated
public interface PartitionAttributes { // FIXME: 0.43 - remove deprecated interface
/**
* A key identifies a specific object in a {@link PartitionAttributes}.
* @param The type of value associated with a {@link PartitionAttributes.Key}.
*/
final class Key implements Comparable {
private static final AtomicInteger nextIdCounter = new AtomicInteger();
private final int id;
private final String toString;
private Key() {
id = nextIdCounter.getAndIncrement();
toString = valueOf(id);
}
private Key(String toString) {
id = nextIdCounter.getAndIncrement();
// Append the id so it is clear that two instances created with the same toString value are different.
this.toString = requireNonNull(toString) + '-' + id;
}
/**
* Create a new {@link Key} which has a {@link String} used only in the {@link #toString()} method for debugging
* visibility.
*
* Comparison between {@link Key} objects should be assumed to be on an instance basis.
* In general {@code newKey(str) != newKey(str)}.
* @param toString The value to use in {@link #toString()}. This WILL NOT be used in
* comparisons between {@link Key} objects.
* @param The value type associated with the {@link Key}.
* @return a new {@link Key} which has a {@link String} used only in the {@link #toString()} method for
* debugging visibility.
*/
public static Key newKey(String toString) {
return new Key<>(toString);
}
/**
* Create a new instance.
*
* Comparison between {@link Key} objects should be assumed to be on an instance basis.
* In general {@code newKey() != newKey()}.
* @param The value type associated with the {@link Key}.
* @return a new instance.
*/
public static Key newKey() {
return new Key<>();
}
@Override
public String toString() {
return toString;
}
@Override
public boolean equals(Object o) {
return (o instanceof Key) && id == ((Key) o).id;
}
@Override
public int hashCode() {
return id;
}
@Override
public int compareTo(Key o) {
return compare(id, o.id);
}
}
/**
* Get the value associated with {@code key}.
* @param key The key to lookup.
* @param The expected value type associated with {@code key}.
* @return the value associated with {@code key}, or {@code null}.
*/
@Nullable
T get(Key key);
/**
* Determine if there is a value associated with {@code key}.
* @param key The key to check if there is any associated value for.
* @param The expected value type associated with {@code key}.
* @return {@code true} if there is a value associated with {@code key}.
*/
default boolean contains(Key key) {
return get(key) != null;
}
/**
* Iterate over the key/value pairs in this collection.
* @param action Invoked for each key/value pair in this collection.
*/
void forEach(BiConsumer action);
/**
* Determine how many key/value pairs are contained in this collection.
* @return the number of key/value pairs are contained in this collection.
*/
int size();
/**
* Determine if there are no key/value pairs in this collection.
* @return {@code true} if there are no key/value pairs in this collection.
*/
boolean isEmpty();
}