activemq-cpp-3.9.5
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
30namespace decaf {
31namespace util {
32namespace 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
102 ArrayListIterator(const ArrayListIterator&);
103 ArrayListIterator& operator=(const ArrayListIterator&);
104
105 public:
106
108 ListIterator<E> (), array(array), position(index) {
109
110 if (position < 0 || position > array->size) {
111 throw decaf::lang::exceptions::IndexOutOfBoundsException(
112 __FILE__, __LINE__, "Iterator created with invalid index.");
113 }
114 }
115
117 this->array.reset(NULL);
118 };
119
120 virtual E next() {
121 if (position >= array->size) {
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) {
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((std::size_t) 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) {
999 throw decaf::lang::exceptions::IndexOutOfBoundsException(
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) {
1006 throw decaf::lang::exceptions::IndexOutOfBoundsException(
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_ */
Definition Exception.h:38
virtual decaf::util::Iterator< E > * iterator()=0
static short max(short a, short b)
Returns the larger of two short values.
Definition Math.h:426
Decaf's implementation of a Smart Pointer that is a template on a Type and is Thread Safe if the defa...
Definition Pointer.h:53
void reset(T *value=NULL)
Resets the Pointer to hold the new value.
Definition Pointer.h:161
void swap(Pointer &value)
Exception Safe Swap Function.
Definition Pointer.h:198
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 ...
Definition IndexOutOfBoundsException.h:31
Definition UnsupportedOperationException.h:32
The root interface in the collection hierarchy.
Definition Collection.h:69
virtual bool contains(const E &value) const =0
Returns true if this collection contains the specified element.
virtual int size() const =0
Returns the number of elements in this collection.
virtual bool isEmpty() const =0
Defines an object that can be used to iterate over the elements of a collection.
Definition Iterator.h:34
List()
Definition List.h:57
An iterator for lists that allows the programmer to traverse the list in either direction,...
Definition ListIterator.h:38
Definition NoSuchElementException.h:31
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 bool hasPrevious() const
Returns true if this list iterator has more elements when traversing the list in the reverse directio...
Definition CopyOnWriteArrayList.h:147
ArrayListIterator(decaf::lang::Pointer< Array > array, int index)
Definition CopyOnWriteArrayList.h:107
virtual E next()
Returns the next element in the iteration.
Definition CopyOnWriteArrayList.h:120
virtual E previous()
Returns the previous element in the list.
Definition CopyOnWriteArrayList.h:151
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 void remove()
Removes from the underlying collection the last element returned by the iterator (optional operation)...
Definition CopyOnWriteArrayList.h:132
virtual void add(const E &e DECAF_UNUSED)
Definition CopyOnWriteArrayList.h:137
virtual void set(const E &e DECAF_UNUSED)
Definition CopyOnWriteArrayList.h:142
virtual ~ArrayListIterator()
Definition CopyOnWriteArrayList.h:116
virtual bool hasNext() const
Returns true if the iteration has more elements.
Definition CopyOnWriteArrayList.h:128
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
virtual E removeAt(int index)
Removes the element at the specified position in this list.
Definition CopyOnWriteArrayList.h:729
virtual ListIterator< E > * listIterator() const
Definition CopyOnWriteArrayList.h:552
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 bool add(const E &value)
Returns true if this collection changed as a result of the call.
Definition CopyOnWriteArrayList.h:243
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
virtual bool contains(const E &value) const
Returns true if this collection contains the specified element.
Definition CopyOnWriteArrayList.h:292
virtual void wait()
Waits on a signal from this object, which is generated by a call to Notify.
Definition CopyOnWriteArrayList.h:947
virtual E get(int index) const
Gets the element contained at position passed.
Definition CopyOnWriteArrayList.h:633
virtual ListIterator< E > * listIterator(int index) const
Definition CopyOnWriteArrayList.h:579
virtual std::string toString() const
Definition CopyOnWriteArrayList.h:760
virtual void unlock()
Unlocks the object.
Definition CopyOnWriteArrayList.h:943
CopyOnWriteArrayList< E > & operator=(const CopyOnWriteArrayList< E > &list)
Definition CopyOnWriteArrayList.h:201
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
CopyOnWriteArrayList(const Collection< E > &collection)
Definition CopyOnWriteArrayList.h:175
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
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
CopyOnWriteArrayList< E > & operator=(const Collection< E > &list)
Definition CopyOnWriteArrayList.h:215
virtual decaf::util::Iterator< E > * iterator()
Definition CopyOnWriteArrayList.h:510
virtual void lock()
Locks the object.
Definition CopyOnWriteArrayList.h:935
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 bool remove(const E &value)
Removes a single instance of the specified element from the collection.
Definition CopyOnWriteArrayList.h:376
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 int size() const
Returns the number of elements in this collection.
Definition CopyOnWriteArrayList.h:476
virtual void clear()
Removes all of the elements from this collection (optional operation).
Definition CopyOnWriteArrayList.h:279
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
virtual void notify()
Signals a waiter on this object that it can now wake up and continue.
Definition CopyOnWriteArrayList.h:960
virtual void notifyAll()
Signals the waiters on this object that it can now wake up and continue.
Definition CopyOnWriteArrayList.h:964
virtual void add(int index, const E &element)
Inserts the specified element at the specified position in this list.
Definition CopyOnWriteArrayList.h:666
CopyOnWriteArrayList()
Definition CopyOnWriteArrayList.h:171
virtual ListIterator< E > * listIterator()
Definition CopyOnWriteArrayList.h:539
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 isEmpty() const
Definition CopyOnWriteArrayList.h:362
virtual decaf::util::Iterator< E > * iterator() const
Definition CopyOnWriteArrayList.h:523
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 addAll(const Collection< E > &collection)
Adds all of the elements in the specified collection to this collection.
Definition CopyOnWriteArrayList.h:260
virtual std::vector< E > toArray() const
Returns an array containing all of the elements in this collection.
Definition CopyOnWriteArrayList.h:490
CopyOnWriteArrayList(const CopyOnWriteArrayList< E > &collection)
Definition CopyOnWriteArrayList.h:180
virtual void copy(const Collection< E > &collection)
Renders this Collection as a Copy of the given Collection.
Definition CopyOnWriteArrayList.h:231
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 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
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
virtual ~CopyOnWriteArrayList()
Definition CopyOnWriteArrayList.h:195
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
CopyOnWriteArrayList(const E *array, int size)
Definition CopyOnWriteArrayList.h:185
virtual ListIterator< E > * listIterator(int index)
Definition CopyOnWriteArrayList.h:566
static const TimeUnit MILLISECONDS
Definition TimeUnit.h:79
virtual bool tryLock()=0
Acquires the lock only if it is free at the time of invocation.
virtual void unlock()=0
Releases the lock.
virtual void lock()=0
Acquires the lock.
Definition ReentrantReadWriteLock.h:38
virtual decaf::util::concurrent::locks::Lock & writeLock()
Returns the lock used for writing.the lock used for writing.
virtual decaf::util::concurrent::locks::Lock & readLock()
Returns the lock used for reading.the lock used for reading.
#define NULL
Definition Config.h:33
Definition AbstractExecutorService.h:28
Definition AbstractCollection.h:33
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.
Definition AprPool.h:25