001: ///////////////////////////////////////////////////////////////////////////////
002: // Copyright (c) 2001, Eric D. Friedman All Rights Reserved.
003: //
004: // This library is free software; you can redistribute it and/or
005: // modify it under the terms of the GNU Lesser General Public
006: // License as published by the Free Software Foundation; either
007: // version 2.1 of the License, or (at your option) any later version.
008: //
009: // This library is distributed in the hope that it will be useful,
010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: // GNU General Public License for more details.
013: //
014: // You should have received a copy of the GNU Lesser General Public
015: // License along with this program; if not, write to the Free Software
016: // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: ///////////////////////////////////////////////////////////////////////////////
018:
019: package gnu.trove;
020:
021: import java.util.ConcurrentModificationException;
022: import java.util.NoSuchElementException;
023:
024: /**
025: * Abstract iterator class for THash implementations. This class provides some
026: * of the common iterator operations (hasNext(), remove()) and allows subclasses
027: * to define the mechanism(s) for advancing the iterator and returning data.
028: *
029: * @author Eric D. Friedman
030: * @version $Id: TIterator.java,v 1.3 2007/06/29 20:03:10 robeden Exp $
031: */
032: abstract class TIterator {
033: /** the data structure this iterator traverses */
034: protected final THash _hash;
035: /** the number of elements this iterator believes are in the
036: * data structure it accesses. */
037: protected int _expectedSize;
038: /** the index used for iteration. */
039: protected int _index;
040:
041: /**
042: * Create an instance of TIterator over the specified THash.
043: */
044: public TIterator(THash hash) {
045: _hash = hash;
046: _expectedSize = _hash.size();
047: _index = _hash.capacity();
048: }
049:
050: /**
051: * Returns true if the iterator can be advanced past its current
052: * location.
053: *
054: * @return a <code>boolean</code> value
055: */
056: public boolean hasNext() {
057: return nextIndex() >= 0;
058: }
059:
060: /**
061: * Removes the last entry returned by the iterator.
062: * Invoking this method more than once for a single entry
063: * will leave the underlying data structure in a confused
064: * state.
065: */
066: public void remove() {
067: if (_expectedSize != _hash.size()) {
068: throw new ConcurrentModificationException();
069: }
070:
071: // Disable auto compaction during the remove. This is a workaround for bug 1642768.
072: try {
073: _hash.tempDisableAutoCompaction();
074: _hash.removeAt(_index);
075: } finally {
076: _hash.reenableAutoCompaction(false);
077: }
078:
079: _expectedSize--;
080: }
081:
082: /**
083: * Sets the internal <tt>index</tt> so that the `next' object
084: * can be returned.
085: */
086: protected final void moveToNextIndex() {
087: // doing the assignment && < 0 in one line shaves
088: // 3 opcodes...
089: if ((_index = nextIndex()) < 0) {
090: throw new NoSuchElementException();
091: }
092: }
093:
094: /**
095: * Returns the index of the next value in the data structure
096: * or a negative value if the iterator is exhausted.
097: *
098: * @return an <code>int</code> value
099: */
100: abstract protected int nextIndex();
101: } // TIterator
|