You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aurora.apache.org by zm...@apache.org on 2015/08/26 23:00:35 UTC
[45/51] [partial] aurora git commit: Move packages from
com.twitter.common to org.apache.aurora.common
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/collections/BoundedQueue.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/collections/BoundedQueue.java b/commons/src/main/java/com/twitter/common/collections/BoundedQueue.java
deleted file mode 100644
index 5c37f1c..0000000
--- a/commons/src/main/java/com/twitter/common/collections/BoundedQueue.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * 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 com.twitter.common.collections;
-
-import java.util.Iterator;
-import java.util.concurrent.LinkedBlockingDeque;
-
-/**
- * A limited implementation of a bounded queue. Values can be added and iterated over, and will
- * automatically expire when the queue exceeds capacity.
- *
- * @param <T> The type that this queue contains.
- *
- * @author William Farner
-*/
-public class BoundedQueue<T> implements Iterable<T> {
- private final LinkedBlockingDeque<T> values;
-
- /**
- * Creates a new bounded queue.
- *
- * @param limit Maximum number of items that can be in the queue at any time.
- */
- public BoundedQueue(int limit) {
- values = new LinkedBlockingDeque<T>(limit);
- }
-
- /**
- * Adds a value to head of the queue, evicting the oldest item if the queue is at capacity.
- *
- * @param value Value to add.
- */
- public synchronized void add(T value) {
- if (values.remainingCapacity() == 0) {
- values.removeFirst();
- }
- values.addLast(value);
- }
-
- /**
- * Removes all values from the queue.
- */
- public synchronized void clear() {
- values.clear();
- }
-
- /**
- * Returns the size of the queue.
- *
- * @return The current queue length.
- */
- public synchronized int size() {
- return values.size();
- }
-
- @Override
- public synchronized Iterator<T> iterator() {
- return values.iterator();
- }
-
- @Override
- public synchronized String toString() {
- return values.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/collections/Iterables2.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/collections/Iterables2.java b/commons/src/main/java/com/twitter/common/collections/Iterables2.java
deleted file mode 100644
index 7f80c8e..0000000
--- a/commons/src/main/java/com/twitter/common/collections/Iterables2.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/**
- * 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 com.twitter.common.collections;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import com.google.common.base.Function;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-/**
- * Utility functions for dealing with iterables.
- *
- * @author William Farner
- */
-public final class Iterables2 {
-
- private Iterables2() {
- // Utility class.
- }
-
- /**
- * An iterator that zips multiple iterables into a single list iterator, filling missing values
- * with a provided default.
- *
- * @param <T> The value type for the iterator.
- */
- private static class ZippingIterator<T> implements Iterator<List<T>> {
-
- private final Iterable<Iterable<T>> iterables;
- private final T defaultValue;
-
- private List<Iterator<T>> iterators = null;
- private final LoadingCache<Iterator<T>, Boolean> overflowing = CacheBuilder.newBuilder().build(
- new CacheLoader<Iterator<T>, Boolean>() {
- @Override public Boolean load(Iterator<T> iterator) {
- return false;
- }
- });
-
- ZippingIterator(Iterable<Iterable<T>> iterables, T defaultValue) {
- this.iterables = iterables;
- this.defaultValue = defaultValue;
- }
-
- private void init() {
- if (iterators == null) {
- // Iterables -> Iterators.
- iterators = ImmutableList.copyOf(Iterables.transform(iterables,
- new Function<Iterable<T>, Iterator<T>>() {
- @Override public Iterator<T> apply(Iterable<T> it) { return it.iterator(); }
- }));
- }
- }
-
- @Override public boolean hasNext() {
- init();
- for (Iterator<T> it : iterators) {
- if (it.hasNext()) {
- return true;
- }
- }
-
- return false;
- }
-
- @Override public List<T> next() {
- init();
- List<T> data = new ArrayList<T>(iterators.size());
-
- for (Iterator<T> it : iterators) {
- if (it.hasNext()) {
- data.add(it.next());
- } else {
- overflowing.asMap().put(it, true);
- data.add(defaultValue);
- }
- }
-
- return data;
- }
-
- @Override public void remove() {
- init();
- for (Iterator<T> it : iterators) {
- if (!overflowing.getUnchecked(it)) {
- it.remove();
- }
- }
- }
-
- @Override public String toString() {
- return Lists.newArrayList(iterables).toString();
- }
- }
-
- /**
- * Zips multiple iterables into one iterable that will return iterators to step over
- * rows of the input iterators (columns). The order of the returned values within each row will
- * match the ordering of the input iterables. The iterators will iterate the length of the longest
- * input iterable, filling other columns with {@code defaultValue}.
- * The returned iterator is lazy, in that 'rows' are constructed as they are requested.
- *
- * @param iterables Columns to iterate over.
- * @param defaultValue Default fill value when an input iterable is exhausted.
- * @param <T> Type of value being iterated over.
- * @return An iterator that iterates over rows of the input iterables.
- */
- public static <T> Iterable<List<T>> zip(final Iterable<Iterable<T>> iterables,
- final T defaultValue) {
-
- return new Iterable<List<T>>() {
- @Override public Iterator<List<T>> iterator() {
- return new ZippingIterator<T>(iterables, defaultValue);
- }
- };
- }
-
- /**
- * Varargs convenience function to call {@link #zip(Iterable, Object)}.
- *
- * @param defaultValue Default fill value when an input iterable is exhausted.
- * @param iterables Columns to iterate over.
- * @param <T> Type of value being iterated over.
- * @return An iterator that iterates over rows of the input iterables.
- */
- public static <T> Iterable<List<T>> zip(T defaultValue, Iterable<T>... iterables) {
- return zip(Arrays.asList(iterables), defaultValue);
- }
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/collections/Multimaps.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/collections/Multimaps.java b/commons/src/main/java/com/twitter/common/collections/Multimaps.java
deleted file mode 100644
index d09cc07..0000000
--- a/commons/src/main/java/com/twitter/common/collections/Multimaps.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/**
- * 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 com.twitter.common.collections;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multiset;
-import com.google.common.collect.Ordering;
-import com.google.common.collect.Sets;
-
-/**
- * Utility class for functions related to Multimaps in the java collections library.
- *
- * @author William Farner
- */
-public final class Multimaps {
-
- private Multimaps() {
- // Utility.
- }
-
- /**
- * Prunes a multimap based on a predicate, returning the pruned values. The input map will be
- * modified.
- *
- * @param map The multimap to prune.
- * @param filterRule The pruning rule. When the predicate returns {@code false} for an entry, it
- * will be pruned, otherwise it will be retained.
- * @param <K> The key type in the multimap.
- * @param <V> The value type in the multimap.
- * @return A new multimap, containing the pruned keys/values.
- */
- public static <K, V> Multimap<K, V> prune(Multimap<K, V> map,
- Predicate<? super Collection<V>> filterRule) {
- Preconditions.checkNotNull(map);
- Preconditions.checkNotNull(filterRule);
- Multimap<K, V> pruned = ArrayListMultimap.create();
- Iterator<Map.Entry<K, Collection<V>>> asMapItr = map.asMap().entrySet().iterator();
- while (asMapItr.hasNext()) {
- Map.Entry<K, Collection<V>> asMapEntry = asMapItr.next();
- if (!filterRule.apply(asMapEntry.getValue())) {
- pruned.putAll(asMapEntry.getKey(), asMapEntry.getValue());
- asMapItr.remove();
- }
- }
-
- return pruned;
- }
-
- private static final class AtLeastSize implements Predicate<Collection<?>> {
- private final int minSize;
-
- AtLeastSize(int minSize) {
- Preconditions.checkArgument(minSize >= 0);
- this.minSize = minSize;
- }
-
- @Override
- public boolean apply(Collection<?> c) {
- return c.size() >= minSize;
- }
- }
-
- /**
- * Convenience method to prune key/values pairs where the size of the value collection is below a
- * threshold.
- *
- * @param map The multimap to prune.
- * @param minSize The minimum size for retained value collections.
- * @param <K> The key type in the multimap.
- * @param <V> The value type in the multimap.
- * @return A new multimap, containing the pruned keys/values.
- * @throws IllegalArgumentException if minSize < 0
- */
- public static <K, V> Multimap<K, V> prune(Multimap<K, V> map, int minSize) {
- return prune(map, new AtLeastSize(minSize));
- }
-
- /**
- * Returns the set of keys associated with groups of a size greater than or equal to a given size.
- *
- * @param map The multimap to search.
- * @param minSize The minimum size to return associated keys for.
- * @param <K> The key type for the multimap.
- * @return The keys associated with groups of size greater than or equal to {@code minSize}.
- * @throws IllegalArgumentException if minSize < 0
- */
- public static <K> Set<K> getLargeGroups(Multimap<K, ?> map, int minSize) {
- return Sets.newHashSet(
- Maps.filterValues(map.asMap(), new AtLeastSize(minSize)).keySet());
- }
-
- /**
- * Returns the set of keys associated with the largest values in the multimap.
- *
- * @param map The multimap to search.
- * @param topValues Number of groupings to find the keys for.
- * @return The keys associated with the largest groups, of maximum size {@code topValues}.
- */
- public static <K> Set<K> getLargestGroups(Multimap<K, ?> map, int topValues) {
- Ordering<Multiset.Entry<K>> groupOrdering = new Ordering<Multiset.Entry<K>>() {
- @Override
- public int compare(Multiset.Entry<K> entry1, Multiset.Entry<K> entry2) {
- return entry1.getCount() - entry2.getCount();
- // overflow-safe, since sizes are nonnegative
- }
- };
- Set<K> topKeys = Sets.newHashSetWithExpectedSize(topValues);
- for (Multiset.Entry<K> entry
- : groupOrdering.greatestOf(map.keys().entrySet(), topValues)) {
- topKeys.add(entry.getElement());
- }
- return topKeys;
- }
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/collections/Pair.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/collections/Pair.java b/commons/src/main/java/com/twitter/common/collections/Pair.java
deleted file mode 100644
index 3de6d26..0000000
--- a/commons/src/main/java/com/twitter/common/collections/Pair.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * 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 com.twitter.common.collections;
-
-import javax.annotation.Nullable;
-
-import com.google.common.base.Function;
-
-import org.apache.commons.lang.builder.EqualsBuilder;
-import org.apache.commons.lang.builder.HashCodeBuilder;
-
-
-/**
- * An immutable 2-tuple with value-equals semantics.
- *
- * @param <A> The type of the 1st item in the pair.
- * @param <B> The type of the 2nd item in the pair.
- *
- * @author William Farner
- */
-public class Pair<A, B> {
-
- @Nullable
- private final A first;
- @Nullable
- private final B second;
-
- /**
- * Creates a new pair.
- *
- * @param first The first value.
- * @param second The second value.
- */
- public Pair(@Nullable A first, @Nullable B second) {
- this.first = first;
- this.second = second;
- }
-
- @Nullable
- public A getFirst() {
- return first;
- }
-
- @Nullable
- public B getSecond() {
- return second;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) { return true; }
- if (!(o instanceof Pair)) { return false; }
-
- Pair<?, ?> that = (Pair<?, ?>) o;
- return new EqualsBuilder()
- .append(this.first, that.first)
- .append(this.second, that.second)
- .isEquals();
- }
-
- @Override
- public String toString() {
- return String.format("(%s, %s)", getFirst(), getSecond());
- }
-
- @Override
- public int hashCode() {
- return new HashCodeBuilder()
- .append(first)
- .append(second)
- .toHashCode();
- }
-
- /**
- * Creates a function that can extract the first item of pairs of the given type parametrization.
- *
- * @param <S> The type of the 1st item in the pair.
- * @param <T> The type of the 2nd item in the pair.
- * @return A function that will extract the 1st item in a pair.
- */
- public static <S, T> Function<Pair<S, T>, S> first() {
- return new Function<Pair<S, T>, S>() {
- @Override public S apply(Pair<S, T> pair) {
- return pair.first;
- }
- };
- }
-
- /**
- * Creates a function that can extract the second item of pairs of the given type parametrization.
- *
- * @param <S> The type of the 1st item in the pair.
- * @param <T> The type of the 2nd item in the pair.
- * @return A function that will extract the 2nd item in a pair.
- */
- public static <S, T> Function<Pair<S, T>, T> second() {
- return new Function<Pair<S, T>, T>() {
- @Override public T apply(Pair<S, T> pair) {
- return pair.second;
- }
- };
- }
-
- /**
- * Convenience method to create a pair.
- *
- * @param a The first value.
- * @param b The second value.
- * @param <A> The type of the 1st item in the pair.
- * @param <B> The type of the 2nd item in the pair.
- * @return A new pair of [a, b].
- */
- public static <A, B> Pair<A, B> of(@Nullable A a, @Nullable B b) {
- return new Pair<A, B>(a, b);
- }
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/inject/Bindings.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/inject/Bindings.java b/commons/src/main/java/com/twitter/common/inject/Bindings.java
deleted file mode 100644
index 57654de..0000000
--- a/commons/src/main/java/com/twitter/common/inject/Bindings.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/**
- * 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 com.twitter.common.inject;
-
-import java.lang.annotation.Annotation;
-
-import javax.inject.Qualifier;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.inject.AbstractModule;
-import com.google.inject.Binder;
-import com.google.inject.BindingAnnotation;
-import com.google.inject.Key;
-import com.google.inject.Module;
-import com.google.inject.PrivateModule;
-import com.google.inject.TypeLiteral;
-import com.google.inject.binder.LinkedBindingBuilder;
-import com.google.inject.multibindings.Multibinder;
-import com.google.inject.name.Names;
-
-/**
- * A utility that helps with guice bindings.
- *
- * @author John Sirois
- */
-public final class Bindings {
-
-
- private Bindings() {
- // utility
- }
-
- /**
- * Equivalent to calling {@code requireBinding(binder, Key.get(required, Names.named(namedKey)))}.
- */
- public static void requireNamedBinding(Binder binder, Class<?> required, String namedKey) {
- requireBinding(binder, Key.get(Preconditions.checkNotNull(required),
- Names.named(Preconditions.checkNotNull(namedKey))));
- }
-
- /**
- * Equivalent to calling {@code requireBinding(binder, Key.get(required))}.
- */
- public static void requireBinding(Binder binder, Class<?> required) {
- requireBinding(binder, Key.get(Preconditions.checkNotNull(required)));
- }
-
- /**
- * Registers {@code required} as non-optional dependency in the {@link com.google.inject.Injector}
- * associated with {@code binder}.
- *
- * @param binder A binder to require bindings against.
- * @param required The dependency that is required.
- */
- public static void requireBinding(Binder binder, final Key<?> required) {
- Preconditions.checkNotNull(binder);
- Preconditions.checkNotNull(required);
-
- binder.install(new AbstractModule() {
- @Override protected void configure() {
- requireBinding(required);
- }
- });
- }
-
- /**
- * A convenient version of {@link #exposing(Iterable, com.google.inject.Module)} when you just
- * want to expose a single binding.
- */
- public static Module exposing(Key<?> key, Module module) {
- return exposing(ImmutableList.of(key), module);
- }
-
- /**
- * Creates a module that hides all the given module's bindings and only exposes bindings for
- * the given key.
- *
- * @param keys The keys of the bindings to expose.
- * @param module The module to hide most bindings for.
- * @return A limited visibility module.
- */
- public static Module exposing(final Iterable<? extends Key<?>> keys, final Module module) {
- Preconditions.checkNotNull(keys);
- Preconditions.checkNotNull(module);
-
- return new PrivateModule() {
- @Override protected void configure() {
- install(module);
- for (Key<?> key : keys) {
- expose(key);
- }
- }
- };
- }
-
- /**
- * A guice binding helper that allows for any combination of Class, TypeLiteral or Key binding
- * without forcing guiced implementation to provide all the overloaded binding methods they would
- * otherwise have to.
- *
- * @param <T> The type this helper can be used to bind implementations for.
- */
- public interface BindHelper<T> {
-
- /**
- * Associates this BindHelper with an Injector instance.
- *
- * @param binder The binder for the injector implementations will be bound in.
- * @return A binding builder that can be used to bind an implementation with.
- */
- LinkedBindingBuilder<T> with(Binder binder);
- }
-
- /**
- * Creates a BindHelper for the given binding key that can be used to bind a single instance.
- *
- * @param key The binding key the returned BindHelper can be use to bind implementations for.
- * @param <T> The type the returned BindHelper can be used to bind implementations for.
- * @return A BindHelper that can be used to bind an implementation with.
- */
- public static <T> BindHelper<T> binderFor(final Key<T> key) {
- return new BindHelper<T>() {
- public LinkedBindingBuilder<T> with(Binder binder) {
- return binder.bind(key);
- }
- };
- }
-
- /**
- * Creates a BindHelper for the given type that can be used to add a binding of to a set.
- *
- * @param type The type the returned BindHelper can be use to bind implementations for.
- * @param <T> The type the returned BindHelper can be used to bind implementations for.
- * @return A BindHelper that can be used to bind an implementation with.
- */
- public static <T> BindHelper<T> multiBinderFor(final Class<T> type) {
- return new BindHelper<T>() {
- public LinkedBindingBuilder<T> with(Binder binder) {
- return Multibinder.newSetBinder(binder, type).addBinding();
- }
- };
- }
-
- /**
- * Checks that the given annotation instance is a {@link BindingAnnotation @BindingAnnotation}.
- *
- * @param annotation The annotation instance to check.
- * @param <T> The type of the binding annotation.
- * @return The checked binding annotation.
- * @throws NullPointerException If the given {@code annotation} is null.
- * @throws IllegalArgumentException If the given {@code annotation} is not a
- * {@literal @BindingAnnotation}.
- */
- public static <T extends Annotation> T checkBindingAnnotation(T annotation) {
- Preconditions.checkNotNull(annotation);
- checkBindingAnnotation(annotation.annotationType());
- return annotation;
- }
-
- /**
- * Checks that the given annotation type is a {@link BindingAnnotation @BindingAnnotation}.
- *
- * @param annotationType The annotation type to check.
- * @param <T> The type of the binding annotation.
- * @return The checked binding annotation type.
- * @throws NullPointerException If the given {@code annotationType} is null.
- * @throws IllegalArgumentException If the given {@code annotationType} is not a
- * {@literal @BindingAnnotation}.
- */
- public static <T extends Annotation> Class<T> checkBindingAnnotation(Class<T> annotationType) {
- Preconditions.checkNotNull(annotationType);
- boolean bindingAnnotation = annotationType.isAnnotationPresent(BindingAnnotation.class);
- boolean qualifier = annotationType.isAnnotationPresent(Qualifier.class);
- Preconditions.checkArgument(bindingAnnotation || qualifier,
- "%s is not a @BindingAnnotation or @Qualifier", annotationType);
- return annotationType;
- }
-
- /**
- * A factory for binding {@link Key keys}.
- */
- public interface KeyFactory {
-
- /**
- * Creates plain un-annotated keys.
- */
- KeyFactory PLAIN = new KeyFactory() {
- @Override public <T> Key<T> create(Class<T> type) {
- return Key.get(type);
- }
- @Override public <T> Key<T> create(TypeLiteral<T> type) {
- return Key.get(type);
- }
- };
-
- /**
- * Creates a key for the given type.
- *
- * @param type The type to create a key for.
- * @param <T> The keyed type.
- * @return A key.
- */
- <T> Key<T> create(Class<T> type);
-
- /**
- * Creates a key for the given type.
- *
- * @param type The type to create a key for.
- * @param <T> The keyed type.
- * @return A key.
- */
- <T> Key<T> create(TypeLiteral<T> type);
- }
-
- /**
- * Creates a key factory that produces keys for a given annotation instance.
- *
- * @param annotation The annotation instance to apply to all keys.
- * @return A key factory that creates annotated keys.
- */
- public static KeyFactory annotatedKeyFactory(final Annotation annotation) {
- checkBindingAnnotation(annotation);
- return new KeyFactory() {
- @Override public <T> Key<T> create(Class<T> type) {
- return Key.get(type, annotation);
- }
- @Override public <T> Key<T> create(TypeLiteral<T> type) {
- return Key.get(type, annotation);
- }
- };
- }
-
- /**
- * Creates a key factory that produces keys for a given annotation type.
- *
- * @param annotationType The annotation type to apply to all keys.
- * @return A key factory that creates annotated keys.
- */
- public static KeyFactory annotatedKeyFactory(final Class<? extends Annotation> annotationType) {
- checkBindingAnnotation(annotationType);
- return new KeyFactory() {
- @Override public <T> Key<T> create(Class<T> type) {
- return Key.get(type, annotationType);
- }
- @Override public <T> Key<T> create(TypeLiteral<T> type) {
- return Key.get(type, annotationType);
- }
- };
- }
-
- /**
- * A utility that helps rebind keys.
- */
- public static final class Rebinder {
- private final Binder binder;
- private final KeyFactory bindToFactory;
-
- /**
- * Creates a Rebinder that links bindings to keys from the given {@code bindToFactory}.
- *
- * @param binder A binder to rebind keys in.
- * @param bindToFactory A factory for the rebinding key.
- */
- public Rebinder(Binder binder, KeyFactory bindToFactory) {
- this.binder = Preconditions.checkNotNull(binder);
- this.bindToFactory = Preconditions.checkNotNull(bindToFactory);
- }
-
- /**
- * Rebinds the given key to another, linking bindings.
- *
- * @param fromKey The source key to rebind.
- * @return The key that {@code key} was rebound to.
- */
- public <T> Key<T> rebind(Key<T> fromKey) {
- Key<T> toKey = bindToFactory.create(fromKey.getTypeLiteral());
- binder.bind(toKey).to(fromKey);
- requireBinding(binder, fromKey);
- return toKey;
- }
- }
-
- /**
- * Creates a Rebinder that rebinds keys to the given annotation instance.
- *
- * @param binder A binder to rebind keys in.
- * @param annotation The annotation instance to rebind keys to.
- * @return A Rebinder targeting the given {@code annotationType}.
- */
- public static Rebinder rebinder(Binder binder, Annotation annotation) {
- return new Rebinder(binder, annotatedKeyFactory(annotation));
- }
-
- /**
- * Creates a Rebinder that rebinds keys to the given annotation type.
- *
- * @param binder A binder to rebind keys in.
- * @param annotationType The annotation type to rebind keys to.
- * @return A Rebinder targeting the given {@code annotationType}.
- */
- public static Rebinder rebinder(Binder binder, Class<? extends Annotation> annotationType) {
- return new Rebinder(binder, annotatedKeyFactory(annotationType));
- }
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/inject/DefaultProvider.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/inject/DefaultProvider.java b/commons/src/main/java/com/twitter/common/inject/DefaultProvider.java
deleted file mode 100644
index 446a9ba..0000000
--- a/commons/src/main/java/com/twitter/common/inject/DefaultProvider.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/**
- * 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 com.twitter.common.inject;
-
-import com.google.common.base.Preconditions;
-import com.google.inject.AbstractModule;
-import com.google.inject.Binder;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.Provider;
-import com.google.inject.TypeLiteral;
-import com.google.inject.name.Named;
-import com.google.inject.name.Names;
-
-/**
- * Provider that has a default value which can be overridden.
- *
- * The intended use of this class is:
- * <pre>
- * Default installer:
- * bind(DefaultProvider.makeDefaultKey(Runnable.class, "mykey").toInstance(defaultRunnable);
- * DefaultProvider.bindOrElse(Runnable.class, "mykey", binder());
- *
- * Custom override:
- * bind(DefaultProvider.makeCustomKey(Runnable.class, "mykey")).toInstance(myCustomRunnable);
- *
- * Injection:
- * {@literal Inject} Named("myKey") Runnable runnable;
- *
- * </pre>
- *
- * @param <T> the type of object this provides
- *
- * @author William Farner
- * @author John Sirois
- */
-public class DefaultProvider<T> implements Provider<T> {
- private static final String DEFAULT_BINDING_KEY_SUFFIX = "_default";
- private static final String CUSTOM_BINDING_KEY_SUFFIX = "_custom";
-
- private final Key<T> defaultProviderKey;
- private final Key<T> customProviderKey;
-
- private Injector injector;
-
- public DefaultProvider(Key<T> defaultProviderKey, Key<T> customProviderKey) {
- this.defaultProviderKey = Preconditions.checkNotNull(defaultProviderKey);
- this.customProviderKey = Preconditions.checkNotNull(customProviderKey);
- Preconditions.checkArgument(!defaultProviderKey.equals(customProviderKey));
- }
-
- @Inject
- public void setInjector(Injector injector) {
- this.injector = injector;
- }
-
- @Override
- public T get() {
- Preconditions.checkNotNull(injector);
- return injector.getBindings().containsKey(customProviderKey)
- ? injector.getInstance(customProviderKey)
- : injector.getInstance(defaultProviderKey);
- }
-
- /**
- * Creates a DefaultProvider and installs a new module to {@code binder}, which will serve as
- * an indirection layer for swapping the default binding with a custom one.
- *
- * @param customBinding The custom binding key.
- * @param defaultBinding The default binding key.
- * @param exposedBinding The exposed binding key.
- * @param binder The binder to install bindings to.
- * @param <T> The type of binding to make.
- */
- public static <T> void bindOrElse(final Key<T> customBinding, final Key<T> defaultBinding,
- final Key<T> exposedBinding, Binder binder) {
- Preconditions.checkNotNull(customBinding);
- Preconditions.checkNotNull(defaultBinding);
- Preconditions.checkNotNull(exposedBinding);
- Preconditions.checkArgument(!customBinding.equals(defaultBinding)
- && !customBinding.equals(exposedBinding));
-
- binder.install(new AbstractModule() {
- @Override protected void configure() {
- Provider<T> defaultProvider = new DefaultProvider<T>(defaultBinding, customBinding);
- requestInjection(defaultProvider);
- bind(exposedBinding).toProvider(defaultProvider);
- }
- });
- }
-
- /**
- * Convenience function for creating and installing a DefaultProvider. This will use internal
- * suffixes to create names for the custom and default bindings. When bound this way, callers
- * should use one of the functions such as {@link #makeDefaultBindingKey(String)} to set default
- * and custom bindings.
- *
- * @param type The type of object to bind.
- * @param exposedKey The exposed key.
- * @param binder The binder to install to.
- * @param <T> The type of binding to make.
- */
- public static <T> void bindOrElse(TypeLiteral<T> type, String exposedKey, Binder binder) {
- bindOrElse(Key.get(type, Names.named(makeCustomBindingKey(exposedKey))),
- Key.get(type, Names.named(makeDefaultBindingKey(exposedKey))),
- Key.get(type, Names.named(exposedKey)),
- binder);
- }
-
- /**
- * Convenience method for calls to {@link #bindOrElse(TypeLiteral, String, Binder)}, that are not
- * binding a parameterized type.
- *
- * @param type The class of the object to bind.
- * @param exposedKey The exposed key.
- * @param binder The binder to install to.
- * @param <T> The type of binding to make.
- */
- public static <T> void bindOrElse(Class<T> type, String exposedKey, Binder binder) {
- bindOrElse(TypeLiteral.get(type), exposedKey, binder);
- }
-
- public static String makeDefaultBindingKey(String rootKey) {
- return rootKey + DEFAULT_BINDING_KEY_SUFFIX;
- }
-
- public static Named makeDefaultBindingName(String rootKey) {
- return Names.named(makeDefaultBindingKey(rootKey));
- }
-
- public static <T> Key<T> makeDefaultKey(TypeLiteral<T> type, String rootKey) {
- return Key.get(type, makeDefaultBindingName(rootKey));
- }
-
- public static <T> Key<T> makeDefaultKey(Class<T> type, String rootKey) {
- return makeDefaultKey(TypeLiteral.get(type), rootKey);
- }
-
- public static String makeCustomBindingKey(String rootKey) {
- return rootKey + CUSTOM_BINDING_KEY_SUFFIX;
- }
-
- public static Named makeCustomBindingName(String rootKey) {
- return Names.named(makeCustomBindingKey(rootKey));
- }
-
- public static <T> Key<T> makeCustomKey(Class<T> type, String rootKey) {
- return Key.get(type, makeCustomBindingName(rootKey));
- }
-
- public static <T> Key<T> makeCustomKey(TypeLiteral<T> type, String rootKey) {
- return Key.get(type, makeCustomBindingName(rootKey));
- }
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/inject/ProviderMethodModule.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/inject/ProviderMethodModule.java b/commons/src/main/java/com/twitter/common/inject/ProviderMethodModule.java
deleted file mode 100644
index 8406631..0000000
--- a/commons/src/main/java/com/twitter/common/inject/ProviderMethodModule.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * 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 com.twitter.common.inject;
-
-import com.google.inject.AbstractModule;
-
-/**
- * A convenience base class for modules that do all their binding via provider methods.
- *
- * @author John Sirois
- */
-public abstract class ProviderMethodModule extends AbstractModule {
-
- /**
- * Does no binding; subclasses should implement provider methods.
- */
- @Override
- protected final void configure() {
- // noop
- }
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/inject/TimedInterceptor.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/inject/TimedInterceptor.java b/commons/src/main/java/com/twitter/common/inject/TimedInterceptor.java
deleted file mode 100644
index 94b2551..0000000
--- a/commons/src/main/java/com/twitter/common/inject/TimedInterceptor.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * 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 com.twitter.common.inject;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.lang.reflect.Method;
-
-import com.google.common.base.Preconditions;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.inject.Binder;
-import com.google.inject.matcher.Matchers;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-import org.apache.commons.lang.StringUtils;
-
-import com.twitter.common.stats.SlidingStats;
-import com.twitter.common.stats.TimeSeriesRepository;
-
-/**
- * A method interceptor that exports timing information for methods annotated with
- * {@literal @Timed}.
- *
- * @author John Sirois
- */
-public final class TimedInterceptor implements MethodInterceptor {
-
- /**
- * Marks a method as a target for timing.
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.METHOD)
- public @interface Timed {
-
- /**
- * The base name to export timing data with; empty to use the annotated method's name.
- */
- String value() default "";
- }
-
- private final LoadingCache<Method, SlidingStats> stats =
- CacheBuilder.newBuilder().build(new CacheLoader<Method, SlidingStats>() {
- @Override public SlidingStats load(Method method) {
- return createStats(method);
- }
- });
-
- private TimedInterceptor() {
- // preserve for guice
- }
-
- private SlidingStats createStats(Method method) {
- Timed timed = method.getAnnotation(Timed.class);
- Preconditions.checkArgument(timed != null,
- "TimedInterceptor can only be applied to @Timed methods");
-
- String name = timed.value();
- String statName = !StringUtils.isEmpty(name) ? name : method.getName();
- return new SlidingStats(statName, "nanos");
- }
-
- @Override
- public Object invoke(MethodInvocation methodInvocation) throws Throwable {
- // TODO(John Sirois): consider including a SlidingRate tracking thrown exceptions
- SlidingStats stat = stats.get(methodInvocation.getMethod());
- long start = System.nanoTime();
- try {
- return methodInvocation.proceed();
- } finally {
- stat.accumulate(System.nanoTime() - start);
- }
- }
-
- /**
- * Installs an interceptor in a guice {@link com.google.inject.Injector}, enabling
- * {@literal @Timed} method interception in guice-provided instances. Requires that a
- * {@link TimeSeriesRepository} is bound elsewhere.
- *
- * @param binder a guice binder to require bindings against
- */
- public static void bind(Binder binder) {
- Preconditions.checkNotNull(binder);
-
- Bindings.requireBinding(binder, TimeSeriesRepository.class);
-
- TimedInterceptor interceptor = new TimedInterceptor();
- binder.requestInjection(interceptor);
- binder.bindInterceptor(Matchers.any(), Matchers.annotatedWith(Timed.class), interceptor);
- }
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/Base64ZlibCodec.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/io/Base64ZlibCodec.java b/commons/src/main/java/com/twitter/common/io/Base64ZlibCodec.java
deleted file mode 100644
index ef31735..0000000
--- a/commons/src/main/java/com/twitter/common/io/Base64ZlibCodec.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- * 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 com.twitter.common.io;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
-import java.nio.charset.Charset;
-import java.util.zip.DeflaterOutputStream;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.InflaterInputStream;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Throwables;
-import com.google.common.io.ByteStreams;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.binary.Base64OutputStream;
-
-/**
- * Utility class providing encoding and decoding methods to and from a string to a utf-8 encoded,
- * zlib compressed, Base64 encoded representation of the string. For wider compatibility, the
- * decoder can also automatically recognize GZIP (instead of plain zlib) compressed data too and
- * decode it accordingly.
- *
- * @author Attila Szegedi
- */
-public final class Base64ZlibCodec {
- /**
- * Thrown to indicate invalid data while decoding or unzipping.
- *
- * @author Attila Szegedi
- */
- public static class InvalidDataException extends Exception {
- private static final long serialVersionUID = 1L;
-
- public InvalidDataException(String message) {
- super(message);
- }
-
- public InvalidDataException(String message, Throwable cause) {
- super(message, cause);
- }
- }
-
- /**
- * Text encoding used by the Base64 output stream.
- */
- public static final String BASE64_TEXT_ENCODING = "ASCII";
- private static final int ESTIMATED_PLAINTEXT_TO_ENCODED_RATIO = 4;
-
- // Prefix all Base64-encoded, zlib compressed data must have
- private static final byte[] ZLIB_HEADER_PREFIX = new byte[] { 120 };
- // Prefix all Base64-encoded, GZIP compressed data must have
- private static final byte[] GZIP_HEADER_PREFIX = new byte[] {31, -117, 8, 0, 0, 0, 0, 0, 0 };
- private static final int DIAGNOSTIC_PREFIX_LENGTH = 16;
- // Text encoding for char-to-byte transformation before compressing a stack trace
- private static final Charset TEXT_ENCODING = com.google.common.base.Charsets.UTF_8;
-
- private Base64ZlibCodec() {
- // Utility class
- }
-
- /**
- * Decodes a string. In addition to zlib, it also automatically detects GZIP compressed data and
- * adjusts accordingly.
- *
- * @param encoded the encoded string, represented as a byte array of ASCII-encoded characters
- * @return the decoded string
- * @throws InvalidDataException if the string can not be decoded.
- */
- public static byte[] decode(String encoded) throws InvalidDataException {
- Preconditions.checkNotNull(encoded);
- return decompress(new Base64().decode(encoded));
- }
-
- private static byte[] decompress(byte[] compressed) throws InvalidDataException {
- byte[] bytes;
- try {
- final InputStream bin = new ByteArrayInputStream(compressed);
- final InputStream zin;
- if (startsWith(compressed, GZIP_HEADER_PREFIX)) {
- zin = new GZIPInputStream(bin);
- } else if (startsWith(compressed, ZLIB_HEADER_PREFIX)) {
- zin = new InflaterInputStream(bin);
- } else {
- throw new Base64ZlibCodec.InvalidDataException("Value doesn't start with either GZIP or zlib header");
- }
- try {
- bytes = ByteStreams.toByteArray(zin);
- } finally {
- zin.close();
- }
- } catch (IOException e) {
- throw new Base64ZlibCodec.InvalidDataException("zlib/GZIP decoding error", e);
- }
- return bytes;
- }
-
- private static boolean startsWith(byte[] value, byte[] prefix) {
- final int pl = prefix.length;
- if (value.length < pl) {
- return false;
- }
- for (int i = 0; i < pl; ++i) {
- if (value[i] != prefix[i]) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Encodes a set of bytes.
- *
- * @param plain the non-encoded bytes
- * @return the encoded string
- */
- public static String encode(byte[] plain) {
- final ByteArrayOutputStream out = new ByteArrayOutputStream(plain.length
- / ESTIMATED_PLAINTEXT_TO_ENCODED_RATIO);
- final OutputStream w = getDeflatingEncodingStream(out);
- try {
- w.write(plain);
- w.close();
- return out.toString(BASE64_TEXT_ENCODING);
- } catch (UnsupportedEncodingException e) {
- throw reportUnsupportedEncoding();
- } catch (IOException e) {
- throw Throwables.propagate(e);
- }
- }
-
- private static OutputStream getDeflatingEncodingStream(OutputStream out) {
- return new DeflaterOutputStream(new Base64OutputStream(out, true,
- Integer.MAX_VALUE, null));
- }
-
- /**
- * Returns a writer that writes through to the specified output stream, utf-8 encoding,
- * zlib compressing, and Base64 encoding its input along the way.
- *
- * @param out the output stream that receives the final output
- * @return a writer for the input
- */
- public static Writer getEncodingWriter(OutputStream out) {
- return new OutputStreamWriter(getDeflatingEncodingStream(out), TEXT_ENCODING);
- }
-
- private static AssertionError reportUnsupportedEncoding() {
- return new AssertionError(String.format("JVM doesn't support the %s encoding", TEXT_ENCODING));
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/Codec.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/io/Codec.java b/commons/src/main/java/com/twitter/common/io/Codec.java
deleted file mode 100644
index c9d5882..0000000
--- a/commons/src/main/java/com/twitter/common/io/Codec.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * 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 com.twitter.common.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * A Codec represents a reversible encoding for a given type. Codecs are able to both
- * {@link #deserialize(java.io.InputStream) read} items from streams and
- * {@link #serialize(Object, java.io.OutputStream) write} items to streams.
- *
- * <p> TODO(John Sirois): consider whether this interface should optionally support null items to be
- * read and written.
- *
- * @param <T> The type of object the Codec can handle.
- *
- * @author John Sirois
- */
-public interface Codec<T> {
-
- /**
- * Writes a representation of {@code item} to the {@code sink} that can be read back by
- * {@link #deserialize(java.io.InputStream)}.
- *
- * @param item the item to serialize
- * @param sink the stream to write the item out to
- * @throws IOException if there is a problem serializing the item
- */
- void serialize(T item, OutputStream sink) throws IOException;
-
- /**
- * Reads an item from the {@code source} stream that was written by
- * {@link #serialize(Object, java.io.OutputStream)}.
- *
- * @param source the stream to read an item from
- * @return the deserialized item
- * @throws IOException if there is a problem reading an item
- */
- T deserialize(InputStream source) throws IOException;
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/CompatibilityCodec.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/io/CompatibilityCodec.java b/commons/src/main/java/com/twitter/common/io/CompatibilityCodec.java
deleted file mode 100644
index 878d35d..0000000
--- a/commons/src/main/java/com/twitter/common/io/CompatibilityCodec.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * 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 com.twitter.common.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PushbackInputStream;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-
-/**
- * A codec that composes two codecs: a primary and a compatibility codec. It always serializes with
- * the primary codec, but can make a decision on deserialization based on the first few bytes of the
- * serialized format whether to use the compatibility codec. This allows for easier transition
- * between storage formats as the codec remains able to read the old serialized format.
- *
- * @author Attila Szegedi
- *
- * @param <T> the type of objects this codec is for.
- */
-public class CompatibilityCodec<T> implements Codec<T> {
- private final Codec<T> primaryCodec;
- private final Codec<T> secondaryCodec;
- private final int prefixLength;
- private final Predicate<byte[]> discriminator;
-
- private CompatibilityCodec(Codec<T> primaryCodec, Codec<T> secondaryCodec, int prefixLength,
- Predicate<byte[]> discriminator) {
- Preconditions.checkNotNull(primaryCodec);
- Preconditions.checkNotNull(secondaryCodec);
- this.primaryCodec = primaryCodec;
- this.secondaryCodec = secondaryCodec;
- this.prefixLength = prefixLength;
- this.discriminator = discriminator;
- }
-
- /**
- * Creates a new compatibility codec instance.
- *
- * @param primaryCodec the codec used to serialize objects, as well as deserialize them when the
- * first byte of the serialized format matches the discriminator.
- * @param secondaryCodec the codec used to deserialize objects when the first byte of the
- * serialized format does not match the discriminator.
- * @param prefixLength the length, in bytes, of the prefix of the message that is inspected for
- * determining the format.
- * @param discriminator a predicate that will receive an array of at most prefixLength bytes
- * (it can receive less if the serialized format is shorter) and has to return true
- * if the primary codec should be used for deserialization, otherwise false.
- */
- public static <T> CompatibilityCodec<T> create(Codec<T> primaryCodec, Codec<T> secondaryCodec,
- int prefixLength, Predicate<byte[]> discriminator) {
- return new CompatibilityCodec<T>(primaryCodec, secondaryCodec, prefixLength, discriminator);
- }
-
- @Override
- public T deserialize(InputStream source) throws IOException {
- final PushbackInputStream in = new PushbackInputStream(source, prefixLength);
- final byte[] prefix = readAtMostPrefix(in);
- in.unread(prefix);
- return (discriminator.apply(prefix) ? primaryCodec : secondaryCodec).deserialize(in);
- }
-
- private byte[] readAtMostPrefix(InputStream in) throws IOException {
- final byte[] prefix = new byte[prefixLength];
- int read = 0;
- do {
- final int readNow = in.read(prefix, read, prefixLength - read);
- if (readNow == -1) {
- byte[] newprefix = new byte[read];
- System.arraycopy(prefix, 0, newprefix, 0, read);
- return newprefix;
- }
- read += readNow;
- } while (read < prefixLength);
- return prefix;
- }
-
- @Override
- public void serialize(T item, OutputStream sink) throws IOException {
- primaryCodec.serialize(item, sink);
- }
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/FileUtils.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/io/FileUtils.java b/commons/src/main/java/com/twitter/common/io/FileUtils.java
deleted file mode 100644
index f2ef5f7..0000000
--- a/commons/src/main/java/com/twitter/common/io/FileUtils.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * 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 com.twitter.common.io;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.UUID;
-
-import com.google.common.base.Preconditions;
-
-import org.apache.commons.lang.SystemUtils;
-
-import com.twitter.common.base.ExceptionalClosure;
-import com.twitter.common.base.ExceptionalFunction;
-
-/**
- * Utility methods for working with files and directories.
- *
- * @author John Sirois
- */
-public final class FileUtils {
-
- /**
- * A utility for creating and working with temporary files and directories.
- */
- public static class Temporary {
- private static final int MAX_TMP_DIR_TRIES = 5;
-
- private final File basedir;
-
- /**
- * Creates a new temporary utility that creates files and directories rooted at {@code basedir}.
- *
- * @param basedir The base directory to generate temporary files and directories in.
- */
- public Temporary(File basedir) {
- Preconditions.checkNotNull(basedir);
- this.basedir = basedir;
- }
-
- /**
- * Returns a new empty temporary directory.
- *
- * @return a file representing the newly created directory.
- * @throws IllegalStateException if a new temporary directory could not be created
- */
- public File createDir() {
- File tempDir;
- int tries = 0;
- do {
- // For sanity sake, die eventually if we keep failing to pick a new unique directory name.
- if (++tries > MAX_TMP_DIR_TRIES) {
- throw new IllegalStateException("Failed to create a new temp directory in "
- + MAX_TMP_DIR_TRIES + " attempts, giving up");
- }
- tempDir = new File(basedir, UUID.randomUUID().toString());
- } while (!tempDir.mkdir());
- return tempDir;
- }
-
- /**
- * Creates a new empty temporary file.
- *
- * @return a new empty temporary file
- * @throws IOException if there was a problem creating a new temporary file
- */
- public File createFile() throws IOException {
- return createFile(".tempfile");
- }
-
- /**
- * Creates a new empty temporary file with the given filename {@code suffix}.
- *
- * @param suffix The suffix for the temporary file name
- * @return a new empty temporary file
- * @throws IOException if there was a problem creating a new temporary file
- */
- public File createFile(String suffix) throws IOException {
- return File.createTempFile(FileUtils.class.getName(), suffix, basedir);
- }
-
- /**
- * Creates a new temporary directory and executes the unit of {@code work} against it ensuring
- * the directory and its contents are removed after the work completes normally or abnormally.
- *
- * @param work The unit of work to execute against the new temporary directory.
- * @param <E> The type of exception this unit of work can throw.
- * @throws E bubbled transparently when the unit of work throws
- */
- public <E extends Exception> void doWithDir(final ExceptionalClosure<File, E> work)
- throws E {
- Preconditions.checkNotNull(work);
- doWithDir(new ExceptionalFunction<File, Void, E>() {
- @Override public Void apply(File dir) throws E {
- work.execute(dir);
- return null;
- }
- });
- }
-
- /**
- * Creates a new temporary directory and executes the unit of {@code work} against it ensuring
- * the directory and its contents are removed after the work completes normally or abnormally.
- *
- * @param work The unit of work to execute against the new temporary directory.
- * @param <T> The type of result this unit of work produces.
- * @param <E> The type of exception this unit of work can throw.
- * @return the result when the unit of work completes successfully
- * @throws E bubbled transparently when the unit of work throws
- */
- public <T, E extends Exception> T doWithDir(ExceptionalFunction<File, T, E> work)
- throws E {
- Preconditions.checkNotNull(work);
- return doWithTemp(createDir(), work);
- }
-
- /**
- * Creates a new temporary file and executes the unit of {@code work} against it ensuring
- * the file is removed after the work completes normally or abnormally.
- *
- * @param work The unit of work to execute against the new temporary file.
- * @param <E> The type of exception this unit of work can throw.
- * @throws E bubbled transparently when the unit of work throws
- * @throws IOException if there was a problem creating a new temporary file
- */
- public <E extends Exception> void doWithFile(final ExceptionalClosure<File, E> work)
- throws E, IOException {
- Preconditions.checkNotNull(work);
- doWithFile(new ExceptionalFunction<File, Void, E>() {
- @Override public Void apply(File dir) throws E {
- work.execute(dir);
- return null;
- }
- });
- }
-
- /**
- * Creates a new temporary file and executes the unit of {@code work} against it ensuring
- * the file is removed after the work completes normally or abnormally.
- *
- * @param work The unit of work to execute against the new temporary file.
- * @param <T> The type of result this unit of work produces.
- * @param <E> The type of exception this unit of work can throw.
- * @return the result when the unit of work completes successfully
- * @throws E bubbled transparently when the unit of work throws
- * @throws IOException if there was a problem creating a new temporary file
- */
- public <T, E extends Exception> T doWithFile(ExceptionalFunction<File, T, E> work)
- throws E, IOException {
- Preconditions.checkNotNull(work);
- return doWithTemp(createFile(), work);
- }
-
- private static <T, E extends Exception> T doWithTemp(File file,
- ExceptionalFunction<File, T, E> work) throws E {
- try {
- return work.apply(file);
- } finally {
- org.apache.commons.io.FileUtils.deleteQuietly(file);
- }
- }
- }
-
- /**
- * A temporary based at the default system temporary directory.
- */
- public static final Temporary SYSTEM_TMP = new Temporary(SystemUtils.getJavaIoTmpDir());
-
- /**
- * Returns a new empty temporary directory.
- *
- * @return a file representing the newly created directory.
- * @throws IllegalStateException if a new temporary directory could not be created
- */
- public static File createTempDir() {
- return SYSTEM_TMP.createDir();
- }
-
- private FileUtils() {
- // utility
- }
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/JsonCodec.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/io/JsonCodec.java b/commons/src/main/java/com/twitter/common/io/JsonCodec.java
deleted file mode 100644
index c6c9631..0000000
--- a/commons/src/main/java/com/twitter/common/io/JsonCodec.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * 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 com.twitter.common.io;
-
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.util.BitSet;
-
-import com.google.common.base.Preconditions;
-import com.google.gson.ExclusionStrategy;
-import com.google.gson.FieldAttributes;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
-/**
- * A {@code Codec} that can encode and decode objects to and from JSON using the GSON library
- * (which in turn will use reflection). The codec uses the UTF-8 encoding.
- *
- * @author Attila Szegedi
- */
-public class JsonCodec<T> implements Codec<T> {
-
- private static final String ENCODING = "utf-8";
-
- private final Class<T> clazz;
- private final Gson gson;
-
- /**
- * Creates a new JSON codec instance for objects of the specified class.
- *
- * @param clazz the class of the objects the created codec is for.
- * @return a newly constructed JSON codec instance for objects of the requested class.
- */
- public static <T> JsonCodec<T> create(Class<T> clazz) {
- return new JsonCodec<T>(clazz, DefaultGsonHolder.instance);
- }
-
- /**
- * Creates a new JSON codec instance for objects of the specified class and the specified Gson
- * instance. You can use this method if you need to customize the behavior of the Gson
- * serializer.
- *
- * @param clazz the class of the objects the created codec is for.
- * @param gson the Gson instance to use for serialization/deserialization.
- * @return a newly constructed JSON codec instance for objects of the requested class.
- */
- public static <T> JsonCodec<T> create(Class<T> clazz, Gson gson) {
- return new JsonCodec<T>(clazz, gson);
- }
-
- private JsonCodec(Class<T> clazz, Gson gson) {
- Preconditions.checkNotNull(clazz);
- Preconditions.checkNotNull(gson);
- this.clazz = clazz;
- this.gson = gson;
- }
-
- private static final class DefaultGsonHolder {
- static final Gson instance = new Gson();
- }
-
- /**
- * Returns a Gson exclusion strategy that excludes Thrift synthetic fields from JSON
- * serialization. You can pass it to a {@link GsonBuilder} to construct a customized {@link Gson}
- * instance to use with {@link JsonCodec#create(Class, Gson)}.
- *
- * @return a Gson exclusion strategy for thrift synthetic fields.
- */
- public static ExclusionStrategy getThriftExclusionStrategy() {
- return ThriftExclusionStrategy.instance;
- }
-
- private static final class ThriftExclusionStrategy implements ExclusionStrategy {
- static final ExclusionStrategy instance = new ThriftExclusionStrategy();
-
- public boolean shouldSkipClass(Class<?> clazz) {
- return false;
- }
-
- public boolean shouldSkipField(FieldAttributes f) {
- // Exclude Thrift synthetic fields
- return f.getDeclaredClass() == BitSet.class && f.getName().equals("__isset_bit_vector");
- }
- }
-
- @Override
- public T deserialize(InputStream source) throws IOException {
- return gson.fromJson(new InputStreamReader(source, ENCODING), clazz);
- }
-
- @Override
- public void serialize(T item, OutputStream sink) throws IOException {
- final Writer w = new OutputStreamWriter(new UnflushableOutputStream(sink), ENCODING);
- gson.toJson(item, clazz, w);
- w.flush();
- }
-
- private static class UnflushableOutputStream extends FilterOutputStream {
- UnflushableOutputStream(OutputStream out) {
- super(out);
- }
-
- @Override
- public void flush() throws IOException {
- // Intentionally do nothing
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/Streamer.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/io/Streamer.java b/commons/src/main/java/com/twitter/common/io/Streamer.java
deleted file mode 100644
index ce601b4..0000000
--- a/commons/src/main/java/com/twitter/common/io/Streamer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * 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 com.twitter.common.io;
-
-import com.google.common.base.Predicate;
-import com.twitter.common.base.Closure;
-
-/**
- * Encapsulates iteration over a typed data stream that can be filtered.
- *
- * @author John Sirois
- */
-public interface Streamer<T> {
-
- /**
- * Processes a stream fully. This may cause a database query to be executed, a file to be read
- * or even just call {@link Iterable#iterator()} depending on the implementation. Implementations
- * guaranty that any resources allocated opening the stream will be closed whether or not process
- * completes normally.
- *
- * @param work a closure over the work to be done for each item in the stream.
- */
- void process(Closure<T> work);
-
- /**
- * Returns a {@code Streamer} that will process the same stream as this streamer, but will stop
- * processing when encountering the first item for which {@code cond} is true.
- *
- * @param cond a predicate that returns {@code false} as long as the stream should keep being
- * processed.
- * @return a streamer that will process items until the condition triggers.
- */
- Streamer<T> endOn(Predicate<T> cond);
-
- /**
- * Returns a {@code Streamer} that will process the same stream as this streamer, but with any
- * items failing the filter to be omitted from processing.
- * @param filter a predicate that returns {@code true} if an item in the stream should be
- * processed
- * @return a filtered streamer
- */
- Streamer<T> filter(Predicate<T> filter);
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/io/ThriftCodec.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/io/ThriftCodec.java b/commons/src/main/java/com/twitter/common/io/ThriftCodec.java
deleted file mode 100644
index 4c7c289..0000000
--- a/commons/src/main/java/com/twitter/common/io/ThriftCodec.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * 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 com.twitter.common.io;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Supplier;
-import com.twitter.common.base.MoreSuppliers;
-import org.apache.thrift.TBase;
-import org.apache.thrift.TException;
-import org.apache.thrift.protocol.TBinaryProtocol;
-import org.apache.thrift.protocol.TCompactProtocol;
-import org.apache.thrift.protocol.TJSONProtocol;
-import org.apache.thrift.protocol.TProtocol;
-import org.apache.thrift.transport.TIOStreamTransport;
-import org.apache.thrift.transport.TTransport;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * A {@code Codec} that can encode and decode thrift structs.
- */
-public class ThriftCodec<T extends TBase> implements Codec<T> {
-
- public static final Function<TTransport, TProtocol> JSON_PROTOCOL =
- new Function<TTransport, TProtocol>() {
- @Override public TProtocol apply(TTransport transport) {
- return new TJSONProtocol(transport);
- }
- };
-
- public static final Function<TTransport, TProtocol> BINARY_PROTOCOL =
- new Function<TTransport, TProtocol>() {
- @Override public TProtocol apply(TTransport transport) {
- return new TBinaryProtocol(transport);
- }
- };
-
- public static final Function<TTransport, TProtocol> COMPACT_PROTOCOL =
- new Function<TTransport, TProtocol>() {
- @Override public TProtocol apply(TTransport transport) {
- return new TCompactProtocol(transport);
- }
- };
-
- private final Supplier<T> templateSupplier;
- private final Function<TTransport, TProtocol> protocolFactory;
-
- public static <T extends TBase> ThriftCodec<T> create(final Class<T> thriftStructType,
- Function<TTransport, TProtocol> protocolFactory) {
- return new ThriftCodec<T>(MoreSuppliers.of(thriftStructType), protocolFactory);
- }
-
- /**
- * @deprecated use {@link ThriftCodec#create(Class, Function)} instead.
- */
- @Deprecated
- public ThriftCodec(final Class<T> thriftStructType,
- Function<TTransport, TProtocol> protocolFactory) {
- this(MoreSuppliers.of(thriftStructType), protocolFactory);
- }
-
- public ThriftCodec(Supplier<T> templateSupplier,
- Function<TTransport, TProtocol> protocolFactory) {
- this.templateSupplier = Preconditions.checkNotNull(templateSupplier);
- this.protocolFactory = Preconditions.checkNotNull(protocolFactory);
- }
-
- @Override
- public void serialize(T item, OutputStream sink) throws IOException {
- Preconditions.checkNotNull(item);
- Preconditions.checkNotNull(sink);
- try {
- item.write(protocolFactory.apply(new TIOStreamTransport(null, sink)));
- } catch (TException e) {
- throw new IOException("Problem serializing thrift struct: " + item, e);
- }
- }
-
- @Override
- public T deserialize(InputStream source) throws IOException {
- Preconditions.checkNotNull(source);
- T template = templateSupplier.get();
- try {
- template.read(protocolFactory.apply(new TIOStreamTransport(source, null)));
- } catch (TException e) {
- throw new IOException("Problem de-serializing thrift struct from stream", e);
- }
- return template;
- }
-}
http://git-wip-us.apache.org/repos/asf/aurora/blob/06ddaadb/commons/src/main/java/com/twitter/common/logging/BufferedLog.java
----------------------------------------------------------------------
diff --git a/commons/src/main/java/com/twitter/common/logging/BufferedLog.java b/commons/src/main/java/com/twitter/common/logging/BufferedLog.java
deleted file mode 100644
index 75b05be..0000000
--- a/commons/src/main/java/com/twitter/common/logging/BufferedLog.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/**
- * 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 com.twitter.common.logging;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import com.twitter.common.quantity.Amount;
-import com.twitter.common.quantity.Time;
-import com.twitter.common.stats.StatImpl;
-import com.twitter.common.stats.Stats;
-
-import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.logging.Logger;
-
-/**
- * Log that buffers requests before sending them to a wrapped log.
- *
- * @author William Farner
- */
-public class BufferedLog<T, R> implements Log<T, Void> {
- private static final Logger LOG = Logger.getLogger(BufferedLog.class.getName());
-
- private static final ExecutorService DEFAULT_EXECUTOR_SERVICE =
- Executors.newSingleThreadExecutor(
- new ThreadFactoryBuilder().setDaemon(true).setNameFormat("Log Pusher-%d").build());
- private static final int DEFAULT_MAX_BUFFER_SIZE = 100000;
-
- // TODO(William Farner): Change to use a ScheduledExecutorService instead of a timer.
- private final TimerTask logPusher = new TimerTask() {
- @Override public void run() {
- flush();
- }
- };
-
- // Local buffer of log messages.
- private final List<T> localBuffer = Lists.newLinkedList();
-
- // The log that is being buffered.
- private Log<T, R> bufferedLog;
-
- // Filter to determine when a log request should be retried.
- private Predicate<R> retryFilter = null;
-
- // Maximum number of log entries that can be buffered before truncation (lost messages).
- private int maxBufferSize = DEFAULT_MAX_BUFFER_SIZE;
-
- // Maximum buffer length before attempting to submit.
- private int chunkLength;
-
- // Maximum time for a message to sit in the buffer before attempting to flush.
- private Amount<Integer, Time> flushInterval;
-
- // Service to handle flushing the log.
- private ExecutorService logSubmitService = DEFAULT_EXECUTOR_SERVICE;
-
- private BufferedLog() {
- // Created through builder.
-
- Stats.export(new StatImpl<Integer>("scribe_buffer_size") {
- public Integer read() { return getBacklog(); }
- });
- }
-
- public static <T, R> Builder<T, R> builder() {
- return new Builder<T, R>();
- }
-
- /**
- * Starts the log submission service by scheduling a timer to periodically submit messages.
- */
- private void start() {
- long flushIntervalMillis = flushInterval.as(Time.MILLISECONDS);
-
- new Timer(true).scheduleAtFixedRate(logPusher, flushIntervalMillis, flushIntervalMillis);
- }
-
- /**
- * Gets the current number of messages in the local buffer.
- *
- * @return The number of backlogged messages.
- */
- protected int getBacklog() {
- synchronized (localBuffer) {
- return localBuffer.size();
- }
- }
-
- /**
- * Stores a log entry, flushing immediately if the buffer length limit is exceeded.
- *
- * @param entry Entry to log.
- */
- @Override
- public Void log(T entry) {
- synchronized (localBuffer) {
- localBuffer.add(entry);
-
- if (localBuffer.size() >= chunkLength) {
- logSubmitService.submit(logPusher);
- }
- }
-
- return null;
- }
-
- @Override
- public Void log(List<T> entries) {
- for (T entry : entries) log(entry);
-
- return null;
- }
-
- @Override
- public void flush() {
- List<T> buffer = copyBuffer();
- if (buffer.isEmpty()) return;
-
- R result = bufferedLog.log(buffer);
-
- // Restore the buffer if the write was not successful.
- if (retryFilter != null && retryFilter.apply(result)) {
- LOG.warning("Log request failed, restoring spooled messages.");
- restoreToLocalBuffer(buffer);
- }
- }
-
- /**
- * Creats a snapshot of the local buffer and clears the local buffer.
- *
- * @return A snapshot of the local buffer.
- */
- private List<T> copyBuffer() {
- synchronized (localBuffer) {
- List<T> bufferCopy = ImmutableList.copyOf(localBuffer);
- localBuffer.clear();
- return bufferCopy;
- }
- }
-
- /**
- * Restores log entries back to the local buffer. This can be used to commit entries back to the
- * buffer after a flush operation failed.
- *
- * @param buffer The log entries to restore.
- */
- private void restoreToLocalBuffer(List<T> buffer) {
- synchronized (localBuffer) {
- int restoreRecords = Math.min(buffer.size(), maxBufferSize - localBuffer.size());
-
- if (restoreRecords != buffer.size()) {
- LOG.severe((buffer.size() - restoreRecords) + " log records truncated!");
-
- if (restoreRecords == 0) return;
- }
-
- localBuffer.addAll(0, buffer.subList(buffer.size() - restoreRecords, buffer.size()));
- }
- }
-
- /**
- * Configures a BufferedLog object.
- *
- * @param <T> Log message type.
- * @param <R> Log result type.
- */
- public static class Builder<T, R> {
- private final BufferedLog<T, R> instance;
-
- public Builder() {
- instance = new BufferedLog<T, R>();
- }
-
- /**
- * Specifies the log that should be buffered.
- *
- * @param bufferedLog Log to buffer requests to.
- * @return A reference to the builder.
- */
- public Builder<T, R> buffer(Log<T, R> bufferedLog) {
- instance.bufferedLog = bufferedLog;
- return this;
- }
-
- /**
- * Adds a custom retry filter that will be used to determine whether a log result {@code R}
- * should be used to indicate that a log request should be retried. Log submit retry behavior
- * is not defined when the filter throws uncaught exceptions.
- *
- * @param retryFilter Filter to determine whether to retry.
- * @return A reference to the builder.
- */
- public Builder<T, R> withRetryFilter(Predicate<R> retryFilter) {
- instance.retryFilter = retryFilter;
- return this;
- }
-
- /**
- * Specifies the maximum allowable buffer size, after which log records will be dropped to
- * conserve memory.
- *
- * @param maxBufferSize Maximum buffer size.
- * @return A reference to the builder.
- */
- public Builder<T, R> withMaxBuffer(int maxBufferSize) {
- instance.maxBufferSize = maxBufferSize;
- return this;
- }
-
- /**
- * Specifies the desired number of log records to submit in each request.
- *
- * @param chunkLength Maximum number of records to accumulate before trying to submit.
- * @return A reference to the builder.
- */
- public Builder<T, R> withChunkLength(int chunkLength) {
- instance.chunkLength = chunkLength;
- return this;
- }
-
- /**
- * Specifies the maximum amount of time that a log entry may wait in the buffer before an
- * attempt is made to flush the buffer.
- *
- * @param flushInterval Log flush interval.
- * @return A reference to the builder.
- */
- public Builder<T, R> withFlushInterval(Amount<Integer, Time> flushInterval) {
- instance.flushInterval = flushInterval;
- return this;
- }
-
- /**
- * Specifies the executor service to use for (synchronously or asynchronously) sending
- * log entries.
- *
- * @param logSubmitService Log submit executor service.
- * @return A reference to the builder.
- */
- public Builder<T, R> withExecutorService(ExecutorService logSubmitService) {
- instance.logSubmitService = logSubmitService;
- return this;
- }
-
- /**
- * Creates the buffered log.
- *
- * @return The prepared buffered log.
- */
- public BufferedLog<T, R> build() {
- Preconditions.checkArgument(instance.chunkLength > 0);
- Preconditions.checkArgument(instance.flushInterval.as(Time.MILLISECONDS) > 0);
- Preconditions.checkNotNull(instance.logSubmitService);
- Preconditions.checkArgument(instance.chunkLength <= instance.maxBufferSize);
-
- instance.start();
-
- return instance;
- }
- }
-}