activemq-cpp-3.8.2
CopyOnWriteArrayList.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef _DECAF_UTIL_CONCURRENT_COPYONWRITEARRAYLIST_H_
19 #define _DECAF_UTIL_CONCURRENT_COPYONWRITEARRAYLIST_H_
20 
25 #include <decaf/lang/System.h>
26 #include <decaf/lang/Math.h>
27 #include <decaf/lang/Pointer.h>
28 #include <decaf/util/List.h>
29 
30 namespace decaf {
31 namespace util {
32 namespace concurrent {
33 
34  template< typename E >
35  class CopyOnWriteArrayList : public List<E> {
36  private:
37 
38  struct Array {
39 
40  int size;
41  int capacity;
42  E* elements;
43 
44  Array() : size(0), capacity(0), elements(NULL) {
45  }
46 
47  Array(int capacity) : size(0), capacity(0), elements(NULL) {
48  reserve(capacity);
49  }
50 
51  Array(const Array& src, int capacity) : size(0), capacity(0), elements(NULL) {
52  reserve(decaf::lang::Math::max(src.size, capacity));
53  if (src.size > 0) {
54  decaf::lang::System::arraycopy<E>(src.elements, 0, this->elements, 0, src.size);
55  }
56  this->size = src.size;
57  }
58 
59  ~Array() {
60  delete [] elements;
61  }
62 
63  void reserve(int requested) {
64  if (capacity < requested) {
65  // growth as a factor of 1.5
66  int newlen = decaf::lang::Math::max((int)(capacity*1.5), requested);
67  E* newbuf = newlen ? new E[newlen] : NULL;
68 
69  if (this->elements != NULL) {
70  decaf::lang::System::arraycopy<E>(this->elements, 0, newbuf, 0, size);
71  }
72 
73  delete[] this->elements;
74  this->elements = newbuf;
75  capacity = newlen;
76  }
77  }
78 
79  private:
80 
81  Array(const Array&);
82  Array operator= (const Array&);
83 
84  };
85 
86  private:
87 
91 
92  public:
93 
94  class ArrayListIterator : public ListIterator<E> {
95  private:
96 
98  int position;
99 
100  private:
101 
103  ArrayListIterator& operator=(const ArrayListIterator&);
104 
105  public:
106 
108  ListIterator<E> (), array(array), position(index) {
109 
110  if (position < 0 || position > array->size) {
112  __FILE__, __LINE__, "Iterator created with invalid index.");
113  }
114  }
115 
116  virtual ~ArrayListIterator() {
117  this->array.reset(NULL);
118  };
119 
120  virtual E next() {
121  if (position >= array->size) {
122  throw NoSuchElementException();
123  }
124 
125  return this->array->elements[position++];
126  }
127 
128  virtual bool hasNext() const {
129  return this->position < array->size;
130  }
131 
132  virtual void remove() {
134  __FILE__, __LINE__, "CopyOnWriteArrayList Iterator cannot remove elements.");
135  }
136 
137  virtual void add(const E& e DECAF_UNUSED ) {
139  __FILE__, __LINE__, "CopyOnWriteArrayList Iterator cannot add elements.");
140  }
141 
142  virtual void set(const E& e DECAF_UNUSED ) {
144  __FILE__, __LINE__, "CopyOnWriteArrayList Iterator cannot add elements.");
145  }
146 
147  virtual bool hasPrevious() const {
148  return this->position > 0;
149  }
150 
151  virtual E previous() {
152  if (position <= 0) {
153  throw NoSuchElementException();
154  }
155 
156  return this->array->elements[position--];
157  }
158 
159  virtual int nextIndex() const {
160  return this->position;
161  }
162 
163  virtual int previousIndex() const {
164  return this->position - 1;
165  }
166 
167  };
168 
169  public:
170 
171  CopyOnWriteArrayList() : List<E>(), arrayLock(), condition(), array(new Array()) {
172  this->condition.reset(arrayLock.writeLock().newCondition());
173  }
174 
175  CopyOnWriteArrayList(const Collection<E>& collection) : List<E>(), arrayLock(), condition(), array(new Array()) {
176  this->condition.reset(arrayLock.writeLock().newCondition());
177  this->doCopyCollection(collection);
178  }
179 
180  CopyOnWriteArrayList(const CopyOnWriteArrayList<E>& collection) : List<E>(), arrayLock(), condition(), array(new Array()) {
181  this->condition.reset(arrayLock.writeLock().newCondition());
182  this->doCopyCollection(collection);
183  }
184 
185  CopyOnWriteArrayList(const E* array, int size) : List<E>(), arrayLock(), condition(), array(new Array()) {
186  this->condition.reset(arrayLock.writeLock().newCondition());
187  decaf::lang::Pointer<Array> temp(new Array(size));
188  for (int i = 0; i < size; ++i) {
189  temp->elements[i] = array[i];
190  temp->size++;
191  }
192  this->array.swap(temp);
193  }
194 
196  this->array.reset(NULL);
197  }
198 
199  public:
200 
202  this->arrayLock.writeLock().lock();
203  try {
204  this->clear();
205  this->doCopyCollection(list);
206  } catch (decaf::lang::Exception& ex) {
207  this->writeLock.unlock();
208  throw;
209  }
210 
211  this->arrayLock.writeLock().unlock();
212  return *this;
213  }
214 
216  this->arrayLock.writeLock().lock();
217  try {
218  this->clear();
219  this->doCopyCollection(list);
220  } catch (decaf::lang::Exception& ex) {
221  this->writeLock.unlock();
222  throw;
223  }
224 
225  this->arrayLock.writeLock().unlock();
226  return *this;
227  }
228 
229  public: // Collections API
230 
231  virtual void copy(const Collection<E>& collection) {
232  this->arrayLock.writeLock().lock();
233  try {
234  this->clear();
235  this->doCopyCollection(collection);
236  this->arrayLock.writeLock().unlock();
237  } catch (decaf::lang::Exception& ex) {
238  this->arrayLock.writeLock().unlock();
239  throw;
240  }
241  }
242 
243  virtual bool add(const E& value) {
244  this->arrayLock.writeLock().lock();
245  try {
246  decaf::lang::Pointer<Array> oldArray = this->array;
247  int size = oldArray->size;
248  decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size + 1));
249  newArray->elements[size] = value;
250  newArray->size++;
251  this->array.swap(newArray);
252  this->arrayLock.writeLock().unlock();
253  return true;
254  } catch (decaf::lang::Exception& ex) {
255  this->arrayLock.writeLock().unlock();
256  throw;
257  }
258  }
259 
260  virtual bool addAll(const Collection<E>& collection) {
261  this->arrayLock.writeLock().lock();
262  try {
263  decaf::lang::Pointer<Array> oldArray = this->array;
264  int size = oldArray->size;
265  decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size + collection.size()));
266  std::auto_ptr<Iterator<E> > iter(collection.iterator());
267  while (iter->hasNext()) {
268  newArray->elements[newArray->size++] = iter->next();
269  }
270  this->array.swap(newArray);
271  this->arrayLock.writeLock().unlock();
272  return true;
273  } catch (decaf::lang::Exception& ex) {
274  this->arrayLock.writeLock().unlock();
275  throw;
276  }
277  }
278 
279  virtual void clear() {
280  this->arrayLock.writeLock().lock();
281  try {
282  decaf::lang::Pointer<Array> newArray(new Array());
283  this->array.swap(newArray);
284  } catch (decaf::lang::Exception& ex) {
285  this->arrayLock.writeLock().unlock();
286  throw;
287  }
288 
289  this->arrayLock.writeLock().unlock();
290  }
291 
292  virtual bool contains(const E& value) const {
294  this->arrayLock.readLock().lock();
295  try {
296  current = this->array;
297  this->arrayLock.readLock().unlock();
298  } catch (decaf::lang::Exception& ex) {
299  this->arrayLock.readLock().unlock();
300  throw;
301  }
302 
303  for (int i = 0; i < current->size; ++i) {
304  if (current->elements[i] == value) {
305  return true;
306  }
307  }
308 
309  return false;
310  }
311 
312  virtual bool containsAll(const Collection<E>& collection) const {
313  std::auto_ptr<Iterator<E> > iter(collection.iterator());
314  while (iter->hasNext()) {
315  E next = iter->next();
316  if (!this->contains(next)) {
317  return false;
318  }
319  }
320 
321  return true;
322  }
323 
324  virtual bool equals(const Collection<E>& collection) const {
325 
326  if ((void*) this == &collection) {
327  return true;
328  }
329 
330  const List<E>* asList = dynamic_cast<const List<E>*> (&collection);
331  if (asList == NULL) {
332  return false;
333  }
334 
335  if (this->size() != asList->size()) {
336  return false;
337  }
338 
339  std::auto_ptr<Iterator<E> > thisIter(this->iterator());
340  std::auto_ptr<Iterator<E> > otherIter(asList->iterator());
341 
342  while (thisIter->hasNext()) {
343  if (!otherIter->hasNext()) {
344  return false;
345  }
346 
347  E myNext = thisIter->next();
348  E otherNext = otherIter->next();
349 
350  if (myNext != otherNext) {
351  return false;
352  }
353  }
354 
355  if (otherIter->hasNext()) {
356  return false;
357  }
358 
359  return true;
360  }
361 
362  virtual bool isEmpty() const {
364  this->arrayLock.readLock().lock();
365  try {
366  current = this->array;
367  this->arrayLock.readLock().unlock();
368  } catch (decaf::lang::Exception& ex) {
369  this->arrayLock.readLock().unlock();
370  throw;
371  }
372 
373  return current->size == 0;
374  }
375 
376  virtual bool remove(const E& value) {
377  this->arrayLock.writeLock().lock();
378  try {
379  int index = this->indexOf(value);
380  if (index == -1) {
381  this->arrayLock.writeLock().unlock();
382  return false;
383  }
384  this->removeAt(index);
385  this->arrayLock.writeLock().unlock();
386  return true;
387  } catch (decaf::lang::Exception& ex) {
388  this->arrayLock.writeLock().unlock();
389  throw;
390  }
391  }
392 
393  virtual bool removeAll(const Collection<E>& collection) {
394  if (collection.isEmpty()) {
395  return false;
396  }
397 
398  this->arrayLock.writeLock().lock();
399  try {
400  decaf::lang::Pointer<Array> oldArray = this->array;
401  int size = oldArray->size;
402 
403  if (size == 0) {
404  this->arrayLock.writeLock().unlock();
405  return false;
406  }
407 
408  decaf::lang::Pointer<Array> buffer(new Array(size));
409  int count = 0;
410  for (int i = 0; i < size; ++i) {
411  E value = oldArray->elements[i];
412  if (!collection.contains(value)) {
413  buffer->elements[count++] = value;
414  buffer->size++;
415  }
416  }
417 
418  if (count == 0) {
419  this->array.reset(new Array());
420  } else {
421  decaf::lang::Pointer<Array> newArray(new Array(*buffer, count));
422  this->array.swap(newArray);
423  }
424 
425  this->arrayLock.writeLock().unlock();
426  return true;
427  } catch (decaf::lang::Exception& ex) {
428  this->arrayLock.writeLock().unlock();
429  throw;
430  }
431  }
432 
433  virtual bool retainAll(const Collection<E>& collection) {
434  this->arrayLock.writeLock().lock();
435  try {
436 
437  decaf::lang::Pointer<Array> oldArray = this->array;
438  int size = oldArray->size;
439 
440  if (size == 0) {
441  this->arrayLock.writeLock().unlock();
442  return false;
443  }
444 
445  if (collection.isEmpty()) {
446  this->array.reset(new Array());
447  this->arrayLock.writeLock().unlock();
448  return true;
449  }
450 
451  decaf::lang::Pointer<Array> buffer(new Array(size));
452  int count = 0;
453 
454  for (int i = 0; i < size; ++i) {
455  E value = oldArray->elements[i];
456  if (collection.contains(value)) {
457  buffer->elements[count++] = value;
458  buffer->size++;
459  }
460  }
461 
462  if (count == 0) {
463  this->array.reset(new Array());
464  } else {
465  this->array.swap(buffer);
466  }
467 
468  this->arrayLock.writeLock().unlock();
469  return true;
470  } catch (decaf::lang::Exception& ex) {
471  this->arrayLock.writeLock().unlock();
472  throw;
473  }
474  }
475 
476  virtual int size() const {
478  this->arrayLock.readLock().lock();
479  try {
480  current = this->array;
481  this->arrayLock.readLock().unlock();
482  } catch (decaf::lang::Exception& ex) {
483  this->arrayLock.readLock().unlock();
484  throw;
485  }
486 
487  return current->size;
488  }
489 
490  virtual std::vector<E> toArray() const {
492  this->arrayLock.readLock().lock();
493  try {
494  current = this->array;
495  this->arrayLock.readLock().unlock();
496  } catch (decaf::lang::Exception& ex) {
497  this->arrayLock.readLock().unlock();
498  throw;
499  }
500  std::vector<E> result( current->size );
501  for( int i = 0; i < current->size; ++i ) {
502  result[i] = current->elements[i];
503  }
504 
505  return result;
506  }
507 
508  public: // Iterable API
509 
512  this->arrayLock.readLock().lock();
513  try {
514  current = this->array;
515  this->arrayLock.readLock().unlock();
516  } catch (decaf::lang::Exception& ex) {
517  this->arrayLock.readLock().unlock();
518  throw;
519  }
520 
521  return new ArrayListIterator(current, 0);
522  }
525  this->arrayLock.readLock().lock();
526  try {
527  current = this->array;
528  this->arrayLock.readLock().unlock();
529  } catch (decaf::lang::Exception& ex) {
530  this->arrayLock.readLock().unlock();
531  throw;
532  }
533 
534  return new ArrayListIterator(current, 0);
535  }
536 
537  public: // List API
538 
541  this->arrayLock.readLock().lock();
542  try {
543  current = this->array;
544  this->arrayLock.readLock().unlock();
545  } catch (decaf::lang::Exception& ex) {
546  this->arrayLock.readLock().unlock();
547  throw;
548  }
549 
550  return new ArrayListIterator(current, 0);
551  }
552  virtual ListIterator<E>* listIterator() const {
554  this->arrayLock.readLock().lock();
555  try {
556  current = this->array;
557  this->arrayLock.readLock().unlock();
558  } catch (decaf::lang::Exception& ex) {
559  this->arrayLock.readLock().unlock();
560  throw;
561  }
562 
563  return new ArrayListIterator(current, 0);
564  }
565 
566  virtual ListIterator<E>* listIterator(int index) {
568  this->arrayLock.readLock().lock();
569  try {
570  current = this->array;
571  this->arrayLock.readLock().unlock();
572  } catch (decaf::lang::Exception& ex) {
573  this->arrayLock.readLock().unlock();
574  throw;
575  }
576 
577  return new ArrayListIterator(current, index);
578  }
579  virtual ListIterator<E>* listIterator(int index) const {
581  this->arrayLock.readLock().lock();
582  try {
583  current = this->array;
584  this->arrayLock.readLock().unlock();
585  } catch (decaf::lang::Exception& ex) {
586  this->arrayLock.readLock().unlock();
587  throw;
588  }
589 
590  return new ArrayListIterator(this->array, index);
591  }
592 
593  virtual int indexOf(const E& value) const {
595  this->arrayLock.readLock().lock();
596  try {
597  current = this->array;
598  this->arrayLock.readLock().unlock();
599  } catch (decaf::lang::Exception& ex) {
600  this->arrayLock.readLock().unlock();
601  throw;
602  }
603 
604  for (int i = 0; i < current->size; ++i) {
605  if (current->elements[i] == value) {
606  return i;
607  }
608  }
609 
610  return -1;
611  }
612 
613  virtual int lastIndexOf(const E& value) const {
615  this->arrayLock.readLock().lock();
616  try {
617  current = this->array;
618  this->arrayLock.readLock().unlock();
619  } catch (decaf::lang::Exception& ex) {
620  this->arrayLock.readLock().unlock();
621  throw;
622  }
623 
624  for (int i = current->size - 1; i >= 0; --i) {
625  if (current->elements[i] == value) {
626  return i;
627  }
628  }
629 
630  return -1;
631  }
632 
633  virtual E get(int index) const {
635  this->arrayLock.readLock().lock();
636  try {
637  current = this->array;
638  this->arrayLock.readLock().unlock();
639  } catch (decaf::lang::Exception& ex) {
640  this->arrayLock.readLock().unlock();
641  throw;
642  }
643 
644  checkIndexExclusive(index, current->size);
645  return current->elements[index];
646  }
647 
648  virtual E set(int index, const E& element) {
649  this->arrayLock.writeLock().lock();
650  try {
651  decaf::lang::Pointer<Array> oldArray = this->array;
652  int size = oldArray->size;
653  this->checkIndexExclusive(index, size);
654  decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size));
655  E old = newArray->elements[index];
656  newArray->elements[index] = element;
657  this->array.swap(newArray);
658  this->arrayLock.writeLock().unlock();
659  return old;
660  } catch (decaf::lang::Exception& ex) {
661  this->arrayLock.writeLock().unlock();
662  throw;
663  }
664  }
665 
666  virtual void add(int index, const E& element) {
667  this->arrayLock.writeLock().lock();
668  try {
669  decaf::lang::Pointer<Array> oldArray = this->array;
670  int size = oldArray->size;
671  this->checkIndexInclusive(index, size);
672  decaf::lang::Pointer<Array> newArray(new Array(size + 1));
673 
674  if (size > 0) {
675  decaf::lang::System::arraycopy<E>(oldArray->elements, 0, newArray->elements, 0, index);
676  }
677 
678  if (size > index) {
679  decaf::lang::System::arraycopy<E>(oldArray->elements, index, newArray->elements, index + 1, size - index);
680  }
681 
682  newArray->elements[index] = element;
683  newArray->size = size + 1;
684  this->array.swap(newArray);
685  this->arrayLock.writeLock().unlock();
686  } catch (decaf::lang::Exception& ex) {
687  this->arrayLock.writeLock().unlock();
688  throw;
689  }
690  }
691 
692  virtual bool addAll(int index, const Collection<E>& collection) {
693  this->arrayLock.writeLock().lock();
694  try {
695  decaf::lang::Pointer<Array> oldArray = this->array;
696  int size = oldArray->size;
697  this->checkIndexInclusive(index, size);
698  int csize = collection.size();
699 
700  if (csize == 0) {
701  this->arrayLock.writeLock().unlock();
702  return false;
703  }
704 
705  decaf::lang::Pointer<Array> newArray(new Array(size + csize));
706  if (size > 0) {
707  decaf::lang::System::arraycopy(oldArray->elements, 0, newArray->elements, 0, index);
708  }
709 
710  std::auto_ptr<Iterator<E> > iter(collection.iterator());
711  int pos = index;
712  while (iter->hasNext()) {
713  newArray->elements[pos++] = iter->next();
714  }
715 
716  if (size > index) {
717  decaf::lang::System::arraycopy(oldArray->elements, index, newArray->elements, index + csize, size - index);
718  }
719  newArray->size = size + csize;
720  this->array.swap(newArray);
721  this->arrayLock.writeLock().unlock();
722  return true;
723  } catch (decaf::lang::Exception& ex) {
724  this->arrayLock.writeLock().unlock();
725  throw;
726  }
727  }
728 
729  virtual E removeAt(int index) {
730  this->arrayLock.writeLock().lock();
731  try {
732  decaf::lang::Pointer<Array> oldArray = this->array;
733  int size = oldArray->size;
734  this->checkIndexExclusive(index, size);
735  E old = oldArray->elements[index];
736 
737  if (size == 1) {
738  this->array.reset(new Array());
739  this->arrayLock.writeLock().unlock();
740  return old;
741  }
742 
743  decaf::lang::Pointer<Array> newArray(new Array(size - 1));
744  decaf::lang::System::arraycopy<E>(oldArray->elements, 0, newArray->elements, 0, index);
745 
746  if (size > index) {
747  decaf::lang::System::arraycopy<E>(oldArray->elements, index + 1, newArray->elements, index, size - index - 1);
748  }
749 
750  newArray->size = size - 1;
751  this->array.swap(newArray);
752  this->arrayLock.writeLock().unlock();
753  return old;
754  } catch (decaf::lang::Exception& ex) {
755  this->arrayLock.writeLock().unlock();
756  throw;
757  }
758  }
759 
760  virtual std::string toString() const {
762  this->arrayLock.readLock().lock();
763  try {
764  current = this->array;
765  this->arrayLock.readLock().unlock();
766  } catch (decaf::lang::Exception& ex) {
767  this->arrayLock.readLock().unlock();
768  throw;
769  }
770 
771  std::string result;
772  return result;
773  }
774 
775  public:
776 
786  bool addIfAbsent(const E& value) {
787  this->arrayLock.writeLock().lock();
788  try {
789  decaf::lang::Pointer<Array> oldArray = this->array;
790  int size = oldArray->size;
791 
792  if (size != 0) {
793  if (this->indexOf(value) != -1) {
794  this->arrayLock.writeLock().unlock();
795  return false;
796  }
797  }
798 
799  decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size + 1));
800  newArray->elements[size] = value;
801  newArray->size++;
802  this->array.swap(newArray);
803  this->arrayLock.writeLock().unlock();
804  return true;
805  } catch (decaf::lang::Exception& ex) {
806  this->arrayLock.writeLock().unlock();
807  throw;
808  }
809  }
810 
821  int addAllAbsent(const Collection<E>& collection) {
822 
823  if (collection.size() == 0) {
824  return 0;
825  }
826 
827  this->arrayLock.writeLock().lock();
828  try {
829  decaf::lang::Pointer<Array> oldArray = this->array;
830  int size = oldArray->size;
831  decaf::lang::Pointer<Array> buffer(new Array(collection.size()));
832  int count = 0;
833 
834  std::auto_ptr<Iterator<E> > iter(collection.iterator());
835  while (iter->hasNext()) {
836  E value = iter->next();
837  if (this->indexOf(value) == -1) {
838  buffer->elements[count++] = value;
839  buffer->size++;
840  }
841  }
842 
843  decaf::lang::Pointer<Array> newArray(new Array(*oldArray, size + count));
844  decaf::lang::System::arraycopy(buffer->elements, 0, newArray->elements, size, count);
845  newArray->size = size + count;
846  this->array.swap(newArray);
847  this->arrayLock.writeLock().unlock();
848  return count;
849  } catch (decaf::lang::Exception& ex) {
850  this->arrayLock.writeLock().unlock();
851  throw;
852  }
853  }
854 
868  int lastIndexOf(const E& value, int index) {
870  this->arrayLock.readLock().lock();
871  try {
872  current = this->array;
873  this->arrayLock.readLock().unlock();
874  } catch (decaf::lang::Exception& ex) {
875  this->arrayLock.readLock().unlock();
876  throw;
877  }
878 
879 
880  if (index >= current->size) {
882  __FILE__, __LINE__, "Index given %d, actual size %d", index, current->size);
883  }
884 
885  for (int i = index - 1; i >= 0; --i) {
886  if (current->elements[i] == value) {
887  return i;
888  }
889  }
890 
891  return -1;
892  }
893 
907  int indexOf(const E& value, int index) const {
909  this->arrayLock.readLock().lock();
910  try {
911  current = this->array;
912  this->arrayLock.readLock().unlock();
913  } catch (decaf::lang::Exception& ex) {
914  this->arrayLock.readLock().unlock();
915  throw;
916  }
917 
918 
919  if (index < 0) {
921  __FILE__, __LINE__, "Index given %d, actual size %d", index, current->size);
922  }
923 
924  for (int i = index; i < current->size; ++i) {
925  if (current->elements[i] == value) {
926  return i;
927  }
928  }
929 
930  return -1;
931  }
932 
933  public: // Synchronizable
934 
935  virtual void lock() {
936  this->arrayLock.writeLock().lock();
937  }
938 
939  virtual bool tryLock() {
940  return this->arrayLock.writeLock().tryLock();
941  }
942 
943  virtual void unlock() {
944  this->arrayLock.writeLock().unlock();
945  }
946 
947  virtual void wait() {
948  this->condition->await();
949  }
950 
951  virtual void wait(long long millisecs) {
952  this->condition->await(millisecs, decaf::util::concurrent::TimeUnit::MILLISECONDS);
953  }
954 
955  virtual void wait( long long millisecs, int nanos ) {
956  long long timeout = decaf::util::concurrent::TimeUnit::MILLISECONDS.toNanos(millisecs) + nanos;
957  this->condition->awaitNanos(timeout);
958  }
959 
960  virtual void notify() {
961  this->condition->signal();
962  }
963 
964  virtual void notifyAll() {
965  this->condition->signalAll();
966  }
967 
968  private:
969 
970  void doCopyCollection(const Collection<E>& collection) {
971 
972  if ((void*) this == &collection || collection.isEmpty()) {
973  return;
974  }
975 
976  this->arrayLock.writeLock().lock();
977  try {
978  decaf::lang::Pointer<Array> oldArray = this->array;
979  int size = oldArray->size;
980 
981  decaf::lang::Pointer<Array> buffer(new Array(*oldArray, size + collection.size()));
982  std::auto_ptr<Iterator<E> > iter(collection.iterator());
983  int index = 0;
984  while (iter->hasNext()) {
985  buffer->elements[size + index++] = iter->next();
986  buffer->size++;
987  }
988 
989  this->array.swap(buffer);
990  this->arrayLock.writeLock().unlock();
991  } catch (decaf::lang::Exception& ex) {
992  this->arrayLock.writeLock().unlock();
993  throw;
994  }
995  }
996 
997  static void checkIndexInclusive(int index, int size) {
998  if (index < 0 || index > size) {
1000  __FILE__, __LINE__, "Index is %d, size is %d", index, size);
1001  }
1002  }
1003 
1004  static void checkIndexExclusive(int index, int size) {
1005  if (index < 0 || index >= size) {
1007  __FILE__, __LINE__, "Index is %d, size is %d", index, size);
1008  }
1009  }
1010 
1011  };
1012 
1013 }}}
1014 
1015 #endif /* _DECAF_UTIL_CONCURRENT_COPYONWRITEARRAYLIST_H_ */
void reset(T *value=NULL)
Resets the Pointer to hold the new value.
Definition: Pointer.h:161
virtual ListIterator< E > * listIterator(int index)
Definition: CopyOnWriteArrayList.h:566
The root interface in the collection hierarchy.
Definition: Collection.h:68
virtual E next()
Returns the next element in the iteration.
Definition: CopyOnWriteArrayList.h:120
virtual ListIterator< E > * listIterator()
Definition: CopyOnWriteArrayList.h:539
virtual void notifyAll()
Signals the waiters on this object that it can now wake up and continue.
Definition: CopyOnWriteArrayList.h:964
ArrayListIterator(decaf::lang::Pointer< Array > array, int index)
Definition: CopyOnWriteArrayList.h:107
CopyOnWriteArrayList(const CopyOnWriteArrayList< E > &collection)
Definition: CopyOnWriteArrayList.h:180
virtual bool isEmpty() const
Definition: CopyOnWriteArrayList.h:362
virtual bool containsAll(const Collection< E > &collection) const
Returns true if this collection contains all of the elements in the specified collection.
Definition: CopyOnWriteArrayList.h:312
virtual void set(const E &e DECAF_UNUSED)
Definition: CopyOnWriteArrayList.h:142
virtual ListIterator< E > * listIterator() const
Definition: CopyOnWriteArrayList.h:552
virtual void wait()
Waits on a signal from this object, which is generated by a call to Notify.
Definition: CopyOnWriteArrayList.h:947
#define NULL
Definition: Config.h:33
virtual bool isEmpty() const =0
CopyOnWriteArrayList< E > & operator=(const CopyOnWriteArrayList< E > &list)
Definition: CopyOnWriteArrayList.h:201
virtual decaf::util::concurrent::locks::Lock & readLock()
Returns the lock used for reading.the lock used for reading.
virtual E previous()
Returns the previous element in the list.
Definition: CopyOnWriteArrayList.h:151
virtual void signal()=0
Wakes up one waiting thread.
virtual bool retainAll(const Collection< E > &collection)
Retains only the elements in this collection that are contained in the specified collection (optional...
Definition: CopyOnWriteArrayList.h:433
virtual bool hasNext() const
Returns true if the iteration has more elements.
Definition: CopyOnWriteArrayList.h:128
Definition: CopyOnWriteArrayList.h:35
static void arraycopy(const char *src, std::size_t srcPos, char *dest, std::size_t destPos, std::size_t length)
Copies the number of elements specified by length from the source array starting at the given source ...
An iterator for lists that allows the programmer to traverse the list in either direction, modify the list during iteration, and obtain the iterator's current position in the list.
Definition: ListIterator.h:38
virtual int size() const =0
Returns the number of elements in this collection.
CopyOnWriteArrayList< E > & operator=(const Collection< E > &list)
Definition: CopyOnWriteArrayList.h:215
virtual void add(const E &e DECAF_UNUSED)
Definition: CopyOnWriteArrayList.h:137
virtual bool contains(const E &value) const
Returns true if this collection contains the specified element.
Definition: CopyOnWriteArrayList.h:292
virtual std::string toString() const
Definition: CopyOnWriteArrayList.h:760
virtual bool addAll(const Collection< E > &collection)
Adds all of the elements in the specified collection to this collection.
Definition: CopyOnWriteArrayList.h:260
Defines an object that can be used to iterate over the elements of a collection.
Definition: Iterator.h:34
virtual E set(int index, const E &element)
Replaces the element at the specified position in this list with the specified element.
Definition: CopyOnWriteArrayList.h:648
virtual int indexOf(const E &value) const
Returns the index of the first occurrence of the specified element in this list, or -1 if this list d...
Definition: CopyOnWriteArrayList.h:593
Definition: IndexOutOfBoundsException.h:31
Definition: UnsupportedOperationException.h:32
virtual bool tryLock()=0
Acquires the lock only if it is free at the time of invocation.
int addAllAbsent(const Collection< E > &collection)
Every element in the given collection that is not already contained in this Collection is added to th...
Definition: CopyOnWriteArrayList.h:821
static const TimeUnit MILLISECONDS
Definition: TimeUnit.h:79
virtual decaf::util::Iterator< E > * iterator()
Definition: CopyOnWriteArrayList.h:510
virtual void wait(long long millisecs, int nanos)
Waits on a signal from this object, which is generated by a call to Notify.
Definition: CopyOnWriteArrayList.h:955
virtual bool contains(const E &value) const =0
Returns true if this collection contains the specified element.
virtual void lock()=0
Acquires the lock.
virtual void clear()
Removes all of the elements from this collection (optional operation).
Definition: CopyOnWriteArrayList.h:279
virtual int previousIndex() const
Returns the index of the element that would be returned by a subsequent call to previous.
Definition: CopyOnWriteArrayList.h:163
virtual decaf::util::Iterator< E > * iterator() const
Definition: CopyOnWriteArrayList.h:523
int indexOf(const E &value, int index) const
Searches the List starting from the specified index and returns the index of the first item in the li...
Definition: CopyOnWriteArrayList.h:907
virtual std::vector< E > toArray() const
Returns an array containing all of the elements in this collection.
Definition: CopyOnWriteArrayList.h:490
virtual int nextIndex() const
Returns the index of the element that would be returned by a subsequent call to next.
Definition: CopyOnWriteArrayList.h:159
virtual bool equals(const Collection< E > &collection) const
Compares the passed collection to this one, if they contain the same elements, i.e.
Definition: CopyOnWriteArrayList.h:324
virtual bool addAll(int index, const Collection< E > &collection)
Inserts all of the elements in the specified collection into this list at the specified position (opt...
Definition: CopyOnWriteArrayList.h:692
virtual decaf::util::Iterator< E > * iterator()=0
virtual int size() const
Returns the number of elements in this collection.
Definition: CopyOnWriteArrayList.h:476
virtual bool add(const E &value)
Returns true if this collection changed as a result of the call.
Definition: CopyOnWriteArrayList.h:243
virtual bool hasPrevious() const
Returns true if this list iterator has more elements when traversing the list in the reverse directio...
Definition: CopyOnWriteArrayList.h:147
virtual void add(int index, const E &element)
Inserts the specified element at the specified position in this list.
Definition: CopyOnWriteArrayList.h:666
virtual E removeAt(int index)
Removes the element at the specified position in this list.
Definition: CopyOnWriteArrayList.h:729
bool addIfAbsent(const E &value)
Adds the given value to the end of this List if it is not already contained in this List...
Definition: CopyOnWriteArrayList.h:786
static short max(short a, short b)
Returns the larger of two short values.
Definition: Math.h:426
virtual ~ArrayListIterator()
Definition: CopyOnWriteArrayList.h:116
virtual bool tryLock()
Attempts to Lock the object, if the lock is already held by another thread than this method returns f...
Definition: CopyOnWriteArrayList.h:939
virtual Condition * newCondition()=0
Returns a new Condition instance that is bound to this Lock instance.
virtual long long awaitNanos(long long nanosTimeout)=0
Causes the current thread to wait until it is signaled or interrupted, or the specified waiting time ...
virtual void lock()
Locks the object.
Definition: CopyOnWriteArrayList.h:935
virtual bool removeAll(const Collection< E > &collection)
Removes all this collection's elements that are also contained in the specified collection (optional ...
Definition: CopyOnWriteArrayList.h:393
virtual void unlock()=0
Releases the lock.
virtual void copy(const Collection< E > &collection)
Renders this Collection as a Copy of the given Collection.
Definition: CopyOnWriteArrayList.h:231
virtual void notify()
Signals a waiter on this object that it can now wake up and continue.
Definition: CopyOnWriteArrayList.h:960
virtual ~CopyOnWriteArrayList()
Definition: CopyOnWriteArrayList.h:195
CopyOnWriteArrayList(const E *array, int size)
Definition: CopyOnWriteArrayList.h:185
#define DECAF_UNUSED
Definition: Config.h:160
Definition: NoSuchElementException.h:31
CopyOnWriteArrayList()
Definition: CopyOnWriteArrayList.h:171
CopyOnWriteArrayList(const Collection< E > &collection)
Definition: CopyOnWriteArrayList.h:175
Definition: Exception.h:38
long long toNanos(long long duration) const
Equivalent to NANOSECONDS.convert(duration, this).
Definition: TimeUnit.h:126
virtual decaf::util::concurrent::locks::Lock & writeLock()
Returns the lock used for writing.the lock used for writing.
virtual void signalAll()=0
Wakes up all waiting threads.
int lastIndexOf(const E &value, int index)
Searches backwards through the List for the given element starting at the index specified.
Definition: CopyOnWriteArrayList.h:868
An ordered collection (also known as a sequence).
Definition: List.h:47
virtual void wait(long long millisecs)
Waits on a signal from this object, which is generated by a call to Notify.
Definition: CopyOnWriteArrayList.h:951
Definition: ReentrantReadWriteLock.h:38
virtual void await()=0
Causes the current thread to wait until it is signaled or interrupted.
virtual void unlock()
Unlocks the object.
Definition: CopyOnWriteArrayList.h:943
void swap(Pointer &value)
Exception Safe Swap Function.
Definition: Pointer.h:198
virtual int lastIndexOf(const E &value) const
Returns the index of the last occurrence of the specified element in this list, or -1 if this list do...
Definition: CopyOnWriteArrayList.h:613
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements...
Definition: AprPool.h:25
virtual ListIterator< E > * listIterator(int index) const
Definition: CopyOnWriteArrayList.h:579