📄 storediterator.java
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2000-2006 * Oracle Corporation. All rights reserved. * * $Id: StoredIterator.java,v 12.5 2006/09/08 20:32:13 bostic Exp $ */package com.sleepycat.collections;import java.util.Iterator;import java.util.ListIterator;import java.util.NoSuchElementException;import com.sleepycat.db.DatabaseException;import com.sleepycat.db.OperationStatus;import com.sleepycat.util.RuntimeExceptionWrapper;/** * The Iterator returned by all stored collections. * * <p>While in general this class conforms to the {@link Iterator} interface, * it is important to note that all iterators for stored collections must be * explicitly closed with {@link #close()}. The static method {@link * #close(java.util.Iterator)} allows calling close for all iterators without * harm to iterators that are not from stored collections, and also avoids * casting. If a stored iterator is not closed, unpredictable behavior * including process death may result.</p> * * <p>This class implements the {@link Iterator} interface for all stored * iterators. It also implements {@link ListIterator} because some list * iterator methods apply to all stored iterators, for example, {@link * #previous} and {@link #hasPrevious}. Other list iterator methods are always * supported for lists, but for other types of collections are only supported * under certain conditions. See {@link #nextIndex}, {@link #previousIndex}, * {@link #add} and {@link #set} for details.</p> * * <p>In addition, this class provides the following methods for stored * collection iterators only. Note that the use of these methods is not * compatible with the standard Java collections interface.</p> * <ul> * <li>{@link #close()}</li> * <li>{@link #close(Iterator)}</li> * <li>{@link #count()}</li> * <li>{@link #getCollection}</li> * <li>{@link #setReadModifyWrite}</li> * <li>{@link #isReadModifyWrite}</li> * </ul> * * @author Mark Hayes */public class StoredIterator implements BaseIterator, Cloneable { /** * Closes the given iterator using {@link #close()} if it is a {@link * StoredIterator}. If the given iterator is not a {@link StoredIterator}, * this method does nothing. * * @param i is the iterator to close. * * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is thrown. */ public static void close(Iterator i) { if (i instanceof StoredIterator) { ((StoredIterator) i).close(); } } private static final int MOVE_NEXT = 1; private static final int MOVE_PREV = 2; private static final int MOVE_FIRST = 3; private boolean lockForWrite; private StoredCollection coll; private DataCursor cursor; private int toNext; private int toPrevious; private int toCurrent; private boolean writeAllowed; private boolean setAndRemoveAllowed; private Object currentData; StoredIterator(StoredCollection coll, boolean writeAllowed, DataCursor joinCursor) { try { this.coll = coll; this.writeAllowed = writeAllowed; if (joinCursor == null) this.cursor = new DataCursor(coll.view, writeAllowed); else this.cursor = joinCursor; reset(); } catch (Exception e) { try { /* Ensure that the cursor is closed. [#10516] */ close(); } catch (Exception ignored) { /* Klockwork - ok */ } throw StoredContainer.convertException(e); } } /** * Returns whether write-locks will be obtained when reading with this * cursor. * Obtaining write-locks can prevent deadlocks when reading and then * modifying data. * * @return the write-lock setting. */ public final boolean isReadModifyWrite() { return lockForWrite; } /** * Changes whether write-locks will be obtained when reading with this * cursor. * Obtaining write-locks can prevent deadlocks when reading and then * modifying data. * * @param lockForWrite the write-lock setting. */ public void setReadModifyWrite(boolean lockForWrite) { this.lockForWrite = lockForWrite; } // --- begin Iterator/ListIterator methods --- /** * Returns true if this iterator has more elements when traversing in the * forward direction. False is returned if the iterator has been closed. * This method conforms to the {@link Iterator#hasNext} interface. * * @return whether {@link #next()} will succeed. * * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is thrown. */ public boolean hasNext() { if (cursor == null) { return false; } try { if (toNext != 0) { OperationStatus status = move(toNext); if (status == OperationStatus.SUCCESS) { toNext = 0; toPrevious = MOVE_PREV; toCurrent = MOVE_PREV; } } return (toNext == 0); } catch (Exception e) { throw StoredContainer.convertException(e); } } /** * Returns true if this iterator has more elements when traversing in the * reverse direction. It returns false if the iterator has been closed. * This method conforms to the {@link ListIterator#hasPrevious} interface. * * @return whether {@link #previous()} will succeed. * * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is thrown. */ public boolean hasPrevious() { if (cursor == null) { return false; } try { if (toPrevious != 0) { OperationStatus status = move(toPrevious); if (status == OperationStatus.SUCCESS) { toPrevious = 0; toNext = MOVE_NEXT; toCurrent = MOVE_NEXT; } } return (toPrevious == 0); } catch (Exception e) { throw StoredContainer.convertException(e); } } /** * Returns the next element in the iteration. * This method conforms to the {@link Iterator#next} interface. * * @return the next element. * * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is * thrown. */ public Object next() { try { if (toNext != 0) { OperationStatus status = move(toNext); if (status == OperationStatus.SUCCESS) { toNext = 0; } } if (toNext == 0) { currentData = coll.makeIteratorData(this, cursor); toNext = MOVE_NEXT; toPrevious = 0; toCurrent = 0; setAndRemoveAllowed = true; return currentData; } // else throw NoSuchElementException below } catch (Exception e) { throw StoredContainer.convertException(e); } throw new NoSuchElementException(); } /** * Returns the next element in the iteration. * This method conforms to the {@link ListIterator#previous} interface. * * @return the previous element. * * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is * thrown. */ public Object previous() { try { if (toPrevious != 0) { OperationStatus status = move(toPrevious); if (status == OperationStatus.SUCCESS) { toPrevious = 0; } } if (toPrevious == 0) { currentData = coll.makeIteratorData(this, cursor); toPrevious = MOVE_PREV; toNext = 0; toCurrent = 0; setAndRemoveAllowed = true; return currentData; } // else throw NoSuchElementException below } catch (Exception e) { throw StoredContainer.convertException(e); } throw new NoSuchElementException(); } /** * Returns the index of the element that would be returned by a subsequent * call to next. * This method conforms to the {@link ListIterator#nextIndex} interface * except that it returns Integer.MAX_VALUE for stored lists when * positioned at the end of the list, rather than returning the list size * as specified by the ListIterator interface. This is because the database * size is not available. * * @return the next index. * * @throws UnsupportedOperationException if this iterator's collection does * not use record number keys. * * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is * thrown. */ public int nextIndex() { if (!coll.view.recNumAccess) { throw new UnsupportedOperationException( "Record number access not supported"); } try { return hasNext() ? (cursor.getCurrentRecordNumber() - coll.getIndexOffset()) : Integer.MAX_VALUE; } catch (Exception e) { throw StoredContainer.convertException(e); } } /** * Returns the index of the element that would be returned by a subsequent * call to previous. * This method conforms to the {@link ListIterator#previousIndex} * interface. * * @return the previous index. * * @throws UnsupportedOperationException if this iterator's collection does * not use record number keys. * * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is * thrown. */ public int previousIndex() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -