comparison src/share/vm/utilities/growableArray.hpp @ 20314:46bbe04d1cad

8039498: Add iterators to GrowableArray Summary: To simplify the management of multiple code heaps in the code cache (see JDK-8015774), STL-style iterator capability is added to the GrowableArray. Further, custom iterators allow to only iterate over elements that satisfy a given predicate. Reviewed-by: kvn, twisti Contributed-by: Tobias Hartmann <tobias.hartmann@oracle.com>
author anoll
date Fri, 11 Apr 2014 13:52:51 +0200
parents 55fb97c4c58d
children 411e30e5fbb8
comparison
equal deleted inserted replaced
20310:bfba6779654b 20314:46bbe04d1cad
145 assert(on_stack(), "fast ResourceObj path only"); 145 assert(on_stack(), "fast ResourceObj path only");
146 return (void*)resource_allocate_bytes(thread, elementSize * _max); 146 return (void*)resource_allocate_bytes(thread, elementSize * _max);
147 } 147 }
148 }; 148 };
149 149
150 template<class E> class GrowableArrayIterator;
151 template<class E, class UnaryPredicate> class GrowableArrayFilterIterator;
152
150 template<class E> class GrowableArray : public GenericGrowableArray { 153 template<class E> class GrowableArray : public GenericGrowableArray {
151 friend class VMStructs; 154 friend class VMStructs;
152 155
153 private: 156 private:
154 E* _data; // data array 157 E* _data; // data array
239 } 242 }
240 243
241 E top() const { 244 E top() const {
242 assert(_len > 0, "empty list"); 245 assert(_len > 0, "empty list");
243 return _data[_len-1]; 246 return _data[_len-1];
247 }
248
249 GrowableArrayIterator<E> begin() const {
250 return GrowableArrayIterator<E>(this, 0);
251 }
252
253 GrowableArrayIterator<E> end() const {
254 return GrowableArrayIterator<E>(this, length());
244 } 255 }
245 256
246 void push(const E& elem) { append(elem); } 257 void push(const E& elem) { append(elem); }
247 258
248 E pop() { 259 E pop() {
410 tty->print(": length %ld (_max %ld) { ", _len, _max); 421 tty->print(": length %ld (_max %ld) { ", _len, _max);
411 for (int i = 0; i < _len; i++) tty->print(INTPTR_FORMAT " ", *(intptr_t*)&(_data[i])); 422 for (int i = 0; i < _len; i++) tty->print(INTPTR_FORMAT " ", *(intptr_t*)&(_data[i]));
412 tty->print("}\n"); 423 tty->print("}\n");
413 } 424 }
414 425
426 // Custom STL-style iterator to iterate over GrowableArrays
427 // It is constructed by invoking GrowableArray::begin() and GrowableArray::end()
428 template<class E> class GrowableArrayIterator : public StackObj {
429 friend class GrowableArray<E>;
430 template<class F, class UnaryPredicate> friend class GrowableArrayFilterIterator;
431
432 private:
433 const GrowableArray<E>* _array; // GrowableArray we iterate over
434 int _position; // The current position in the GrowableArray
435
436 // Private constructor used in GrowableArray::begin() and GrowableArray::end()
437 GrowableArrayIterator(const GrowableArray<E>* array, int position) : _array(array), _position(position) {
438 assert(0 <= position && position <= _array->length(), "illegal position");
439 }
440
441 public:
442 GrowableArrayIterator<E>& operator++() { ++_position; return *this; }
443 E operator*() { return _array->at(_position); }
444
445 bool operator==(const GrowableArrayIterator<E>& rhs) {
446 assert(_array == rhs._array, "iterator belongs to different array");
447 return _position == rhs._position;
448 }
449
450 bool operator!=(const GrowableArrayIterator<E>& rhs) {
451 assert(_array == rhs._array, "iterator belongs to different array");
452 return _position != rhs._position;
453 }
454 };
455
456 // Custom STL-style iterator to iterate over elements of a GrowableArray that satisfy a given predicate
457 template<class E, class UnaryPredicate> class GrowableArrayFilterIterator : public StackObj {
458 friend class GrowableArray<E>;
459
460 private:
461 const GrowableArray<E>* _array; // GrowableArray we iterate over
462 int _position; // Current position in the GrowableArray
463 UnaryPredicate _predicate; // Unary predicate the elements of the GrowableArray should satisfy
464
465 public:
466 GrowableArrayFilterIterator(const GrowableArrayIterator<E>& begin, UnaryPredicate filter_predicate)
467 : _array(begin._array), _position(begin._position), _predicate(filter_predicate) {
468 // Advance to first element satisfying the predicate
469 while(_position != _array->length() && !_predicate(_array->at(_position))) {
470 ++_position;
471 }
472 }
473
474 GrowableArrayFilterIterator<E, UnaryPredicate>& operator++() {
475 do {
476 // Advance to next element satisfying the predicate
477 ++_position;
478 } while(_position != _array->length() && !_predicate(_array->at(_position)));
479 return *this;
480 }
481
482 E operator*() { return _array->at(_position); }
483
484 bool operator==(const GrowableArrayIterator<E>& rhs) {
485 assert(_array == rhs._array, "iterator belongs to different array");
486 return _position == rhs._position;
487 }
488
489 bool operator!=(const GrowableArrayIterator<E>& rhs) {
490 assert(_array == rhs._array, "iterator belongs to different array");
491 return _position != rhs._position;
492 }
493
494 bool operator==(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs) {
495 assert(_array == rhs._array, "iterator belongs to different array");
496 return _position == rhs._position;
497 }
498
499 bool operator!=(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs) {
500 assert(_array == rhs._array, "iterator belongs to different array");
501 return _position != rhs._position;
502 }
503 };
504
415 #endif // SHARE_VM_UTILITIES_GROWABLEARRAY_HPP 505 #endif // SHARE_VM_UTILITIES_GROWABLEARRAY_HPP