You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2012/05/20 01:07:14 UTC
svn commit: r1340589 - in /activemq/activemq-cpp/trunk/activemq-cpp/src:
main/decaf/lang/ main/decaf/util/concurrent/
main/decaf/util/concurrent/locks/ test/decaf/util/concurrent/
Author: tabish
Date: Sat May 19 23:07:13 2012
New Revision: 1340589
URL: http://svn.apache.org/viewvc?rev=1340589&view=rev
Log:
Refactor the CopyOnWriteArrayList and add some more testing.
Modified:
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Pointer.h
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/CopyOnWriteArrayList.h
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/CopyOnWriteArraySet.h
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReadWriteLock.h
activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/CopyOnWriteArrayListTest.cpp
activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/CopyOnWriteArrayListTest.h
Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Pointer.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Pointer.h?rev=1340589&r1=1340588&r2=1340589&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Pointer.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/Pointer.h Sat May 19 23:07:13 2012
@@ -49,8 +49,8 @@ namespace lang {
*
* @since 1.0
*/
- template< typename T, typename REFCOUNTER = decaf::util::concurrent::atomic::AtomicRefCounter >
- class Pointer : public REFCOUNTER {
+ template<typename T, typename REFCOUNTER = decaf::util::concurrent::atomic::AtomicRefCounter>
+ class Pointer: public REFCOUNTER {
private:
typedef void (*deletionFuncPtr)(T* p);
@@ -59,14 +59,14 @@ namespace lang {
T* value;
- // Pointer to our internal delete function, allows incompletes.
+ // Pointer to our internal delete function.
deletionFuncPtr onDelete;
public:
- typedef T* PointerType; // type returned by operator->
- typedef T& ReferenceType; // type returned by operator*
- typedef REFCOUNTER CounterType; // Type of the Reference Counter
+ typedef T* PointerType; // type returned by operator->
+ typedef T& ReferenceType; // type returned by operator*
+ typedef REFCOUNTER CounterType; // Type of the Reference Counter
public:
@@ -76,43 +76,47 @@ namespace lang {
* Initialized the contained pointer to NULL, using the -> operator
* results in an exception unless reset to contain a real value.
*/
- Pointer() : REFCOUNTER(), value( NULL ), onDelete( onDeleteFunc ) {}
+ Pointer() : REFCOUNTER(), value(NULL), onDelete(onDeleteFunc) {}
/**
* Explicit Constructor, creates a Pointer that contains value with a
* single reference. This object now has ownership until a call to release.
*
- * @param value - instance of the type we are containing here.
+ * @param value -
+ * The instance of the type we are containing here.
*/
- explicit Pointer( const PointerType value ) : REFCOUNTER(), value( value ), onDelete( onDeleteFunc ) {
- }
+ explicit Pointer(const PointerType value) : REFCOUNTER(), value(value), onDelete(onDeleteFunc) {}
/**
* Copy constructor. Copies the value contained in the pointer to the new
* instance and increments the reference counter.
+ *
+ * @param value
+ * Another instance of a Pointer<T> that this Pointer will copy.
*/
- Pointer( const Pointer& value ) :
- REFCOUNTER( value ), value( value.value ), onDelete( onDeleteFunc ) {}
+ Pointer(const Pointer& value) : REFCOUNTER(value), value(value.value), onDelete(onDeleteFunc) {}
/**
* Copy constructor. Copies the value contained in the pointer to the new
* instance and increments the reference counter.
+ *
+ * @param value
+ * A different but compatible Pointer instance that this Pointer will copy.
*/
- template< typename T1, typename R1 >
- Pointer( const Pointer<T1, R1>& value ) :
- REFCOUNTER( value ), value( value.get() ), onDelete( onDeleteFunc ) {}
+ template<typename T1, typename R1>
+ Pointer(const Pointer<T1, R1>& value) : REFCOUNTER(value), value(value.get()), onDelete(onDeleteFunc) {}
/**
* Static Cast constructor. Copies the value contained in the pointer to the new
* instance and increments the reference counter performing a static cast on the
* value contained in the source Pointer object.
*
- * @param value - Pointer instance to cast to this type.
+ * @param value
+ * Pointer instance to cast to this type using a static_cast.
*/
- template< typename T1, typename R1 >
- Pointer( const Pointer<T1, R1>& value, const STATIC_CAST_TOKEN& ) :
- REFCOUNTER( value ), value( static_cast<T*>( value.get() ) ), onDelete( onDeleteFunc ) {
- }
+ template<typename T1, typename R1>
+ Pointer(const Pointer<T1, R1>& value, const STATIC_CAST_TOKEN&) :
+ REFCOUNTER(value), value(static_cast<T*> (value.get())), onDelete(onDeleteFunc) {}
/**
* Dynamic Cast constructor. Copies the value contained in the pointer to the new
@@ -120,29 +124,28 @@ namespace lang {
* value contained in the source Pointer object. If the cast fails and return NULL
* then this method throws a ClassCastException.
*
- * @param value - Pointer instance to cast to this type.
+ * @param value
+ * Pointer instance to cast to this type using a dynamic_cast.
*
* @throw ClassCastException if the dynamic cast returns NULL
*/
- template< typename T1, typename R1 >
- Pointer( const Pointer<T1, R1>& value, const DYNAMIC_CAST_TOKEN& ) :
- REFCOUNTER( value ), value( dynamic_cast<T*>( value.get() ) ), onDelete( onDeleteFunc ) {
-
- if( this->value == NULL ) {
+ template<typename T1, typename R1>
+ Pointer(const Pointer<T1, R1>& value, const DYNAMIC_CAST_TOKEN&) :
+ REFCOUNTER(value), value(dynamic_cast<T*> (value.get())), onDelete(onDeleteFunc) {
+ if (this->value == NULL) {
// Remove the reference we took in the Reference Counter's ctor since we
// didn't actually create one as the dynamic cast failed.
REFCOUNTER::release();
throw decaf::lang::exceptions::ClassCastException(
- __FILE__, __LINE__,
- "Failed to cast source pointer of type %s to this type: %s.",
- typeid( T1 ).name(), typeid( T ).name() );
+ __FILE__, __LINE__, "Failed to cast source pointer of type %s to this type: %s.",
+ typeid(T1).name(), typeid(T).name());
}
}
virtual ~Pointer() {
- if( REFCOUNTER::release() == true ) {
- onDelete( this->value );
+ if (REFCOUNTER::release() == true) {
+ onDelete(this->value);
}
}
@@ -152,10 +155,11 @@ namespace lang {
* Call reset with a value of NULL is supported and acts to set this Pointer
* to a NULL pointer.
*
- * @param value - The new value to contain.
+ * @param value
+ * The new value to contain or NULL to empty the pointer (default NULL if not set).
*/
- void reset( T* value ) {
- Pointer( value ).swap( *this );
+ void reset(T* value = NULL) {
+ Pointer(value).swap(*this);
}
/**
@@ -163,8 +167,6 @@ namespace lang {
* is not guaranteed to be safe if the Pointer is held by more than one object or this
* method is called from more than one thread.
*
- * @param value - The new value to contain.
- *
* @returns The pointer instance that was held by this Pointer object, the pointer is
* no longer owned by this Pointer and won't be freed when this Pointer goes
* out of scope.
@@ -189,34 +191,36 @@ namespace lang {
/**
* Exception Safe Swap Function
- * @param value - the value to swap with this.
+ *
+ * @param value
+ * The value to swap with this Pointer.
*/
- void swap( Pointer& value ) {
- std::swap( this->value, value.value );
- REFCOUNTER::swap( value );
+ void swap(Pointer& value) {
+ std::swap(this->value, value.value);
+ REFCOUNTER::swap(value);
}
/**
* Assigns the value of right to this Pointer and increments the reference Count.
* @param right - Pointer on the right hand side of an operator= call to this.
*/
- Pointer& operator= ( const Pointer& right ) {
- if( this == (void*)&right ) {
+ Pointer& operator=(const Pointer& right) {
+ if (this == (void*) &right) {
return *this;
}
- Pointer temp( right );
- temp.swap( *this );
+ Pointer temp(right);
+ temp.swap(*this);
return *this;
}
- template< typename T1, typename R1>
- Pointer& operator= ( const Pointer<T1, R1>& right ) {
- if( this == (void*)&right ) {
+ template<typename T1, typename R1>
+ Pointer& operator=(const Pointer<T1, R1>& right) {
+ if (this == (void*) &right) {
return *this;
}
- Pointer temp( right );
- temp.swap( *this );
+ Pointer temp(right);
+ temp.swap(*this);
return *this;
}
@@ -228,20 +232,20 @@ namespace lang {
* @throws NullPointerException if the contained value is Null
*/
ReferenceType operator*() {
- if( this->value == NULL ) {
+ if (this->value == NULL) {
throw decaf::lang::exceptions::NullPointerException(
- __FILE__, __LINE__, "Pointer operator& - Pointee is NULL." );
+ __FILE__, __LINE__, "Pointer operator& - Pointee is NULL.");
}
- return *( this->value );
+ return *(this->value);
}
ReferenceType operator*() const {
- if( this->value == NULL ) {
+ if (this->value == NULL) {
throw decaf::lang::exceptions::NullPointerException(
- __FILE__, __LINE__, "Pointer operator& - Pointee is NULL." );
+ __FILE__, __LINE__, "Pointer operator& - Pointee is NULL.");
}
- return *( this->value );
+ return *(this->value);
}
/**
@@ -252,16 +256,16 @@ namespace lang {
* @throws NullPointerException if the contained value is Null
*/
PointerType operator->() {
- if( this->value == NULL ) {
+ if (this->value == NULL) {
throw decaf::lang::exceptions::NullPointerException(
- __FILE__, __LINE__, "Pointer operator-> - Pointee is NULL." );
+ __FILE__, __LINE__, "Pointer operator-> - Pointee is NULL.");
}
return this->value;
}
PointerType operator->() const {
- if( this->value == NULL ) {
+ if (this->value == NULL) {
throw decaf::lang::exceptions::NullPointerException(
- __FILE__, __LINE__, "Pointer operator-> - Pointee is NULL." );
+ __FILE__, __LINE__, "Pointer operator-> - Pointee is NULL.");
}
return this->value;
}
@@ -270,40 +274,40 @@ namespace lang {
return this->value == NULL;
}
- inline friend bool operator==( const Pointer& left, const T* right ) {
+ inline friend bool operator==(const Pointer& left, const T* right) {
return left.get() == right;
}
- inline friend bool operator==( const T* left, const Pointer& right ) {
+ inline friend bool operator==(const T* left, const Pointer& right) {
return left == right.get();
}
- inline friend bool operator!=( const Pointer& left, const T* right ) {
+ inline friend bool operator!=(const Pointer& left, const T* right) {
return left.get() != right;
}
- inline friend bool operator!=( const T* left, const Pointer& right ) {
+ inline friend bool operator!=(const T* left, const Pointer& right) {
return left != right.get();
}
- template< typename T1, typename R1 >
- bool operator==( const Pointer<T1, R1>& right ) const {
+ template<typename T1, typename R1>
+ bool operator==(const Pointer<T1, R1>& right) const {
return this->value == right.get();
}
- template< typename T1, typename R1 >
- bool operator!=( const Pointer<T1, R1>& right ) const {
- return !( this->value == right.get() );
+ template<typename T1, typename R1>
+ bool operator!=(const Pointer<T1, R1>& right) const {
+ return !(this->value == right.get());
}
- template< typename T1 >
+ template<typename T1>
Pointer<T1, CounterType> dynamicCast() const {
- return Pointer<T1, CounterType>( *this, DYNAMIC_CAST_TOKEN() );
+ return Pointer<T1, CounterType> (*this, DYNAMIC_CAST_TOKEN());
}
- template< typename T1 >
+ template<typename T1>
Pointer<T1, CounterType> staticCast() const {
- return Pointer<T1, CounterType>( *this, STATIC_CAST_TOKEN() );
+ return Pointer<T1, CounterType> (*this, STATIC_CAST_TOKEN());
}
private:
@@ -316,32 +320,32 @@ namespace lang {
};
////////////////////////////////////////////////////////////////////////////
- template< typename T, typename R, typename U >
- inline bool operator==( const Pointer<T, R>& left, const U* right ) {
+ template<typename T, typename R, typename U>
+ inline bool operator==(const Pointer<T, R>& left, const U* right) {
return left.get() == right;
}
////////////////////////////////////////////////////////////////////////////
- template< typename T, typename R, typename U >
- inline bool operator==( const U* left, const Pointer<T, R>& right ) {
+ template<typename T, typename R, typename U>
+ inline bool operator==(const U* left, const Pointer<T, R>& right) {
return right.get() == left;
}
////////////////////////////////////////////////////////////////////////////
- template< typename T, typename R, typename U >
- inline bool operator!=( const Pointer<T, R>& left, const U* right ) {
- return !( left.get() == right );
+ template<typename T, typename R, typename U>
+ inline bool operator!=(const Pointer<T, R>& left, const U* right) {
+ return !(left.get() == right);
}
////////////////////////////////////////////////////////////////////////////
- template< typename T, typename R, typename U >
- inline bool operator!=( const U* left, const Pointer<T, R>& right ) {
+ template<typename T, typename R, typename U>
+ inline bool operator!=(const U* left, const Pointer<T, R>& right) {
return right.get() != left;
}
////////////////////////////////////////////////////////////////////////////
- template< typename T, typename R>
- std::ostream& operator<<(std::ostream &out, const Pointer<T,R>& pointer){
+ template<typename T, typename R>
+ std::ostream& operator<<(std::ostream &out, const Pointer<T, R>& pointer) {
out << pointer.get();
return out;
}
@@ -358,20 +362,20 @@ namespace lang {
* to be compared based on the comparison of the object itself and not just the value of
* the pointer.
*/
- template< typename T, typename R = decaf::util::concurrent::atomic::AtomicRefCounter >
- class PointerComparator : public decaf::util::Comparator< Pointer<T,R> > {
+ template<typename T, typename R = decaf::util::concurrent::atomic::AtomicRefCounter>
+ class PointerComparator: public decaf::util::Comparator<Pointer<T, R> > {
public:
virtual ~PointerComparator() {}
// Allows for operator less on types that implement Comparable or provide
// a workable operator <
- virtual bool operator() (const Pointer<T,R>& left, const Pointer<T,R>& right) const {
+ virtual bool operator()(const Pointer<T, R>& left, const Pointer<T, R>& right) const {
return *left < *right;
}
// Requires that the type in the pointer is an instance of a Comparable.
- virtual int compare(const Pointer<T,R>& left, const Pointer<T,R>& right) const {
+ virtual int compare(const Pointer<T, R>& left, const Pointer<T, R>& right) const {
return *left < *right ? -1 : *right < *left ? 1 : 0;
}
@@ -380,21 +384,16 @@ namespace lang {
}}
////////////////////////////////////////////////////////////////////////////////
-namespace std{
+namespace std {
/**
* An override of the less function object so that the Pointer objects
* can be stored in STL Maps, etc.
*/
- template< typename T >
- struct less< decaf::lang::Pointer<T> > :
- public binary_function< decaf::lang::Pointer<T>,
- decaf::lang::Pointer<T>, bool>
- {
- bool operator()( const decaf::lang::Pointer<T>& left,
- const decaf::lang::Pointer<T>& right ) const
- {
- return less<T*>()( left.get(), right.get() );
+ template<typename T>
+ struct less<decaf::lang::Pointer<T> > : public binary_function<decaf::lang::Pointer<T>, decaf::lang::Pointer<T>, bool> {
+ bool operator()(const decaf::lang::Pointer<T>& left, const decaf::lang::Pointer<T>& right) const {
+ return less<T*> ()(left.get(), right.get());
}
};
}
Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/CopyOnWriteArrayList.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/CopyOnWriteArrayList.h?rev=1340589&r1=1340588&r2=1340589&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/CopyOnWriteArrayList.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/CopyOnWriteArrayList.h Sat May 19 23:07:13 2012
@@ -21,77 +21,121 @@
#include <decaf/util/NoSuchElementException.h>
#include <decaf/lang/exceptions/IndexOutOfBoundsException.h>
#include <decaf/util/concurrent/Synchronizable.h>
-#include <decaf/util/concurrent/Mutex.h>
-#include <decaf/lang/ArrayPointer.h>
+#include <decaf/util/concurrent/locks/ReentrantLock.h>
#include <decaf/lang/System.h>
+#include <decaf/lang/Math.h>
+#include <decaf/lang/Pointer.h>
#include <decaf/util/List.h>
namespace decaf {
namespace util {
namespace concurrent {
- using decaf::lang::ArrayPointer;
- using decaf::lang::System;
-
template< typename E >
class CopyOnWriteArrayList : public List<E> {
private:
- Mutex mutex;
- ArrayPointer<E> array;
+ struct Array {
+
+ int size;
+ int capacity;
+ E* elements;
+
+ Array() : size(0), capacity(0), elements(NULL) {
+ }
+
+ Array(int capacity) : size(0), capacity(0), elements(NULL) {
+ reserve(capacity);
+ }
+
+ Array(const Array& src, int capacity) : size(0), capacity(0), elements(NULL) {
+ reserve(decaf::lang::Math::max(src.size, capacity));
+ if (src.size > 0) {
+ decaf::lang::System::arraycopy<E>(src.elements, 0, this->elements, 0, src.size);
+ }
+ this->size = src.size;
+ }
+
+ ~Array() {
+ delete [] elements;
+ }
+
+ void reserve(int requested) {
+ if (capacity < requested) {
+ // growth as a factor of 1.5
+ int newlen = decaf::lang::Math::max((int)(capacity*1.5), requested);
+ E* newbuf = newlen ? new E[newlen] : NULL;
+
+ if (this->elements != NULL) {
+ decaf::lang::System::arraycopy<E>(this->elements, 0, newbuf, 0, size);
+ }
+
+ delete[] this->elements;
+ this->elements = newbuf;
+ capacity = newlen;
+ }
+ }
+ };
+
+ private:
+
+ mutable decaf::util::concurrent::locks::ReentrantLock writeLock;
+ decaf::lang::Pointer<decaf::util::concurrent::locks::Condition> condition;
+ decaf::lang::Pointer<Array> array;
public:
class ArrayListIterator : public ListIterator<E> {
private:
- ArrayPointer<E> array;
+ decaf::lang::Pointer<Array> array;
int position;
private:
- ArrayListIterator( const ArrayListIterator& );
- ArrayListIterator& operator= ( const ArrayListIterator& );
+ ArrayListIterator(const ArrayListIterator&);
+ ArrayListIterator& operator=(const ArrayListIterator&);
public:
- ArrayListIterator( const ArrayPointer<E>& array, int index ) :
- ListIterator<E>(), array( array ), position( index ) {
+ ArrayListIterator(decaf::lang::Pointer<Array> array, int index) :
+ ListIterator<E> (), array(array), position(index) {
- if( position < 0 || position > array.length() ) {
+ if (position < 0 || position > array->size) {
throw decaf::lang::exceptions::IndexOutOfBoundsException(
- __FILE__, __LINE__, "Iterator created with invalid index." );
+ __FILE__, __LINE__, "Iterator created with invalid index.");
}
}
- virtual ~ArrayListIterator() {};
+ virtual ~ArrayListIterator() {
+ this->array.reset(NULL);
+ };
virtual E next() {
-
- if( position >= array.length() ) {
+ if (position >= array->size) {
throw NoSuchElementException();
}
- return this->array[position++];
+ return this->array->elements[position++];
}
virtual bool hasNext() const {
- return this->position < array.length();
+ return this->position < array->size;
}
virtual void remove() {
throw decaf::lang::exceptions::UnsupportedOperationException(
- __FILE__, __LINE__, "CopyOnWriteArrayList Iterator cannot remove elements." );
+ __FILE__, __LINE__, "CopyOnWriteArrayList Iterator cannot remove elements.");
}
- virtual void add( const E& e DECAF_UNUSED ) {
+ virtual void add(const E& e DECAF_UNUSED ) {
throw decaf::lang::exceptions::UnsupportedOperationException(
- __FILE__, __LINE__, "CopyOnWriteArrayList Iterator cannot add elements." );
+ __FILE__, __LINE__, "CopyOnWriteArrayList Iterator cannot add elements.");
}
- virtual void set( const E& e DECAF_UNUSED ) {
+ virtual void set(const E& e DECAF_UNUSED ) {
throw decaf::lang::exceptions::UnsupportedOperationException(
- __FILE__, __LINE__, "CopyOnWriteArrayList Iterator cannot add elements." );
+ __FILE__, __LINE__, "CopyOnWriteArrayList Iterator cannot add elements.");
}
virtual bool hasPrevious() const {
@@ -99,11 +143,11 @@ namespace concurrent {
}
virtual E previous() {
- if( position <= 0 ) {
+ if (position <= 0) {
throw NoSuchElementException();
}
- return this->array[position--];
+ return this->array->elements[position--];
}
virtual int nextIndex() const {
@@ -118,108 +162,140 @@ namespace concurrent {
public:
- CopyOnWriteArrayList() : List<E>(), mutex(), array() {
+ CopyOnWriteArrayList() : List<E>(), writeLock(), condition(), array(new Array()) {
+ this->condition.reset(writeLock.newCondition());
}
- CopyOnWriteArrayList( const Collection<E>& collection ) : List<E>(), mutex(), array() {
- this->doCopyCollection( collection );
+ CopyOnWriteArrayList(const Collection<E>& collection) : List<E>(), writeLock(), condition(), array(new Array()) {
+ this->condition.reset(writeLock.newCondition());
+ this->doCopyCollection(collection);
}
- CopyOnWriteArrayList( const CopyOnWriteArrayList<E>& collection ) : List<E>(), mutex(), array() {
- this->doCopyCollection( collection );
+ CopyOnWriteArrayList(const CopyOnWriteArrayList<E>& collection) : List<E>(), writeLock(), condition(), array(new Array()) {
+ this->condition.reset(writeLock.newCondition());
+ this->doCopyCollection(collection);
}
- CopyOnWriteArrayList( const E* array, int size ) : List<E>(), mutex(), array() {
-
- E* elements = new E[size];
- for( int i = 0; i < size; ++i ) {
- elements[i] = array[i];
+ CopyOnWriteArrayList(const E* array, int size) : List<E>(), writeLock(), condition(), array(new Array()) {
+ this->condition.reset(writeLock.newCondition());
+ decaf::lang::Pointer<Array> temp(new Array(size));
+ for (int i = 0; i < size; ++i) {
+ temp->elements[i] = array[i];
+ temp->size++;
}
-
- this->array.reset( elements, size );
+ this->array.swap(temp);
}
- virtual ~CopyOnWriteArrayList() {}
+ virtual ~CopyOnWriteArrayList() {
+ this->array.reset(NULL);
+ }
public:
- CopyOnWriteArrayList<E>& operator= ( const CopyOnWriteArrayList<E>& list ) {
- synchronized( &mutex ) {
+ CopyOnWriteArrayList<E>& operator=(const CopyOnWriteArrayList<E>& list) {
+ this->writeLock.lock();
+ try {
this->clear();
- this->doCopyCollection( list );
+ this->doCopyCollection(list);
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
+
+ this->writeLock.unlock();
return *this;
}
- CopyOnWriteArrayList<E>& operator= ( const Collection<E>& list ) {
- synchronized( &mutex ) {
+ CopyOnWriteArrayList<E>& operator=(const Collection<E>& list) {
+ this->writeLock.lock();
+ try {
this->clear();
- this->doCopyCollection( list );
+ this->doCopyCollection(list);
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
+
+ this->writeLock.unlock();
return *this;
}
public: // Collections API
- virtual void copy( const Collection<E>& collection ) {
- this->doCopyCollection( collection );
+ virtual void copy(const Collection<E>& collection) {
+ this->writeLock.lock();
+ try {
+ this->clear();
+ this->doCopyCollection(collection);
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
}
- virtual bool add( const E& value ) {
-
- synchronized( &this->mutex ) {
-
- ArrayPointer<E> oldData = this->array;
- int size = oldData.length();
- E* elements = new E[size + 1];
- if( size > 0 ) {
- System::arraycopy( oldData.get(), 0, elements, 0, size );
- }
- elements[size] = value;
- this->array.reset( elements, size + 1 );
-
+ virtual bool add(const E& value) {
+ this->writeLock.lock();
+ try {
+ decaf::lang::Pointer<Array> oldArray = this->array;
+ int size = oldArray->size;
+ decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size + 1));
+ newArray->elements[size] = value;
+ newArray->size++;
+ this->array.swap(newArray);
+ this->writeLock.unlock();
return true;
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
-
- return false;
}
- virtual bool addAll( const Collection<E>& collection ) {
-
- synchronized( &this->mutex ) {
-
- ArrayPointer<E> oldData = this->array;
- int size = oldData.length();
- E* elements = new E[size + collection.size()];
-
- if( size > 0 ) {
- System::arraycopy( oldData.get(), 0, elements, 0, size );
+ virtual bool addAll(const Collection<E>& collection) {
+ this->writeLock.lock();
+ try {
+ decaf::lang::Pointer<Array> oldArray = this->array;
+ int size = oldArray->size;
+ decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size + collection.size()));
+ std::auto_ptr<Iterator<E> > iter(collection.iterator());
+ while (iter->hasNext()) {
+ newArray->elements[newArray->size++] = iter->next();
}
-
- std::auto_ptr< Iterator<E> > iter( collection.iterator() );
- while( iter->hasNext() ) {
- elements[size++] = iter->next();
- }
-
- this->array.reset( elements, size );
-
+ this->array.swap(newArray);
+ this->writeLock.unlock();
return true;
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
-
- return false;
}
virtual void clear() {
- synchronized( &this->mutex ) {
- this->array.reset( NULL );
+ this->writeLock.lock();
+ try {
+ decaf::lang::Pointer<Array> newArray(new Array());
+ this->array.swap(newArray);
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
+
+ this->writeLock.unlock();
+ }
+
+ virtual bool contains(const E& value) const {
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
- }
- virtual bool contains( const E& value ) const {
-
- ArrayPointer<E> elements = this->array;
- for( int i = 0; i < elements.length(); ++i ) {
- if( elements[i] == value ) {
+ for (int i = 0; i < current->size; ++i) {
+ if (current->elements[i] == value) {
return true;
}
}
@@ -227,13 +303,11 @@ namespace concurrent {
return false;
}
- virtual bool containsAll( const Collection<E>& collection ) const {
-
- ArrayPointer<E> elements = this->array;
- std::auto_ptr< Iterator<E> > iter( collection.iterator() );
- while( iter->hasNext() ) {
+ virtual bool containsAll(const Collection<E>& collection) const {
+ std::auto_ptr<Iterator<E> > iter(collection.iterator());
+ while (iter->hasNext()) {
E next = iter->next();
- if( !this->contains( next ) ) {
+ if (!this->contains(next)) {
return false;
}
}
@@ -241,38 +315,38 @@ namespace concurrent {
return true;
}
- virtual bool equals( const Collection<E>& collection ) const {
+ virtual bool equals(const Collection<E>& collection) const {
- if( (void*)this == &collection ) {
+ if ((void*) this == &collection) {
return true;
}
- const List<E>* asList = dynamic_cast<const List<E>*>( &collection );
- if( asList == NULL ) {
+ const List<E>* asList = dynamic_cast<const List<E>*> (&collection);
+ if (asList == NULL) {
return false;
}
- if( this->size() != asList->size() ) {
+ if (this->size() != asList->size()) {
return false;
}
- std::auto_ptr< Iterator<E> > thisIter( this->iterator() );
- std::auto_ptr< Iterator<E> > otherIter( asList->iterator() );
+ std::auto_ptr<Iterator<E> > thisIter(this->iterator());
+ std::auto_ptr<Iterator<E> > otherIter(asList->iterator());
- while( thisIter->hasNext() ) {
- if( !otherIter->hasNext() ) {
+ while (thisIter->hasNext()) {
+ if (!otherIter->hasNext()) {
return false;
}
E myNext = thisIter->next();
E otherNext = otherIter->next();
- if( myNext != otherNext ) {
+ if (myNext != otherNext) {
return false;
}
}
- if( otherIter->hasNext() ) {
+ if (otherIter->hasNext()) {
return false;
}
@@ -280,117 +354,138 @@ namespace concurrent {
}
virtual bool isEmpty() const {
- return this->getArray().length() == 0;
- }
-
- virtual bool remove( const E& value ) {
-
- synchronized( &this->mutex ) {
-
- int index = this->indexOf( value );
- if( index == -1 ) {
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
+
+ return current->size == 0;
+ }
+
+ virtual bool remove(const E& value) {
+ this->writeLock.lock();
+ try {
+ int index = this->indexOf(value);
+ if (index == -1) {
+ this->writeLock.unlock();
return false;
}
-
- this->removeAt( index );
-
+ this->removeAt(index);
+ this->writeLock.unlock();
return true;
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
-
- return false;
}
- virtual bool removeAll( const Collection<E>& collection ) {
-
- if( collection.isEmpty() ) {
+ virtual bool removeAll(const Collection<E>& collection) {
+ if (collection.isEmpty()) {
return false;
}
- synchronized( &this->mutex ) {
-
- ArrayPointer<E> oldData = this->array;
- int size = oldData.length();
+ this->writeLock.lock();
+ try {
+ decaf::lang::Pointer<Array> oldArray = this->array;
+ int size = oldArray->size;
- if( size == 0 ) {
+ if (size == 0) {
+ this->writeLock.unlock();
return false;
}
- ArrayPointer<E> elements( size );
+ decaf::lang::Pointer<Array> buffer(new Array(size));
int count = 0;
-
- for( int i = 0; i < size; ++i ) {
- E value = oldData[i];
- if( !collection.contains( value ) ) {
- elements[count++] = value;
+ for (int i = 0; i < size; ++i) {
+ E value = oldArray->elements[i];
+ if (!collection.contains(value)) {
+ buffer->elements[count++] = value;
+ buffer->size++;
}
}
- if( count == 0 ) {
- this->array.reset( NULL );
+ if (count == 0) {
+ this->array.reset(new Array());
} else {
- E* newArray = new E[count];
- System::arraycopy( elements.get(), 0, newArray, 0, count );
- this->array.reset( newArray, count );
+ decaf::lang::Pointer<Array> newArray(new Array(*buffer, count));
+ this->array.swap(newArray);
}
+ this->writeLock.unlock();
return true;
-
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
-
- return false;
}
- virtual bool retainAll( const Collection<E>& collection ) {
-
- synchronized( &this->mutex ) {
+ virtual bool retainAll(const Collection<E>& collection) {
+ this->writeLock.lock();
+ try {
- ArrayPointer<E> oldData = this->array;
- int size = oldData.length();
+ decaf::lang::Pointer<Array> oldArray = this->array;
+ int size = oldArray->size;
- if( size == 0 ) {
+ if (size == 0) {
+ this->writeLock.unlock();
return false;
}
- if( collection.isEmpty() ) {
- this->array.reset( NULL );
+ if (collection.isEmpty()) {
+ this->array.reset(new Array());
+ this->writeLock.unlock();
return true;
}
- ArrayPointer<E> elements( size );
+ decaf::lang::Pointer<Array> buffer(new Array(size));
int count = 0;
- for( int i = 0; i < size; ++i ) {
- E value = oldData[i];
- if( collection.contains( value ) ) {
- elements[count++] = value;
+ for (int i = 0; i < size; ++i) {
+ E value = oldArray->elements[i];
+ if (collection.contains(value)) {
+ buffer->elements[count++] = value;
+ buffer->size++;
}
}
- if( count == 0 ) {
- this->array.reset( NULL );
+ if (count == 0) {
+ this->array.reset(new Array());
} else {
- E* newArray = new E[count];
- System::arraycopy( elements.get(), 0, newArray, 0, count );
- this->array.reset( newArray, count );
+ this->array.swap(buffer);
}
+ this->writeLock.unlock();
return true;
-
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
-
- return false;
}
virtual int size() const {
- return this->getArray().length();
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
+
+ return current->size;
}
virtual std::vector<E> toArray() const {
-
- ArrayPointer<E> data = this->getArray();
- std::vector<E> result( data.length() );
- for( int i = 0; i < data.length(); ++i ) {
- result[i] = data[i];
+ decaf::lang::Pointer<Array> current = this->array;
+ std::vector<E> result( current->size );
+ for( int i = 0; i < current->size; ++i ) {
+ result[i] = current->elements[i];
}
return result;
@@ -399,33 +494,101 @@ namespace concurrent {
public: // Iterable API
virtual decaf::util::Iterator<E>* iterator() {
- return new ArrayListIterator( this->getArray(), 0 );
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
+
+ return new ArrayListIterator(current, 0);
}
virtual decaf::util::Iterator<E>* iterator() const {
- return new ArrayListIterator( this->getArray(), 0 );
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
+
+ return new ArrayListIterator(current, 0);
}
public: // List API
virtual ListIterator<E>* listIterator() {
- return new ArrayListIterator( this->getArray(), 0 );
- }
- virtual ListIterator<E>* listIterator() const {
- return new ArrayListIterator( this->getArray(), 0 );
- }
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
- virtual ListIterator<E>* listIterator( int index ) {
- return new ArrayListIterator( this->getArray(), index );
- }
- virtual ListIterator<E>* listIterator( int index ) const {
- return new ArrayListIterator( this->getArray(), index );
+ return new ArrayListIterator(current, 0);
}
+ virtual ListIterator<E>* listIterator() const {
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
+
+ return new ArrayListIterator(current, 0);
+ }
+
+ virtual ListIterator<E>* listIterator(int index) {
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
+
+ return new ArrayListIterator(current, index);
+ }
+ virtual ListIterator<E>* listIterator(int index) const {
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
+
+ return new ArrayListIterator(this->array, index);
+ }
+
+ virtual int indexOf(const E& value) const {
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
- virtual int indexOf( const E& value ) const {
-
- ArrayPointer<E> elements = this->array;
- for( int i = 0; i < elements.length(); ++i ) {
- if( elements[i] == value ) {
+ for (int i = 0; i < current->size; ++i) {
+ if (current->elements[i] == value) {
return i;
}
}
@@ -433,11 +596,19 @@ namespace concurrent {
return -1;
}
- virtual int lastIndexOf( const E& value ) const {
+ virtual int lastIndexOf(const E& value) const {
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
- ArrayPointer<E> elements = this->array;
- for( int i = elements.length() - 1; i >= 0; --i ) {
- if( elements[i] == value ) {
+ for (int i = current->size - 1; i >= 0; --i) {
+ if (current->elements[i] == value) {
return i;
}
}
@@ -445,123 +616,145 @@ namespace concurrent {
return -1;
}
- virtual E get( int index ) const {
- ArrayPointer<E> array = this->getArray();
- checkIndexExclusive( index, array.length() );
- return array[index];
- }
-
- virtual E set( int index, const E& element ) {
-
- synchronized( &this->mutex ) {
-
- ArrayPointer<E> previous = this->getArray();
- int size = previous.length();
- this->checkIndexExclusive( index, size );
- E* newArray = new E[size];
- System::arraycopy( previous.get(), 0, newArray, 0, size );
- E old = newArray[index];
- newArray[index] = element;
- this->array.reset( newArray, size );
-
+ virtual E get(int index) const {
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
+
+ checkIndexExclusive(index, current->size);
+ return current->elements[index];
+ }
+
+ virtual E set(int index, const E& element) {
+ this->writeLock.lock();
+ try {
+ decaf::lang::Pointer<Array> oldArray = this->array;
+ int size = oldArray->size;
+ this->checkIndexExclusive(index, size);
+ decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size));
+ E old = newArray->elements[index];
+ newArray->elements[index] = element;
+ this->array.swap(newArray);
+ this->writeLock.unlock();
return old;
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
-
- return E();
}
- virtual void add( int index, const E& element ) {
+ virtual void add(int index, const E& element) {
+ this->writeLock.lock();
+ try {
+ decaf::lang::Pointer<Array> oldArray = this->array;
+ int size = oldArray->size;
+ this->checkIndexInclusive(index, size);
+ decaf::lang::Pointer<Array> newArray(new Array(size + 1));
- synchronized( &this->mutex ) {
-
- ArrayPointer<E> previous = this->getArray();
- int size = previous.length();
- checkIndexInclusive( index, size );
- E* newArray = new E[size+1];
-
- if( size > 0 ) {
- System::arraycopy( previous.get(), 0, newArray, 0, index);
+ if (size > 0) {
+ decaf::lang::System::arraycopy<E>(oldArray->elements, 0, newArray->elements, 0, index);
}
- if( size > index ) {
- System::arraycopy( previous.get(), index, newArray, index + 1, size - index );
+ if (size > index) {
+ decaf::lang::System::arraycopy<E>(oldArray->elements, index, newArray->elements, index + 1, size - index);
}
- newArray[index] = element;
-
- this->array.reset( newArray, size+1 );
+ newArray->elements[index] = element;
+ newArray->size = size + 1;
+ this->array.swap(newArray);
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
}
- virtual bool addAll( int index, const Collection<E>& collection ) {
-
- synchronized( &this->mutex ) {
-
- ArrayPointer<E> previous = this->getArray();
- int size = previous.length();
- checkIndexInclusive( index, size );
+ virtual bool addAll(int index, const Collection<E>& collection) {
+ this->writeLock.lock();
+ try {
+ decaf::lang::Pointer<Array> oldArray = this->array;
+ int size = oldArray->size;
+ this->checkIndexInclusive(index, size);
int csize = collection.size();
- if( csize == 0 ) {
+ if (csize == 0) {
+ this->writeLock.unlock();
return false;
}
- E* newArray = new E[size+csize];
-
- if( size > 0 ) {
- System::arraycopy( previous.get(), 0, newArray, 0, index);
+ decaf::lang::Pointer<Array> newArray(new Array(size + csize));
+ if (size > 0) {
+ decaf::lang::System::arraycopy(oldArray->elements, 0, newArray->elements, 0, index);
}
- std::auto_ptr< Iterator<E> > iter( collection.iterator() );
+ std::auto_ptr<Iterator<E> > iter(collection.iterator());
int pos = index;
- while( iter->hasNext() ) {
- newArray[pos++] = iter->next();
+ while (iter->hasNext()) {
+ newArray->elements[pos++] = iter->next();
}
- if( size > index ) {
- System::arraycopy( previous.get(), index, newArray, index + csize, size - index );
+ if (size > index) {
+ decaf::lang::System::arraycopy(oldArray->elements, index, newArray->elements, index + csize, size - index);
}
-
- this->array.reset( newArray, size+csize );
+ newArray->size = size + csize;
+ this->array.swap(newArray);
+ this->writeLock.unlock();
+ return true;
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
-
- return true;
}
- virtual E removeAt( int index ) {
-
- synchronized( &this->mutex ) {
-
- ArrayPointer<E> previous = this->getArray();
- int size = previous.length();
- this->checkIndexExclusive( index, size );
- E old = previous[index];
-
- if( size == 1 ) {
- this->array.reset( NULL );
+ virtual E removeAt(int index) {
+ this->writeLock.lock();
+ try {
+ decaf::lang::Pointer<Array> oldArray = this->array;
+ int size = oldArray->size;
+ this->checkIndexExclusive(index, size);
+ E old = oldArray->elements[index];
+
+ if (size == 1) {
+ this->array.reset(new Array());
+ this->writeLock.unlock();
return old;
}
- E* newArray = new E[size-1];
- System::arraycopy( previous.get(), 0, newArray, 0, index );
+ decaf::lang::Pointer<Array> newArray(new Array(size - 1));
+ decaf::lang::System::arraycopy<E>(oldArray->elements, 0, newArray->elements, 0, index);
- if( size > index ) {
- System::arraycopy( previous.get(), index + 1, newArray, index, size - index - 1 );
+ if (size > index) {
+ decaf::lang::System::arraycopy<E>(oldArray->elements, index + 1, newArray->elements, index, size - index - 1);
}
- this->array.reset( newArray, size - 1 );
-
+ newArray->size = size - 1;
+ this->array.swap(newArray);
+ this->writeLock.unlock();
return old;
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
-
- return E();
}
virtual std::string toString() const {
- ArrayPointer<E> current = this->getArray();
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
std::string result;
-
return result;
}
@@ -576,31 +769,29 @@ namespace concurrent {
*
* @returns true if the element is added to this List.
*/
- bool addIfAbsent( const E& value ) {
-
- synchronized( &this->mutex ) {
-
- ArrayPointer<E> previous = this->getArray();
- int size = previous.length();
-
- if( size != 0 ) {
- if( this->indexOf( value ) != -1 ) {
+ bool addIfAbsent(const E& value) {
+ this->writeLock.lock();
+ try {
+ decaf::lang::Pointer<Array> oldArray = this->array;
+ int size = oldArray->size;
+
+ if (size != 0) {
+ if (this->indexOf(value) != -1) {
+ this->writeLock.unlock();
return false;
}
}
- E* newArray = new E[size+1];
- if( size > 0 ) {
- System::arraycopy( previous.get(), 0, newArray, 0, size );
- }
- newArray[size] = value;
-
- this->array.reset( newArray, size+1 );
-
+ decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size + 1));
+ newArray->elements[size] = value;
+ newArray->size++;
+ this->array.swap(newArray);
+ this->writeLock.unlock();
return true;
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
-
- return false;
}
/**
@@ -613,38 +804,38 @@ namespace concurrent {
*
* @returns the number of elements that are added to this List.
*/
- int addAllAbsent( const Collection<E>& collection ) {
+ int addAllAbsent(const Collection<E>& collection) {
- if( collection.size() == 0 ) {
+ if (collection.size() == 0) {
return 0;
}
- synchronized( &this->mutex ) {
-
- ArrayPointer<E> previous = this->getArray();
- int size = previous.length();
-
- ArrayPointer<E> add( collection.size() );
+ this->writeLock.lock();
+ try {
+ decaf::lang::Pointer<Array> oldArray = this->array;
+ int size = oldArray->size;
+ decaf::lang::Pointer<Array> buffer(new Array(collection.size()));
int count = 0;
- std::auto_ptr< Iterator<E> > iter( collection.iterator() );
- while( iter->hasNext() ) {
+ std::auto_ptr<Iterator<E> > iter(collection.iterator());
+ while (iter->hasNext()) {
E value = iter->next();
- if( this->indexOf( value ) == -1 ) {
- add[count++] = value;
+ if (this->indexOf(value) == -1) {
+ buffer->elements[count++] = value;
+ buffer->size++;
}
}
- E* newArray = new E[size+count];
- System::arraycopy( previous.get(), 0, newArray, 0, size );
- System::arraycopy( add.get(), 0, newArray, size, count );
-
- this->array.reset( newArray, size+count );
-
+ decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size + count));
+ decaf::lang::System::arraycopy(buffer->elements, 0, newArray->elements, size, count);
+ newArray->size = size + count;
+ this->array.swap(newArray);
+ this->writeLock.unlock();
return count;
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
-
- return 0;
}
/**
@@ -660,17 +851,25 @@ namespace concurrent {
*
* @throws IndexOutOfBoundsException if the given index is greater than or equal to the List size.
*/
- int lastIndexOf( const E& value, int index ) {
+ int lastIndexOf(const E& value, int index) {
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
- ArrayPointer<E> elements = this->array;
- if( index >= elements.length() ) {
+ if (index >= current->size) {
throw decaf::lang::exceptions::IndexOutOfBoundsException(
- __FILE__, __LINE__, "Index given %d, actual size %d", index, elements.length() );
+ __FILE__, __LINE__, "Index given %d, actual size %d", index, current->size);
}
- for( int i = index - 1; i >= 0; --i ) {
- if( elements[i] == value ) {
+ for (int i = index - 1; i >= 0; --i) {
+ if (current->elements[i] == value) {
return i;
}
}
@@ -691,17 +890,25 @@ namespace concurrent {
*
* @throws IndexOutOfBoundsException if the given index is negative.
*/
- int indexOf( const E& value, int index ) const {
+ int indexOf(const E& value, int index) const {
+ decaf::lang::Pointer<Array> current;
+ this->writeLock.lock();
+ try {
+ current = this->array;
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
+ }
- ArrayPointer<E> elements = this->array;
- if( index < 0 ) {
+ if (index < 0) {
throw decaf::lang::exceptions::IndexOutOfBoundsException(
- __FILE__, __LINE__, "Index given %d, actual size %d", index, elements.length() );
+ __FILE__, __LINE__, "Index given %d, actual size %d", index, current->size);
}
- for( int i = index; i < elements.length(); ++i ) {
- if( elements[i] == value ) {
+ for (int i = index; i < current->size; ++i) {
+ if (current->elements[i] == value) {
return i;
}
}
@@ -712,78 +919,78 @@ namespace concurrent {
public: // Synchronizable
virtual void lock() {
- mutex.lock();
+ this->writeLock.lock();
}
virtual bool tryLock() {
- return mutex.tryLock();
+ return this->writeLock.tryLock();
}
virtual void unlock() {
- mutex.unlock();
+ this->writeLock.unlock();
}
virtual void wait() {
- mutex.wait();
+ this->condition->await();
}
- virtual void wait( long long millisecs ) {
- mutex.wait( millisecs );
+ virtual void wait(long long millisecs) {
+ this->condition->await(millisecs, decaf::util::concurrent::TimeUnit::MILLISECONDS);
}
virtual void wait( long long millisecs, int nanos ) {
- mutex.wait( millisecs, nanos );
+ long long timeout = decaf::util::concurrent::TimeUnit::MILLISECONDS.toNanos(millisecs) + nanos;
+ this->condition->awaitNanos(timeout);
}
virtual void notify() {
- mutex.notify();
+ this->condition->signal();
}
virtual void notifyAll() {
- mutex.notifyAll();
+ this->condition->signalAll();
}
private:
- template<typename T>
- friend class CopyOnWriteArraySet;
+ void doCopyCollection(const Collection<E>& collection) {
- void doCopyCollection( const Collection<E>& collection ) {
-
- if( (void*)this == &collection ) {
+ if ((void*) this == &collection || collection.isEmpty()) {
return;
}
- synchronized( &this->mutex ) {
-
- ArrayPointer<E> data( collection.size() );
+ this->writeLock.lock();
+ try {
+ decaf::lang::Pointer<Array> oldArray = this->array;
+ int size = oldArray->size;
- std::auto_ptr< Iterator<E> > iter( collection.iterator() );
+ decaf::lang::Pointer<Array> buffer(new Array(*oldArray, size + collection.size()));
+ std::auto_ptr<Iterator<E> > iter(collection.iterator());
int index = 0;
-
- while( iter->hasNext() ) {
- data[index++] = iter->next();
+ while (iter->hasNext()) {
+ buffer->elements[size + index++] = iter->next();
+ buffer->size++;
}
- this->array = data;
+ this->array.swap(buffer);
+ this->writeLock.unlock();
+ } catch (decaf::lang::Exception& ex) {
+ this->writeLock.unlock();
+ throw;
}
}
- ArrayPointer<E> getArray() const {
- return this->array;
- }
-
- static void checkIndexInclusive( int index, int size ) {
- if( index < 0 || index > size ) {
+ static void checkIndexInclusive(int index, int size) {
+ if (index < 0 || index > size) {
throw decaf::lang::exceptions::IndexOutOfBoundsException(
- __FILE__, __LINE__, "Index is %d, size is %d", index, size );
+ __FILE__, __LINE__, "Index is %d, size is %d", index, size);
}
}
- static void checkIndexExclusive( int index, int size ) {
- if( index < 0 || index >= size ) {
+ static void checkIndexExclusive(int index, int size) {
+ if (index < 0 || index >= size) {
throw decaf::lang::exceptions::IndexOutOfBoundsException(
- __FILE__, __LINE__, "Index is %d, size is %d", index, size );
+ __FILE__, __LINE__, "Index is %d, size is %d", index, size);
}
}
Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/CopyOnWriteArraySet.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/CopyOnWriteArraySet.h?rev=1340589&r1=1340588&r2=1340589&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/CopyOnWriteArraySet.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/CopyOnWriteArraySet.h Sat May 19 23:07:13 2012
@@ -21,6 +21,7 @@
#include <decaf/util/NoSuchElementException.h>
#include <decaf/lang/exceptions/IndexOutOfBoundsException.h>
#include <decaf/lang/ArrayPointer.h>
+#include <decaf/lang/Pointer.h>
#include <decaf/util/concurrent/CopyOnWriteArrayList.h>
#include <decaf/util/concurrent/Synchronizable.h>
#include <decaf/util/Set.h>
@@ -31,8 +32,6 @@ namespace decaf {
namespace util {
namespace concurrent {
- using decaf::lang::ArrayPointer;
-
/**
* Since the CopyOnWriteArraySet and the CopyOnWriteArrayList share much of the same
* operational semantics this class uses the CopyOnWriteArrayList for all its underlying
@@ -54,26 +53,26 @@ namespace concurrent {
public:
- CopyOnWriteArraySet() : AbstractSet<E>(), array() {
+ CopyOnWriteArraySet() : AbstractSet<E> (), array() {
}
- CopyOnWriteArraySet( const Collection<E>& collection ) : AbstractSet<E>(), array() {
- this->copy( collection );
+ CopyOnWriteArraySet(const Collection<E>& collection) : AbstractSet<E> (), array() {
+ this->copy(collection);
}
- CopyOnWriteArraySet( const E* array, int size ) : AbstractSet<E>(), array() {
-
- for( int i = 0; i < size; ++i ) {
- this->array.addIfAbsent( array[i] );
+ CopyOnWriteArraySet(const E* array, int size) : AbstractSet<E> (), array() {
+ for (int i = 0; i < size; ++i) {
+ this->array.addIfAbsent(array[i]);
}
}
- virtual ~CopyOnWriteArraySet() {}
+ virtual ~CopyOnWriteArraySet() {
+ }
public:
- virtual void copy( const Collection<E>& collection ) {
- this->array.copy( collection );
+ virtual void copy(const Collection<E>& collection) {
+ this->array.copy(collection);
}
virtual decaf::util::Iterator<E>* iterator() {
@@ -92,78 +91,74 @@ namespace concurrent {
return this->array.isEmpty();
}
- virtual bool add( const E& value ) {
- return this->array.addIfAbsent( value );
+ virtual bool add(const E& value) {
+ return this->array.addIfAbsent(value);
}
- virtual bool addAll( const Collection<E>& collection ) {
- return this->array.addAllAbsent( collection ) > 0 ? true : false;
+ virtual bool addAll(const Collection<E>& collection) {
+ return this->array.addAllAbsent(collection) > 0 ? true : false;
}
virtual void clear() {
this->array.clear();
}
- virtual bool contains( const E& value ) const {
- return this->array.contains( value );
+ virtual bool contains(const E& value) const {
+ return this->array.contains(value);
}
- virtual bool containsAll( const Collection<E>& collection ) const {
- return this->array.containsAll( collection );
+ virtual bool containsAll(const Collection<E>& collection) const {
+ return this->array.containsAll(collection);
}
- virtual bool remove( const E& value ) {
- return this->array.remove( value );
+ virtual bool remove(const E& value) {
+ return this->array.remove(value);
}
- virtual bool removeAll( const Collection<E>& collection ) {
- return this->array.removeAll( collection );
+ virtual bool removeAll(const Collection<E>& collection) {
+ return this->array.removeAll(collection);
}
- virtual bool retainAll( const Collection<E>& collection ) {
- return this->array.retainAll( collection );
+ virtual bool retainAll(const Collection<E>& collection) {
+ return this->array.retainAll(collection);
}
virtual std::vector<E> toArray() const {
return this->array.toArray();
}
- virtual bool equals( const Collection<E>& collection ) const {
+ virtual bool equals(const Collection<E>& collection) const {
- if( (void*)this == &collection ) {
+ if ((void*) this == &collection) {
return true;
}
- const Set<E>* asSet = dynamic_cast<const Set<E>*>( &collection );
- if( asSet == NULL ) {
+ const Set<E>* asSet = dynamic_cast<const Set<E>*> (&collection);
+ if (asSet == NULL) {
return false;
}
- if( this->size() != asSet->size() ) {
+ if (this->size() != asSet->size()) {
return false;
}
- std::auto_ptr< Iterator<E> > setIter( asSet->iterator() );
-
- // Use a single snapshot of underlying array
- ArrayPointer<E> elements = this->array.getArray();
- int length = elements.length();
-
- ArrayPointer<bool> matched( length, false );
+ std::auto_ptr<Iterator<E> > setIter(asSet->iterator());
- while( setIter->hasNext() ) {
+ // Use a single snapshot of underlying array
+ CopyOnWriteArrayList<E> array(this->array);
+ int length = array.size();
+ decaf::lang::ArrayPointer<bool> matched(length, false);
+ while (setIter->hasNext()) {
E value = setIter->next();
- for( int i = 0; i < length; ++i ) {
- if( !matched[i] && value == elements[i] ) {
- matched[i] = true;
- break;
- }
+ int matchedAt = array.indexOf(value);
+ if (matchedAt >= 0) {
+ matched[matchedAt] = true;
}
}
- for( int i = 0; i < length; ++i ) {
- if( matched[i] == false ) {
+ for (int i = 0; i < length; ++i) {
+ if (matched[i] == false) {
return false;
}
}
Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReadWriteLock.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReadWriteLock.h?rev=1340589&r1=1340588&r2=1340589&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReadWriteLock.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/locks/ReadWriteLock.h Sat May 19 23:07:13 2012
@@ -18,6 +18,9 @@
#ifndef _DECAF_UTIL_CONCURRENT_LOCKS_READWRITELOCK_H_
#define _DECAF_UTIL_CONCURRENT_LOCKS_READWRITELOCK_H_
+#include <decaf/util/Config.h>
+#include <decaf/util/concurrent/locks/Lock.h>
+
namespace decaf {
namespace util {
namespace concurrent {
@@ -84,7 +87,7 @@ namespace locks {
*
* @since 1.0
*/
- class ReadWriteLock {
+ class DECAF_API ReadWriteLock {
public:
virtual ~ReadWriteLock() {}
Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/CopyOnWriteArrayListTest.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/CopyOnWriteArrayListTest.cpp?rev=1340589&r1=1340588&r2=1340589&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/CopyOnWriteArrayListTest.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/CopyOnWriteArrayListTest.cpp Sat May 19 23:07:13 2012
@@ -983,11 +983,11 @@ namespace {
private:
Random rand;
- CopyOnWriteArrayList<Target*>* list;
+ CopyOnWriteArrayList<Pointer<Target> >* list;
public:
- AddRemoveItemRunnable(CopyOnWriteArrayList<Target*>* list) :
+ AddRemoveItemRunnable(CopyOnWriteArrayList<Pointer<Target> >* list) :
Runnable(), rand(), list(list) {
}
@@ -995,11 +995,10 @@ namespace {
virtual void run() {
TimeUnit::MILLISECONDS.sleep(rand.nextInt(10));
- Target* target = new Target();
+ Pointer<Target> target(new Target());
list->add(target);
TimeUnit::MILLISECONDS.sleep(rand.nextInt(10));
list->remove(target);
- delete target;
}
};
@@ -1007,11 +1006,11 @@ namespace {
private:
Random rand;
- CopyOnWriteArrayList<Target*>* list;
+ CopyOnWriteArrayList<Pointer<Target> >* list;
public:
- IterateAndExecuteMethodRunnable(CopyOnWriteArrayList<Target*>* list) :
+ IterateAndExecuteMethodRunnable(CopyOnWriteArrayList<Pointer<Target> >* list) :
Runnable(), rand(), list(list) {
}
@@ -1019,7 +1018,7 @@ namespace {
virtual void run() {
TimeUnit::MILLISECONDS.sleep(rand.nextInt(15));
- Pointer< Iterator<Target*> > iter(list->iterator());
+ Pointer< Iterator<Pointer<Target> > > iter(list->iterator());
while(iter->hasNext()) {
iter->next()->increment();
}
@@ -1032,7 +1031,7 @@ namespace {
void CopyOnWriteArrayListTest::testConcurrentRandomAddRemoveAndIterate() {
ThreadPoolExecutor executor(50, Integer::MAX_VALUE, 60LL, TimeUnit::SECONDS, new LinkedBlockingQueue<Runnable*>());
- CopyOnWriteArrayList<Target*> list;
+ CopyOnWriteArrayList<Pointer<Target> > list;
Random rand;
Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/CopyOnWriteArrayListTest.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/CopyOnWriteArrayListTest.h?rev=1340589&r1=1340588&r2=1340589&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/CopyOnWriteArrayListTest.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/CopyOnWriteArrayListTest.h Sat May 19 23:07:13 2012
@@ -79,7 +79,7 @@ namespace concurrent {
CPPUNIT_TEST( testGet2IndexOutOfBoundsException );
CPPUNIT_TEST( testSet1IndexOutOfBoundsException );
CPPUNIT_TEST( testSet2IndexOutOfBoundsException );
-// CPPUNIT_TEST( testConcurrentRandomAddRemoveAndIterate );
+ CPPUNIT_TEST( testConcurrentRandomAddRemoveAndIterate );
CPPUNIT_TEST_SUITE_END();
private: