/**
* Runs {@link Supplier} with provided {@link ClassLoader}.
*
- * Invokes supplies function and makes sure that original {@link ClassLoader}
+ * <p>Invokes supplies function and makes sure that original {@link ClassLoader}
* is context {@link ClassLoader} after execution.
*
* @param cls {@link ClassLoader} to be used.
}
/**
- *
* Loads class using this supplied classloader.
*
- *
- * @param cls
* @param name String name of class.
- * @return
- * @throws ClassNotFoundException
*/
public static Class<?> loadClass(final ClassLoader cls, final String name) throws ClassNotFoundException {
if ("byte[]".equals(name)) {
}
public static <S,G,P> Class<P> findFirstGenericArgument(final Class<S> scannedClass, final Class<G> genericType) {
- return withClassLoader(scannedClass.getClassLoader(), ClassLoaderUtils.findFirstGenericArgumentTask(scannedClass, genericType));
+ return withClassLoader(scannedClass.getClassLoader(),
+ ClassLoaderUtils.findFirstGenericArgumentTask(scannedClass, genericType));
}
- private static <S,G,P> Supplier<Class<P>> findFirstGenericArgumentTask(final Class<S> scannedClass, final Class<G> genericType) {
+ private static <S, G, P> Supplier<Class<P>> findFirstGenericArgumentTask(final Class<S> scannedClass,
+ final Class<G> genericType) {
return new Supplier<Class<P>>() {
@Override
@SuppressWarnings("unchecked")
*/
// TODO: once DurationStatsTracker is gone make this class final
class ConcurrentDurationStatisticsTracker extends DurationStatisticsTracker {
- private static final AtomicReferenceFieldUpdater<ConcurrentDurationStatisticsTracker, DurationWithTime> LONGEST_UPDATER =
- AtomicReferenceFieldUpdater.newUpdater(ConcurrentDurationStatisticsTracker.class, DurationWithTime.class, "longest");
- private static final AtomicReferenceFieldUpdater<ConcurrentDurationStatisticsTracker, DurationWithTime> SHORTEST_UPDATER =
- AtomicReferenceFieldUpdater.newUpdater(ConcurrentDurationStatisticsTracker.class, DurationWithTime.class, "shortest");
+
+ private static final AtomicReferenceFieldUpdater<ConcurrentDurationStatisticsTracker, DurationWithTime>
+ LONGEST_UPDATER = AtomicReferenceFieldUpdater.newUpdater(ConcurrentDurationStatisticsTracker.class,
+ DurationWithTime.class, "longest");
+
+ private static final AtomicReferenceFieldUpdater<ConcurrentDurationStatisticsTracker, DurationWithTime>
+ SHORTEST_UPDATER = AtomicReferenceFieldUpdater.newUpdater(ConcurrentDurationStatisticsTracker.class,
+ DurationWithTime.class, "shortest");
+
private static final AtomicLongFieldUpdater<ConcurrentDurationStatisticsTracker> COUNT_UPDATER =
AtomicLongFieldUpdater.newUpdater(ConcurrentDurationStatisticsTracker.class, "count");
private static final AtomicLongFieldUpdater<ConcurrentDurationStatisticsTracker> SUM_UPDATER =
private static String abbreviate(final TimeUnit unit) {
switch (unit) {
- case NANOSECONDS:
- return "ns";
- case MICROSECONDS:
- return "\u03bcs"; // μs
- case MILLISECONDS:
- return "ms";
- case SECONDS:
- return "s";
- case MINUTES:
- return "m";
- case HOURS:
- return "h";
- case DAYS:
- return "d";
- default:
- LOG.warn("Unhandled time unit {}", unit);
- return "";
+ case NANOSECONDS:
+ return "ns";
+ case MICROSECONDS:
+ return "\u03bcs"; // μs
+ case MILLISECONDS:
+ return "ms";
+ case SECONDS:
+ return "s";
+ case MINUTES:
+ return "m";
+ case HOURS:
+ return "h";
+ case DAYS:
+ return "d";
+ default:
+ LOG.warn("Unhandled time unit {}", unit);
+ return "";
}
}
}
if (!executor.awaitTermination(timeout, unit)) {
executor.shutdownNow();
}
- } catch( InterruptedException e ) {
+ } catch (InterruptedException e) {
executor.shutdownNow();
}
}
*/
public final class HashCodeBuilder<T> implements Builder<Integer> {
/**
- *
* The value 31 was chosen because it is an odd prime. If it were even and the multiplication
* overflowed, information would be lost, as multiplication by 2 is equivalent to shifting. The
* advantage of using a prime is less clear, but it is traditional. A nice property of 31 is
* that the multiplication can be replaced by a shift and a subtraction for better performance:
* 31 * i == (i << 5) - i. Modern VMs do this sort of optimization automatically.
*
- * (from Joshua Bloch's Effective Java, Chapter 3, Item 9: Always override hashcode when you
+ * <p>(from Joshua Bloch's Effective Java, Chapter 3, Item 9: Always override hashcode when you
* override equals, page 48)
*/
private static final int PRIME = 31;
import org.opendaylight.yangtools.concepts.Identifiable;
public final class Identifiables {
- private static final Function<Identifiable<Object>, Object> EXTRACT_IDENTIFIER = new Function<Identifiable<Object>, Object>() {
+
+ private static final Function<Identifiable<Object>, Object> EXTRACT_IDENTIFIER =
+ new Function<Identifiable<Object>, Object>() {
@Override
public Object apply(@Nonnull final Identifiable<Object> input) {
Preconditions.checkNotNull(input);
abstract void setFields(List<K> keys, V[] values) throws IOException;
/**
- * Create an {@link ImmutableOffsetMap} as a copy of an existing map. This is actually not completely true,
- * as this method returns an {@link ImmutableMap} for empty and singleton inputs, as those are more memory-efficient.
- * This method also recognizes {@link ImmutableOffsetMap} on input, and returns it back without doing anything else.
- * It also recognizes {@link MutableOffsetMap} (as returned by {@link #toModifiableMap()}) and makes an efficient
- * copy of its contents. All other maps are converted to an {@link ImmutableOffsetMap} with the same iteration
- * order as input.
+ * Create an {@link ImmutableOffsetMap} as a copy of an existing map. This
+ * is actually not completely true, as this method returns an
+ * {@link ImmutableMap} for empty and singleton inputs, as those are more
+ * memory-efficient. This method also recognizes {@link ImmutableOffsetMap}
+ * on input, and returns it back without doing anything else. It also
+ * recognizes {@link MutableOffsetMap} (as returned by
+ * {@link #toModifiableMap()}) and makes an efficient copy of its contents.
+ * All other maps are converted to an {@link ImmutableOffsetMap} with the
+ * same iteration order as input.
*
- * @param m Input map, may not be null.
+ * @param m
+ * Input map, may not be null.
* @return An isolated, immutable copy of the input map
*/
@Nonnull public static <K, V> Map<K, V> orderedCopyOf(@Nonnull final Map<K, V> m) {
}
/**
- * Create an {@link ImmutableOffsetMap} as a copy of an existing map. This is actually not completely true,
- * as this method returns an {@link ImmutableMap} for empty and singleton inputs, as those are more memory-efficient.
- * This method also recognizes {@link ImmutableOffsetMap} on input, and returns it back without doing anything else.
- * It also recognizes {@link MutableOffsetMap} (as returned by {@link #toModifiableMap()}) and makes an efficient
- * copy of its contents. All other maps are converted to an {@link ImmutableOffsetMap}. Iterator order is not
- * guaranteed to be retained.
+ * Create an {@link ImmutableOffsetMap} as a copy of an existing map. This
+ * is actually not completely true, as this method returns an
+ * {@link ImmutableMap} for empty and singleton inputs, as those are more
+ * memory-efficient. This method also recognizes {@link ImmutableOffsetMap}
+ * on input, and returns it back without doing anything else. It also
+ * recognizes {@link MutableOffsetMap} (as returned by
+ * {@link #toModifiableMap()}) and makes an efficient copy of its contents.
+ * All other maps are converted to an {@link ImmutableOffsetMap}. Iterator
+ * order is not guaranteed to be retained.
*
- * @param m Input map, may not be null.
+ * @param m
+ * Input map, may not be null.
* @return An isolated, immutable copy of the input map
*/
@Nonnull public static <K, V> Map<K, V> unorderedCopyOf(@Nonnull final Map<K, V> m) {
return f;
}
- private static void setField(final ImmutableOffsetMap<?, ?> map, final Field field, final Object value) throws IOException {
+ private static void setField(final ImmutableOffsetMap<?, ?> map, final Field field, final Object value)
+ throws IOException {
try {
field.set(map, value);
} catch (IllegalArgumentException | IllegalAccessException e) {
/**
* Determines if object is known to be immutable
*
- * Note: This method may return false to immutable objects which
+ * <p>Note: This method may return false to immutable objects which
* immutability is not known, was defined not using concepts term.
*
* @param o
final List<T> ret;
switch (list.size()) {
- case 0:
- return Collections.singletonList(obj);
- case 1:
- ret = new ArrayList<>(2);
- ret.addAll(list);
- break;
- default:
- ret = list;
+ case 0:
+ return Collections.singletonList(obj);
+ case 1:
+ ret = new ArrayList<>(2);
+ ret.addAll(list);
+ break;
+ default:
+ ret = list;
}
ret.add(obj);
return DEFAULT_INSTANCE;
}
- public static MapAdaptor getInstance(final boolean useSingleton, final int copyMaxItems, final int persistMinItems) {
+ public static MapAdaptor getInstance(final boolean useSingleton, final int copyMaxItems,
+ final int persistMinItems) {
Preconditions.checkArgument(copyMaxItems >= 0, "copyMaxItems has to be a non-negative integer");
Preconditions.checkArgument(persistMinItems >= 0, "persistMinItems has to be a positive integer");
- Preconditions.checkArgument(persistMinItems <= copyMaxItems, "persistMinItems must be less than or equal to copyMaxItems");
+ Preconditions.checkArgument(persistMinItems <= copyMaxItems,
+ "persistMinItems must be less than or equal to copyMaxItems");
return new MapAdaptor(useSingleton, copyMaxItems, persistMinItems);
}
/**
* Input is treated is supposed to be left unmodified, result must be mutable.
- *
- * @param input
- * @return
*/
@SuppressWarnings("static-method")
public <K, V> Map<K, V> takeSnapshot(final Map<K, V> input) {
if (size <= 6) {
final int target;
switch (size) {
- case 0:
- case 1:
- target = 1;
- break;
- case 2:
- target = 2;
- break;
- case 3:
- target = 4;
- break;
- default:
- target = 8;
+ case 0:
+ case 1:
+ target = 1;
+ break;
+ case 2:
+ target = 2;
+ break;
+ case 3:
+ target = 4;
+ break;
+ default:
+ target = 8;
}
ret = new HashMap<>(target);
import org.opendaylight.yangtools.concepts.Mutable;
/**
- * A {@link Map} which can be modified and supports efficient conversion to an unmodifiable map. This interface is the
- * logical counterpart to {@link UnmodifiableMapPhase}, but it does not require implementations of {@link #toUnmodifiableMap()}
- * to return an implementation of that interface. The reason for that empty and singleton mappings are efficiently
- * represented as {@link ImmutableMap}, which does not implement {@link UnmodifiableMapPhase}.
+ * A {@link Map} which can be modified and supports efficient conversion to an
+ * unmodifiable map. This interface is the logical counterpart to
+ * {@link UnmodifiableMapPhase}, but it does not require implementations of
+ * {@link #toUnmodifiableMap()} to return an implementation of that interface.
+ * The reason for that empty and singleton mappings are efficiently represented
+ * as {@link ImmutableMap}, which does not implement
+ * {@link UnmodifiableMapPhase}.
*
- * @param <K> the type of keys maintained by this map
- * @param <V> the type of mapped values
+ * @param <K>
+ * the type of keys maintained by this map
+ * @param <V>
+ * the type of mapped values
*/
@Beta
public interface ModifiableMapPhase<K, V> extends Map<K, V>, Mutable {
* </code>
* results in source and result sharing the backing objects.
*
- * This map does not support null keys nor values.
+ * <p>This map does not support null keys nor values.
*
* @param <K> the type of keys maintained by this map
* @param <V> the type of mapped values
}
abstract Object removedObject();
+
abstract UnmodifiableMapPhase<K, V> modifiedMap(List<K> keys, V[] objects);
+
abstract UnmodifiableMapPhase<K, V> unmodifiedMap(Map<K, Integer> offsets, V[] objects);
+
abstract SharedSingletonMap<K, V> singletonMap();
@Override
try {
ret = (MutableOffsetMap<K, V>) super.clone();
} catch (CloneNotSupportedException e) {
- throw new IllegalStateException("Clone is expected to work", e);
+ throw new IllegalStateException("Clone is expected to work", e);
}
ret.newKeys = (HashMap<K, V>) newKeys.clone();
private final Iterator<Entry<K, Integer>> oldIterator = offsets.entrySet().iterator();
private final Iterator<K> newIterator = newKeys.keySet().iterator();
private int expectedModCount = modCount;
- private K currentKey, nextKey;
+ private K currentKey;
+ private K nextKey;
AbstractSetIterator() {
updateNextKey();
public Map<?, Integer> load(final List<?> key) {
return createMap(key);
}
- });
+ });
/*
* Cache for offsets where order does not mapper. The key is a Set of elements. We use manual two-stage loading
* because of the nature of the objects we store as values, which is ImmutableMaps. An ImmutableMap, when queried
* their size, and determining the size of a TrieMap is expensive, we make sure
* to update it as we go.
*
- * FIXME: this map does not support modification view the keySet()/values()/entrySet()
+ * <p>FIXME: this map does not support modification view the keySet()/values()/entrySet()
* methods.
*
* @param <K> Key type
* {@link Collections#unmodifiableCollection(Collection)}, this class checks its
* argument to ensure multiple encapsulation does not occur.
*
- * this class checks
+ * <p>This class checks
* the argument so it prevents multiple encapsulation. Subclasses of
* {@link ImmutableCollection} are also recognized and not encapsulated.
- * An attempt is also made to identi
*
* @param <E> the type of elements in this collection
*/
* to avoid blocking the thread that completed this task, as a common use case is to pass an
* executor that runs tasks in the same thread as the caller (ie MoreExecutors#sameThreadExecutor)
* to {@link #addListener}.
- * <p>
- * Note: the Executor specified on construction does not replace the Executor specified in
+ *
+ * <p>Note: the Executor specified on construction does not replace the Executor specified in
* {@link #addListener}. The latter Executor is still used however, if it is detected that the
* listener Runnable would execute in the thread that completed this task, the listener
* is executed on Executor specified on construction.
*
- * Also note that the use of this task may attach some (small) amount of state to the threads
+ * <p>Also note that the use of this task may attach some (small) amount of state to the threads
* interacting with it. That state will not be detached automatically, but you can use
* {@link #cleanStateForCurrentThread()} to clean it up.
*
* @param <V> the Future result value type
*/
public class AsyncNotifyingListenableFutureTask<V> extends FutureTask<V> implements ListenableFuture<V> {
- private static final class DelegatingAsyncNotifyingListenableFutureTask<V> extends AsyncNotifyingListenableFutureTask<V> {
+
+ private static final class DelegatingAsyncNotifyingListenableFutureTask<V>
+ extends AsyncNotifyingListenableFutureTask<V> {
+
/**
* The executor used to run listener callbacks.
*/
private final Executor listenerExecutor;
- private DelegatingAsyncNotifyingListenableFutureTask(final Callable<V> callable, @Nullable final Executor listenerExecutor) {
+ private DelegatingAsyncNotifyingListenableFutureTask(final Callable<V> callable,
+ @Nullable final Executor listenerExecutor) {
super(callable);
this.listenerExecutor = Preconditions.checkNotNull(listenerExecutor);
}
import javax.annotation.Nullable;
/**
- * An {@link com.google.common.util.concurrent.ListeningExecutorService} implementation that also allows for an {@link Executor} to be
- * specified on construction that is used to execute {@link ListenableFuture} callback Runnables,
- * registered via {@link com.google.common.util.concurrent.Futures#addCallback} or {@link ListenableFuture#addListener} directly,
- * asynchronously when a task that is run on this executor completes. This is useful when you want
- * to guarantee listener callback executions are off-loaded onto another thread to avoid blocking
- * the thread that completed the task, as a common use case is to pass an executor that runs tasks
- * in the same thread as the caller (ie <code>MoreExecutors#sameThreadExecutor</code>}) to
+ * An {@link com.google.common.util.concurrent.ListeningExecutorService}
+ * implementation that also allows for an {@link Executor} to be specified on
+ * construction that is used to execute {@link ListenableFuture} callback
+ * Runnables, registered via
+ * {@link com.google.common.util.concurrent.Futures#addCallback} or
+ * {@link ListenableFuture#addListener} directly, asynchronously when a task
+ * that is run on this executor completes. This is useful when you want to
+ * guarantee listener callback executions are off-loaded onto another thread to
+ * avoid blocking the thread that completed the task, as a common use case is to
+ * pass an executor that runs tasks in the same thread as the caller (ie
+ * <code>MoreExecutors#sameThreadExecutor</code>}) to
* {@link ListenableFuture#addListener}.
+ *
* <p>
- * Most commonly, this class would be used in lieu of <code>MoreExecutors#listeningDecorator</code>
- * when the underlying delegate Executor is single-threaded, in which case, you may not want
- * ListenableFuture callbacks to block the single thread.
+ * Most commonly, this class would be used in lieu of
+ * <code>MoreExecutors#listeningDecorator</code> when the underlying delegate
+ * Executor is single-threaded, in which case, you may not want ListenableFuture
+ * callbacks to block the single thread.
+ *
* <p>
- * Note: the Executor specified on construction does not replace the Executor specified in
- * {@link ListenableFuture#addListener}. The latter Executor is still used however, if it is
- * detected that the listener Runnable would execute in the thread that completed the task, the
- * listener is executed on Executor specified on construction.
+ * Note: the Executor specified on construction does not replace the Executor
+ * specified in {@link ListenableFuture#addListener}. The latter Executor is
+ * still used however, if it is detected that the listener Runnable would
+ * execute in the thread that completed the task, the listener is executed on
+ * Executor specified on construction.
*
* @author Thomas Pantelis
* @see AsyncNotifyingListenableFutureTask
/**
* A ThreadPoolExecutor with a specified bounded queue capacity that favors reusing previously
* constructed threads, when they are available, over creating new threads.
- * <p>
- * See {@link SpecialExecutors#newBoundedCachedThreadPool} for more details.
+ *
+ * <p>See {@link SpecialExecutors#newBoundedCachedThreadPool} for more details.
*
* @author Thomas Pantelis
*/
* @param threadPrefix
* the name prefix for threads created by this executor.
*/
- public CachedThreadPoolExecutor( final int maximumPoolSize, final int maximumQueueSize, final String threadPrefix ) {
+ public CachedThreadPoolExecutor(final int maximumPoolSize, final int maximumQueueSize, final String threadPrefix) {
// We're using a custom SynchronousQueue that has a backing bounded LinkedBlockingQueue.
// We don't specify any core threads (first parameter) so, when a task is submitted,
// the base class will always try to offer to the queue. If there is an existing waiting
this.delegateRejectedExecutionHandler = delegateRejectedExecutionHandler;
}
- RejectedExecutionHandler getDelegateRejectedExecutionHandler(){
+ RejectedExecutionHandler getDelegateRejectedExecutionHandler() {
return delegateRejectedExecutionHandler;
}
/**
* An implementation of ListeningExecutorService that attempts to detect deadlock scenarios that
* could occur if clients invoke the returned Future's <code>get</code> methods synchronously.
- * <p>
- * Deadlock scenarios are most apt to occur with a backing single-threaded executor where setting of
+ *
+ * <p>Deadlock scenarios are most apt to occur with a backing single-threaded executor where setting of
* the Future's result is executed on the single thread. Here's a scenario:
* <ul>
* <li>Client code is currently executing in an executor's single thread.</li>
* The second submitted task will never execute since the single thread is currently executing
* the client code which is blocked waiting for the submitted task to complete. Thus, deadlock has
* occurred.
- * <p>
- * This class prevents this scenario via the use of a ThreadLocal variable. When a task is invoked,
+ *
+ * <p>This class prevents this scenario via the use of a ThreadLocal variable. When a task is invoked,
* the ThreadLocal is set and, when a task completes, the ThreadLocal is cleared. Futures returned
* from this class override the <code>get</code> methods to check if the ThreadLocal is set. If it is,
* an ExecutionException is thrown with a custom cause.
*
- * Note that the ThreadLocal is not removed automatically, so some state may be left hanging off of
+ * <p>Note that the ThreadLocal is not removed automatically, so some state may be left hanging off of
* threads which have encountered this class. If you need to clean that state up, use
* {@link #cleanStateForCurrentThread()}.
*
import java.util.concurrent.ExecutionException;
/**
- * Utility exception mapper which translates an Exception to a specified type of Exception.
+ * Utility exception mapper which translates an Exception to a specified type of
+ * Exception.
*
- * This mapper is intended to be used with {@link com.google.common.util.concurrent.Futures#makeChecked(com.google.common.util.concurrent.ListenableFuture, Function)}
+ * <p>
+ * This mapper is intended to be used with
+ * {@link com.google.common.util.concurrent.Futures#makeChecked(com.google.common.util.concurrent.ListenableFuture, Function)}
* <ul>
- * <li>if exception is the specified type or one of its subclasses, it returns original exception.
- * <li>if exception is {@link ExecutionException} and the cause is of the specified type, it returns the cause
- * <li>otherwise returns an instance of the specified exception type with original exception as the cause.
+ * <li>if exception is the specified type or one of its subclasses, it returns
+ * original exception.
+ * <li>if exception is {@link ExecutionException} and the cause is of the
+ * specified type, it returns the cause
+ * <li>otherwise returns an instance of the specified exception type with
+ * original exception as the cause.
* </ul>
*
* @author Thomas Pantelis
*
- * @param <X> the exception type
+ * @param <X>
+ * the exception type
*/
public abstract class ExceptionMapper<X extends Exception> implements Function<Exception, X> {
+
private final Class<X> exceptionType;
private final String opName;
/**
* A ThreadPoolExecutor with a specified bounded queue capacity that favors creating new threads
* over queuing, as the former is faster.
- * <p>
- * See {@link SpecialExecutors#newBoundedFastThreadPool} for more details.
+ *
+ * <p>See {@link SpecialExecutors#newBoundedFastThreadPool} for more details.
*
* @author Thomas Pantelis
*/
/**
* An implementation of CheckedFuture that provides similar behavior for the <code>get</code> methods
* that the <code>checkedGet</code> methods provide.
- * <p>
- * For {@link CancellationException} and {@link InterruptedException}, the specified exception mapper
+ *
+ * <p>For {@link CancellationException} and {@link InterruptedException}, the specified exception mapper
* is invoked to translate them to the checked exception type.
- * <p>
- * For {@link ExecutionException}, the mapper is invoked to translate the cause to the checked exception
+ *
+ * <p>For {@link ExecutionException}, the mapper is invoked to translate the cause to the checked exception
* and a new ExecutionException is thrown with the translated cause.
*
* @author Thomas Pantelis
public V get() throws InterruptedException, ExecutionException {
try {
return super.get();
- } catch( final InterruptedException e ) {
+ } catch (final InterruptedException e) {
Thread.currentThread().interrupt();
throw wrapInExecutionException( "Operation was interrupted", e );
- } catch( final CancellationException e ) {
+ } catch (final CancellationException e) {
throw wrapInExecutionException( "Operation was cancelled", e );
- } catch( final ExecutionException e ) {
+ } catch (final ExecutionException e) {
throw wrapInExecutionException( e.getMessage(), e );
}
}
throws InterruptedException, ExecutionException, TimeoutException {
try {
return super.get( timeout, unit );
- } catch( final InterruptedException e ) {
+ } catch (final InterruptedException e) {
Thread.currentThread().interrupt();
throw wrapInExecutionException( "Operation was interrupted", e );
- } catch( final CancellationException e ) {
+ } catch (final CancellationException e) {
throw wrapInExecutionException( "Operation was cancelled", e );
- } catch( final ExecutionException e ) {
+ } catch (final ExecutionException e) {
throw wrapInExecutionException( e.getMessage(), e );
}
}
/**
* Submits a notification to be queued and dispatched to the given listener.
- * <p>
- * <b>Note:</b> This method may block if the listener queue is currently full.
+ *
+ * <p><b>Note:</b> This method may block if the listener queue is currently full.
*
* @param listener the listener to notify
* @param notification the notification to dispatch
/**
* Submits notifications to be queued and dispatched to the given listener.
- * <p>
- * <b>Note:</b> This method may block if the listener queue is currently full.
+ *
+ * <p><b>Note:</b> This method may block if the listener queue is currently full.
*
* @param listener the listener to notify
* @param notifications the notifications to dispatch
*/
void submitNotifications( final L listener, Iterable<N> notifications);
-}
\ No newline at end of file
+}
* This class manages queuing and dispatching notifications for multiple listeners concurrently.
* Notifications are queued on a per-listener basis and dispatched serially to each listener via an
* {@link Executor}.
- * <p>
- * This class optimizes its memory footprint by only allocating and maintaining a queue and executor
+ *
+ * <p>This class optimizes its memory footprint by only allocating and maintaining a queue and executor
* task for a listener when there are pending notifications. On the first notification(s), a queue
* is created and a task is submitted to the executor to dispatch the queue to the associated
* listener. Any subsequent notifications that occur before all previous notifications have been
break;
}
}
- } catch( InterruptedException e ) {
+ } catch (InterruptedException e) {
// We were interrupted trying to offer to the listener's queue. Somebody's probably
// telling us to quit.
/**
* Returns the maximum listener queue capacity.
*/
- public int getMaxQueueCapacity(){
+ public int getMaxQueueCapacity() {
return maxQueueCapacity;
}
/**
* Returns the {@link Executor} to used for notification tasks.
*/
- public Executor getExecutor(){
+ public Executor getExecutor() {
return executor;
}
private final L listener;
- public ListenerKey( L listener ) {
+ ListenerKey( L listener ) {
this.listener = listener;
}
}
LOG.warn(
- "{}: Timed out trying to offer a notification to the queue for listener {} " +
- "on attempt {} of {}. " +
- "The queue has reached its capacity of {}",
- name, listenerKey.toString(), notificationOfferAttempts, MAX_NOTIFICATION_OFFER_ATTEMPTS,
- maxQueueCapacity );
+ "{}: Timed out trying to offer a notification to the queue for listener {} "
+ + "on attempt {} of {}. " + "The queue has reached its capacity of {}",
+ name, listenerKey.toString(), notificationOfferAttempts,
+ MAX_NOTIFICATION_OFFER_ATTEMPTS, maxQueueCapacity);
}
if (!notificationOfferAttemptSuccess) {
LOG.warn(
- "{}: Failed to offer a notification to the queue for listener {}. " +
- "Exceeded max allowable attempts of {} in {} minutes; the listener " +
- "is likely in an unrecoverable state (deadlock or endless loop).",
- name, listenerKey.toString(), MAX_NOTIFICATION_OFFER_ATTEMPTS,
- MAX_NOTIFICATION_OFFER_ATTEMPTS );
+ "{}: Failed to offer a notification to the queue for listener {}. "
+ + "Exceeded max allowable attempts of {} in {} minutes; the listener "
+ + "is likely in an unrecoverable state (deadlock or endless loop).",
+ name, listenerKey.toString(), MAX_NOTIFICATION_OFFER_ATTEMPTS,
+ MAX_NOTIFICATION_OFFER_ATTEMPTS);
}
}
notifyListener( notification );
}
- } catch( InterruptedException e ) {
+ } catch (InterruptedException e) {
// The executor is probably shutting down so log as debug.
LOG.debug( "{}: Interrupted trying to remove from {} listener's queue",
listenerInvoker.invokeListener( listenerKey.getListener(), notification );
- } catch( RuntimeException e ) {
+ } catch (RuntimeException e ) {
// We'll let a RuntimeException from the listener slide and keep sending any
// remaining notifications.
LOG.error( String.format( "%1$s: Error notifying listener %2$s", name,
listenerKey.toString() ), e );
- } catch( Error e ) {
+ } catch (Error e) {
// A JVM Error is severe - best practice is to throw them up the chain. Set done to
// true so no new notifications can be added to this task as we're about to bail.
* @throws IllegalArgumentException when the supplied exception class does not pass sanity checks
* @throws SecurityException when the required constructor is not accessible
*/
- public static <X extends Exception> ReflectiveExceptionMapper<X> create(final String opName, final Class<X> exceptionType) throws SecurityException {
+ public static <X extends Exception> ReflectiveExceptionMapper<X> create(final String opName,
+ final Class<X> exceptionType) throws SecurityException {
final Constructor<X> c;
try {
c = exceptionType.getConstructor(String.class, Throwable.class);
try {
c.newInstance(opName, new Throwable());
- } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
+ | InvocationTargetException e) {
throw new IllegalArgumentException("Constructor " + c.getName() + " failed to pass instantiation test", e);
}
* threads over queuing, as the former is faster, so threads will only be reused when the thread
* limit is exceeded and tasks are queued. If the maximum queue capacity is reached, subsequent
* tasks will be rejected.
- * <p>
- * For example, if the maximum number of threads is 100 and 100 short-lived tasks are submitted
+ *
+ * <p>For example, if the maximum number of threads is 100 and 100 short-lived tasks are submitted
* within say 10 seconds, then 100 threads will be created and used - previously constructed
* idle threads will not be reused. This provides the fastest execution of the 100 tasks at the
* expense of memory and thread resource overhead. Therefore it is advisable to specify a
* relatively small thread limit (probably no more than 50).
- * <p>
- * Threads that have not been used for 15 seconds are terminated and removed from the pool.
+ *
+ * <p>Threads that have not been used for 15 seconds are terminated and removed from the pool.
* Thus, a pool that remains idle for long enough will not consume any resources.
- * <p>
- * If you need an executor with less memory and thread resource overhead where slower execution
+ *
+ * <p>If you need an executor with less memory and thread resource overhead where slower execution
* time is acceptable, consider using {@link #newBoundedCachedThreadPool }.
*
* @param maximumPoolSize
* thread to execute. If the specified maximum thread limit is reached, subsequent tasks will be
* queued and will execute as threads become available. If the maximum queue capacity is
* reached, subsequent tasks will be rejected.
- * <p>
- * Threads that have not been used for sixty seconds are terminated and removed from the pool.
+ *
+ * <p>Threads that have not been used for sixty seconds are terminated and removed from the pool.
* Thus, a pool that remains idle for long enough will not consume any resources.
- * <p>
- * By reusing threads when possible, this executor optimizes for reduced memory and thread
+ *
+ * <p>By reusing threads when possible, this executor optimizes for reduced memory and thread
* resource overhead at the expense of execution time.
- * <p>
- * If you need an executor with faster execution time where increased memory and thread resource
+ *
+ * <p>If you need an executor with faster execution time where increased memory and thread resource
* overhead is acceptable, consider using {@link #newBoundedFastThreadPool }.
*
* @param maximumPoolSize
* @param <E> the element t.ype
*/
public class TrackingLinkedBlockingQueue<E> extends LinkedBlockingQueue<E> {
- @SuppressWarnings("rawtypes")
- private static final AtomicIntegerFieldUpdater<TrackingLinkedBlockingQueue> LARGEST_QUEUE_SIZE_UPDATER = AtomicIntegerFieldUpdater.newUpdater(TrackingLinkedBlockingQueue.class, "largestQueueSize");
private static final long serialVersionUID = 1L;
+ @SuppressWarnings("rawtypes")
+ private static final AtomicIntegerFieldUpdater<TrackingLinkedBlockingQueue> LARGEST_QUEUE_SIZE_UPDATER
+ = AtomicIntegerFieldUpdater.newUpdater(TrackingLinkedBlockingQueue.class, "largestQueueSize");
+
/**
* Holds largestQueueSize, this long field should be only accessed
- * using {@link #LARGEST_QUEUE_SIZE_UPDATER}
+ * using {@link #LARGEST_QUEUE_SIZE_UPDATER}.
*/
private volatile int largestQueueSize = 0;
/**
* Returns the largest queue size.
*
- * FIXME: the this return will be changed to int in a future release.
+ * <p>FIXME: the this return will be changed to int in a future release.
*/
@Beta
public long getLargestQueueSize() {
}
@Override
- public boolean offer( final E e, final long timeout, final TimeUnit unit ) throws InterruptedException {
+ public boolean offer(final E e, final long timeout, final TimeUnit unit) throws InterruptedException {
if (super.offer( e, timeout, unit ) ) {
updateLargestQueueSize();
return true;
}
@Override
- public boolean offer( final E e ) {
+ public boolean offer(final E e) {
if (super.offer( e ) ) {
updateLargestQueueSize();
return true;
}
@Override
- public boolean add( final E e ) {
+ public boolean add(final E e) {
boolean result = super.add( e );
updateLargestQueueSize();
return result;
}
@Override
- public boolean addAll( final Collection<? extends E> c ) {
+ public boolean addAll(final Collection<? extends E> c) {
try {
return super.addAll( c );
} finally {
c.add(null);
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
c.remove(null);
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
c.addAll(null);
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
c.removeAll(null);
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
c.retainAll(null);
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
c.clear();
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
}
}
OffsetMapCache.invalidateCache();
}
- @Test(expected=IllegalArgumentException.class)
+ @Test(expected = IllegalArgumentException.class)
public void testWrongImmutableConstruction() {
new ImmutableOffsetMap.Ordered<>(Collections.<String, Integer>emptyMap(), new String[1]);
}
map.values().add("v1");
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
map.values().remove("v1");
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
map.values().clear();
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
it.remove();
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
map.keySet().add("k1");
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
map.keySet().clear();
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
map.keySet().remove("k1");
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
it.remove();
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
map.entrySet().clear();
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
map.entrySet().add(new SimpleEntry<>("k1", "v1"));
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
map.entrySet().remove(new SimpleEntry<>("k1", "v1"));
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
it.remove();
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
map.clear();
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
map.put("k1", "fail");
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
map.putAll(ImmutableMap.of("k1", "fail"));
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
try {
map.remove("k1");
fail();
} catch (UnsupportedOperationException e) {
+ // OK
}
}
mutable.remove("non-existent");
// Resulting map should be equal, but not the same object
- final ImmutableOffsetMap<String, String> result = (ImmutableOffsetMap<String, String>) mutable.toUnmodifiableMap();
+ final ImmutableOffsetMap<String, String> result = (ImmutableOffsetMap<String, String>) mutable
+ .toUnmodifiableMap();
assertNotSame(source, result);
assertEquals(source, result);
mutable.remove("k1");
mutable.put("k1", "v1");
- final ImmutableOffsetMap<String, String> result = (ImmutableOffsetMap<String, String>) mutable.toUnmodifiableMap();
+ final ImmutableOffsetMap<String, String> result = (ImmutableOffsetMap<String, String>) mutable
+ .toUnmodifiableMap();
assertTrue(source.equals(result));
assertTrue(result.equals(source));
mutable.remove("k1");
mutable.put("k1", "v1");
- final ImmutableOffsetMap<String, String> result = (ImmutableOffsetMap<String, String>) mutable.toUnmodifiableMap();
+ final ImmutableOffsetMap<String, String> result = (ImmutableOffsetMap<String, String>) mutable
+ .toUnmodifiableMap();
assertEquals(source, result);
// Only offsets should be shared
mutable.put("k1", "replaced");
- final ImmutableOffsetMap<String, String> result = (ImmutableOffsetMap<String, String>) mutable.toUnmodifiableMap();
+ final ImmutableOffsetMap<String, String> result = (ImmutableOffsetMap<String, String>) mutable
+ .toUnmodifiableMap();
final Map<String, String> reference = ImmutableMap.of("k1", "replaced", "k2", "v2");
assertEquals(reference, result);
assertTrue(result.needClone());
// Forced copy, no cloning needed, but maps are equal
- final ImmutableOffsetMap<String, String> immutable = (ImmutableOffsetMap<String, String>) source.toUnmodifiableMap();
+ final ImmutableOffsetMap<String, String> immutable = (ImmutableOffsetMap<String, String>) source
+ .toUnmodifiableMap();
assertFalse(source.needClone());
assertTrue(source.equals(immutable));
assertTrue(immutable.equals(source));
assertTrue(result.needClone());
// Creates a immutable view, which shares the array
- final ImmutableOffsetMap<String, String> immutable = (ImmutableOffsetMap<String, String>) source.toUnmodifiableMap();
+ final ImmutableOffsetMap<String, String> immutable = (ImmutableOffsetMap<String, String>) source
+ .toUnmodifiableMap();
assertTrue(source.needClone());
assertSame(source.array(), immutable.objects());
}
it.hasNext();
fail();
} catch (ConcurrentModificationException e) {
+ // OK
}
try {
it.next();
fail();
} catch (ConcurrentModificationException e) {
+ // OK
}
try {
it.remove();
fail();
} catch (ConcurrentModificationException e) {
+ // OK
}
}
it.remove();
fail();
} catch (IllegalStateException e) {
+ // OK
}
assertTrue(it.hasNext());
it.next();
fail();
} catch (NoSuchElementException e) {
+ // OK
}
}
100000, "TestPool", 0 );
}
- @Test(expected=RejectedExecutionException.class)
+ @Test(expected = RejectedExecutionException.class)
public void testFastThreadPoolRejectingTask() throws Exception {
executor = SpecialExecutors.newBoundedFastThreadPool( 1, 1, "TestPool" );
100000, "TestPool", 0 );
}
- @Test(expected=RejectedExecutionException.class)
+ @Test(expected = RejectedExecutionException.class)
public void testCachedThreadRejectingTask() throws Exception {
ExecutorService executor = SpecialExecutors.newBoundedCachedThreadPool( 1, 1, "TestPool" );
this.executor = executor;
- System.out.println( "\nTesting " + executor.getClass().getSimpleName() + " with " +
- numTasksToRun + " tasks." );
+ System.out.println("\nTesting " + executor.getClass().getSimpleName() + " with " + numTasksToRun + " tasks.");
final CountDownLatch tasksRunLatch = new CountDownLatch( numTasksToRun );
final ConcurrentMap<Thread, AtomicLong> taskCountPerThread = new ConcurrentHashMap<>();
stopWatch.stop();
if (!done) {
- fail( (numTasksToRun - tasksRunLatch.getCount()) + " tasks out of " +
- numTasksToRun + " executed" );
+ fail((numTasksToRun - tasksRunLatch.getCount()) + " tasks out of " + numTasksToRun + " executed");
}
if (threadError.get() != null) {
} else if (blockLatch != null) {
blockLatch.await();
}
- } catch( InterruptedException e ) {}
+ } catch (InterruptedException e) {
+ }
if (expThreadPrefix != null) {
assertEquals( "Thread name starts with " + expThreadPrefix, true,
count.incrementAndGet();
}
- } catch( AssertionError e ) {
+ } catch (AssertionError e) {
if (threadError != null) {
threadError.set( e );
}