00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _DECAF_UTIL_CONCURRENT_COPYONWRITEARRAYLIST_H_
00019 #define _DECAF_UTIL_CONCURRENT_COPYONWRITEARRAYLIST_H_
00020
00021 #include <decaf/util/NoSuchElementException.h>
00022 #include <decaf/lang/exceptions/IndexOutOfBoundsException.h>
00023 #include <decaf/util/concurrent/Synchronizable.h>
00024 #include <decaf/util/concurrent/locks/ReentrantReadWriteLock.h>
00025 #include <decaf/lang/System.h>
00026 #include <decaf/lang/Math.h>
00027 #include <decaf/lang/Pointer.h>
00028 #include <decaf/util/List.h>
00029
00030 namespace decaf {
00031 namespace util {
00032 namespace concurrent {
00033
00034 template< typename E >
00035 class CopyOnWriteArrayList : public List<E> {
00036 private:
00037
00038 struct Array {
00039
00040 int size;
00041 int capacity;
00042 E* elements;
00043
00044 Array() : size(0), capacity(0), elements(NULL) {
00045 }
00046
00047 Array(int capacity) : size(0), capacity(0), elements(NULL) {
00048 reserve(capacity);
00049 }
00050
00051 Array(const Array& src, int capacity) : size(0), capacity(0), elements(NULL) {
00052 reserve(decaf::lang::Math::max(src.size, capacity));
00053 if (src.size > 0) {
00054 decaf::lang::System::arraycopy<E>(src.elements, 0, this->elements, 0, src.size);
00055 }
00056 this->size = src.size;
00057 }
00058
00059 ~Array() {
00060 delete [] elements;
00061 }
00062
00063 void reserve(int requested) {
00064 if (capacity < requested) {
00065
00066 int newlen = decaf::lang::Math::max((int)(capacity*1.5), requested);
00067 E* newbuf = newlen ? new E[newlen] : NULL;
00068
00069 if (this->elements != NULL) {
00070 decaf::lang::System::arraycopy<E>(this->elements, 0, newbuf, 0, size);
00071 }
00072
00073 delete[] this->elements;
00074 this->elements = newbuf;
00075 capacity = newlen;
00076 }
00077 }
00078
00079 private:
00080
00081 Array(const Array&);
00082 Array operator= (const Array&);
00083
00084 };
00085
00086 private:
00087
00088 mutable decaf::util::concurrent::locks::ReentrantReadWriteLock arrayLock;
00089 decaf::lang::Pointer<decaf::util::concurrent::locks::Condition> condition;
00090 decaf::lang::Pointer<Array> array;
00091
00092 public:
00093
00094 class ArrayListIterator : public ListIterator<E> {
00095 private:
00096
00097 decaf::lang::Pointer<Array> array;
00098 int position;
00099
00100 private:
00101
00102 ArrayListIterator(const ArrayListIterator&);
00103 ArrayListIterator& operator=(const ArrayListIterator&);
00104
00105 public:
00106
00107 ArrayListIterator(decaf::lang::Pointer<Array> array, int index) :
00108 ListIterator<E> (), array(array), position(index) {
00109
00110 if (position < 0 || position > array->size) {
00111 throw decaf::lang::exceptions::IndexOutOfBoundsException(
00112 __FILE__, __LINE__, "Iterator created with invalid index.");
00113 }
00114 }
00115
00116 virtual ~ArrayListIterator() {
00117 this->array.reset(NULL);
00118 };
00119
00120 virtual E next() {
00121 if (position >= array->size) {
00122 throw NoSuchElementException();
00123 }
00124
00125 return this->array->elements[position++];
00126 }
00127
00128 virtual bool hasNext() const {
00129 return this->position < array->size;
00130 }
00131
00132 virtual void remove() {
00133 throw decaf::lang::exceptions::UnsupportedOperationException(
00134 __FILE__, __LINE__, "CopyOnWriteArrayList Iterator cannot remove elements.");
00135 }
00136
00137 virtual void add(const E& e DECAF_UNUSED ) {
00138 throw decaf::lang::exceptions::UnsupportedOperationException(
00139 __FILE__, __LINE__, "CopyOnWriteArrayList Iterator cannot add elements.");
00140 }
00141
00142 virtual void set(const E& e DECAF_UNUSED ) {
00143 throw decaf::lang::exceptions::UnsupportedOperationException(
00144 __FILE__, __LINE__, "CopyOnWriteArrayList Iterator cannot add elements.");
00145 }
00146
00147 virtual bool hasPrevious() const {
00148 return this->position > 0;
00149 }
00150
00151 virtual E previous() {
00152 if (position <= 0) {
00153 throw NoSuchElementException();
00154 }
00155
00156 return this->array->elements[position--];
00157 }
00158
00159 virtual int nextIndex() const {
00160 return this->position;
00161 }
00162
00163 virtual int previousIndex() const {
00164 return this->position - 1;
00165 }
00166
00167 };
00168
00169 public:
00170
00171 CopyOnWriteArrayList() : List<E>(), arrayLock(), condition(), array(new Array()) {
00172 this->condition.reset(arrayLock.writeLock().newCondition());
00173 }
00174
00175 CopyOnWriteArrayList(const Collection<E>& collection) : List<E>(), arrayLock(), condition(), array(new Array()) {
00176 this->condition.reset(arrayLock.writeLock().newCondition());
00177 this->doCopyCollection(collection);
00178 }
00179
00180 CopyOnWriteArrayList(const CopyOnWriteArrayList<E>& collection) : List<E>(), arrayLock(), condition(), array(new Array()) {
00181 this->condition.reset(arrayLock.writeLock().newCondition());
00182 this->doCopyCollection(collection);
00183 }
00184
00185 CopyOnWriteArrayList(const E* array, int size) : List<E>(), arrayLock(), condition(), array(new Array()) {
00186 this->condition.reset(arrayLock.writeLock().newCondition());
00187 decaf::lang::Pointer<Array> temp(new Array(size));
00188 for (int i = 0; i < size; ++i) {
00189 temp->elements[i] = array[i];
00190 temp->size++;
00191 }
00192 this->array.swap(temp);
00193 }
00194
00195 virtual ~CopyOnWriteArrayList() {
00196 this->array.reset(NULL);
00197 }
00198
00199 public:
00200
00201 CopyOnWriteArrayList<E>& operator=(const CopyOnWriteArrayList<E>& list) {
00202 this->arrayLock.writeLock().lock();
00203 try {
00204 this->clear();
00205 this->doCopyCollection(list);
00206 } catch (decaf::lang::Exception& ex) {
00207 this->writeLock.unlock();
00208 throw;
00209 }
00210
00211 this->arrayLock.writeLock().unlock();
00212 return *this;
00213 }
00214
00215 CopyOnWriteArrayList<E>& operator=(const Collection<E>& list) {
00216 this->arrayLock.writeLock().lock();
00217 try {
00218 this->clear();
00219 this->doCopyCollection(list);
00220 } catch (decaf::lang::Exception& ex) {
00221 this->writeLock.unlock();
00222 throw;
00223 }
00224
00225 this->arrayLock.writeLock().unlock();
00226 return *this;
00227 }
00228
00229 public:
00230
00231 virtual void copy(const Collection<E>& collection) {
00232 this->arrayLock.writeLock().lock();
00233 try {
00234 this->clear();
00235 this->doCopyCollection(collection);
00236 this->arrayLock.writeLock().unlock();
00237 } catch (decaf::lang::Exception& ex) {
00238 this->arrayLock.writeLock().unlock();
00239 throw;
00240 }
00241 }
00242
00243 virtual bool add(const E& value) {
00244 this->arrayLock.writeLock().lock();
00245 try {
00246 decaf::lang::Pointer<Array> oldArray = this->array;
00247 int size = oldArray->size;
00248 decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size + 1));
00249 newArray->elements[size] = value;
00250 newArray->size++;
00251 this->array.swap(newArray);
00252 this->arrayLock.writeLock().unlock();
00253 return true;
00254 } catch (decaf::lang::Exception& ex) {
00255 this->arrayLock.writeLock().unlock();
00256 throw;
00257 }
00258 }
00259
00260 virtual bool addAll(const Collection<E>& collection) {
00261 this->arrayLock.writeLock().lock();
00262 try {
00263 decaf::lang::Pointer<Array> oldArray = this->array;
00264 int size = oldArray->size;
00265 decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size + collection.size()));
00266 std::auto_ptr<Iterator<E> > iter(collection.iterator());
00267 while (iter->hasNext()) {
00268 newArray->elements[newArray->size++] = iter->next();
00269 }
00270 this->array.swap(newArray);
00271 this->arrayLock.writeLock().unlock();
00272 return true;
00273 } catch (decaf::lang::Exception& ex) {
00274 this->arrayLock.writeLock().unlock();
00275 throw;
00276 }
00277 }
00278
00279 virtual void clear() {
00280 this->arrayLock.writeLock().lock();
00281 try {
00282 decaf::lang::Pointer<Array> newArray(new Array());
00283 this->array.swap(newArray);
00284 } catch (decaf::lang::Exception& ex) {
00285 this->arrayLock.writeLock().unlock();
00286 throw;
00287 }
00288
00289 this->arrayLock.writeLock().unlock();
00290 }
00291
00292 virtual bool contains(const E& value) const {
00293 decaf::lang::Pointer<Array> current;
00294 this->arrayLock.readLock().lock();
00295 try {
00296 current = this->array;
00297 this->arrayLock.readLock().unlock();
00298 } catch (decaf::lang::Exception& ex) {
00299 this->arrayLock.readLock().unlock();
00300 throw;
00301 }
00302
00303 for (int i = 0; i < current->size; ++i) {
00304 if (current->elements[i] == value) {
00305 return true;
00306 }
00307 }
00308
00309 return false;
00310 }
00311
00312 virtual bool containsAll(const Collection<E>& collection) const {
00313 std::auto_ptr<Iterator<E> > iter(collection.iterator());
00314 while (iter->hasNext()) {
00315 E next = iter->next();
00316 if (!this->contains(next)) {
00317 return false;
00318 }
00319 }
00320
00321 return true;
00322 }
00323
00324 virtual bool equals(const Collection<E>& collection) const {
00325
00326 if ((void*) this == &collection) {
00327 return true;
00328 }
00329
00330 const List<E>* asList = dynamic_cast<const List<E>*> (&collection);
00331 if (asList == NULL) {
00332 return false;
00333 }
00334
00335 if (this->size() != asList->size()) {
00336 return false;
00337 }
00338
00339 std::auto_ptr<Iterator<E> > thisIter(this->iterator());
00340 std::auto_ptr<Iterator<E> > otherIter(asList->iterator());
00341
00342 while (thisIter->hasNext()) {
00343 if (!otherIter->hasNext()) {
00344 return false;
00345 }
00346
00347 E myNext = thisIter->next();
00348 E otherNext = otherIter->next();
00349
00350 if (myNext != otherNext) {
00351 return false;
00352 }
00353 }
00354
00355 if (otherIter->hasNext()) {
00356 return false;
00357 }
00358
00359 return true;
00360 }
00361
00362 virtual bool isEmpty() const {
00363 decaf::lang::Pointer<Array> current;
00364 this->arrayLock.readLock().lock();
00365 try {
00366 current = this->array;
00367 this->arrayLock.readLock().unlock();
00368 } catch (decaf::lang::Exception& ex) {
00369 this->arrayLock.readLock().unlock();
00370 throw;
00371 }
00372
00373 return current->size == 0;
00374 }
00375
00376 virtual bool remove(const E& value) {
00377 this->arrayLock.writeLock().lock();
00378 try {
00379 int index = this->indexOf(value);
00380 if (index == -1) {
00381 this->arrayLock.writeLock().unlock();
00382 return false;
00383 }
00384 this->removeAt(index);
00385 this->arrayLock.writeLock().unlock();
00386 return true;
00387 } catch (decaf::lang::Exception& ex) {
00388 this->arrayLock.writeLock().unlock();
00389 throw;
00390 }
00391 }
00392
00393 virtual bool removeAll(const Collection<E>& collection) {
00394 if (collection.isEmpty()) {
00395 return false;
00396 }
00397
00398 this->arrayLock.writeLock().lock();
00399 try {
00400 decaf::lang::Pointer<Array> oldArray = this->array;
00401 int size = oldArray->size;
00402
00403 if (size == 0) {
00404 this->arrayLock.writeLock().unlock();
00405 return false;
00406 }
00407
00408 decaf::lang::Pointer<Array> buffer(new Array(size));
00409 int count = 0;
00410 for (int i = 0; i < size; ++i) {
00411 E value = oldArray->elements[i];
00412 if (!collection.contains(value)) {
00413 buffer->elements[count++] = value;
00414 buffer->size++;
00415 }
00416 }
00417
00418 if (count == 0) {
00419 this->array.reset(new Array());
00420 } else {
00421 decaf::lang::Pointer<Array> newArray(new Array(*buffer, count));
00422 this->array.swap(newArray);
00423 }
00424
00425 this->arrayLock.writeLock().unlock();
00426 return true;
00427 } catch (decaf::lang::Exception& ex) {
00428 this->arrayLock.writeLock().unlock();
00429 throw;
00430 }
00431 }
00432
00433 virtual bool retainAll(const Collection<E>& collection) {
00434 this->arrayLock.writeLock().lock();
00435 try {
00436
00437 decaf::lang::Pointer<Array> oldArray = this->array;
00438 int size = oldArray->size;
00439
00440 if (size == 0) {
00441 this->arrayLock.writeLock().unlock();
00442 return false;
00443 }
00444
00445 if (collection.isEmpty()) {
00446 this->array.reset(new Array());
00447 this->arrayLock.writeLock().unlock();
00448 return true;
00449 }
00450
00451 decaf::lang::Pointer<Array> buffer(new Array(size));
00452 int count = 0;
00453
00454 for (int i = 0; i < size; ++i) {
00455 E value = oldArray->elements[i];
00456 if (collection.contains(value)) {
00457 buffer->elements[count++] = value;
00458 buffer->size++;
00459 }
00460 }
00461
00462 if (count == 0) {
00463 this->array.reset(new Array());
00464 } else {
00465 this->array.swap(buffer);
00466 }
00467
00468 this->arrayLock.writeLock().unlock();
00469 return true;
00470 } catch (decaf::lang::Exception& ex) {
00471 this->arrayLock.writeLock().unlock();
00472 throw;
00473 }
00474 }
00475
00476 virtual int size() const {
00477 decaf::lang::Pointer<Array> current;
00478 this->arrayLock.readLock().lock();
00479 try {
00480 current = this->array;
00481 this->arrayLock.readLock().unlock();
00482 } catch (decaf::lang::Exception& ex) {
00483 this->arrayLock.readLock().unlock();
00484 throw;
00485 }
00486
00487 return current->size;
00488 }
00489
00490 virtual std::vector<E> toArray() const {
00491 decaf::lang::Pointer<Array> current;
00492 this->arrayLock.readLock().lock();
00493 try {
00494 current = this->array;
00495 this->arrayLock.readLock().unlock();
00496 } catch (decaf::lang::Exception& ex) {
00497 this->arrayLock.readLock().unlock();
00498 throw;
00499 }
00500 std::vector<E> result( current->size );
00501 for( int i = 0; i < current->size; ++i ) {
00502 result[i] = current->elements[i];
00503 }
00504
00505 return result;
00506 }
00507
00508 public:
00509
00510 virtual decaf::util::Iterator<E>* iterator() {
00511 decaf::lang::Pointer<Array> current;
00512 this->arrayLock.readLock().lock();
00513 try {
00514 current = this->array;
00515 this->arrayLock.readLock().unlock();
00516 } catch (decaf::lang::Exception& ex) {
00517 this->arrayLock.readLock().unlock();
00518 throw;
00519 }
00520
00521 return new ArrayListIterator(current, 0);
00522 }
00523 virtual decaf::util::Iterator<E>* iterator() const {
00524 decaf::lang::Pointer<Array> current;
00525 this->arrayLock.readLock().lock();
00526 try {
00527 current = this->array;
00528 this->arrayLock.readLock().unlock();
00529 } catch (decaf::lang::Exception& ex) {
00530 this->arrayLock.readLock().unlock();
00531 throw;
00532 }
00533
00534 return new ArrayListIterator(current, 0);
00535 }
00536
00537 public:
00538
00539 virtual ListIterator<E>* listIterator() {
00540 decaf::lang::Pointer<Array> current;
00541 this->arrayLock.readLock().lock();
00542 try {
00543 current = this->array;
00544 this->arrayLock.readLock().unlock();
00545 } catch (decaf::lang::Exception& ex) {
00546 this->arrayLock.readLock().unlock();
00547 throw;
00548 }
00549
00550 return new ArrayListIterator(current, 0);
00551 }
00552 virtual ListIterator<E>* listIterator() const {
00553 decaf::lang::Pointer<Array> current;
00554 this->arrayLock.readLock().lock();
00555 try {
00556 current = this->array;
00557 this->arrayLock.readLock().unlock();
00558 } catch (decaf::lang::Exception& ex) {
00559 this->arrayLock.readLock().unlock();
00560 throw;
00561 }
00562
00563 return new ArrayListIterator(current, 0);
00564 }
00565
00566 virtual ListIterator<E>* listIterator(int index) {
00567 decaf::lang::Pointer<Array> current;
00568 this->arrayLock.readLock().lock();
00569 try {
00570 current = this->array;
00571 this->arrayLock.readLock().unlock();
00572 } catch (decaf::lang::Exception& ex) {
00573 this->arrayLock.readLock().unlock();
00574 throw;
00575 }
00576
00577 return new ArrayListIterator(current, index);
00578 }
00579 virtual ListIterator<E>* listIterator(int index) const {
00580 decaf::lang::Pointer<Array> current;
00581 this->arrayLock.readLock().lock();
00582 try {
00583 current = this->array;
00584 this->arrayLock.readLock().unlock();
00585 } catch (decaf::lang::Exception& ex) {
00586 this->arrayLock.readLock().unlock();
00587 throw;
00588 }
00589
00590 return new ArrayListIterator(this->array, index);
00591 }
00592
00593 virtual int indexOf(const E& value) const {
00594 decaf::lang::Pointer<Array> current;
00595 this->arrayLock.readLock().lock();
00596 try {
00597 current = this->array;
00598 this->arrayLock.readLock().unlock();
00599 } catch (decaf::lang::Exception& ex) {
00600 this->arrayLock.readLock().unlock();
00601 throw;
00602 }
00603
00604 for (int i = 0; i < current->size; ++i) {
00605 if (current->elements[i] == value) {
00606 return i;
00607 }
00608 }
00609
00610 return -1;
00611 }
00612
00613 virtual int lastIndexOf(const E& value) const {
00614 decaf::lang::Pointer<Array> current;
00615 this->arrayLock.readLock().lock();
00616 try {
00617 current = this->array;
00618 this->arrayLock.readLock().unlock();
00619 } catch (decaf::lang::Exception& ex) {
00620 this->arrayLock.readLock().unlock();
00621 throw;
00622 }
00623
00624 for (int i = current->size - 1; i >= 0; --i) {
00625 if (current->elements[i] == value) {
00626 return i;
00627 }
00628 }
00629
00630 return -1;
00631 }
00632
00633 virtual E get(int index) const {
00634 decaf::lang::Pointer<Array> current;
00635 this->arrayLock.readLock().lock();
00636 try {
00637 current = this->array;
00638 this->arrayLock.readLock().unlock();
00639 } catch (decaf::lang::Exception& ex) {
00640 this->arrayLock.readLock().unlock();
00641 throw;
00642 }
00643
00644 checkIndexExclusive(index, current->size);
00645 return current->elements[index];
00646 }
00647
00648 virtual E set(int index, const E& element) {
00649 this->arrayLock.writeLock().lock();
00650 try {
00651 decaf::lang::Pointer<Array> oldArray = this->array;
00652 int size = oldArray->size;
00653 this->checkIndexExclusive(index, size);
00654 decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size));
00655 E old = newArray->elements[index];
00656 newArray->elements[index] = element;
00657 this->array.swap(newArray);
00658 this->arrayLock.writeLock().unlock();
00659 return old;
00660 } catch (decaf::lang::Exception& ex) {
00661 this->arrayLock.writeLock().unlock();
00662 throw;
00663 }
00664 }
00665
00666 virtual void add(int index, const E& element) {
00667 this->arrayLock.writeLock().lock();
00668 try {
00669 decaf::lang::Pointer<Array> oldArray = this->array;
00670 int size = oldArray->size;
00671 this->checkIndexInclusive(index, size);
00672 decaf::lang::Pointer<Array> newArray(new Array(size + 1));
00673
00674 if (size > 0) {
00675 decaf::lang::System::arraycopy<E>(oldArray->elements, 0, newArray->elements, 0, index);
00676 }
00677
00678 if (size > index) {
00679 decaf::lang::System::arraycopy<E>(oldArray->elements, index, newArray->elements, index + 1, size - index);
00680 }
00681
00682 newArray->elements[index] = element;
00683 newArray->size = size + 1;
00684 this->array.swap(newArray);
00685 this->arrayLock.writeLock().unlock();
00686 } catch (decaf::lang::Exception& ex) {
00687 this->arrayLock.writeLock().unlock();
00688 throw;
00689 }
00690 }
00691
00692 virtual bool addAll(int index, const Collection<E>& collection) {
00693 this->arrayLock.writeLock().lock();
00694 try {
00695 decaf::lang::Pointer<Array> oldArray = this->array;
00696 int size = oldArray->size;
00697 this->checkIndexInclusive(index, size);
00698 int csize = collection.size();
00699
00700 if (csize == 0) {
00701 this->arrayLock.writeLock().unlock();
00702 return false;
00703 }
00704
00705 decaf::lang::Pointer<Array> newArray(new Array(size + csize));
00706 if (size > 0) {
00707 decaf::lang::System::arraycopy(oldArray->elements, 0, newArray->elements, 0, index);
00708 }
00709
00710 std::auto_ptr<Iterator<E> > iter(collection.iterator());
00711 int pos = index;
00712 while (iter->hasNext()) {
00713 newArray->elements[pos++] = iter->next();
00714 }
00715
00716 if (size > index) {
00717 decaf::lang::System::arraycopy(oldArray->elements, index, newArray->elements, index + csize, size - index);
00718 }
00719 newArray->size = size + csize;
00720 this->array.swap(newArray);
00721 this->arrayLock.writeLock().unlock();
00722 return true;
00723 } catch (decaf::lang::Exception& ex) {
00724 this->arrayLock.writeLock().unlock();
00725 throw;
00726 }
00727 }
00728
00729 virtual E removeAt(int index) {
00730 this->arrayLock.writeLock().lock();
00731 try {
00732 decaf::lang::Pointer<Array> oldArray = this->array;
00733 int size = oldArray->size;
00734 this->checkIndexExclusive(index, size);
00735 E old = oldArray->elements[index];
00736
00737 if (size == 1) {
00738 this->array.reset(new Array());
00739 this->arrayLock.writeLock().unlock();
00740 return old;
00741 }
00742
00743 decaf::lang::Pointer<Array> newArray(new Array(size - 1));
00744 decaf::lang::System::arraycopy<E>(oldArray->elements, 0, newArray->elements, 0, index);
00745
00746 if (size > index) {
00747 decaf::lang::System::arraycopy<E>(oldArray->elements, index + 1, newArray->elements, index, size - index - 1);
00748 }
00749
00750 newArray->size = size - 1;
00751 this->array.swap(newArray);
00752 this->arrayLock.writeLock().unlock();
00753 return old;
00754 } catch (decaf::lang::Exception& ex) {
00755 this->arrayLock.writeLock().unlock();
00756 throw;
00757 }
00758 }
00759
00760 virtual std::string toString() const {
00761 decaf::lang::Pointer<Array> current;
00762 this->arrayLock.readLock().lock();
00763 try {
00764 current = this->array;
00765 this->arrayLock.readLock().unlock();
00766 } catch (decaf::lang::Exception& ex) {
00767 this->arrayLock.readLock().unlock();
00768 throw;
00769 }
00770
00771 std::string result;
00772 return result;
00773 }
00774
00775 public:
00776
00786 bool addIfAbsent(const E& value) {
00787 this->arrayLock.writeLock().lock();
00788 try {
00789 decaf::lang::Pointer<Array> oldArray = this->array;
00790 int size = oldArray->size;
00791
00792 if (size != 0) {
00793 if (this->indexOf(value) != -1) {
00794 this->arrayLock.writeLock().unlock();
00795 return false;
00796 }
00797 }
00798
00799 decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size + 1));
00800 newArray->elements[size] = value;
00801 newArray->size++;
00802 this->array.swap(newArray);
00803 this->arrayLock.writeLock().unlock();
00804 return true;
00805 } catch (decaf::lang::Exception& ex) {
00806 this->arrayLock.writeLock().unlock();
00807 throw;
00808 }
00809 }
00810
00821 int addAllAbsent(const Collection<E>& collection) {
00822
00823 if (collection.size() == 0) {
00824 return 0;
00825 }
00826
00827 this->arrayLock.writeLock().lock();
00828 try {
00829 decaf::lang::Pointer<Array> oldArray = this->array;
00830 int size = oldArray->size;
00831 decaf::lang::Pointer<Array> buffer(new Array(collection.size()));
00832 int count = 0;
00833
00834 std::auto_ptr<Iterator<E> > iter(collection.iterator());
00835 while (iter->hasNext()) {
00836 E value = iter->next();
00837 if (this->indexOf(value) == -1) {
00838 buffer->elements[count++] = value;
00839 buffer->size++;
00840 }
00841 }
00842
00843 decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size + count));
00844 decaf::lang::System::arraycopy(buffer->elements, 0, newArray->elements, size, count);
00845 newArray->size = size + count;
00846 this->array.swap(newArray);
00847 this->arrayLock.writeLock().unlock();
00848 return count;
00849 } catch (decaf::lang::Exception& ex) {
00850 this->arrayLock.writeLock().unlock();
00851 throw;
00852 }
00853 }
00854
00868 int lastIndexOf(const E& value, int index) {
00869 decaf::lang::Pointer<Array> current;
00870 this->arrayLock.readLock().lock();
00871 try {
00872 current = this->array;
00873 this->arrayLock.readLock().unlock();
00874 } catch (decaf::lang::Exception& ex) {
00875 this->arrayLock.readLock().unlock();
00876 throw;
00877 }
00878
00879
00880 if (index >= current->size) {
00881 throw decaf::lang::exceptions::IndexOutOfBoundsException(
00882 __FILE__, __LINE__, "Index given %d, actual size %d", index, current->size);
00883 }
00884
00885 for (int i = index - 1; i >= 0; --i) {
00886 if (current->elements[i] == value) {
00887 return i;
00888 }
00889 }
00890
00891 return -1;
00892 }
00893
00907 int indexOf(const E& value, int index) const {
00908 decaf::lang::Pointer<Array> current;
00909 this->arrayLock.readLock().lock();
00910 try {
00911 current = this->array;
00912 this->arrayLock.readLock().unlock();
00913 } catch (decaf::lang::Exception& ex) {
00914 this->arrayLock.readLock().unlock();
00915 throw;
00916 }
00917
00918
00919 if (index < 0) {
00920 throw decaf::lang::exceptions::IndexOutOfBoundsException(
00921 __FILE__, __LINE__, "Index given %d, actual size %d", index, current->size);
00922 }
00923
00924 for (int i = index; i < current->size; ++i) {
00925 if (current->elements[i] == value) {
00926 return i;
00927 }
00928 }
00929
00930 return -1;
00931 }
00932
00933 public:
00934
00935 virtual void lock() {
00936 this->arrayLock.writeLock().lock();
00937 }
00938
00939 virtual bool tryLock() {
00940 return this->arrayLock.writeLock().tryLock();
00941 }
00942
00943 virtual void unlock() {
00944 this->arrayLock.writeLock().unlock();
00945 }
00946
00947 virtual void wait() {
00948 this->condition->await();
00949 }
00950
00951 virtual void wait(long long millisecs) {
00952 this->condition->await(millisecs, decaf::util::concurrent::TimeUnit::MILLISECONDS);
00953 }
00954
00955 virtual void wait( long long millisecs, int nanos ) {
00956 long long timeout = decaf::util::concurrent::TimeUnit::MILLISECONDS.toNanos(millisecs) + nanos;
00957 this->condition->awaitNanos(timeout);
00958 }
00959
00960 virtual void notify() {
00961 this->condition->signal();
00962 }
00963
00964 virtual void notifyAll() {
00965 this->condition->signalAll();
00966 }
00967
00968 private:
00969
00970 void doCopyCollection(const Collection<E>& collection) {
00971
00972 if ((void*) this == &collection || collection.isEmpty()) {
00973 return;
00974 }
00975
00976 this->arrayLock.writeLock().lock();
00977 try {
00978 decaf::lang::Pointer<Array> oldArray = this->array;
00979 int size = oldArray->size;
00980
00981 decaf::lang::Pointer<Array> buffer(new Array(*oldArray, size + collection.size()));
00982 std::auto_ptr<Iterator<E> > iter(collection.iterator());
00983 int index = 0;
00984 while (iter->hasNext()) {
00985 buffer->elements[size + index++] = iter->next();
00986 buffer->size++;
00987 }
00988
00989 this->array.swap(buffer);
00990 this->arrayLock.writeLock().unlock();
00991 } catch (decaf::lang::Exception& ex) {
00992 this->arrayLock.writeLock().unlock();
00993 throw;
00994 }
00995 }
00996
00997 static void checkIndexInclusive(int index, int size) {
00998 if (index < 0 || index > size) {
00999 throw decaf::lang::exceptions::IndexOutOfBoundsException(
01000 __FILE__, __LINE__, "Index is %d, size is %d", index, size);
01001 }
01002 }
01003
01004 static void checkIndexExclusive(int index, int size) {
01005 if (index < 0 || index >= size) {
01006 throw decaf::lang::exceptions::IndexOutOfBoundsException(
01007 __FILE__, __LINE__, "Index is %d, size is %d", index, size);
01008 }
01009 }
01010
01011 };
01012
01013 }}}
01014
01015 #endif