Added intellij support. Compiled as java6, supports java8 ConcurrentHashMap

master
nathan 2015-06-28 00:16:38 +02:00
parent 894da4c980
commit 8f312a8012
42 changed files with 724 additions and 449 deletions

View File

@ -3,7 +3,7 @@ package dorkbox.util.messagebus;
import org.jctools.queues.MpmcArrayQueue;
import org.jctools.util.UnsafeAccess;
import java.util.concurrent.ThreadLocalRandom;
import java.util.Random;
final
@ -38,14 +38,6 @@ class MpmcMultiTransferArrayQueue extends MpmcArrayQueue<Object> {
*/
private static final int PARK_UNTIMED_SPINS = PARK_TIMED_SPINS * 16;
private final int consumerCount;
public
MpmcMultiTransferArrayQueue(final int consumerCount) {
super(1024); // must be power of 2
this.consumerCount = consumerCount;
}
private static final ThreadLocal<Object> nodeThreadLocal = new ThreadLocal<Object>() {
@Override
protected
@ -54,6 +46,22 @@ class MpmcMultiTransferArrayQueue extends MpmcArrayQueue<Object> {
}
};
private static final ThreadLocal<Random> randomThreadLocal = new ThreadLocal<Random>() {
@Override
protected
Random initialValue() {
return new Random();
}
};
private final int consumerCount;
public
MpmcMultiTransferArrayQueue(final int consumerCount) {
super(1024); // must be power of 2
this.consumerCount = consumerCount;
}
/**
* PRODUCER method
@ -714,7 +722,7 @@ class MpmcMultiTransferArrayQueue extends MpmcArrayQueue<Object> {
private
void park(final Object node, final Thread myThread) throws InterruptedException {
int spins = -1; // initialized after first item and cancel checks
ThreadLocalRandom randomYields = null; // bound if needed
Random randomYields = null; // bound if needed
for (; ; ) {
if (MultiNode.lvThread(node) == null) {
@ -725,7 +733,7 @@ class MpmcMultiTransferArrayQueue extends MpmcArrayQueue<Object> {
}
else if (spins < 0) {
spins = PARK_UNTIMED_SPINS;
randomYields = ThreadLocalRandom.current();
randomYields = randomThreadLocal.get();
}
else if (spins > 0) {
if (randomYields.nextInt(1024) == 0) {

View File

@ -1,10 +1,6 @@
package dorkbox.util.messagebus.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.*;
/**
* Mark any method of any class(=listener) as a message handler and configure the handler
@ -17,8 +13,9 @@ import java.lang.annotation.Target;
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Inherited
@Target(value = {ElementType.METHOD,ElementType.ANNOTATION_TYPE})
public @interface Handler {
@Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public
@interface Handler {
/**
* Define whether or not the handler accepts variable arguments it declares in its signature.

View File

@ -1,23 +1,18 @@
package dorkbox.util.messagebus.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.*;
/**
*
* This annotation is meant to carry configuration that is shared among all instances of the annotated
* listener. Supported configurations are:
*
* Reference type: The bus will use either strong or weak references to its registered listeners,
* depending on which reference type (@see References) is set
* <p/>
* Reference type: The bus will use either strong or weak references to its registered listeners,
* depending on which reference type (@see References) is set
*
* @author bennidi
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Inherited
public @interface Listener {
}
public
@interface Listener {}

View File

@ -1,10 +1,6 @@
package dorkbox.util.messagebus.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.*;
/**
* A handler marked with this annotation is guaranteed to be invoked in a thread-safe manner, that is, no
@ -12,16 +8,14 @@ import java.lang.annotation.Target;
* listener until the handler completed. It is equal to wrapping the handler code in a synchronized{} block.
* This feature will reduce performance of message publication. Try to avoid shared mutable state whenever possible
* and use immutable data instead.
*
* <p/>
* Note: Unsynchronized handlers may still be invoked concurrently with synchronized ones
*
*
*
* @author bennidi
* Date: 3/31/13
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Inherited
@Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface Synchronized {
}
public
@interface Synchronized {}

View File

@ -16,7 +16,8 @@ import java.util.concurrent.atomic.AtomicLong;
* @author bennidi
* Date: 2/12/12
*/
public abstract class AbstractConcurrentSet<T> implements Set<T> {
public abstract
class AbstractConcurrentSet<T> implements Set<T> {
private static final AtomicLong id = new AtomicLong();
private final transient long ID = id.getAndIncrement();
@ -28,14 +29,17 @@ public abstract class AbstractConcurrentSet<T> implements Set<T> {
volatile long z0, z1, z2, z4, z5, z6 = 7L;
protected AbstractConcurrentSet(Map<T, ISetEntry<T>> entries) {
protected
AbstractConcurrentSet(Map<T, ISetEntry<T>> entries) {
this.entries = entries;
}
protected abstract Entry<T> createEntry(T value, Entry<T> next);
protected abstract
Entry<T> createEntry(T value, Entry<T> next);
@Override
public boolean add(T element) {
public
boolean add(T element) {
if (element == null) {
return false;
}
@ -62,7 +66,8 @@ public abstract class AbstractConcurrentSet<T> implements Set<T> {
}
@Override
public boolean contains(Object element) {
public
boolean contains(Object element) {
final StampedLock lock = this.lock;
long stamp = lock.readLock();
@ -73,7 +78,8 @@ public abstract class AbstractConcurrentSet<T> implements Set<T> {
return entry != null && entry.getValue() != null;
}
private boolean insert(T element) {
private
boolean insert(T element) {
if (!this.entries.containsKey(element)) {
this.head = createEntry(element, this.head);
this.entries.put(element, this.head);
@ -83,17 +89,20 @@ public abstract class AbstractConcurrentSet<T> implements Set<T> {
}
@Override
public int size() {
public
int size() {
return this.entries.size();
}
@Override
public boolean isEmpty() {
public
boolean isEmpty() {
return this.head == null;
}
@Override
public boolean addAll(Collection<? extends T> elements) {
public
boolean addAll(Collection<? extends T> elements) {
StampedLock lock = this.lock;
boolean changed = false;
@ -116,7 +125,8 @@ public abstract class AbstractConcurrentSet<T> implements Set<T> {
* @return TRUE if the element was successfully removed
*/
@Override
public boolean remove(Object element) {
public
boolean remove(Object element) {
StampedLock lock = this.lock;
long stamp = lock.readLock();
@ -126,13 +136,15 @@ public abstract class AbstractConcurrentSet<T> implements Set<T> {
if (entry == null || entry.getValue() == null) {
return false; // fast exit
} else {
}
else {
stamp = lock.writeLock();
try {
if (entry != this.head) {
entry.remove();
} else {
}
else {
// if it was second, now it's first
this.head = this.head.next();
//oldHead.clear(); // optimize for GC not possible because of potentially running iterators
@ -146,32 +158,38 @@ public abstract class AbstractConcurrentSet<T> implements Set<T> {
}
@Override
public Object[] toArray() {
public
Object[] toArray() {
return this.entries.entrySet().toArray();
}
@Override
public <T2> T2[] toArray(T2[] a) {
public
<T2> T2[] toArray(T2[] a) {
return this.entries.entrySet().toArray(a);
}
@Override
public boolean containsAll(Collection<?> c) {
public
boolean containsAll(Collection<?> c) {
throw new UnsupportedOperationException("Not implemented");
}
@Override
public boolean removeAll(Collection<?> c) {
public
boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException("Not implemented");
}
@Override
public boolean retainAll(Collection<?> c) {
public
boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException("Not implemented");
}
@Override
public void clear() {
public
void clear() {
StampedLock lock = this.lock;
long stamp = lock.writeLock();
@ -181,7 +199,8 @@ public abstract class AbstractConcurrentSet<T> implements Set<T> {
}
@Override
public int hashCode() {
public
int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (this.ID ^ this.ID >>> 32);
@ -189,7 +208,8 @@ public abstract class AbstractConcurrentSet<T> implements Set<T> {
}
@Override
public boolean equals(Object obj) {
public
boolean equals(Object obj) {
if (this == obj) {
return true;
}

View File

@ -11,34 +11,40 @@ import java.util.Arrays;
* @author dorkbox, llc
* Date: 2/2/15
*/
public final class DeadMessage {
public final
class DeadMessage {
private final Object[] relatedMessages;
public DeadMessage(Object message) {
public
DeadMessage(Object message) {
this.relatedMessages = new Object[1];
this.relatedMessages[0] = message;
}
public DeadMessage(Object message1, Object message2) {
public
DeadMessage(Object message1, Object message2) {
this.relatedMessages = new Object[2];
this.relatedMessages[0] = message1;
this.relatedMessages[1] = message2;
}
public DeadMessage(Object message1, Object message2, Object message3) {
public
DeadMessage(Object message1, Object message2, Object message3) {
this.relatedMessages = new Object[3];
this.relatedMessages[0] = message1;
this.relatedMessages[1] = message2;
this.relatedMessages[2] = message3;
}
public DeadMessage(Object[] messages) {
public
DeadMessage(Object[] messages) {
this.relatedMessages = Arrays.copyOf(messages, messages.length);
}
public Object[] getMessages() {
public
Object[] getMessages() {
return this.relatedMessages;
}
}

View File

@ -32,7 +32,7 @@ public class HashMapTree<KEY, VALUE> {
* can be overridden to provide a custom backing map
*/
protected Map<KEY, HashMapTree<KEY, VALUE>> createChildren(int defaultSize, float loadFactor) {
return JavaVersionAdapter.get.concurrentMap(defaultSize, loadFactor, 1);
return JavaVersionAdapter.concurrentMap(defaultSize, loadFactor, 1);
}
public final VALUE getValue() {

View File

@ -13,26 +13,28 @@ import java.util.Arrays;
* Any method in any class annotated with the @Handler annotation represents a message handler. The class that contains
* the handler is called a message listener and more generally, any class containing a message handler in its class hierarchy
* defines such a message listener.
* <p>
* <p>
* <p/>
* <p/>
* Note: When sending messages to a handler that is of type ARRAY (either an object of type array, or a vararg), the JVM cannot
* tell the difference (the message that is being sent), if it is a vararg or array.
* <p>
* <p>
* BECAUSE OF THIS, we always treat the two the same
* <p>
* <p>
* tell the difference (the message that is being sent), if it is a vararg or array.
* <p/>
* <p/>
* BECAUSE OF THIS, we always treat the two the same
* <p/>
* <p/>
*
* @author bennidi
* Date: 11/14/12
* @author dorkbox, llc
* Date: 2/2/15
*/
public class MessageHandler {
public
class MessageHandler {
// publish all listeners defined by the given class (includes
// listeners defined in super classes)
public static MessageHandler[] get(final Class<?> target) {
public static
MessageHandler[] get(final Class<?> target) {
// publish all handlers (this will include all (inherited) methods directly annotated using @Handler)
final Method[] allMethods = ReflectionUtils.getMethods(target);
@ -41,7 +43,7 @@ public class MessageHandler {
final ArrayList<MessageHandler> finalMethods = new ArrayList<MessageHandler>(length);
Method method;
for (int i=0;i<length;i++) {
for (int i = 0; i < length; i++) {
method = allMethods[i];
// retain only those that are at the bottom of their respective class hierarchy (deepest overriding method)
@ -79,7 +81,8 @@ public class MessageHandler {
private final boolean isSynchronized;
public MessageHandler(Method handler, Handler handlerConfig) {
public
MessageHandler(Method handler, Handler handlerConfig) {
super();
if (handler == null) {
@ -92,7 +95,7 @@ public class MessageHandler {
this.methodIndex = this.handler.getIndex(handler.getName(), handledMessages);
this.acceptsSubtypes = handlerConfig.acceptSubtypes();
this.isSynchronized = ReflectionUtils.getAnnotation(handler, Synchronized.class) != null;
this.isSynchronized = ReflectionUtils.getAnnotation(handler, Synchronized.class) != null;
this.handledMessages = handledMessages;
if (handledMessages.length == 1 && handledMessages[0].isArray() && handlerConfig.acceptVarargs()) {
@ -103,36 +106,44 @@ public class MessageHandler {
}
}
public final boolean isSynchronized() {
public final
boolean isSynchronized() {
return this.isSynchronized;
}
public final MethodAccess getHandler() {
public final
MethodAccess getHandler() {
return this.handler;
}
public final int getMethodIndex() {
public final
int getMethodIndex() {
return this.methodIndex;
}
public final Class<?>[] getHandledMessages() {
public final
Class<?>[] getHandledMessages() {
return this.handledMessages;
}
public final Class<?> getVarArgClass() {
public final
Class<?> getVarArgClass() {
return this.varArgClass;
}
public final boolean acceptsSubtypes() {
public final
boolean acceptsSubtypes() {
return this.acceptsSubtypes;
}
public final boolean acceptsVarArgs() {
public final
boolean acceptsVarArgs() {
return this.varArgClass != null;
}
@Override
public final int hashCode() {
public final
int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (this.acceptsSubtypes ? 1231 : 1237);
@ -143,7 +154,8 @@ public class MessageHandler {
}
@Override
public final boolean equals(Object obj) {
public final
boolean equals(Object obj) {
if (this == obj) {
return true;
}
@ -164,7 +176,8 @@ public class MessageHandler {
if (other.handler != null) {
return false;
}
} else if (!this.handler.equals(other.handler)) {
}
else if (!this.handler.equals(other.handler)) {
return false;
}
if (this.isSynchronized != other.isSynchronized) {

View File

@ -1,4 +1,5 @@
package dorkbox.util.messagebus.common;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@ -10,33 +11,40 @@ import java.util.Map;
* @author bennidi
* Date: 2/12/12
*/
public class StrongConcurrentSet<T> extends AbstractConcurrentSet<T> {
public
class StrongConcurrentSet<T> extends AbstractConcurrentSet<T> {
public StrongConcurrentSet() {
public
StrongConcurrentSet() {
this(16, 0.75f);
}
public StrongConcurrentSet(int size, float loadFactor) {
public
StrongConcurrentSet(int size, float loadFactor) {
this(new HashMap<T, ISetEntry<T>>(size, loadFactor));
}
public StrongConcurrentSet(Map<T, ISetEntry<T>> entries) {
public
StrongConcurrentSet(Map<T, ISetEntry<T>> entries) {
super(entries);
}
@Override
public Iterator<T> iterator() {
public
Iterator<T> iterator() {
return new Iterator<T>() {
private ISetEntry<T> current = StrongConcurrentSet.this.head;
@Override
public boolean hasNext() {
public
boolean hasNext() {
return this.current != null;
}
@Override
public T next() {
public
T next() {
if (this.current == null) {
return null;
}
@ -48,7 +56,8 @@ public class StrongConcurrentSet<T> extends AbstractConcurrentSet<T> {
}
@Override
public void remove() {
public
void remove() {
if (this.current == null) {
return;
}
@ -60,27 +69,32 @@ public class StrongConcurrentSet<T> extends AbstractConcurrentSet<T> {
}
@Override
protected Entry<T> createEntry(T value, Entry<T> next) {
protected
Entry<T> createEntry(T value, Entry<T> next) {
return next != null ? new StrongEntry<T>(value, next) : new StrongEntry<T>(value);
}
public static class StrongEntry<T> extends Entry<T> {
public static
class StrongEntry<T> extends Entry<T> {
private T value;
private StrongEntry(T value, Entry<T> next) {
private
StrongEntry(T value, Entry<T> next) {
super(next);
this.value = value;
}
private StrongEntry(T value) {
private
StrongEntry(T value) {
super();
this.value = value;
}
@Override
public T getValue() {
public
T getValue() {
return this.value;
}
}

View File

@ -13,11 +13,11 @@ public class StrongConcurrentSetV8<T> extends StrongConcurrentSet<T> {
public StrongConcurrentSetV8(int size, float loadFactor) {
// 1 for the stripe size, because that is the max concurrency with our concurrent set (since it uses R/W locks)
super(JavaVersionAdapter.get.<T, ISetEntry<T>>concurrentMap(size, loadFactor, 16));
super(JavaVersionAdapter.<T, ISetEntry<T>>concurrentMap(size, loadFactor, 16));
}
public StrongConcurrentSetV8(int size, float loadFactor, int stripeSize) {
// 1 for the stripe size, because that is the max concurrency with our concurrent set (since it uses R/W locks)
super(JavaVersionAdapter.get.<T, ISetEntry<T>>concurrentMap(size, loadFactor, stripeSize));
super(JavaVersionAdapter.<T, ISetEntry<T>>concurrentMap(size, loadFactor, stripeSize));
}
}

View File

@ -13,15 +13,18 @@ import java.util.WeakHashMap;
* @author bennidi
* Date: 2/12/12
*/
public class WeakConcurrentSet<T> extends AbstractConcurrentSet<T>{
public
class WeakConcurrentSet<T> extends AbstractConcurrentSet<T> {
public WeakConcurrentSet() {
public
WeakConcurrentSet() {
super(new WeakHashMap<T, ISetEntry<T>>());
}
@Override
public Iterator<T> iterator() {
public
Iterator<T> iterator() {
return new Iterator<T>() {
// the current list element of this iterator
@ -31,20 +34,20 @@ public class WeakConcurrentSet<T> extends AbstractConcurrentSet<T>{
// this method will remove all orphaned entries
// until it finds the first entry whose value has not yet been garbage collected
// the method assumes that the current element is already orphaned and will remove it
private void removeOrphans(){
private
void removeOrphans() {
StampedLock lock = WeakConcurrentSet.this.lock;
long stamp = lock.writeLock();
// final Lock writeLock = WeakConcurrentSet.this.lock.writeLock();
// writeLock.lock();
try{
try {
do {
ISetEntry<T> orphaned = this.current;
this.current = this.current.next();
orphaned.remove();
} while(this.current != null && this.current.getValue() == null);
}
finally {
} while (this.current != null && this.current.getValue() == null);
} finally {
lock.unlockWrite(stamp);
// writeLock.unlock();
}
@ -52,7 +55,8 @@ public class WeakConcurrentSet<T> extends AbstractConcurrentSet<T>{
@Override
public boolean hasNext() {
public
boolean hasNext() {
if (this.current == null) {
return false;
}
@ -61,13 +65,15 @@ public class WeakConcurrentSet<T> extends AbstractConcurrentSet<T>{
// because a null value indicates that the value has been garbage collected
removeOrphans();
return this.current != null; // if any entry is left then it will have a value
} else {
}
else {
return true;
}
}
@Override
public T next() {
public
T next() {
if (this.current == null) {
return null;
}
@ -75,14 +81,16 @@ public class WeakConcurrentSet<T> extends AbstractConcurrentSet<T>{
if (value == null) { // auto-removal of orphan references
removeOrphans();
return next();
} else {
}
else {
this.current = this.current.next();
return value;
}
}
@Override
public void remove() {
public
void remove() {
//throw new UnsupportedOperationException("Explicit removal of set elements is only allowed via the controlling set. Sorry!");
if (this.current == null) {
return;
@ -95,27 +103,32 @@ public class WeakConcurrentSet<T> extends AbstractConcurrentSet<T>{
}
@Override
protected Entry<T> createEntry(T value, Entry<T> next) {
protected
Entry<T> createEntry(T value, Entry<T> next) {
return next != null ? new WeakEntry<T>(value, next) : new WeakEntry<T>(value);
}
public static class WeakEntry<T> extends Entry<T> {
public static
class WeakEntry<T> extends Entry<T> {
private WeakReference<T> value;
private WeakEntry(T value, Entry<T> next) {
private
WeakEntry(T value, Entry<T> next) {
super(next);
this.value = new WeakReference<T>(value);
}
private WeakEntry(T value) {
private
WeakEntry(T value) {
super();
this.value = new WeakReference<T>(value);
}
@Override
public T getValue() {
public
T getValue() {
return this.value.get();
}
}

View File

@ -21,7 +21,6 @@ import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

View File

@ -5,10 +5,12 @@ import java.util.concurrent.ConcurrentMap;
/**
*
*/
public class Java7Adapter extends JavaVersionAdapter {
public
class Java6Adapter implements MapAdapter {
@Override
public final <K, V> ConcurrentMap<K, V> concurrentMap(final int size, final float loadFactor, final int stripeSize) {
public final
<K, V> ConcurrentMap<K, V> concurrentMap(final int size, final float loadFactor, final int stripeSize) {
return new ConcurrentHashMapV8<K, V>(size, loadFactor, stripeSize);
}
}

View File

@ -3,9 +3,11 @@ package dorkbox.util.messagebus.common.adapter;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class Java8Adapter extends JavaVersionAdapter {
public
class Java8Adapter implements MapAdapter {
@Override
public final <K, V> ConcurrentMap<K, V> concurrentMap(final int size, final float loadFactor, final int stripeSize) {
public final
<K, V> ConcurrentMap<K, V> concurrentMap(final int size, final float loadFactor, final int stripeSize) {
return new ConcurrentHashMap<K, V>(size, loadFactor, stripeSize);
}
}

View File

@ -1,29 +1,29 @@
package dorkbox.util.messagebus.common.adapter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public abstract class JavaVersionAdapter {
public
class JavaVersionAdapter {
public static final JavaVersionAdapter get;
private static final MapAdapter get;
static {
// get = new Java7Adapter();
get = new Java8Adapter();
MapAdapter adapter;
try {
Class.forName("java.util.concurrent.locks.StampedLock");
adapter = new Java8Adapter();
} catch (Exception e) {
adapter = new Java6Adapter();
}
get = adapter;
}
public abstract <K, V> ConcurrentMap<K, V> concurrentMap(final int size, final float loadFactor, final int stripeSize);
public <K, V> Map<K, V> hashMap(final int size, final float loadFactor) {
return new ConcurrentHashMap<K, V>(size, loadFactor, 1);
public static
<K, V> ConcurrentMap<K, V> concurrentMap(final int size, final float loadFactor, final int stripeSize) {
return get.concurrentMap(size, loadFactor, stripeSize);
}
}

View File

@ -0,0 +1,11 @@
package dorkbox.util.messagebus.common.adapter;
import java.util.concurrent.ConcurrentMap;
/**
*
*/
public
interface MapAdapter {
<K, V> ConcurrentMap<K, V> concurrentMap(final int size, final float loadFactor, final int stripeSize);
}

View File

@ -6,7 +6,7 @@
package dorkbox.util.messagebus.common.adapter;
import java.util.concurrent.ThreadLocalRandom;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
@ -282,6 +282,14 @@ public class StampedLock implements java.io.Serializable {
private static final int RMODE = 0;
private static final int WMODE = 1;
private static final ThreadLocal<Random> randomThreadLocal = new ThreadLocal<Random>() {
@Override
protected
Random initialValue() {
return new Random();
}
};
/** Wait nodes */
static final class WNode {
volatile WNode prev;
@ -308,6 +316,7 @@ public class StampedLock implements java.io.Serializable {
/** extra reader count when state read count saturated */
private transient int readerOverflow;
/**
* Creates a new lock, initially in unlocked state.
*/
@ -1004,7 +1013,7 @@ public class StampedLock implements java.io.Serializable {
return s;
}
}
else if ((ThreadLocalRandom.current().nextInt() &
else if ((randomThreadLocal.get().nextInt() &
OVERFLOW_YIELD_RATE) == 0) {
Thread.yield();
}
@ -1032,7 +1041,7 @@ public class StampedLock implements java.io.Serializable {
return next;
}
}
else if ((ThreadLocalRandom.current().nextInt() &
else if ((randomThreadLocal.get().nextInt() &
OVERFLOW_YIELD_RATE) == 0) {
Thread.yield();
}
@ -1084,7 +1093,7 @@ public class StampedLock implements java.io.Serializable {
else if (spins < 0) {
spins = m == WBIT && this.wtail == this.whead ? SPINS : 0;
} else if (spins > 0) {
if (ThreadLocalRandom.current().nextInt() >= 0) {
if (randomThreadLocal.get().nextInt() >= 0) {
--spins;
}
}
@ -1122,7 +1131,7 @@ public class StampedLock implements java.io.Serializable {
return ns;
}
}
else if (ThreadLocalRandom.current().nextInt() >= 0 &&
else if (randomThreadLocal.get().nextInt() >= 0 &&
--k <= 0) {
break;
}
@ -1198,7 +1207,7 @@ public class StampedLock implements java.io.Serializable {
return ns;
} else if (m >= WBIT) {
if (spins > 0) {
if (ThreadLocalRandom.current().nextInt() >= 0) {
if (randomThreadLocal.get().nextInt() >= 0) {
--spins;
}
}
@ -1307,7 +1316,7 @@ public class StampedLock implements java.io.Serializable {
return ns;
}
else if (m >= WBIT &&
ThreadLocalRandom.current().nextInt() >= 0 && --k <= 0) {
randomThreadLocal.get().nextInt() >= 0 && --k <= 0) {
break;
}
}

View File

@ -15,7 +15,8 @@ import java.util.concurrent.atomic.AtomicLong;
* structure. Remove operations can affect any running iterator such that a removed element that has not yet
* been reached by the iterator will not appear in that iterator anymore.
*/
public class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
public
class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
private static final long serialVersionUID = -2729855178402529784L;
private static final AtomicLong id = new AtomicLong();
@ -25,17 +26,20 @@ public class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
private final Node<T> IN_PROGRESS_MARKER = new Node<T>(null);
private ConcurrentMap<T, Node<T>> entries;
public ConcurrentSet() {
public
ConcurrentSet() {
this(16, 0.75f, Runtime.getRuntime().availableProcessors());
}
public ConcurrentSet(int size, float loadFactor, int stripeSize) {
public
ConcurrentSet(int size, float loadFactor, int stripeSize) {
super();
this.entries = JavaVersionAdapter.get.concurrentMap(size, loadFactor, 32);
this.entries = JavaVersionAdapter.concurrentMap(size, loadFactor, 32);
}
@Override
public boolean add(T element) {
public
boolean add(T element) {
if (element == null) {
return false;
}
@ -54,7 +58,8 @@ public class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
}
@Override
public boolean contains(Object element) {
public
boolean contains(Object element) {
if (element == null) {
return false;
}
@ -72,12 +77,14 @@ public class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
}
@Override
public int size() {
public
int size() {
return this.entries.size();
}
@Override
public boolean isEmpty() {
public
boolean isEmpty() {
return super.isEmpty();
}
@ -85,7 +92,8 @@ public class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
* @return TRUE if the element was successfully removed
*/
@Override
public boolean remove(Object element) {
public
boolean remove(Object element) {
while (this.entries.get(element) == this.IN_PROGRESS_MARKER) {
; // data race
}
@ -113,11 +121,13 @@ public class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
}
@Override
public Iterator<T> iterator() {
public
Iterator<T> iterator() {
return new Itr2();
}
private class Itr2 implements Iterator<T> {
private
class Itr2 implements Iterator<T> {
/**
* Next node to return item for.
*/
@ -144,7 +154,8 @@ public class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
* Moves to next valid node and returns item to return for
* next(), or null if no such.
*/
private T advance() {
private
T advance() {
this.lastRet = this.nextNode; // for removing items via iterator
T nextItem = this.nextItem;
@ -152,12 +163,13 @@ public class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
if (this.nextNode == null) {
p = first();
pred = null;
} else {
}
else {
pred = this.nextNode;
p = succ(this.nextNode);
}
for (;;) {
for (; ; ) {
if (p == null) {
this.nextNode = null;
this.nextItem = null;
@ -169,7 +181,8 @@ public class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
this.nextNode = p;
this.nextItem = item;
return nextItem;
} else {
}
else {
// skip over nulls
Node<T> next = succ(p);
if (pred != null && next != null) {
@ -183,12 +196,14 @@ public class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
@Override
public boolean hasNext() {
public
boolean hasNext() {
return this.nextNode != null;
}
@Override
public T next() {
public
T next() {
if (this.nextNode == null) {
throw new NoSuchElementException();
}
@ -196,7 +211,8 @@ public class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
}
@Override
public void remove() {
public
void remove() {
Node<T> l = this.lastRet;
if (l == null) {
throw new IllegalStateException();
@ -220,37 +236,44 @@ public class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
}
@Override
public Object[] toArray() {
public
Object[] toArray() {
return this.entries.keySet().toArray();
}
@Override
public <T> T[] toArray(T[] a) {
public
<T> T[] toArray(T[] a) {
return this.entries.keySet().toArray(a);
}
@Override
public boolean containsAll(Collection<?> c) {
public
boolean containsAll(Collection<?> c) {
throw new UnsupportedOperationException("Not implemented");
}
@Override
public boolean removeAll(Collection<?> c) {
public
boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException("Not implemented");
}
@Override
public boolean retainAll(Collection<?> c) {
public
boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException("Not implemented");
}
@Override
public void clear() {
public
void clear() {
super.clear();
}
@Override
public int hashCode() {
public
int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (this.ID ^ this.ID >>> 32);
@ -258,7 +281,8 @@ public class ConcurrentSet<T> extends ConcurrentLinkedQueue2<T> {
}
@Override
public boolean equals(Object obj) {
public
boolean equals(Object obj) {
if (this == obj) {
return true;
}

View File

@ -10,14 +10,15 @@ import java.util.concurrent.atomic.AtomicInteger;
* @author dorkbox, llc
* Date: 2/2/15
*/
public class NamedThreadFactory implements ThreadFactory {
public
class NamedThreadFactory implements ThreadFactory {
/**
* The stack size is arbitrary based on JVM implementation. Default is 0
* 8k is the size of the android stack. Depending on the version of android, this can either change, or will always be 8k
* <p>
* <p/>
* To be honest, 8k is pretty reasonable for an asynchronous/event based system (32bit) or 16k (64bit)
* Setting the size MAY or MAY NOT have any effect!!!
* <p>
* <p/>
* Stack size must be specified in bytes. Default is 8k
*/
private static final long stackSizeForThreads;
@ -67,13 +68,15 @@ public class NamedThreadFactory implements ThreadFactory {
private final ThreadGroup group;
private final String groupName;
public NamedThreadFactory(String groupName) {
public
NamedThreadFactory(String groupName) {
this.groupName = groupName;
this.group = new ThreadGroup(groupName);
}
@Override
public Thread newThread(Runnable r) {
public
Thread newThread(Runnable r) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(this.groupName);
stringBuilder.append('-');
@ -83,7 +86,8 @@ public class NamedThreadFactory implements ThreadFactory {
return newThread(stringBuilder.toString(), r);
}
public Thread newThread(String name, Runnable r) {
public
Thread newThread(String name, Runnable r) {
// stack size is arbitrary based on JVM implementation. Default is 0
// 8k is the size of the android stack. Depending on the version of android, this can either change, or will always be 8k
// To be honest, 8k is pretty reasonable for an asynchronous/event based system (32bit) or 16k (64bit)

View File

@ -10,29 +10,37 @@ import com.esotericsoftware.reflectasm.MethodAccess;
* @author dorkbox, llc
* Date: 2/2/15
*/
public class ReflectiveHandlerInvocation implements IHandlerInvocation {
public
class ReflectiveHandlerInvocation implements IHandlerInvocation {
public ReflectiveHandlerInvocation() {
public
ReflectiveHandlerInvocation() {
super();
}
@Override
public void invoke(final Object listener, final MethodAccess handler, final int methodIndex, final Object message) throws Throwable {
public
void invoke(final Object listener, final MethodAccess handler, final int methodIndex, final Object message) throws Throwable {
handler.invoke(listener, methodIndex, message);
}
@Override
public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2) throws Throwable {
public
void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2)
throws Throwable {
handler.invoke(listener, methodIndex, message1, message2);
}
@Override
public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2, final Object message3) throws Throwable {
public
void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2,
final Object message3) throws Throwable {
handler.invoke(listener, methodIndex, message1, message2, message3);
}
@Override
public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object... messages) throws Throwable {
public
void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object... messages) throws Throwable {
handler.invoke(listener, methodIndex, messages);
}
}

View File

@ -10,37 +10,45 @@ import com.esotericsoftware.reflectasm.MethodAccess;
* @author dorkbox, llc
* Date: 2/2/15
*/
public class SynchronizedHandlerInvocation implements IHandlerInvocation {
public
class SynchronizedHandlerInvocation implements IHandlerInvocation {
private IHandlerInvocation delegate;
public SynchronizedHandlerInvocation(IHandlerInvocation delegate) {
public
SynchronizedHandlerInvocation(IHandlerInvocation delegate) {
this.delegate = delegate;
}
@Override
public void invoke(final Object listener, final MethodAccess handler, final int methodIndex, final Object message) throws Throwable {
public
void invoke(final Object listener, final MethodAccess handler, final int methodIndex, final Object message) throws Throwable {
synchronized (listener) {
this.delegate.invoke(listener, handler, methodIndex, message);
}
}
@Override
public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2) throws Throwable {
public
void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2)
throws Throwable {
synchronized (listener) {
this.delegate.invoke(listener, handler, methodIndex, message1, message2);
}
}
@Override
public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2, final Object message3) throws Throwable {
public
void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object message1, final Object message2,
final Object message3) throws Throwable {
synchronized (listener) {
this.delegate.invoke(listener, handler, methodIndex, message1, message2, message3);
}
}
@Override
public void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object... messages) throws Throwable {
public
void invoke(final Object listener, MethodAccess handler, int methodIndex, final Object... messages) throws Throwable {
synchronized (listener) {
this.delegate.invoke(listener, handler, methodIndex, messages);
}

View File

@ -6,28 +6,33 @@ import java.util.Collection;
/**
*
*/
public class DefaultErrorHandler implements ErrorHandlingSupport {
public
class DefaultErrorHandler implements ErrorHandlingSupport {
private static final String ERROR_HANDLER_MSG = "INFO: No error handler has been configured to handle exceptions during publication.\n" +
"Publication error handlers can be added by bus.getErrorHandler().addErrorHandler()\n" +
"Falling back to console logger.";
private static final String ERROR_HANDLER_MSG =
"INFO: No error handler has been configured to handle exceptions during publication.\n" +
"Publication error handlers can be added by bus.getErrorHandler().addErrorHandler()\n" +
"Falling back to console logger.";
// this handler will receive all errors that occur during message dispatch or message handling
private final Collection<IPublicationErrorHandler> errorHandlers = new ArrayDeque<IPublicationErrorHandler>();
public DefaultErrorHandler() {
public
DefaultErrorHandler() {
}
@Override
public final void addErrorHandler(IPublicationErrorHandler handler) {
public final
void addErrorHandler(IPublicationErrorHandler handler) {
synchronized (this.errorHandlers) {
this.errorHandlers.add(handler);
}
}
@Override
public final void handlePublicationError(PublicationError error) {
public final
void handlePublicationError(PublicationError error) {
synchronized (this.errorHandlers) {
for (IPublicationErrorHandler errorHandler : this.errorHandlers) {
errorHandler.handleError(error);
@ -36,7 +41,8 @@ public class DefaultErrorHandler implements ErrorHandlingSupport {
}
@Override
public void handleError(final String error, final Class<?> listenerClass) {
public
void handleError(final String error, final Class<?> listenerClass) {
synchronized (this.errorHandlers) {
for (IPublicationErrorHandler errorHandler : this.errorHandlers) {
errorHandler.handleError(error, listenerClass);
@ -45,7 +51,8 @@ public class DefaultErrorHandler implements ErrorHandlingSupport {
}
@Override
public void start() {
public
void start() {
synchronized (this.errorHandlers) {
if (this.errorHandlers.isEmpty()) {
this.errorHandlers.add(new IPublicationErrorHandler.ConsoleLogger());

View File

@ -5,7 +5,8 @@ package dorkbox.util.messagebus.error;
* @author dorkbox, llc
* Date: 2/2/15
*/
public interface ErrorHandlingSupport {
public
interface ErrorHandlingSupport {
/**
* Publication errors may occur at various points of time during message delivery. A handler may throw an exception,

View File

@ -5,12 +5,13 @@ package dorkbox.util.messagebus.error;
* error occurs during message publication.
* A handler might fail with an exception, not be accessible because of the presence
* of a security manager or other reasons might lead to failures during the message publication process.
* <p>
* <p/>
*
* @author bennidi
* Date: 2/22/12
*/
public interface IPublicationErrorHandler {
public
interface IPublicationErrorHandler {
/**
* Handle the given publication error.
@ -22,7 +23,7 @@ public interface IPublicationErrorHandler {
/**
* Handle the given publication error.
*
* @param error The PublicationError to handle.
* @param error The PublicationError to handle.
* @param listenerClass
*/
void handleError(String error, final Class<?> listenerClass);
@ -32,12 +33,14 @@ public interface IPublicationErrorHandler {
* The default error handler will simply log to standard out and
* print the stack trace if available.
*/
final class ConsoleLogger implements IPublicationErrorHandler {
final
class ConsoleLogger implements IPublicationErrorHandler {
/**
* {@inheritDoc}
*/
@Override
public void handleError(final PublicationError error) {
public
void handleError(final PublicationError error) {
// Printout the error itself
System.out.println(error);
@ -51,7 +54,8 @@ public interface IPublicationErrorHandler {
* {@inheritDoc}
*/
@Override
public void handleError(final String error, final Class<?> listenerClass) {
public
void handleError(final String error, final Class<?> listenerClass) {
// Printout the error itself
System.out.println(new StringBuilder().append(error).append(": ").append(listenerClass.getSimpleName()).toString());
}

View File

@ -6,21 +6,26 @@ package dorkbox.util.messagebus.error;
* @author bennidi
* Date: 3/29/13
*/
public class MessageBusException extends Exception {
public
class MessageBusException extends Exception {
private static final long serialVersionUID = 1L;
public MessageBusException() {
public
MessageBusException() {
}
public MessageBusException(String message) {
public
MessageBusException(String message) {
super(message);
}
public MessageBusException(String message, Throwable cause) {
public
MessageBusException(String message, Throwable cause) {
super(message, cause);
}
public MessageBusException(Throwable cause) {
public
MessageBusException(Throwable cause) {
super(cause);
}
}

View File

@ -14,7 +14,8 @@ import java.util.Arrays;
* @author dorkbox, llc
* Date: 2/2/15
*/
public class PublicationError {
public
class PublicationError {
// Internal state
private Throwable cause;
@ -25,14 +26,16 @@ public class PublicationError {
/**
* Default constructor.
*/
public PublicationError() {
public
PublicationError() {
super();
}
/**
* @return The Throwable giving rise to this PublicationError.
*/
public Throwable getCause() {
public
Throwable getCause() {
return this.cause;
}
@ -42,32 +45,38 @@ public class PublicationError {
* @param cause A Throwable which gave rise to this PublicationError.
* @return This PublicationError.
*/
public PublicationError setCause(Throwable cause) {
public
PublicationError setCause(Throwable cause) {
this.cause = cause;
return this;
}
public String getMessage() {
public
String getMessage() {
return this.message;
}
public PublicationError setMessage(String message) {
public
PublicationError setMessage(String message) {
this.message = message;
return this;
}
public Object[] getPublishedObject() {
public
Object[] getPublishedObject() {
return this.publishedObjects;
}
public PublicationError setPublishedObject(Object publishedObject) {
public
PublicationError setPublishedObject(Object publishedObject) {
this.publishedObjects = new Object[1];
this.publishedObjects[0] = publishedObject;
return this;
}
public PublicationError setPublishedObject(Object publishedObject1, Object publishedObject2) {
public
PublicationError setPublishedObject(Object publishedObject1, Object publishedObject2) {
this.publishedObjects = new Object[2];
this.publishedObjects[0] = publishedObject1;
this.publishedObjects[1] = publishedObject2;
@ -75,7 +84,8 @@ public class PublicationError {
return this;
}
public PublicationError setPublishedObject(Object publishedObject1, Object publishedObject2, Object publishedObject3) {
public
PublicationError setPublishedObject(Object publishedObject1, Object publishedObject2, Object publishedObject3) {
this.publishedObjects = new Object[3];
this.publishedObjects[0] = publishedObject1;
this.publishedObjects[1] = publishedObject2;
@ -88,15 +98,16 @@ public class PublicationError {
* {@inheritDoc}
*/
@Override
public String toString() {
public
String toString() {
String newLine = System.getProperty("line.separator");
return "PublicationError{" +
newLine +
"\tcause=" + this.cause +
newLine +
"\tmessage='" + this.message + '\'' +
newLine +
"\tpublishedObject=" + Arrays.deepToString(this.publishedObjects) +
'}';
newLine +
"\tcause=" + this.cause +
newLine +
"\tmessage='" + this.message + '\'' +
newLine +
"\tpublishedObject=" + Arrays.deepToString(this.publishedObjects) +
'}';
}
}

View File

@ -11,7 +11,8 @@ import dorkbox.util.messagebus.utils.VarArgUtils;
import java.lang.reflect.Array;
import java.util.concurrent.atomic.AtomicBoolean;
public class PublisherAll_MultiArg implements Publisher {
public
class PublisherAll_MultiArg implements Publisher {
private final ErrorHandlingSupport errorHandler;
private final Subscriber subscriber;
@ -20,7 +21,8 @@ public class PublisherAll_MultiArg implements Publisher {
private final AtomicBoolean varArgPossibility;
final VarArgUtils varArgUtils;
public PublisherAll_MultiArg(final ErrorHandlingSupport errorHandler, final Subscriber subscriber, final StampedLock lock) {
public
PublisherAll_MultiArg(final ErrorHandlingSupport errorHandler, final Subscriber subscriber, final StampedLock lock) {
this.errorHandler = errorHandler;
this.subscriber = subscriber;
this.lock = lock;
@ -30,7 +32,8 @@ public class PublisherAll_MultiArg implements Publisher {
}
@Override
public void publish(final Object message1) {
public
void publish(final Object message1) {
try {
final Class<?> messageClass = message1.getClass();
final boolean isArray = messageClass.isArray();
@ -117,13 +120,14 @@ public class PublisherAll_MultiArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1));
}
}
@Override
public void publish(final Object message1, final Object message2) {
public
void publish(final Object message1, final Object message2) {
try {
final Class<?> messageClass1 = message1.getClass();
final Class<?> messageClass2 = message2.getClass();
@ -215,13 +219,14 @@ public class PublisherAll_MultiArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1, message2));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1, message2));
}
}
@Override
public void publish(final Object message1, final Object message2, final Object message3) {
public
void publish(final Object message1, final Object message2, final Object message3) {
try {
final Class<?> messageClass1 = message1.getClass();
final Class<?> messageClass2 = message2.getClass();
@ -319,13 +324,14 @@ public class PublisherAll_MultiArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1, message2, message3));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1, message2, message3));
}
}
@Override
public void publish(final Object[] messages) {
public
void publish(final Object[] messages) {
publish((Object) messages);
}
}

View File

@ -9,20 +9,22 @@ import dorkbox.util.messagebus.subscription.Subscription;
import java.util.Arrays;
public class PublisherExactWithSuperTypes_FirstArg implements Publisher {
public
class PublisherExactWithSuperTypes_FirstArg implements Publisher {
private final ErrorHandlingSupport errorHandler;
private final Subscriber subscriber;
private final StampedLock lock;
public PublisherExactWithSuperTypes_FirstArg(final ErrorHandlingSupport errorHandler, final Subscriber subscriber,
final StampedLock lock) {
public
PublisherExactWithSuperTypes_FirstArg(final ErrorHandlingSupport errorHandler, final Subscriber subscriber, final StampedLock lock) {
this.errorHandler = errorHandler;
this.subscriber = subscriber;
this.lock = lock;
}
@Override
public void publish(final Object message1) {
public
void publish(final Object message1) {
try {
final Class<?> messageClass = message1.getClass();
@ -61,13 +63,14 @@ public class PublisherExactWithSuperTypes_FirstArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1));
}
}
@Override
public void publish(final Object message1, final Object message2) {
public
void publish(final Object message1, final Object message2) {
try {
final Class<?> messageClass = message1.getClass();
@ -106,13 +109,14 @@ public class PublisherExactWithSuperTypes_FirstArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1, message2));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1, message2));
}
}
@Override
public void publish(final Object message1, final Object message2, final Object message3) {
public
void publish(final Object message1, final Object message2, final Object message3) {
try {
final Class<?> messageClass = message1.getClass();
@ -151,13 +155,14 @@ public class PublisherExactWithSuperTypes_FirstArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1, message2, message3));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1, message2, message3));
}
}
@Override
public void publish(final Object[] messages) {
public
void publish(final Object[] messages) {
try {
final Object message1 = messages[0];
final Class<?> messageClass = message1.getClass();
@ -199,8 +204,8 @@ public class PublisherExactWithSuperTypes_FirstArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(messages));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(messages));
}
}
}

View File

@ -7,20 +7,22 @@ import dorkbox.util.messagebus.error.PublicationError;
import dorkbox.util.messagebus.subscription.Subscriber;
import dorkbox.util.messagebus.subscription.Subscription;
public class PublisherExactWithSuperTypes_MultiArg implements Publisher {
public
class PublisherExactWithSuperTypes_MultiArg implements Publisher {
private final ErrorHandlingSupport errorHandler;
private final Subscriber subscriber;
private final StampedLock lock;
public PublisherExactWithSuperTypes_MultiArg(final ErrorHandlingSupport errorHandler, final Subscriber subscriber,
final StampedLock lock) {
public
PublisherExactWithSuperTypes_MultiArg(final ErrorHandlingSupport errorHandler, final Subscriber subscriber, final StampedLock lock) {
this.errorHandler = errorHandler;
this.subscriber = subscriber;
this.lock = lock;
}
@Override
public void publish(final Object message1) {
public
void publish(final Object message1) {
try {
final Class<?> messageClass = message1.getClass();
@ -54,13 +56,14 @@ public class PublisherExactWithSuperTypes_MultiArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1));
}
}
@Override
public void publish(final Object message1, final Object message2) {
public
void publish(final Object message1, final Object message2) {
try {
final Class<?> messageClass1 = message1.getClass();
final Class<?> messageClass2 = message2.getClass();
@ -95,13 +98,14 @@ public class PublisherExactWithSuperTypes_MultiArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1, message2));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1, message2));
}
}
@Override
public void publish(final Object message1, final Object message2, final Object message3) {
public
void publish(final Object message1, final Object message2, final Object message3) {
try {
final Class<?> messageClass1 = message1.getClass();
final Class<?> messageClass2 = message2.getClass();
@ -110,7 +114,8 @@ public class PublisherExactWithSuperTypes_MultiArg implements Publisher {
final StampedLock lock = this.lock;
long stamp = lock.readLock();
final Subscription[] subscriptions = subscriber.getExactAndSuper(messageClass1, messageClass2, messageClass3); // can return null
final Subscription[] subscriptions = subscriber.getExactAndSuper(messageClass1, messageClass2,
messageClass3); // can return null
lock.unlockRead(stamp);
// Run subscriptions
@ -138,13 +143,14 @@ public class PublisherExactWithSuperTypes_MultiArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1, message2, message3));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1, message2, message3));
}
}
@Override
public void publish(final Object[] messages) {
public
void publish(final Object[] messages) {
publish((Object) messages);
}
}

View File

@ -7,19 +7,22 @@ import dorkbox.util.messagebus.error.PublicationError;
import dorkbox.util.messagebus.subscription.Subscriber;
import dorkbox.util.messagebus.subscription.Subscription;
public class PublisherExact_FirstArg implements Publisher {
public
class PublisherExact_FirstArg implements Publisher {
private final ErrorHandlingSupport errorHandler;
private final Subscriber subscriber;
private final StampedLock lock;
public PublisherExact_FirstArg(final ErrorHandlingSupport errorHandler, final Subscriber subscriber, final StampedLock lock) {
public
PublisherExact_FirstArg(final ErrorHandlingSupport errorHandler, final Subscriber subscriber, final StampedLock lock) {
this.errorHandler = errorHandler;
this.subscriber = subscriber;
this.lock = lock;
}
@Override
public void publish(final Object message1) {
public
void publish(final Object message1) {
try {
final Class<?> messageClass = message1.getClass();
@ -58,13 +61,14 @@ public class PublisherExact_FirstArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1));
}
}
@Override
public void publish(final Object message1, final Object message2) {
public
void publish(final Object message1, final Object message2) {
try {
final Class<?> messageClass = message1.getClass();
@ -103,13 +107,14 @@ public class PublisherExact_FirstArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1, message2));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1, message2));
}
}
@Override
public void publish(final Object message1, final Object message2, final Object message3) {
public
void publish(final Object message1, final Object message2, final Object message3) {
try {
final Class<?> messageClass = message1.getClass();
@ -148,13 +153,14 @@ public class PublisherExact_FirstArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1, message2, message3));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1, message2, message3));
}
}
@Override
public void publish(final Object[] messages) {
public
void publish(final Object[] messages) {
try {
final Class<?> messageClass = messages[0].getClass();
final int length = messages.length;
@ -194,8 +200,8 @@ public class PublisherExact_FirstArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(messages));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(messages));
}
}
}

View File

@ -7,19 +7,22 @@ import dorkbox.util.messagebus.error.PublicationError;
import dorkbox.util.messagebus.subscription.Subscriber;
import dorkbox.util.messagebus.subscription.Subscription;
public class PublisherExact_MultiArg implements Publisher {
public
class PublisherExact_MultiArg implements Publisher {
private final ErrorHandlingSupport errorHandler;
private final Subscriber subscriber;
private final StampedLock lock;
public PublisherExact_MultiArg(final ErrorHandlingSupport errorHandler, final Subscriber subscriber, final StampedLock lock) {
public
PublisherExact_MultiArg(final ErrorHandlingSupport errorHandler, final Subscriber subscriber, final StampedLock lock) {
this.errorHandler = errorHandler;
this.subscriber = subscriber;
this.lock = lock;
}
@Override
public void publish(final Object message1) {
public
void publish(final Object message1) {
try {
final Class<?> messageClass = message1.getClass();
@ -53,13 +56,14 @@ public class PublisherExact_MultiArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1));
}
}
@Override
public void publish(final Object message1, final Object message2) {
public
void publish(final Object message1, final Object message2) {
try {
final Class<?> messageClass1 = message1.getClass();
final Class<?> messageClass2 = message2.getClass();
@ -94,13 +98,14 @@ public class PublisherExact_MultiArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1, message2));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1, message2));
}
}
@Override
public void publish(final Object message1, final Object message2, final Object message3) {
public
void publish(final Object message1, final Object message2, final Object message3) {
try {
final Class<?> messageClass1 = message1.getClass();
final Class<?> messageClass2 = message2.getClass();
@ -136,13 +141,14 @@ public class PublisherExact_MultiArg implements Publisher {
}
}
} catch (Throwable e) {
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(e)
.setPublishedObject(message1, message2, message3));
errorHandler.handlePublicationError(new PublicationError().setMessage("Error during invocation of message handler.").setCause(
e).setPublishedObject(message1, message2, message3));
}
}
@Override
public void publish(final Object[] messages) {
public
void publish(final Object[] messages) {
publish((Object) messages);
}
}

View File

@ -33,7 +33,7 @@ public class FirstArgSubscriber implements Subscriber {
this.errorHandler = errorHandler;
// the following are used ONLY for FIRST ARG subscription/publication. (subscriptionsPerMessageMulti isn't used in this case)
this.subscriptionsPerMessage = JavaVersionAdapter.get.concurrentMap(32, LOAD_FACTOR, 1);
this.subscriptionsPerMessage = JavaVersionAdapter.concurrentMap(32, LOAD_FACTOR, 1);
}
// inside a write lock

View File

@ -15,7 +15,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
/**
* Permits subscriptions with a varying length of parameters as the signature, which must be match by the publisher for it to be accepted
*/
public class MultiArgSubscriber implements Subscriber {
public
class MultiArgSubscriber implements Subscriber {
private final ErrorHandlingSupport errorHandler;
@ -31,10 +32,11 @@ public class MultiArgSubscriber implements Subscriber {
// shortcut publication if we know there is no possibility of varArg (ie: a method that has an array as arguments)
private final AtomicBoolean varArgPossibility = new AtomicBoolean(false);
public MultiArgSubscriber(final ErrorHandlingSupport errorHandler, final ClassUtils classUtils) {
public
MultiArgSubscriber(final ErrorHandlingSupport errorHandler, final ClassUtils classUtils) {
this.errorHandler = errorHandler;
this.subscriptionsPerMessageSingle = JavaVersionAdapter.get.concurrentMap(32, LOAD_FACTOR, 1);
this.subscriptionsPerMessageSingle = JavaVersionAdapter.concurrentMap(32, LOAD_FACTOR, 1);
this.subscriptionsPerMessageMulti = new HashMapTree<Class<?>, ArrayList<Subscription>>(4, LOAD_FACTOR);
this.subUtils = new SubscriptionUtils(classUtils, Subscriber.LOAD_FACTOR);
@ -45,17 +47,20 @@ public class MultiArgSubscriber implements Subscriber {
}
@Override
public AtomicBoolean getVarArgPossibility() {
public
AtomicBoolean getVarArgPossibility() {
return varArgPossibility;
}
@Override
public VarArgUtils getVarArgUtils() {
public
VarArgUtils getVarArgUtils() {
return varArgUtils;
}
@Override
public void clear() {
public
void clear() {
this.subUtils.clear();
this.varArgUtils.clear();
}
@ -63,10 +68,10 @@ public class MultiArgSubscriber implements Subscriber {
// inside a write lock
// add this subscription to each of the handled types
// to activate this sub for publication
private void registerMulti(final Subscription subscription, final Class<?> listenerClass,
final Map<Class<?>, ArrayList<Subscription>> subsPerMessageSingle,
final HashMapTree<Class<?>, ArrayList<Subscription>> subsPerMessageMulti,
final AtomicBoolean varArgPossibility) {
private
void registerMulti(final Subscription subscription, final Class<?> listenerClass,
final Map<Class<?>, ArrayList<Subscription>> subsPerMessageSingle,
final HashMapTree<Class<?>, ArrayList<Subscription>> subsPerMessageMulti, final AtomicBoolean varArgPossibility) {
final MessageHandler handler = subscription.getHandler();
final Class<?>[] messageHandlerTypes = handler.getHandledMessages();
@ -131,7 +136,8 @@ public class MultiArgSubscriber implements Subscriber {
}
@Override
public void register(final Class<?> listenerClass, final int handlersSize, final Subscription[] subsPerListener) {
public
void register(final Class<?> listenerClass, final int handlersSize, final Subscription[] subsPerListener) {
final Map<Class<?>, ArrayList<Subscription>> subsPerMessageSingle = this.subscriptionsPerMessageSingle;
final HashMapTree<Class<?>, ArrayList<Subscription>> subsPerMessageMulti = this.subscriptionsPerMessageMulti;
@ -149,7 +155,8 @@ public class MultiArgSubscriber implements Subscriber {
}
@Override
public void shutdown() {
public
void shutdown() {
this.subscriptionsPerMessageSingle.clear();
this.subscriptionsPerMessageMulti.clear();
@ -157,24 +164,27 @@ public class MultiArgSubscriber implements Subscriber {
}
@Override
public ArrayList<Subscription> getExactAsArray(final Class<?> messageClass) {
public
ArrayList<Subscription> getExactAsArray(final Class<?> messageClass) {
return subscriptionsPerMessageSingle.get(messageClass);
}
@Override
public ArrayList<Subscription> getExactAsArray(final Class<?> messageClass1, final Class<?> messageClass2) {
public
ArrayList<Subscription> getExactAsArray(final Class<?> messageClass1, final Class<?> messageClass2) {
return subscriptionsPerMessageMulti.get(messageClass1, messageClass2);
}
@Override
public ArrayList<Subscription> getExactAsArray(final Class<?> messageClass1, final Class<?> messageClass2,
final Class<?> messageClass3) {
public
ArrayList<Subscription> getExactAsArray(final Class<?> messageClass1, final Class<?> messageClass2, final Class<?> messageClass3) {
return subscriptionsPerMessageMulti.get(messageClass1, messageClass2, messageClass3);
}
// can return null
@Override
public Subscription[] getExactAndSuper(final Class<?> messageClass) {
public
Subscription[] getExactAndSuper(final Class<?> messageClass) {
ArrayList<Subscription> collection = getExactAsArray(messageClass); // can return null
// now publish superClasses
@ -203,7 +213,8 @@ public class MultiArgSubscriber implements Subscriber {
// can return null
@Override
public Subscription[] getExact(final Class<?> messageClass) {
public
Subscription[] getExact(final Class<?> messageClass) {
final ArrayList<Subscription> collection = getExactAsArray(messageClass);
if (collection != null) {
@ -218,7 +229,8 @@ public class MultiArgSubscriber implements Subscriber {
// can return null
@Override
public Subscription[] getExact(final Class<?> messageClass1, final Class<?> messageClass2) {
public
Subscription[] getExact(final Class<?> messageClass1, final Class<?> messageClass2) {
final ArrayList<Subscription> collection = getExactAsArray(messageClass1, messageClass2);
if (collection != null) {
@ -233,7 +245,8 @@ public class MultiArgSubscriber implements Subscriber {
// can return null
@Override
public Subscription[] getExact(final Class<?> messageClass1, final Class<?> messageClass2, final Class<?> messageClass3) {
public
Subscription[] getExact(final Class<?> messageClass1, final Class<?> messageClass2, final Class<?> messageClass3) {
final ArrayList<Subscription> collection = getExactAsArray(messageClass1, messageClass2, messageClass3);
@ -251,7 +264,8 @@ public class MultiArgSubscriber implements Subscriber {
// can return null
@Override
public Subscription[] getExactAndSuper(final Class<?> messageClass1, final Class<?> messageClass2) {
public
Subscription[] getExactAndSuper(final Class<?> messageClass1, final Class<?> messageClass2) {
ArrayList<Subscription> collection = getExactAsArray(messageClass1, messageClass2); // can return null
// now publish superClasses
@ -281,7 +295,8 @@ public class MultiArgSubscriber implements Subscriber {
// can return null
@Override
public Subscription[] getExactAndSuper(final Class<?> messageClass1, final Class<?> messageClass2, final Class<?> messageClass3) {
public
Subscription[] getExactAndSuper(final Class<?> messageClass1, final Class<?> messageClass2, final Class<?> messageClass3) {
ArrayList<Subscription> collection = getExactAsArray(messageClass1, messageClass2, messageClass3); // can return null

View File

@ -5,7 +5,8 @@ import dorkbox.util.messagebus.utils.VarArgUtils;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
public interface Subscriber {
public
interface Subscriber {
float LOAD_FACTOR = 0.8F;
AtomicBoolean getVarArgPossibility();

View File

@ -15,10 +15,10 @@ import java.util.concurrent.atomic.AtomicInteger;
* A subscription is a thread-safe container that manages exactly one message handler of all registered
* message listeners of the same class, i.e. all subscribed instances (excluding subclasses) of a SingleMessageHandler.class
* will be referenced in the subscription created for SingleMessageHandler.class.
* <p>
* <p/>
* There will be as many unique subscription objects per message listener class as there are message handlers
* defined in the message listeners class hierarchy.
* <p>
* <p/>
* The subscription provides functionality for message publication by means of delegation to the respective
* message dispatcher.
*
@ -26,7 +26,8 @@ import java.util.concurrent.atomic.AtomicInteger;
* @author dorkbox, llc
* Date: 2/2/15
*/
public final class Subscription {
public final
class Subscription {
private static final AtomicInteger ID_COUNTER = new AtomicInteger();
public final int ID = ID_COUNTER.getAndIncrement();
@ -37,7 +38,8 @@ public final class Subscription {
private final IHandlerInvocation invocation;
private final Collection<Object> listeners;
public Subscription(final MessageHandler handler, final float loadFactor, final int stripeSize) {
public
Subscription(final MessageHandler handler, final float loadFactor, final int stripeSize) {
this.handlerMetadata = handler;
this.listeners = new StrongConcurrentSetV8<Object>(16, loadFactor, stripeSize);
// this.listeners = new StrongConcurrentSet<Object>(16, 0.85F);
@ -52,31 +54,37 @@ public final class Subscription {
this.invocation = invocation;
}
public MessageHandler getHandler() {
public
MessageHandler getHandler() {
return handlerMetadata;
}
public boolean isEmpty() {
public
boolean isEmpty() {
return this.listeners.isEmpty();
}
public void subscribe(Object listener) {
public
void subscribe(Object listener) {
this.listeners.add(listener);
}
/**
* @return TRUE if the element was removed
*/
public boolean unsubscribe(Object existingListener) {
public
boolean unsubscribe(Object existingListener) {
return this.listeners.remove(existingListener);
}
// only used in unit-test
public int size() {
public
int size() {
return this.listeners.size();
}
public void publish(final Object message) throws Throwable {
public
void publish(final Object message) throws Throwable {
final MethodAccess handler = this.handlerMetadata.getHandler();
final int handleIndex = this.handlerMetadata.getMethodIndex();
final IHandlerInvocation invocation = this.invocation;
@ -91,7 +99,8 @@ public final class Subscription {
}
}
public void publish(final Object message1, final Object message2) throws Throwable {
public
void publish(final Object message1, final Object message2) throws Throwable {
final MethodAccess handler = this.handlerMetadata.getHandler();
final int handleIndex = this.handlerMetadata.getMethodIndex();
final IHandlerInvocation invocation = this.invocation;
@ -106,7 +115,8 @@ public final class Subscription {
}
}
public void publish(final Object message1, final Object message2, final Object message3) throws Throwable {
public
void publish(final Object message1, final Object message2, final Object message3) throws Throwable {
final MethodAccess handler = this.handlerMetadata.getHandler();
final int handleIndex = this.handlerMetadata.getMethodIndex();
final IHandlerInvocation invocation = this.invocation;
@ -121,7 +131,8 @@ public final class Subscription {
}
}
public void publishToSubscription(final Object... messages) throws Throwable {
public
void publishToSubscription(final Object... messages) throws Throwable {
final MethodAccess handler = this.handlerMetadata.getHandler();
final int handleIndex = this.handlerMetadata.getMethodIndex();
final IHandlerInvocation invocation = this.invocation;
@ -138,12 +149,14 @@ public final class Subscription {
@Override
public int hashCode() {
public
int hashCode() {
return this.ID;
}
@Override
public boolean equals(Object obj) {
public
boolean equals(Object obj) {
if (this == obj) {
return true;
}

View File

@ -15,7 +15,8 @@ import java.util.Map;
* @author dorkbox, llc
* Date: 2/2/15
*/
public final class SubscriptionManager {
public final
class SubscriptionManager {
// remember already processed classes that do not contain any message handlers
private final Map<Class<?>, Boolean> nonListeners;
@ -31,27 +32,30 @@ public final class SubscriptionManager {
private final Subscriber subscriber;
public SubscriptionManager(final int numberOfThreads, final Subscriber subscriber, final StampedLock lock) {
public
SubscriptionManager(final int numberOfThreads, final Subscriber subscriber, final StampedLock lock) {
this.numberOfThreads = numberOfThreads;
this.subscriber = subscriber;
this.lock = lock;
// modified ONLY during SUB/UNSUB
this.nonListeners = JavaVersionAdapter.get.concurrentMap(4, Subscriber.LOAD_FACTOR, numberOfThreads);
this.nonListeners = JavaVersionAdapter.concurrentMap(4, Subscriber.LOAD_FACTOR, numberOfThreads);
// only used during SUB/UNSUB, in a rw lock
this.subscriptionsPerListener = JavaVersionAdapter.get.concurrentMap(32, Subscriber.LOAD_FACTOR, 1);
this.subscriptionsPerListener = JavaVersionAdapter.concurrentMap(32, Subscriber.LOAD_FACTOR, 1);
}
public void shutdown() {
public
void shutdown() {
this.nonListeners.clear();
subscriber.shutdown();
this.subscriptionsPerListener.clear();
}
public void subscribe(final Object listener) {
public
void subscribe(final Object listener) {
if (listener == null) {
return;
}
@ -133,7 +137,8 @@ public final class SubscriptionManager {
}
}
public void unsubscribe(final Object listener) {
public
void unsubscribe(final Object listener) {
if (listener == null) {
return;
}
@ -158,7 +163,8 @@ public final class SubscriptionManager {
}
}
private Subscription[] getListenerSubs(final Class<?> listenerClass) {
private
Subscription[] getListenerSubs(final Class<?> listenerClass) {
final StampedLock lock = this.lock;
final long stamp = lock.readLock();

View File

@ -7,25 +7,28 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
public final class ClassUtils {
public final
class ClassUtils {
private final Map<Class<?>, Class<?>> arrayCache;
private final Map<Class<?>, Class<?>[]> superClassesCache;
public ClassUtils(final float loadFactor) {
this.arrayCache = JavaVersionAdapter.get.concurrentMap(32, loadFactor, 1);
this.superClassesCache = JavaVersionAdapter.get.concurrentMap(32, loadFactor, 1);
public
ClassUtils(final float loadFactor) {
this.arrayCache = JavaVersionAdapter.concurrentMap(32, loadFactor, 1);
this.superClassesCache = JavaVersionAdapter.concurrentMap(32, loadFactor, 1);
}
/**
* never returns null
* never reset, since it never needs to be reset (as the class hierarchy doesn't change at runtime)
* <p>
* <p/>
* if parameter clazz is of type array, then the super classes are of array type as well
* <p>
* <p/>
* protected by read lock by caller. The cache version is called first, by write lock
*/
public Class<?>[] getSuperClasses(final Class<?> clazz) {
public
Class<?>[] getSuperClasses(final Class<?> clazz) {
// this is never reset, since it never needs to be.
final Map<Class<?>, Class<?>[]> local = this.superClassesCache;
@ -75,7 +78,8 @@ public final class ClassUtils {
* never returns null
* never reset
*/
public Class<?> getArrayClass(final Class<?> c) {
public
Class<?> getArrayClass(final Class<?> c) {
final Map<Class<?>, Class<?>> arrayCache = this.arrayCache;
Class<?> clazz = arrayCache.get(c);
@ -93,12 +97,14 @@ public final class ClassUtils {
/**
* Clears the caches
*/
public void clear() {
public
void clear() {
this.arrayCache.clear();
this.superClassesCache.clear();
}
public static <T> ArrayList<T> findCommon(final T[] arrayOne, final T[] arrayTwo) {
public static
<T> ArrayList<T> findCommon(final T[] arrayOne, final T[] arrayTwo) {
T[] arrayToHash;
T[] arrayToSearch;
@ -141,7 +147,8 @@ public final class ClassUtils {
return intersection;
}
public static <T> ArrayList<T> findCommon(final ArrayList<T> arrayOne, final ArrayList<T> arrayTwo) {
public static
<T> ArrayList<T> findCommon(final ArrayList<T> arrayOne, final ArrayList<T> arrayTwo) {
ArrayList<T> arrayToHash;
ArrayList<T> arrayToSearch;

View File

@ -16,12 +16,15 @@ import java.util.HashSet;
* @author dorkbox
* Date: 2/2/15
*/
public final class ReflectionUtils {
public final
class ReflectionUtils {
private ReflectionUtils() {
private
ReflectionUtils() {
}
public static Method[] getMethods(Class<?> target) {
public static
Method[] getMethods(Class<?> target) {
ArrayList<Method> methods = new ArrayList<Method>();
getMethods(target, methods);
@ -30,7 +33,8 @@ public final class ReflectionUtils {
return array;
}
private static void getMethods(Class<?> target, ArrayList<Method> methods) {
private static
void getMethods(Class<?> target, ArrayList<Method> methods) {
try {
for (Method method : target.getDeclaredMethods()) {
if (getAnnotation(method, Handler.class) != null) {
@ -51,7 +55,8 @@ public final class ReflectionUtils {
* for an override of the given methods -> finds the bottom most override of the given
* method if any exists
*/
public static Method getOverridingMethod(final Method overridingMethod, final Class<?> subclass) {
public static
Method getOverridingMethod(final Method overridingMethod, final Class<?> subclass) {
Class<?> current = subclass;
while (!current.equals(overridingMethod.getDeclaringClass())) {
try {
@ -70,7 +75,8 @@ public final class ReflectionUtils {
* @param from The root class to start with
* @return A set of classes, each representing a super type of the root class
*/
public static Class<?>[] getSuperTypes(Class<?> from) {
public static
Class<?>[] getSuperTypes(Class<?> from) {
ArrayList<Class<?>> superclasses = new ArrayList<Class<?>>();
collectInterfaces(from, superclasses);
@ -86,14 +92,16 @@ public final class ReflectionUtils {
return classes;
}
public static void collectInterfaces(Class<?> from, Collection<Class<?>> accumulator) {
public static
void collectInterfaces(Class<?> from, Collection<Class<?>> accumulator) {
for (Class<?> intface : from.getInterfaces()) {
accumulator.add(intface);
collectInterfaces(intface, accumulator);
}
}
public static boolean containsOverridingMethod(final Method[] allMethods, final Method methodToCheck) {
public static
boolean containsOverridingMethod(final Method[] allMethods, final Method methodToCheck) {
final int length = allMethods.length;
Method method;
@ -117,8 +125,8 @@ public final class ReflectionUtils {
* @param <A> Class of annotation type
* @return Annotation instance or null
*/
private static <A extends Annotation> A getAnnotation(AnnotatedElement from, Class<A> annotationType,
Collection<AnnotatedElement> visited) {
private static
<A extends Annotation> A getAnnotation(AnnotatedElement from, Class<A> annotationType, Collection<AnnotatedElement> visited) {
if (visited.contains(from)) {
return null;
}
@ -136,13 +144,15 @@ public final class ReflectionUtils {
return null;
}
public static <A extends Annotation> A getAnnotation(AnnotatedElement from, Class<A> annotationType) {
public static
<A extends Annotation> A getAnnotation(AnnotatedElement from, Class<A> annotationType) {
A annotation = getAnnotation(from, annotationType, new HashSet<AnnotatedElement>(16));
return annotation;
}
//
private static boolean isOverriddenBy(final Method superclassMethod, final Method subclassMethod) {
private static
boolean isOverriddenBy(final Method superclassMethod, final Method subclassMethod) {
// if the declaring classes are the same or the subclass method is not defined in the subclass
// hierarchy of the given superclass method or the method names are not the same then
// subclassMethod does not override superclassMethod

View File

@ -8,7 +8,8 @@ import dorkbox.util.messagebus.subscription.Subscription;
import java.util.ArrayList;
import java.util.Map;
public final class SubscriptionUtils {
public final
class SubscriptionUtils {
private final ClassUtils superClass;
// superClassSubscriptions keeps track of all subscriptions of super classes. SUB/UNSUB dumps it, so it is recreated dynamically.
@ -18,17 +19,19 @@ public final class SubscriptionUtils {
private final HashMapTree<Class<?>, ArrayList<Subscription>> superClassSubscriptionsMulti;
public SubscriptionUtils(final ClassUtils superClass, final float loadFactor) {
public
SubscriptionUtils(final ClassUtils superClass, final float loadFactor) {
this.superClass = superClass;
// superClassSubscriptions keeps track of all subscriptions of super classes. SUB/UNSUB dumps it, so it is recreated dynamically.
// it's a hit on SUB/UNSUB, but improves performance of handlers
this.superClassSubscriptions = JavaVersionAdapter.get.concurrentMap(8, loadFactor, 1);
this.superClassSubscriptions = JavaVersionAdapter.concurrentMap(8, loadFactor, 1);
this.superClassSubscriptionsMulti = new HashMapTree<Class<?>, ArrayList<Subscription>>(4, loadFactor);
}
public void clear() {
public
void clear() {
this.superClassSubscriptions.clear();
this.superClassSubscriptionsMulti.clear();
}
@ -43,7 +46,8 @@ public final class SubscriptionUtils {
*
* @return CAN NOT RETURN NULL
*/
public ArrayList<Subscription> getSuperSubscriptions(final Class<?> clazz, final Subscriber subscriber) {
public
ArrayList<Subscription> getSuperSubscriptions(final Class<?> clazz, final Subscriber subscriber) {
// whenever our subscriptions change, this map is cleared.
final Map<Class<?>, ArrayList<Subscription>> local = this.superClassSubscriptions;
@ -95,7 +99,8 @@ public final class SubscriptionUtils {
*
* @return CAN NOT RETURN NULL
*/
public ArrayList<Subscription> getSuperSubscriptions(final Class<?> clazz1, final Class<?> clazz2, final Subscriber subscriber) {
public
ArrayList<Subscription> getSuperSubscriptions(final Class<?> clazz1, final Class<?> clazz2, final Subscriber subscriber) {
// whenever our subscriptions change, this map is cleared.
final HashMapTree<Class<?>, ArrayList<Subscription>> cached = this.superClassSubscriptionsMulti;
@ -162,8 +167,9 @@ public final class SubscriptionUtils {
*
* @return CAN NOT RETURN NULL
*/
public ArrayList<Subscription> getSuperSubscriptions(final Class<?> clazz1, final Class<?> clazz2, final Class<?> clazz3,
final Subscriber subscriber) {
public
ArrayList<Subscription> getSuperSubscriptions(final Class<?> clazz1, final Class<?> clazz2, final Class<?> clazz3,
final Subscriber subscriber) {
// whenever our subscriptions change, this map is cleared.
final HashMapTree<Class<?>, ArrayList<Subscription>> local = this.superClassSubscriptionsMulti;

View File

@ -9,7 +9,8 @@ import dorkbox.util.messagebus.subscription.Subscription;
import java.util.ArrayList;
import java.util.Map;
public final class VarArgUtils {
public final
class VarArgUtils {
private final Map<Class<?>, ArrayList<Subscription>> varArgSubscriptionsSingle;
private final HashMapTree<Class<?>, ArrayList<Subscription>> varArgSubscriptionsMulti;
@ -19,19 +20,21 @@ public final class VarArgUtils {
private final ClassUtils superClassUtils;
public VarArgUtils(final ClassUtils superClassUtils, final float loadFactor) {
public
VarArgUtils(final ClassUtils superClassUtils, final float loadFactor) {
this.superClassUtils = superClassUtils;
this.varArgSubscriptionsSingle = JavaVersionAdapter.get.concurrentMap(16, loadFactor, 1);
this.varArgSubscriptionsSingle = JavaVersionAdapter.concurrentMap(16, loadFactor, 1);
this.varArgSubscriptionsMulti = new HashMapTree<Class<?>, ArrayList<Subscription>>(4, loadFactor);
this.varArgSuperSubscriptionsSingle = JavaVersionAdapter.get.concurrentMap(16, loadFactor, 1);
this.varArgSuperSubscriptionsSingle = JavaVersionAdapter.concurrentMap(16, loadFactor, 1);
this.varArgSuperSubscriptionsMulti = new HashMapTree<Class<?>, ArrayList<Subscription>>(4, loadFactor);
}
public void clear() {
public
void clear() {
this.varArgSubscriptionsSingle.clear();
this.varArgSubscriptionsMulti.clear();
@ -43,7 +46,8 @@ public final class VarArgUtils {
// CAN NOT RETURN NULL
// check to see if the messageType can convert/publish to the "array" version, without the hit to JNI
// and then, returns the array'd version subscriptions
public Subscription[] getVarArgSubscriptions(final Class<?> messageClass, final Subscriber subscriber) {
public
Subscription[] getVarArgSubscriptions(final Class<?> messageClass, final Subscriber subscriber) {
// whenever our subscriptions change, this map is cleared.
final Map<Class<?>, ArrayList<Subscription>> local = this.varArgSubscriptionsSingle;
@ -84,7 +88,8 @@ public final class VarArgUtils {
// CAN NOT RETURN NULL
// check to see if the messageType can convert/publish to the "array" superclass version, without the hit to JNI
// and then, returns the array'd version superclass subscriptions
public Subscription[] getVarArgSuperSubscriptions(final Class<?> messageClass, final Subscriber subscriber) {
public
Subscription[] getVarArgSuperSubscriptions(final Class<?> messageClass, final Subscriber subscriber) {
final ArrayList<Subscription> subs = getVarArgSuperSubscriptions_List(messageClass, subscriber);
final Subscription[] returnedSubscriptions = new Subscription[subs.size()];
@ -93,7 +98,8 @@ public final class VarArgUtils {
}
// CAN NOT RETURN NULL
private ArrayList<Subscription> getVarArgSuperSubscriptions_List(final Class<?> messageClass, final Subscriber subscriber) {
private
ArrayList<Subscription> getVarArgSuperSubscriptions_List(final Class<?> messageClass, final Subscriber subscriber) {
// whenever our subscriptions change, this map is cleared.
final Map<Class<?>, ArrayList<Subscription>> local = this.varArgSuperSubscriptionsSingle;
@ -151,7 +157,8 @@ public final class VarArgUtils {
// CAN NOT RETURN NULL
// check to see if the messageType can convert/publish to the "array" superclass version, without the hit to JNI
// and then, returns the array'd version superclass subscriptions
public Subscription[] getVarArgSuperSubscriptions(final Class<?> messageClass1, final Class<?> messageClass2, final Subscriber subscriber) {
public
Subscription[] getVarArgSuperSubscriptions(final Class<?> messageClass1, final Class<?> messageClass2, final Subscriber subscriber) {
// whenever our subscriptions change, this map is cleared.
final HashMapTree<Class<?>, ArrayList<Subscription>> local = this.varArgSuperSubscriptionsMulti;
@ -178,8 +185,9 @@ public final class VarArgUtils {
// CAN NOT RETURN NULL
// check to see if the messageType can convert/publish to the "array" superclass version, without the hit to JNI
// and then, returns the array'd version superclass subscriptions
public Subscription[] getVarArgSuperSubscriptions(final Class<?> messageClass1, final Class<?> messageClass2,
final Class<?> messageClass3, final Subscriber subscriber) {
public
Subscription[] getVarArgSuperSubscriptions(final Class<?> messageClass1, final Class<?> messageClass2, final Class<?> messageClass3,
final Subscriber subscriber) {
// whenever our subscriptions change, this map is cleared.
final HashMapTree<Class<?>, ArrayList<Subscription>> local = this.varArgSuperSubscriptionsMulti;

View File

@ -15,7 +15,8 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedTransferQueue;
public class PerfTest_Collections {
public
class PerfTest_Collections {
public static final int REPETITIONS = 10 * 1000 * 100;
public static final Integer TEST_VALUE = Integer.valueOf(777);
@ -24,7 +25,8 @@ public class PerfTest_Collections {
private static final MessageHandler[] allHandlers = MessageHandler.get(Listener.class);
public static void main(final String[] args) throws Exception {
public static
void main(final String[] args) throws Exception {
final int size = 16;
@ -33,52 +35,56 @@ public class PerfTest_Collections {
// have to warm-up the JVM.
System.err.print("\nWarming up JVM.");
// for (int i=0;i<2;i++) {
bench(size, new ConcurrentLinkedQueue<Subscription>(), false);
System.err.print(".");
bench(size, new ArrayList<Subscription>(size*2), false);
System.err.print(".");
bench(size, new ArrayDeque<Subscription>(size*2), false);
System.err.print(".");
bench(size, new ConcurrentLinkedQueue<Subscription>(), false);
System.err.print(".");
bench(size, new LinkedList<Subscription>(), false);
System.err.print(".");
bench(size, new ConcurrentLinkedQueue<Subscription>(), false);
System.err.print(".");
bench(size, new ArrayList<Subscription>(size * 2), false);
System.err.print(".");
bench(size, new ArrayDeque<Subscription>(size * 2), false);
System.err.print(".");
bench(size, new ConcurrentLinkedQueue<Subscription>(), false);
System.err.print(".");
bench(size, new LinkedList<Subscription>(), false);
System.err.print(".");
// }
System.err.println("Done");
bench(size, new ArrayList<Subscription>(size*2));
bench(size, new ConcurrentSet<Subscription>(size*2, LOAD_FACTOR, 5));
bench(size, new ArrayList<Subscription>(size * 2));
bench(size, new ConcurrentSet<Subscription>(size * 2, LOAD_FACTOR, 5));
bench(size, new ConcurrentLinkedQueue2<Subscription>());
bench(size, new ConcurrentLinkedQueue<Subscription>());
bench(size, new LinkedTransferQueue<Subscription>());
bench(size, new ArrayDeque<Subscription>(size*2));
bench(size, new ArrayDeque<Subscription>(size * 2));
bench(size, new LinkedList<Subscription>());
bench(size, new StrongConcurrentSetV8<Subscription>(size*2, LOAD_FACTOR));
bench(size, new StrongConcurrentSet<Subscription>(size*2, LOAD_FACTOR));
bench(size, Collections.newSetFromMap(new ConcurrentHashMap<Subscription, Boolean>(size*2, LOAD_FACTOR, 1)));
bench(size, new StrongConcurrentSetV8<Subscription>(size * 2, LOAD_FACTOR));
bench(size, new StrongConcurrentSet<Subscription>(size * 2, LOAD_FACTOR));
bench(size, Collections.newSetFromMap(new ConcurrentHashMap<Subscription, Boolean>(size * 2, LOAD_FACTOR, 1)));
bench(size, new HashSet<Subscription>());
// bench(size, new ConcurrentSkipListSet<Subscription>()); // needs comparable
}
public static void bench(final int size, Collection<Subscription> set) throws Exception {
public static
void bench(final int size, Collection<Subscription> set) throws Exception {
bench(size, set, true);
}
public static void bench(final int size, Collection<Subscription> set, boolean showOutput) throws Exception {
public static
void bench(final int size, Collection<Subscription> set, boolean showOutput) throws Exception {
final int warmupRuns = 2;
final int runs = 3;
for (int i=0;i<size;i++) {
for (int i = 0; i < size; i++) {
for (MessageHandler x : allHandlers) {
set.add(new Subscription(x, .85F, 1));
}
}
if (!showOutput) {
for (int i=2;i<6;i++) {
for (int i = 2; i < 6; i++) {
averageRun(warmupRuns, runs, set, false, i, REPETITIONS);
}
} else {
for (int i=1;i<10;i++) {
}
else {
for (int i = 1; i < 10; i++) {
long average = averageRun(warmupRuns, runs, set, false, i, REPETITIONS);
System.out.format("summary,IteratorPerfTest,%s - %,d (%d)\n", set.getClass().getSimpleName(), average, i);
}
@ -87,11 +93,13 @@ public class PerfTest_Collections {
set.clear();
}
public static long averageRun(int warmUpRuns, int sumCount, Collection<Subscription> set, boolean showStats, int concurrency, int repetitions) throws Exception {
public static
long averageRun(int warmUpRuns, int sumCount, Collection<Subscription> set, boolean showStats, int concurrency, int repetitions)
throws Exception {
int runs = warmUpRuns + sumCount;
final long[] results = new long[runs];
for (int i = 0; i < runs; i++) {
WeakReference<Object> weakReference = new WeakReference<>(new Object());
WeakReference<Object> weakReference = new WeakReference<Object>(new Object());
while (weakReference.get() != null) {
System.gc();
Thread.sleep(100L);
@ -104,24 +112,25 @@ public class PerfTest_Collections {
sum += results[i];
}
return sum/sumCount;
return sum / sumCount;
}
private static long performanceRun(int runNumber, Collection<Subscription> set, boolean showStats, int concurrency, int repetitions) throws Exception {
private static
long performanceRun(int runNumber, Collection<Subscription> set, boolean showStats, int concurrency, int repetitions) throws Exception {
Producer[] producers = new Producer[concurrency];
Thread[] threads = new Thread[concurrency*2];
Thread[] threads = new Thread[concurrency * 2];
for (int i=0;i<concurrency;i++) {
for (int i = 0; i < concurrency; i++) {
producers[i] = new Producer(set, repetitions);
threads[i] = new Thread(producers[i], "Producer " + i);
}
for (int i=0;i<concurrency;i++) {
for (int i = 0; i < concurrency; i++) {
threads[i].start();
}
for (int i=0;i<concurrency;i++) {
for (int i = 0; i < concurrency; i++) {
threads[i].join();
}
@ -129,7 +138,7 @@ public class PerfTest_Collections {
long end = -1;
long count = 0;
for (int i=0;i<concurrency;i++) {
for (int i = 0; i < concurrency; i++) {
if (producers[i].start < start) {
start = producers[i].start;
}
@ -143,7 +152,7 @@ public class PerfTest_Collections {
long duration = end - start;
long ops = repetitions * 1_000_000_000L / duration;
long ops = repetitions * 1000000000L / duration;
if (showStats) {
System.out.format("%d (%d) - ops/sec=%,d\n", runNumber, count, ops);
@ -151,21 +160,24 @@ public class PerfTest_Collections {
return ops;
}
public static class Producer implements Runnable {
public static
class Producer implements Runnable {
private final Collection<Subscription> set;
volatile long start;
volatile long end;
private int repetitions;
volatile int count;
public Producer(Collection<Subscription> set, int repetitions) {
public
Producer(Collection<Subscription> set, int repetitions) {
this.set = set;
this.repetitions = repetitions;
}
@SuppressWarnings("unused")
@Override
public void run() {
public
void run() {
Collection<Subscription> set = this.set;
int i = this.repetitions;
this.start = System.nanoTime();
@ -178,7 +190,7 @@ public class PerfTest_Collections {
int count = 0;
do {
for (iterator = set.iterator(); iterator.hasNext();) {
for (iterator = set.iterator(); iterator.hasNext(); ) {
sub = iterator.next();
// if (sub.acceptsSubtypes()) {
// count--;
@ -201,14 +213,18 @@ public class PerfTest_Collections {
}
}
@SuppressWarnings("unused")
public static class Listener {
public static
class Listener {
@Handler
public void handleSync(Integer o1) {
public
void handleSync(Integer o1) {
}
@Handler(acceptVarargs=true)
public void handleSync(Object... o) {
@Handler(acceptVarargs = true)
public
void handleSync(Object... o) {
}
}
}

View File

@ -3,13 +3,15 @@ package dorkbox.util.messagebus;
import dorkbox.util.messagebus.annotations.Handler;
public class PerfTest_MBassador {
public
class PerfTest_MBassador {
public static final int REPETITIONS = 50 * 1000 * 100;
public static final Integer TEST_VALUE = Integer.valueOf(777);
private static final int concurrency = 1;
public static void main(final String[] args) throws Exception {
public static
void main(final String[] args) throws Exception {
System.out.println("reps:" + REPETITIONS + " Concurrency " + concurrency);
final int warmupRuns = 4;
@ -24,8 +26,8 @@ public class PerfTest_MBassador {
System.out.format("summary,PublishPerfTest, %,d\n", average);
}
public static long averageRun(int warmUpRuns, int sumCount, MessageBus bus, boolean showStats, int concurrency, int repetitions)
throws Exception {
public static
long averageRun(int warmUpRuns, int sumCount, MessageBus bus, boolean showStats, int concurrency, int repetitions) throws Exception {
int runs = warmUpRuns + sumCount;
final long[] results = new long[runs];
for (int i = 0; i < runs; i++) {
@ -38,32 +40,32 @@ public class PerfTest_MBassador {
sum += results[i];
}
return sum/sumCount;
return sum / sumCount;
}
private static long performanceRun(int runNumber, MessageBus bus, boolean showStats, int concurrency, int repetitions)
throws Exception {
private static
long performanceRun(int runNumber, MessageBus bus, boolean showStats, int concurrency, int repetitions) throws Exception {
Producer[] producers = new Producer[concurrency];
Thread[] threads = new Thread[concurrency*2];
Thread[] threads = new Thread[concurrency * 2];
for (int i=0;i<concurrency;i++) {
for (int i = 0; i < concurrency; i++) {
producers[i] = new Producer(bus, repetitions);
threads[i] = new Thread(producers[i], "Producer " + i);
}
for (int i=0;i<concurrency;i++) {
for (int i = 0; i < concurrency; i++) {
threads[i].start();
}
for (int i=0;i<concurrency;i++) {
for (int i = 0; i < concurrency; i++) {
threads[i].join();
}
long start = Long.MAX_VALUE;
long end = -1;
for (int i=0;i<concurrency;i++) {
for (int i = 0; i < concurrency; i++) {
if (producers[i].start < start) {
start = producers[i].start;
}
@ -75,7 +77,7 @@ public class PerfTest_MBassador {
long duration = end - start;
long ops = repetitions * 1_000_000_000L / duration;
long ops = repetitions * 1000000000L / duration;
if (showStats) {
System.out.format("%d - ops/sec=%,d\n", runNumber, ops);
@ -83,19 +85,22 @@ public class PerfTest_MBassador {
return ops;
}
public static class Producer implements Runnable {
public static
class Producer implements Runnable {
private final MessageBus bus;
volatile long start;
volatile long end;
private int repetitions;
public Producer(MessageBus bus, int repetitions) {
public
Producer(MessageBus bus, int repetitions) {
this.bus = bus;
this.repetitions = repetitions;
}
@Override
public void run() {
public
void run() {
MessageBus bus = this.bus;
int i = this.repetitions;
this.start = System.nanoTime();
@ -108,14 +113,18 @@ public class PerfTest_MBassador {
}
}
@SuppressWarnings("unused")
public static class Listener {
public static
class Listener {
@Handler
public void handleSync(Integer o1) {
public
void handleSync(Integer o1) {
}
@Handler(acceptVarargs=true)
public void handleSync(Object... o) {
@Handler(acceptVarargs = true)
public
void handleSync(Object... o) {
}
}
}