You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2015/09/10 08:59:30 UTC
svn commit: r1702174 [3/5] - in
/river/jtsk/skunk/qa-refactor-namespace/trunk: ./
qa/src/org/apache/river/test/impl/outrigger/javaspace05/ src/manifest/
src/net/jini/core/entry/ src/net/jini/core/lookup/ src/net/jini/entry/
src/net/jini/loader/ src/net...
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceDeque.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceDeque.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceDeque.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceDeque.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,150 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.util.Deque;
+import java.util.Iterator;
+
+/**
+ *
+ * @author Peter Firmstone
+ */
+class ReferenceDeque<T> extends ReferencedQueue<T> implements Deque<T>{
+ private static final long serialVersionUID = 1L;
+ private final Deque<Referrer<T>> deque;
+ ReferenceDeque(Deque<Referrer<T>> deque, Ref type, boolean gcThreads, long gcCycle){
+ super(deque, type, gcThreads, gcCycle);
+ this.deque = deque;
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws InvalidObjectException{
+ throw new InvalidObjectException("Builder required");
+ }
+
+ public void addFirst(T e) {
+ processQueue();
+ Referrer<T> r = wrapObj(e, true, false);
+ deque.addFirst(r);
+ }
+
+ public void addLast(T e) {
+ processQueue();
+ Referrer<T> r = wrapObj(e, true, false);
+ deque.addLast(r);
+ }
+
+ public boolean offerFirst(T e) {
+ processQueue();
+ Referrer<T> r = wrapObj(e, true, false);
+ return deque.offerFirst(r);
+ }
+
+ public boolean offerLast(T e) {
+ processQueue();
+ Referrer<T> r = wrapObj(e, true, false);
+ return deque.offerLast(r);
+ }
+
+ public T removeFirst() {
+ processQueue();
+ Referrer<T> t = deque.removeFirst();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T removeLast() {
+ processQueue();
+ Referrer<T> t = deque.removeLast();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T pollFirst() {
+ processQueue();
+ Referrer<T> t = deque.pollFirst();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T pollLast() {
+ processQueue();
+ Referrer<T> t = deque.pollLast();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T getFirst() {
+ processQueue();
+ Referrer<T> t = deque.getFirst();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T getLast() {
+ processQueue();
+ Referrer<T> t = deque.getLast();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T peekFirst() {
+ processQueue();
+ Referrer<T> t = deque.peekFirst();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T peekLast() {
+ processQueue();
+ Referrer<T> t = deque.peekLast();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public boolean removeFirstOccurrence(Object o) {
+ processQueue();
+ @SuppressWarnings("unchecked")
+ Referrer<T> r = wrapObj((T) o, false, true);
+ return deque.removeFirstOccurrence(r);
+ }
+
+ public boolean removeLastOccurrence(Object o) {
+ processQueue();
+ @SuppressWarnings("unchecked")
+ Referrer<T> r = wrapObj((T) o, false, true);
+ return deque.removeLastOccurrence(r);
+ }
+
+ public void push(T e) {
+ processQueue();
+ Referrer<T> r = wrapObj(e, true, false);
+ deque.push(r);
+ }
+
+ public T pop() {
+ processQueue();
+ Referrer<T> t = deque.pop();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public Iterator<T> descendingIterator() {
+ return new ReferenceIterator<T>(deque.descendingIterator());
+ }
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceEntryFacade.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceEntryFacade.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceEntryFacade.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceEntryFacade.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,83 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.lang.ref.Reference;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ *
+ * @author Peter Firmstone.
+ */
+class ReferenceEntryFacade<K, V> implements Map.Entry<K, V> {
+ private final Entry<Referrer<K>, Referrer<V>> entry;
+ private final ReferenceQueuingFactory<V, Referrer<V>> rqf;
+
+ ReferenceEntryFacade(Entry<Referrer<K>, Referrer<V>> entry, ReferenceQueuingFactory<V, Referrer<V>> rqf){
+ this.entry = entry;
+ this.rqf = rqf;
+ }
+
+ public K getKey() {
+ Referrer<K> k = entry.getKey();
+ if ( k != null ) return k.get();
+ return null;
+ }
+
+ public V getValue() {
+ Referrer<V> v = entry.getValue();
+ if ( v != null ) return v.get();
+ return null;
+ }
+
+ public V setValue(V value) {
+ Referrer<V> v = entry.setValue(wrapVal(value, true));
+ if ( v != null ) return v.get();
+ return null;
+ }
+
+ /**
+ * Implementation copied directly from Entry javadoc.
+ * @see Entry#hashCode()
+ * @return
+ */
+ @Override
+ public int hashCode() {
+ return (getKey()==null ? 0 : getKey().hashCode()) ^
+ (getValue()==null ? 0 : getValue().hashCode());
+ }
+
+ /**
+ * Implementation copied directly from Entry javadoc.
+ * @see Entry#equals(java.lang.Object)
+ */
+ public boolean equals(Object o){
+ if ( o == this ) return true;
+ if ( !(o instanceof Entry) ) return false;
+ Entry e1 = this;
+ Entry e2 = (Entry) o;
+ return ( (e1.getKey()==null ? e2.getKey()==null :
+ e1.getKey().equals(e2.getKey())) &&
+ (e1.getValue()==null ? e2.getValue()==null :
+ e1.getValue().equals(e2.getValue())));
+ }
+
+ private Referrer<V> wrapVal(V val, boolean enque) {
+ return rqf.referenced(val, enque, false);
+}
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceFactory.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceFactory.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceFactory.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceFactory.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,105 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+
+/**
+ * ReferenceFactory creates References, representing the various subclasses
+ * of Reference, such as WEAK, SOFT and STRONG for
+ * use in collections.
+ *
+ * These subtypes override equals and hashcode, so that References may be used
+ * in Collections, Maps, Sets and Lists to represent their referent.
+ *
+ * @see Reference
+ * @see Ref
+ * @author Peter Firmstone.
+ */
+class ReferenceFactory<T> {
+
+ // Non instantiable.
+ private ReferenceFactory(){}
+
+ static <T> Referrer<T> create(T t, RefQueue<? super T> queue, Ref type ){
+ if (t == null) throw new NullPointerException("Reference collections cannot contain null");
+ RefReferenceQueue<? super T> refQueue = null;
+ TimedRefQueue timedRefQue = null;
+ if (queue instanceof RefReferenceQueue) refQueue = (RefReferenceQueue<? super T>) queue;
+ if (queue instanceof TimedRefQueue) timedRefQue = (TimedRefQueue) queue;
+ switch (type){
+ case WEAK_IDENTITY:
+ return new ReferrerDecorator<T>(new WeakIdentityReference<T>(t, refQueue));
+ case SOFT_IDENTITY:
+ return new ReferrerDecorator<T>(new SoftIdentityReference<T>(t, refQueue));
+ case WEAK:
+ if (t instanceof Comparable)
+ return new ComparableReferrerDecorator<T>(new WeakEqualityReference<T>(t, refQueue));
+ return new ReferrerDecorator<T>(new WeakEqualityReference<T>(t, refQueue));
+ case SOFT:
+ if (t instanceof Comparable)
+ return new ComparableReferrerDecorator<T>(new SoftEqualityReference<T>(t, refQueue));
+ return new ReferrerDecorator<T>(new SoftEqualityReference<T>(t, refQueue));
+ case TIME:
+ if (t instanceof Comparable)
+ return new TimedComparableReferrerDecorator<T>(new TimedReferrer<T>(t, timedRefQue));
+ return new TimedReferrerDecorator<T>(new TimedReferrer<T>(t, timedRefQue));
+ default:
+ if (t instanceof Comparable)
+ return new ComparableReferrerDecorator<T>(new StrongReference<T>(t, refQueue));
+ return new ReferrerDecorator<T>(new StrongReference<T>(t, refQueue));
+ }
+ }
+
+ /**
+ * This doesn't create a genuine reference, only a simple wrapper object
+ * that will be used once then discarded. The Referrer will be allocated
+ * to the stack by the jvm and not the heap. There is no queue, no
+ * reference, this is simply a wrapper class that provides the correct
+ * equals, hashcode and comparator semantics.
+ *
+ * This object must not be added to any collection classes, it is not
+ * serialisable, it's sole intended purpose is to improve read performance
+ * by being allocated to the stack, not the heap space and avoiding a
+ * cache miss. To achieve this goal, it must not be shared with other
+ * Threads either.
+ *
+ * @param <T>
+ * @param t
+ * @param type
+ * @return
+ */
+ static <T> Referrer<T> singleUseForLookup(T t, Ref type){
+ if (t == null) throw new NullPointerException("Reference collections cannot contain null");
+ switch (type){
+ case WEAK_IDENTITY:
+ return new TempIdentityReferrer<T>(t);
+ case SOFT_IDENTITY:
+ return new TempIdentityReferrer<T>(t);
+ case WEAK:
+ if (t instanceof Comparable) return new TempComparableReferrer<T>(t);
+ return new TempEqualReferrer<T>(t);
+ case SOFT:
+ if (t instanceof Comparable) return new TempComparableReferrer<T>(t);
+ return new TempEqualReferrer<T>(t);
+ default:
+ if (t instanceof Comparable) return new TempComparableReferrer<T>(t);
+ return new TempEqualReferrer<T>(t);
+ }
+ }
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceIterator.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceIterator.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceIterator.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceIterator.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,58 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.lang.ref.Reference;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ *
+ * @author Peter Firmstone.
+ */
+class ReferenceIterator<T> implements Iterator<T> {
+ private final Iterator<Referrer<T>> iterator;
+ private T next;
+
+ ReferenceIterator(Iterator<Referrer<T>> iterator) {
+ if ( iterator == null ) throw new IllegalArgumentException("iterator cannot be null");
+ this.iterator = iterator;
+ next = null;
+ }
+
+ public boolean hasNext() {
+ while ( iterator.hasNext()){
+ Referrer<T> t = iterator.next();
+ if ( t != null ) {
+ next = t.get();
+ if (next != null) return true;
+ else iterator.remove(); // garbage collected.
+ }
+ }
+ next = null;
+ return false;
+ }
+
+ public T next() {
+ if (next == null) throw new NoSuchElementException();
+ return next;
+ }
+
+ public void remove() {
+ iterator.remove();
+ }
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceList.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceList.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceList.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceList.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,215 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * A List implementation that uses References.
+ *
+ * This enables a Collection or List to contain, softly, weakly or strongly referenced
+ * objects. Objects that are no longer reachable will simply vanish from
+ * the Collection.
+ *
+ * For example, this could be used as an Object cache containing softly reachable
+ * objects which are only collected when the jvm is experiencing low memory
+ * conditions.
+ *
+ * Synchronisation must be performed by the underlying List, it cannot be
+ * performed externally, since every read is also potentially a mutable
+ * change, caused by removal of garbage collected Objects.
+ *
+ * Removal of garbage collected objects is performed before iteration, but not
+ * during, instead some Object's returned during iteration may be null.
+ *
+ * @author Peter Firmstone.
+ */
+class ReferenceList<T> extends ReferenceCollection<T> implements List<T> {
+ private static final long serialVersionUID = 1L;
+ private final List<Referrer<T>> list;
+ ReferenceList(List<Referrer<T>> list, Ref type, boolean gcThreads, long gcCycle){
+ super(list, type, gcThreads, gcCycle);
+ this.list = list;
+ }
+
+ ReferenceList(List<Referrer<T>> list, ReferenceQueuingFactory<T, Referrer<T>> rqf, Ref type){
+ super(list, rqf, type);
+ this.list = list;
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws InvalidObjectException{
+ throw new InvalidObjectException("Builder required");
+ }
+
+ /**
+ * Implemented as per the List interface definition of equals.
+ * @see List#equals(java.lang.Object)
+ * @param o
+ * @return
+ */
+ public boolean equals(Object o){
+ if ( o == null ) return false;
+ if (!( o instanceof List)) return false;
+ List l = (List) o;
+ if ( l.size() != size()) return false;
+ Iterator<T> li = iterator();
+ int i = 0;
+ while(li.hasNext()){
+ T t = li.next();
+ if ( t != null ){
+ if ( !(t.equals(l.get(i))) ) return false;
+ } else {
+ if ( l.get(i) != null ) return false; // both must be null
+ }
+ i++;
+ }
+ return true;
+ }
+
+ /**
+ * Implemented as per List interface definition.
+ *
+ * @see List#hashCode()
+ * @return
+ */
+ public int hashCode() {
+ // hash code calculation copied directly from List interface contract.
+ int hashCode = 1;
+ Iterator<T> i = iterator();
+ while (i.hasNext()) {
+ T obj = i.next();
+ hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
+ }
+ return hashCode;
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean addAll(int index, Collection<? extends T> c) {
+ processQueue();
+ return list.addAll(index, new CollectionDecorator<T>((Collection<T>) c, getRQF(), true, false));
+ }
+
+ public T get(int index) {
+ processQueue();
+ Referrer<T> r = list.get(index);
+ if (r != null) return r.get();
+ return null;
+ }
+
+ public T set(int index, T element) {
+ processQueue();
+ Referrer<T> r = list.set(index, wrapObj(element, true, false));
+ if (r != null) return r.get();
+ return null;
+ }
+
+ public void add(int index, T element) {
+ processQueue();
+ list.add(index, wrapObj(element, true, false));
+ }
+
+ public T remove(int index) {
+ processQueue();
+ Referrer<T> r = list.remove(index);
+ if (r != null) return r.get();
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public int indexOf(Object o) {
+ processQueue();
+ return list.indexOf(wrapObj((T) o, false, true));
+ }
+
+ @SuppressWarnings("unchecked")
+ public int lastIndexOf(Object o) {
+ processQueue();
+ return list.lastIndexOf(wrapObj((T)o, false, true));
+ }
+
+ public ListIterator<T> listIterator() {
+ processQueue();
+ return new ReferenceListIterator<T>(list.listIterator(), getRQF());
+ }
+
+ public ListIterator<T> listIterator(int index) {
+ processQueue();
+ return new ReferenceListIterator<T>(list.listIterator(index), getRQF());
+ }
+
+ public List<T> subList(int fromIndex, int toIndex) {
+ processQueue();
+ List<T> sub = new ReferenceList<T>(list.subList(fromIndex, toIndex), getRQF(), null);
+ return sub;
+ }
+
+ private class ReferenceListIterator<T> implements ListIterator<T>{
+ ListIterator<Referrer<T>> iterator;
+ ReferenceQueuingFactory<T, Referrer<T>> rqf;
+ private ReferenceListIterator(ListIterator<Referrer<T>> iterator, ReferenceQueuingFactory<T, Referrer<T>> rqf ){
+ if ( iterator == null || rqf == null ) throw
+ new NullPointerException("Null iterator or reference queuing factory not allowed");
+ this.iterator = iterator;
+ this.rqf = rqf;
+ }
+
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ public T next() {
+ Referrer<T> t = iterator.next();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public boolean hasPrevious() {
+ return iterator.hasPrevious();
+ }
+
+ public T previous() {
+ Referrer<T> t = iterator.previous();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public int nextIndex() {
+ return iterator.nextIndex();
+ }
+
+ public int previousIndex() {
+ return iterator.previousIndex();
+ }
+
+ public void remove() {
+ iterator.remove();
+ }
+
+ public void set(T e) {
+ iterator.set(rqf.referenced(e, true, false));
+ }
+
+ public void add(T e) {
+ iterator.add(rqf.referenced( e, true, false));
+ }
+ }
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceMap.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceMap.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceMap.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceMap.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,251 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.lang.ref.ReferenceQueue;
+import java.util.AbstractMap;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * ReferenceMap is a wrapper object that encapsulates another Map implementation
+ * which it uses to store references.
+ *
+ * Synchronisation must be performed by the underlying map, using external
+ * synchronisation will fail, since each read is also potentially a
+ * mutation to remove a garbage collected reference.
+ *
+ * Implementation note:
+ *
+ * ReferenceQueue's must be allowed to be used by any views when creating
+ * new References using the wrapper, so the Reference is passed to the
+ * correct ReferenceQueue when it becomes unreachable.
+ *
+ * There is only one ReferenceQueue for each Collection, whether that is a
+ * Collection of Key's or Values. Defensive copies cannot be made by the
+ * underlying encapsulated collections.
+ *
+ * Abstract map is extended to take advantage of it's equals, hashCode and
+ * toString methods, which rely on calling entrySet() which this class
+ * overrides.
+ *
+ * @param <K>
+ * @param <V>
+ * @author Peter Firmstone.
+ */
+class ReferenceMap<K, V> extends AbstractMap<K, V> implements Map<K, V> {
+
+ private final Map<Referrer<K>, Referrer<V>> map;
+ // ReferenceQueuingFactory's handle ReferenceQueue locking policy.
+ private final ReferenceQueuingFactory<K, Referrer<K>> krqf;
+ private final ReferenceQueuingFactory<V, Referrer<V>> vrqf;
+ private final Ref key;
+ private final Ref val;
+
+ // Views of values and keys, reduces object creation.
+ private final Collection<V> values;
+ private final Set<K> keys;
+ private final Set<Entry<K,V>> entrys;
+
+ @SuppressWarnings("unchecked")
+ ReferenceMap(Map<Referrer<K>,Referrer<V>> map, Ref key, Ref val, boolean gcThreads, long gcKeyCycle, long gcValCycle){
+ // Note the ReferenceProcessor must synchronize on map, not the keySet or values for iteration.
+ // This no effect on ConcurrentMap implementations, it's just in case of
+ // Synchronized maps.
+ RefQueue<K> keyQue = null;
+ if (key.equals(Ref.TIME)) keyQue = new TimedRefQueue();
+ else if (!key.equals(Ref.STRONG)) keyQue = new RefReferenceQueue<K>();
+ RefQueue<V> valQue = null;
+ if (val.equals(Ref.TIME)) valQue = new TimedRefQueue();
+ else if (!val.equals(Ref.STRONG)) valQue = new RefReferenceQueue<V>();
+ ReferenceProcessor<K> krp = new ReferenceProcessor<K>(map.keySet(), key, keyQue, gcThreads, map);
+ ReferenceProcessor<V> vrp = new ReferenceProcessor<V>(map.values(), val, valQue, gcThreads, map);
+ this.krqf = krp;
+ this.vrqf = vrp;
+ this.map = map;
+ this.key = key;
+ this.val = val;
+ values = new ReferenceCollection<V>(this.map.values(), vrqf, val);
+ keys = new ReferenceSet<K>(this.map.keySet(), krqf, key);
+ // We let this escape during construction, but it's package private only
+ // and doesn't escape the package.
+ entrys = new EntrySetFacade<Entry<K,V>, Entry<Referrer<K>,Referrer<V>>>(
+ map.entrySet(),
+ new EntryFacadeConverter<K,V>(krqf, vrqf)
+ );
+ krp.start(gcKeyCycle);
+ vrp.start(gcValCycle);
+ }
+
+ ReferenceMap(Map<Referrer<K>, Referrer<V>> map, ReferenceQueuingFactory<K, Referrer<K>> krqf, ReferenceQueuingFactory<V, Referrer<V>> vrqf, Ref key, Ref val){
+ this.map = map;
+ this.krqf = krqf;
+ this.vrqf = vrqf;
+ this.key = key;
+ this.val = val;
+ values = new ReferenceCollection<V>(this.map.values(), vrqf, val);
+ keys = new ReferenceSet<K>(this.map.keySet(), krqf, key);
+ // We let this escape during construction, but it's package private only
+ // and doesn't escape the package.
+ entrys = new EntrySetFacade<Entry<K,V>, Entry<Referrer<K>,Referrer<V>>>(
+ map.entrySet(),
+ new EntryFacadeConverter<K,V>(krqf, vrqf)
+ );
+ }
+
+
+
+ ReferenceQueuingFactory<K, Referrer<K>> getKeyRQF(){
+ return krqf;
+ }
+
+ ReferenceQueuingFactory<V, Referrer<V>> getValRQF(){
+ return vrqf;
+ }
+
+ Ref keyRef() {
+ return key;
+ }
+
+ Ref valRef() {
+ return val;
+ }
+
+ /**
+ * Removes all associations from this map.
+ */
+ public void clear() {
+ processQueue();
+ map.clear();
+ }
+
+ @SuppressWarnings(value = "unchecked")
+ public boolean containsKey(Object key) {
+ processQueue();
+ return map.containsKey(wrapKey((K)key, false, true));
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean containsValue(Object value) {
+ processQueue();
+ return map.containsValue(wrapVal((V) value, false, true));
+ }
+
+ /**
+ * Returns a Set view of the mappings contained in the underlying map.
+ *
+ * The behaviour of this Set depends on the underlying Map passed in
+ * at construction time.
+ *
+ * The set supports element removal, which removes the corresponding
+ * mapping from the map, via the Iterator.remove, Set.remove, removeAll,
+ * retainAll and clear operations.
+ *
+ * @return
+ */
+ public Set<Entry<K,V>> entrySet() {
+ return entrys;
+ }
+
+ /**
+ * Returns value associated with given key, or null if none.
+ */
+ public V get(Object key) {
+ processQueue();
+ @SuppressWarnings(value = "unchecked")
+ Referrer<V> refVal = map.get(wrapKey((K) key, false, true));
+ if (refVal != null) return refVal.get();
+ return null;
+ }
+
+ public boolean isEmpty() {
+ processQueue();
+ return map.isEmpty();
+ }
+
+ /**
+ * The key Set returned, is encapsulated by ReferenceSet, which encapsulates
+ * it's objects using the same Ref type as ReferenceMap
+ *
+ * @see Ref
+ * @see ReferenceSet
+ * @return
+ */
+ public Set<K> keySet() {
+ processQueue();
+ return keys;
+ }
+
+ public void processQueue() {
+ // If someone else is cleaning out the trash, don't bother waiting,
+ // the underlying Map is responsible for it's own synchronization.
+ // Null values or keys may be returned as a result.
+ // Or a ConcurrentMap that contains a value may no longer contain
+ // it after checking.
+// krqf.processQueue();
+// vrqf.processQueue();
+ }
+
+ /**
+ * Associates value with given key, returning value previously associated
+ * with key, or null if none.
+ * @param key - Key
+ * @param value - Value
+ * @return previous value or null
+ */
+ public V put(K key, V value) {
+ processQueue();
+ Referrer<V> val = map.put(wrapKey(key, true, false),wrapVal(value, true, false));
+ if (val != null) return val.get();
+ return null;
+ }
+
+ /**
+ * Removes association for given key, returning value previously associated
+ * with key, or null if none.
+ */
+ public V remove(Object key) {
+ processQueue();
+ @SuppressWarnings(value = "unchecked")
+ Referrer<V> val = map.remove(wrapKey((K) key, false, true));
+ if (val != null) return val.get();
+ return null;
+ }
+
+ public int size() {
+ processQueue();
+ return map.size();
+ }
+
+ /**
+ * Returns collection containing all values currently held in this map.
+ */
+ public Collection<V> values() {
+ processQueue();
+ return values;
+ }
+
+ Referrer<V> wrapVal(V val, boolean enque, boolean temporary) {
+ return vrqf.referenced(val, enque, temporary);
+ }
+
+ Referrer<K> wrapKey(K key, boolean enque, boolean temporary) {
+ return krqf.referenced(key, enque, temporary);
+ }
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceMapSerialData.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceMapSerialData.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceMapSerialData.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceMapSerialData.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,24 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+/**
+ *
+ * @author peter
+ */
+class ReferenceMapSerialData<K,V> {
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceNavigableMap.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceNavigableMap.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceNavigableMap.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceNavigableMap.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,184 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+
+/**
+ *
+ * @author Peter Firmstone.
+ */
+class ReferenceNavigableMap<K,V> extends ReferenceSortedMap<K,V> implements NavigableMap<K,V> {
+ private final NavigableMap<Referrer<K>, Referrer<V>> map;
+
+ ReferenceNavigableMap(NavigableMap<Referrer<K>, Referrer<V>> map, Ref keyRef, Ref valRef, boolean gcThreads, long gcKeyCycle, long gcValCycle){
+ super(map, keyRef, valRef, gcThreads, gcKeyCycle, gcValCycle);
+ this.map = map;
+ }
+
+ ReferenceNavigableMap(NavigableMap<Referrer<K>, Referrer<V>> map,
+ ReferenceQueuingFactory<K, Referrer<K>> krqf,
+ ReferenceQueuingFactory<V, Referrer<V>> vrqf, Ref key, Ref val){
+ super(map, krqf, vrqf, key, val);
+ this.map = map;
+ }
+
+ public Entry<K, V> lowerEntry(K key) {
+ processQueue();
+ return new ReferenceEntryFacade<K,V>(
+ map.lowerEntry(wrapKey(key, false, true)),
+ getValRQF()
+ );
+ }
+
+ public K lowerKey(K key) {
+ processQueue();
+ Referrer<K> k = map.lowerKey(wrapKey(key, false, true));
+ if (k != null) return k.get();
+ return null;
+ }
+
+ public Entry<K, V> floorEntry(K key) {
+ processQueue();
+ return new ReferenceEntryFacade<K,V>(
+ map.floorEntry(wrapKey(key, false, true)),
+ getValRQF()
+ );
+ }
+
+ public K floorKey(K key) {
+ processQueue();
+ Referrer<K> k = map.floorKey(wrapKey(key, false, true));
+ if (k != null) return k.get();
+ return null;
+ }
+
+ public Entry<K, V> ceilingEntry(K key) {
+ processQueue();
+ return new ReferenceEntryFacade<K,V>(
+ map.ceilingEntry(wrapKey(key, false, true)),
+ getValRQF()
+ );
+ }
+
+ public K ceilingKey(K key) {
+ processQueue();
+ Referrer<K> k = map.ceilingKey(wrapKey(key, false, true));
+ if (k != null) return k.get();
+ return null;
+ }
+
+ public Entry<K, V> higherEntry(K key) {
+ processQueue();
+ return new ReferenceEntryFacade<K,V>(
+ map.higherEntry(wrapKey(key, false, true)),
+ getValRQF()
+ );
+ }
+
+ public K higherKey(K key) {
+ processQueue();
+ Referrer<K> k = map.higherKey(wrapKey(key, false, true));
+ if (k != null) return k.get();
+ return null;
+ }
+
+ public Entry<K, V> firstEntry() {
+ processQueue();
+ return new ReferenceEntryFacade<K,V>(
+ map.firstEntry(),
+ getValRQF()
+ );
+ }
+
+ public Entry<K, V> lastEntry() {
+ processQueue();
+ return new ReferenceEntryFacade<K,V>(
+ map.lastEntry(),
+ getValRQF()
+ );
+ }
+
+ public Entry<K, V> pollFirstEntry() {
+ processQueue();
+ return new ReferenceEntryFacade<K,V>(
+ map.pollFirstEntry(),
+ getValRQF()
+ );
+ }
+
+ public Entry<K, V> pollLastEntry() {
+ processQueue();
+ return new ReferenceEntryFacade<K,V>(
+ map.pollLastEntry(),
+ getValRQF()
+ );
+ }
+
+ public NavigableMap<K, V> descendingMap() {
+ processQueue();
+ return new ReferenceNavigableMap<K,V>(
+ map.descendingMap(),
+ getKeyRQF(),
+ getValRQF(), keyRef(), valRef()
+ );
+ }
+
+ public NavigableSet<K> navigableKeySet() {
+ processQueue();
+ return new ReferenceNavigableSet<K>(map.navigableKeySet(), getKeyRQF(), keyRef());
+ }
+
+ public NavigableSet<K> descendingKeySet() {
+ processQueue();
+ return new ReferenceNavigableSet<K>(map.descendingKeySet(), getKeyRQF(), keyRef());
+ }
+
+ public NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
+ processQueue();
+ return new ReferenceNavigableMap<K,V>(
+ map.subMap(
+ wrapKey(fromKey, false, true),
+ fromInclusive,
+ wrapKey(toKey, false, true),
+ toInclusive
+ ),
+ getKeyRQF(),
+ getValRQF(), keyRef(), valRef()
+ );
+
+ }
+
+ public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
+ processQueue();
+ return new ReferenceNavigableMap<K,V>(
+ map.headMap(wrapKey(toKey, false, true),inclusive),
+ getKeyRQF(),
+ getValRQF(), keyRef(), valRef()
+ );
+ }
+
+ public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
+ processQueue();
+ return new ReferenceNavigableMap<K,V>(
+ map.tailMap(wrapKey(fromKey, false, true),inclusive),
+ getKeyRQF(),
+ getValRQF(), keyRef(), valRef()
+ );
+ }
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceNavigableSet.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceNavigableSet.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceNavigableSet.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceNavigableSet.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,132 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.util.Iterator;
+import java.util.NavigableSet;
+
+/**
+ *
+ * @param <T>
+ * @author Peter Firmstone.
+ */
+class ReferenceNavigableSet<T>
+ extends ReferenceSortedSet<T> implements NavigableSet<T> {
+ private static final long serialVersionUID = 1L;
+ private final NavigableSet<Referrer<T>> set;
+
+ public ReferenceNavigableSet(NavigableSet<Referrer<T>> set, Ref type, boolean gcThreads, long gcCycle){
+ super(set, type, gcThreads, gcCycle);
+ this.set = set;
+ }
+
+ ReferenceNavigableSet(NavigableSet<Referrer<T>> set, ReferenceQueuingFactory<T, Referrer<T>> rqf, Ref type){
+ super(set, rqf, type);
+ this.set = set;
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws InvalidObjectException{
+ throw new InvalidObjectException("Builder required");
+ }
+
+ public T lower(T e) {
+ processQueue();
+ Referrer<T> t = set.lower(wrapObj(e, false, true));
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T floor(T e) {
+ processQueue();
+ Referrer<T> t = set.floor(wrapObj(e, false, true));
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T ceiling(T e) {
+ processQueue();
+ Referrer<T> t = set.ceiling(wrapObj(e, false, true));
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T higher(T e) {
+ processQueue();
+ Referrer<T> t = set.higher(wrapObj(e, false, true));
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T pollFirst() {
+ processQueue();
+ Referrer<T> t = set.pollFirst();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T pollLast() {
+ processQueue();
+ Referrer<T> t = set.pollLast();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public NavigableSet<T> descendingSet() {
+ processQueue();
+ return new ReferenceNavigableSet<T>(set.descendingSet(), getRQF(), null);
+ }
+
+ public Iterator<T> descendingIterator() {
+ processQueue();
+ return new ReferenceIterator<T>(set.descendingIterator());
+ }
+
+ public NavigableSet<T> subSet(T fromElement, boolean fromInclusive, T toElement, boolean toInclusive) {
+ processQueue();
+ return new ReferenceNavigableSet<T>(
+ set.subSet(
+ wrapObj(fromElement, false, true),
+ fromInclusive,
+ wrapObj(toElement, false, true),
+ toInclusive
+ ), getRQF(), getRef());
+ }
+
+ public NavigableSet<T> headSet(T toElement, boolean inclusive) {
+ processQueue();
+ return new ReferenceNavigableSet<T>(
+ set.headSet(
+ wrapObj(toElement, false, true), inclusive),
+ getRQF(),
+ getRef()
+ );
+ }
+
+ public NavigableSet<T> tailSet(T fromElement, boolean inclusive) {
+ processQueue();
+ return new ReferenceNavigableSet<T>(
+ set.tailSet(
+ wrapObj(fromElement, false, true),
+ inclusive),
+ getRQF(),
+ getRef()
+ );
+ }
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceProcessor.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceProcessor.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceProcessor.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceProcessor.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,285 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.lang.ref.PhantomReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * ReferenceProcessor is responsible for creation and collection of References
+ * on behalf of Reference Collection implementations.
+ *
+ * @param <T>
+ * @author peter
+ */
+class ReferenceProcessor<T> implements ReferenceQueuingFactory<T, Referrer<T>> {
+
+ private final static ScheduledExecutorService garbageCleaner =
+ Executors.newScheduledThreadPool(1, new SystemThreadFactory());
+ // Map to register newly created object references.
+ private final static Map<Reference,ScheduledFuture> finalizerTasks =
+ new ConcurrentHashMap<Reference,ScheduledFuture>();
+ // Finalizer queue to advise cancellation of ScheduledFuture's,
+ // when their ReferenceProcessor has been collected.
+ private final static ReferenceQueue<Reference> phantomQueue =
+ new ReferenceQueue<Reference>();
+ static {
+ // Finizer Task to cancel unneeded tasks.
+ garbageCleaner.scheduleAtFixedRate(
+ new FinalizerTask(phantomQueue, finalizerTasks),
+ 5L, 5L, TimeUnit.MINUTES
+ );
+ }
+
+ private final Collection<Referrer<T>> col;
+ private final Object colLock;
+ private final RefQueue<T> queue;
+ private final Ref type;
+ private final Lock queueLock;
+ private final boolean gcThreads;
+ private volatile boolean started = false;
+
+ ReferenceProcessor(Collection<Referrer<T>> col, Ref type, RefQueue<T> queue, boolean gcThreads, Object lock){
+ if (col == null || type == null ) throw new NullPointerException("collection or reference type cannot be null");
+ this.col = col;
+ colLock = lock;
+ this.type = type;
+ this.queue = type == Ref.STRONG ? null : queue;
+ this.gcThreads = gcThreads;
+ queueLock = new ReentrantLock();
+ }
+
+ /**
+ * Register with executor service and finaliser for cleanup.
+ * @param GcInterval time interval between scheduled cleaning runs.
+ */
+ public void start(long GcInterval){
+ if (started) return; // Start once only.
+ synchronized (this){
+ if (started) return;
+ started = true;
+ }
+ if (queue == null) return;
+ long enqDelay = GcInterval * (9L/10L);
+ // Enque garbage task preceeds cleaner task slightly, so we don't
+ // consume too much memory with massive collections.
+ // It would be more efficient for the enque task to perform removal
+ // from the collection while iterating, however it has been left
+ // this way in case we want to combine time and soft or weak reference
+ // behaviour in some way.
+ ScheduledFuture task;
+ task = ( queue != null && (gcThreads || type.equals(Ref.TIME)))
+ ? garbageCleaner.scheduleAtFixedRate(new CleanerTask(col, queue), GcInterval, GcInterval, TimeUnit.MILLISECONDS)
+ : null;
+ scheduleFinaliserTask(task);
+ task = (type.equals(Ref.TIME))
+ ? garbageCleaner.scheduleAtFixedRate(new EnqueGarbageTask(col, colLock), enqDelay, GcInterval, TimeUnit.MILLISECONDS)
+ : null;
+ scheduleFinaliserTask(task);
+ }
+
+ private void scheduleFinaliserTask(ScheduledFuture task){
+ if ( task != null ){
+ // Register with finaliser.
+ @SuppressWarnings("unchecked")
+ Reference r = new PhantomReference(this, phantomQueue);
+ finalizerTasks.put(r, task);
+ }
+ }
+
+ @Override
+ public T pseudoReferent(Referrer<T> u) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public Referrer<T> referenced(T w, boolean enque, boolean temporary) {
+ if (w == null) return null;
+ if (temporary) return ReferenceFactory.singleUseForLookup(w, type);
+ return ReferenceFactory.create(w, enque == true ? queue : null, type);
+ }
+
+ @Override
+ public void processQueue() {
+ if (queue == null || gcThreads) return;
+ Object t = null;
+ /*
+ * The reason for using an explicit lock is if another thread is
+ * removing the garbage, we don't want to prevent all other threads
+ * accessing the underlying collection, when it blocks on poll,
+ * this means that some client threads will receive null values
+ * on occassion, but this is a small price to pay.
+ * Might have to employ the null object pattern.
+ */
+ if ( queueLock.tryLock()){
+ try {
+ while ( (t = queue.poll()) != null){
+ col.remove(t);
+ }
+ }finally{
+ queueLock.unlock();
+ }
+ }
+ }
+
+ private static class EnqueGarbageTask implements Runnable{
+ private final Collection col;
+ private final Object lock; // This could be the same as col, or a map.
+
+ EnqueGarbageTask(Collection c, Object lock){
+ col = c;
+ this.lock = lock;
+ }
+
+ public void run() {
+ long time = System.nanoTime();
+ synchronized (lock){
+ Iterator it = col.iterator();
+ while (it.hasNext()){
+ Object r = it.next();
+ if (r instanceof TimeBomb) {
+ ((TimeBomb)r).updateClock(time);
+ }
+ }
+ }
+ }
+
+ }
+
+ private static class CleanerTask implements Runnable {
+
+ private final Collection col;
+ private final RefQueue queue;
+
+ private CleanerTask(Collection c, RefQueue queue){
+ col = c;
+ this.queue = queue;
+ }
+
+ @Override
+ public void run() {
+ try {
+ for ( Object t = queue.poll(); t != null; t = queue.poll()){
+ col.remove(t);
+ }
+ }catch(Exception e){
+ e.printStackTrace(System.err);
+ }
+ }
+
+ }
+
+ private static class FinalizerTask implements Runnable {
+
+ private final ReferenceQueue phantomQueue;
+ private final Map<Reference,ScheduledFuture> finalizerTasks ;
+
+ private FinalizerTask(ReferenceQueue queue,
+ Map<Reference,ScheduledFuture> tasks){
+ phantomQueue = queue;
+ finalizerTasks = tasks;
+ }
+
+ @Override
+ public void run() {
+ Reference p;
+ while ( (p = phantomQueue.poll()) != null){
+ ScheduledFuture sf = finalizerTasks.remove(p);
+ if (sf !=null) sf.cancel(true);
+ // phantom reference is eligible for gc we don't have to
+ // clear it, but might as well.
+ p.clear();
+ }
+ }
+
+ }
+
+ private static class SystemThreadFactory implements ThreadFactory{
+ private static final ThreadGroup g;
+
+ static {
+ ThreadGroup tg = Thread.currentThread().getThreadGroup();
+ g = AccessController.doPrivileged( new ThreadGroupAction(tg));
+ }
+
+ private SystemThreadFactory(){
+ }
+
+ @Override
+ public Thread newThread(Runnable r) {
+ return AccessController.doPrivileged( new CreateThread(g, r));
+ }
+
+ }
+
+ private static class ThreadGroupAction implements PrivilegedAction<ThreadGroup>{
+ private ThreadGroup tg;
+
+ ThreadGroupAction(ThreadGroup g){
+ tg = g;
+ }
+ public ThreadGroup run() {
+ try {
+ ThreadGroup parent = tg.getParent();
+ while (parent != null){
+ tg = parent;
+ parent = tg.getParent();
+ }
+ }catch (SecurityException e){
+ Logger.getLogger(ReferenceProcessor.class.getName()).log(Level.FINE, "Unable to get parent thread group", e);
+ }
+ return tg;
+ }
+ }
+
+ private static class CreateThread implements PrivilegedAction<Thread>{
+ private ThreadGroup g;
+ private Runnable r;
+
+ CreateThread(ThreadGroup g, Runnable r){
+ this.g = g;
+ this.r = r;
+ }
+ public Thread run() {
+ Thread t = new Thread(g, r);
+ try {
+ t.setContextClassLoader(null);
+ t.setPriority(Thread.MAX_PRIORITY);
+ } catch (SecurityException e){
+ Logger.getLogger(ReferenceProcessor.class.getName()).log(Level.FINE, "Unable to set ContextClassLoader or Priority", e);
+ }
+ return t;
+ }
+
+ }
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceQueuingFactory.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceQueuingFactory.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceQueuingFactory.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceQueuingFactory.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,40 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+/**
+ * An interface for processing ReferenceQueue's and encapsulating Objects
+ * in references and for making references appear as their referent.
+ *
+ * @author Peter Firmstone
+ */
+interface ReferenceQueuingFactory<O, R> {
+
+ O pseudoReferent(R u);
+
+ R referenced(O w, boolean enque, boolean temporary);
+
+ /**
+ * This method was originally intended to process the reference queue
+ * prior to access, however this severely hurts scalability. Now
+ * reference queue's are processed with a background garbage collection
+ * thread.
+ *
+ * @deprecated
+ */
+ void processQueue();
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSerializationFactory.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSerializationFactory.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSerializationFactory.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSerializationFactory.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,31 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+/**
+ *
+ * @author Peter Firmstone.
+ */
+class ReferenceSerializationFactory<T> {
+
+ // Not instantiable.
+ private ReferenceSerializationFactory(){}
+
+ static <T> Referrer<T> create(T t) {
+ return new ReferenceSerializedForm<T>(t);
+ }
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSerializedForm.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSerializedForm.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSerializedForm.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSerializedForm.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,98 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+/**
+ * A temporary but functional replacement for ReferenceKey's. No attempt is
+ * made to use readResolve to replace the original, that responsibility is left
+ * up to the collection implementation during de-serialisation.
+ *
+ * @author peter
+ */
+class ReferenceSerializedForm<T> implements Referrer<T>, Serializable{
+ private static final long serialVersionUID = 1L;
+
+ private T obj;
+ private transient int hash;
+
+ ReferenceSerializedForm(){
+ obj = null;
+ hash = 0;
+ }
+
+ ReferenceSerializedForm(T t){
+ obj = t;
+ int hash = 7;
+ hash = 29 * hash + System.identityHashCode(t);
+ hash = 29 * hash + (t!= null ? t.getClass().hashCode() :0);
+ this.hash = hash;
+ }
+
+ public T get() {
+ T t = obj;
+ obj = null;
+ return t;
+ }
+
+ public void clear() {
+ obj = null;
+ }
+
+ public boolean isEnqueued() {
+ return false;
+ }
+
+ public boolean enqueue() {
+ return false;
+ }
+
+ /* In this case we're using Identity because it has a wider scope.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true; // Same reference.
+ if (!(o instanceof Referrer)) return false;
+ Object k1 = get();
+ Object k2 = ((Referrer) o).get();
+ if ( k1 != null && k1 == k2) return true;
+ return ( k1 == null && k2 == null && hashCode() == o.hashCode()); // Both objects were collected.
+ }
+
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ int hash = 7;
+ hash = 29 * hash + System.identityHashCode(obj);
+ hash = 29 * hash + (obj != null ? obj.getClass().hashCode() :0);
+ this.hash = hash;
+ }
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ }
+
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSet.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSet.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSet.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSet.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,74 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * A Referenced Set.
+ *
+ *
+ * @see ReferenceCollection
+ * @author Peter Firmstone.
+ */
+class ReferenceSet<T> extends ReferenceCollection<T> implements Set<T>{
+ private static final long serialVersionUID = 1L;
+
+ ReferenceSet(Set<Referrer<T>> col, Ref type, boolean gcThreads, long gcCycle){
+ super(col, type, gcThreads, gcCycle);
+ }
+
+ ReferenceSet(Set<Referrer<T>> col, ReferenceQueuingFactory<T, Referrer<T>> rqf, Ref type){
+ super(col, rqf, type);
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws InvalidObjectException{
+ throw new InvalidObjectException("Builder required");
+ }
+
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (!(o instanceof Set)) return false;
+ @SuppressWarnings("unchecked")
+ Set<T> s = (Set<T>) o;
+ if (s.size() != size())
+ return false;
+ try {
+ return containsAll(s);
+ } catch (ClassCastException e) {
+ return false;
+ } catch (NullPointerException e) {
+ return false;
+}
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 0;
+ Iterator<T> i = iterator();
+ while (i.hasNext()){
+ T next = i.next();
+ if ( next != null) {
+ hash = hash + next.hashCode();
+ }
+ }
+ return hash;
+ }
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSortedMap.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSortedMap.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSortedMap.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSortedMap.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,98 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.lang.ref.Reference;
+import java.util.Comparator;
+import java.util.SortedMap;
+
+/**
+ *
+ * @param <K>
+ * @param <V>
+ * @author peter
+ */
+class ReferenceSortedMap<K,V> extends ReferenceMap<K,V> implements SortedMap<K,V>{
+ private SortedMap<Referrer<K>, Referrer<V>> map;
+
+ ReferenceSortedMap(SortedMap<Referrer<K>, Referrer<V>> map, Ref keyRef, Ref valRef, boolean gcThreads, long gcKeyCycle, long gcValCycle){
+ super(map, keyRef, valRef, gcThreads, gcKeyCycle, gcValCycle);
+ this.map = map;
+ }
+
+ ReferenceSortedMap(SortedMap<Referrer<K>, Referrer<V>> map,
+ ReferenceQueuingFactory<K, Referrer<K>> krqf,
+ ReferenceQueuingFactory<V, Referrer<V>> vrqf, Ref key, Ref val){
+ super(map, krqf, vrqf, key, val);
+ this.map = map;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Comparator<? super K> comparator() {
+ processQueue();
+ Comparator<? super Referrer<K>> c = map.comparator();
+ if ( c instanceof ReferenceComparator){
+ return ((ReferenceComparator) c).get();
+ }
+ return null;
+ }
+
+ public SortedMap<K, V> subMap(K fromKey, K toKey) {
+ processQueue();
+ return new ReferenceSortedMap<K,V>(
+ map.subMap(wrapKey(fromKey, false, true), wrapKey(toKey, false, true)),
+ getKeyRQF(),
+ getValRQF(), keyRef(), valRef()
+ );
+ }
+
+
+ public SortedMap<K, V> headMap(K toKey) {
+ processQueue();
+ return new ReferenceSortedMap<K,V>(
+ map.headMap(wrapKey(toKey, false, true)),
+ getKeyRQF(),
+ getValRQF(), keyRef(), valRef()
+ );
+ }
+
+
+ public SortedMap<K, V> tailMap(K fromKey) {
+ processQueue();
+ return new ReferenceSortedMap<K,V>(
+ map.tailMap(wrapKey(fromKey, false, true)),
+ getKeyRQF(),
+ getValRQF(), keyRef(), valRef()
+ );
+ }
+
+
+ public K firstKey() {
+ processQueue();
+ Referrer<K> k = map.firstKey();
+ if (k != null) return k.get();
+ return null;
+ }
+
+
+ public K lastKey() {
+ processQueue();
+ Referrer<K> k = map.lastKey();
+ if (k != null) return k.get();
+ return null;
+ }
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSortedSet.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSortedSet.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSortedSet.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferenceSortedSet.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,95 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.util.Comparator;
+import java.util.SortedSet;
+
+/**
+ * Referenced set supports sorting Object based on their natural ordering
+ * or a Comparator, which must be wrapped in a ReferenceComparator.
+ *
+ * @param <T>
+ * @see Comparable
+ * @see Comparator
+ * @see ReferenceComparator
+ * @author Peter Firmstone.
+ */
+class ReferenceSortedSet<T> extends ReferenceSet<T> implements SortedSet<T> {
+ private static final long serialVersionUID = 1L;
+ private final SortedSet<Referrer<T>> set;
+
+ ReferenceSortedSet( SortedSet<Referrer<T>> set, Ref type, boolean gcThreads, long gcCycle){
+ super(set, type, gcThreads, gcCycle);
+ this.set = set;
+ }
+
+ ReferenceSortedSet(SortedSet<Referrer<T>> set, ReferenceQueuingFactory<T, Referrer<T>> rqf, Ref type){
+ super(set, rqf, type);
+ this.set = set;
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws InvalidObjectException{
+ throw new InvalidObjectException("Builder required");
+ }
+
+ @SuppressWarnings("unchecked")
+ public Comparator<? super T> comparator() {
+ processQueue();
+ Comparator<? super Referrer<T>> c = set.comparator();
+ if ( c instanceof ReferenceComparator){
+ return ((ReferenceComparator) c).get();
+ }
+ return null;
+ }
+
+ public SortedSet<T> subSet(T fromElement, T toElement) {
+ processQueue();
+ Referrer<T> from = wrapObj(fromElement, false, true);
+ Referrer<T> to = wrapObj(toElement, false, true);
+ return new ReferenceSortedSet<T>( set.subSet(from, to), getRQF(), getRef());
+ }
+
+ public SortedSet<T> headSet(T toElement) {
+ processQueue();
+ Referrer<T> to = wrapObj(toElement, false, true);
+ return new ReferenceSortedSet<T>(set.headSet(to), getRQF(), getRef());
+ }
+
+ public SortedSet<T> tailSet(T fromElement) {
+ processQueue();
+ Referrer<T> from = wrapObj(fromElement, false, true);
+ return new ReferenceSortedSet<T>(set.tailSet(from), getRQF(), getRef());
+ }
+
+ public T first() {
+ processQueue();
+ Referrer<T> t = set.first();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T last() {
+ processQueue();
+ Referrer<T> t = set.last();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferencedQueue.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferencedQueue.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferencedQueue.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferencedQueue.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,82 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+
+/**
+ *
+ * @param <T>
+ * @author Peter Firmstone.
+ */
+class ReferencedQueue<T> extends ReferenceCollection<T> implements Queue<T> {
+ private static final long serialVersionUID = 1L;
+ private final Queue<Referrer<T>> queue;
+
+ public ReferencedQueue( Queue<Referrer<T>> queue, Ref type, boolean gcThreads, long gcCycle){
+ super(queue, type, gcThreads, gcCycle);
+ this.queue = queue;
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws InvalidObjectException{
+ throw new InvalidObjectException("Builder required");
+ }
+
+ public boolean offer(T e) {
+ processQueue();
+ Referrer<T> r = wrapObj(e, true, false);
+ return queue.offer(r);
+ }
+
+ public T remove() {
+ processQueue();
+ do {
+ Referrer<T> r = queue.remove();
+ T t = r == null? null: r.get();
+ if (t != null) return t;
+ } while (!queue.isEmpty());
+ throw new NoSuchElementException("Queue is empty");
+ }
+
+ public T poll() {
+ processQueue();
+ do {
+ Referrer<T> r = queue.poll();
+ T t = r == null? null: r.get();
+ if (t != null) return t;
+ } while (!queue.isEmpty());
+ return null;
+ }
+
+ public T element() {
+ processQueue();
+ Referrer<T> t = queue.element();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+ public T peek() {
+ processQueue();
+ Referrer<T> t = queue.peek();
+ if ( t != null ) return t.get();
+ return null;
+ }
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/Referrer.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/Referrer.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/Referrer.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/Referrer.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,110 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.lang.ref.Reference;
+
+/**
+ * <p>
+ * The public API of package private Reference implementations, it defines the equals
+ * and hashCode contracts as well as methods identical to Reference.
+ * </p>
+ * @see Reference
+ * @see Ref
+ * @param <T> Referent
+ * @author Peter Firmstone
+ */
+public interface Referrer<T> {
+
+ /**
+ * @see Reference#get()
+ */
+ public T get() ;
+ /**
+ * @see Reference#clear()
+ */
+ public void clear();
+ /**
+ * @see Reference#isEnqueued()
+ * @return true if enqueued.
+ */
+ public boolean isEnqueued();
+ /**
+ * @see Reference#enqueue()
+ * @return true if successfully enqueued.
+ */
+ public boolean enqueue();
+
+ /**
+ * <p>
+ * Equals is calculated on IDENTITY or EQUALITY.
+ * </p>
+ * IDENTITY calculation:<BR>
+ * <BR><CODE>
+ * if (this == o) return true;<BR>
+ * if (!(o instanceof Referrer)) return false;<BR>
+ * Object k1 = get();<BR>
+ * Object k2 = ((Referrer) o).get();<BR>
+ * if ( k1 != null && k1 == k2 ) return true;<BR>
+ * return ( k1 == null && k2 == null && hashCode() == o.hashCode());<BR>
+ * </CODE>
+ * <BR>
+ * EQUALITY calculation:<BR>
+ * <BR><CODE>
+ * if (this == o) return true; // Same reference.<BR>
+ * if (!(o instanceof Referrer)) return false;<BR>
+ * Object k1 = get();<BR>
+ * Object k2 = ((Referrer) o).get();<BR>
+ * if ( k1 != null && k1.equals(k2)) return true;<BR>
+ * return ( k1 == null && k2 == null && hashCode() == o.hashCode());<BR>
+ * <BR>
+ *
+ * @see Ref
+ * @param o
+ * @return true if equal
+ */
+ public boolean equals(Object o);
+
+ /**
+ * <p>
+ * Standard hashCode calculation for IDENTITY based references, where k
+ * is the referent. This may be stored in a final field:
+ * </p>
+ * <BR><CODE>
+ * int hash = 7;<BR>
+ * hash = 29 * hash + System.identityHashCode(k);<BR>
+ * hash = 29 * hash + k.getClass().hashCode();<BR>
+ * </CODE>
+ * <BR>
+ * <p>
+ * Standard hashCode calculation for EQUALITY based references, where k
+ * is the referent:
+ * </p>
+ * <BR><CODE>
+ * int hash = 7;<BR>
+ * hash = 29 * hash + k.hashCode();<BR>
+ * hash = 29 * hash + k.getClass().hashCode();<BR>
+ * </CODE>
+ * <BR>
+ * <p>
+ * The hash must be calculated during construction and if the reference is
+ * cleared, the recorded hashCode returned. While the referent remains
+ * reachable the hashCode must be calculated each time.
+ * </p>
+ * @return hash
+ */
+ public int hashCode();
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferrerDecorator.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferrerDecorator.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferrerDecorator.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/ReferrerDecorator.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,70 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+/**
+ * I've thought about refactoring so the equals and comparator behaviour is
+ * implemented by the wrapper classes and only accepting References in
+ * constructors as this would allow the use of standard java Reference classes
+ * without extension, reducing the number of classes created,
+ * however that would create serial form lock in. The current arrangement
+ * allows for
+ *
+ *
+ *
+ * @author peter
+ */
+class ReferrerDecorator<T> extends AbstractReferrerDecorator<T> implements Serializable{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @serialField
+ */
+ private volatile Referrer<T> reference;
+
+ ReferrerDecorator(Referrer<T> ref){
+ if (ref == null) throw new NullPointerException("Referrer cannot be null");
+ reference = ref;
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ if (getReference() == null) throw new IOException("Attempt to write null Referrer");
+ }
+
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ }
+
+ @Override
+ public void refresh(Referrer<T> r) {
+ reference = r;
+ }
+
+ /**
+ * @return the reference
+ */
+ public Referrer<T> getReference() {
+ return reference;
+ }
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/SerializationOfReferenceCollection.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/SerializationOfReferenceCollection.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/SerializationOfReferenceCollection.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/SerializationOfReferenceCollection.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,38 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.io.ObjectStreamException;
+import java.util.AbstractCollection;
+import java.util.Collection;
+
+/**
+ *
+ * @author peter
+ */
+abstract class SerializationOfReferenceCollection<T> extends AbstractCollection<T> {
+
+ static <T> SerializationOfReferenceCollection<T> create(
+ Class clazz,
+ Collection<Referrer<T>> refCol,
+ Ref type) throws InstantiationException, IllegalAccessException{
+ return new ReferenceCollectionSerialData<T>(clazz, refCol, type);
+ }
+
+ abstract Collection<T> build() throws InstantiationException,
+ IllegalAccessException, ObjectStreamException;
+
+}
Added: river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/SerializationOfReferenceMap.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/SerializationOfReferenceMap.java?rev=1702174&view=auto
==============================================================================
--- river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/SerializationOfReferenceMap.java (added)
+++ river/jtsk/skunk/qa-refactor-namespace/trunk/src/org/apache/river/concurrent/SerializationOfReferenceMap.java Thu Sep 10 06:59:28 2015
@@ -0,0 +1,38 @@
+/* Copyright (c) 2010-2012 Zeus Project Services Pty Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.concurrent;
+
+import java.io.ObjectStreamException;
+import java.util.AbstractMap;
+import java.util.Map;
+
+/**
+ *
+ * @author peter
+ */
+abstract class SerializationOfReferenceMap<K,V> extends AbstractMap<K,V>{
+
+ static <K,V> SerializationOfReferenceMap<K,V> create(
+ Class clazz,
+ Map<Referrer<K>, Referrer<V>> refmap,
+ Ref type) throws InstantiationException, IllegalAccessException{
+ return null;
+ // return new ReferenceMapSerialData<K,V>(clazz, refmap, type);
+ }
+
+ abstract Map<K,V> build() throws InstantiationException,
+ IllegalAccessException, ObjectStreamException;
+}