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 
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_ */
virtual std::vector< E > toArray() const
Returns an array containing all of the elements in this collection.
Definition: CopyOnWriteArrayList.h:490
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
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
The root interface in the collection hierarchy.
Definition: Collection.h:68
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 E next()
Returns the next element in the iteration.
Definition: CopyOnWriteArrayList.h:120
virtual ListIterator< E > * listIterator()
Definition: CopyOnWriteArrayList.h:539
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
long long toNanos(long long duration) const
Equivalent to NANOSECONDS.convert(duration, this).
Definition: TimeUnit.h:126
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
virtual int size() const
Returns the number of elements in this collection.
Definition: CopyOnWriteArrayList.h:476
CopyOnWriteArrayList(const CopyOnWriteArrayList< E > &collection)
Definition: CopyOnWriteArrayList.h:180
virtual std::string toString() const
Definition: CopyOnWriteArrayList.h:760
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
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 ...
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
An iterator for lists that allows the programmer to traverse the list in either direction, modify the list during iteration, and obtain the iterator&#39;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 ListIterator< E > * listIterator(int index) const
Definition: CopyOnWriteArrayList.h:579
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 bool hasNext() const
Returns true if the iteration has more elements.
Definition: CopyOnWriteArrayList.h:128
virtual int previousIndex() const
Returns the index of the element that would be returned by a subsequent call to previous.
Definition: CopyOnWriteArrayList.h:163
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 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() const
Definition: CopyOnWriteArrayList.h:523
virtual decaf::util::Iterator< E > * iterator()=0
virtual bool add(const E &value)
Returns true if this collection changed as a result of the call.
Definition: CopyOnWriteArrayList.h:243
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&#39;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 bool contains(const E &value) const
Returns true if this collection contains the specified element.
Definition: CopyOnWriteArrayList.h:292
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
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
CopyOnWriteArrayList()
Definition: CopyOnWriteArrayList.h:171
CopyOnWriteArrayList(const Collection< E > &collection)
Definition: CopyOnWriteArrayList.h:175
Definition: Exception.h:38
virtual decaf::util::concurrent::locks::Lock & writeLock()
Returns the lock used for writing.the lock used for writing.
virtual ListIterator< E > * listIterator() const
Definition: CopyOnWriteArrayList.h:552
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
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
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
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements...
Definition: AprPool.h:25
virtual bool isEmpty() const
Definition: CopyOnWriteArrayList.h:362