⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blockiterator.java

📁 嵌入式数据库Berkeley DB-4.5.20源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2000-2006 *      Oracle Corporation.  All rights reserved. * * $Id: BlockIterator.java,v 12.3 2006/09/08 20:32:13 bostic Exp $ */package com.sleepycat.collections;import java.util.ListIterator;import java.util.NoSuchElementException;import com.sleepycat.compat.DbCompat;import com.sleepycat.db.DatabaseEntry;import com.sleepycat.db.DatabaseException;import com.sleepycat.db.OperationStatus;import com.sleepycat.util.keyrange.KeyRange;/** * An iterator that does need closing because a cursor is not kept open across * method calls.  A cursor is opened to read a block of records at a time and * then closed before the method returns. * * @author Mark Hayes */class BlockIterator implements BaseIterator {    private StoredCollection coll;    private boolean writeAllowed;    /**     * Slots for a block of record keys and values.  The priKeys array is only     * used for secondary databases; otherwise it is set to the keys array.     */    private byte[][] keys;    private byte[][] priKeys;    private byte[][] values;    /**     * The slot index of the record that would be returned by next().     * nextIndex is always greater or equal to zero.  If the next record is not     * available, then nextIndex is equal to keys.length or keys[nextIndex] is     * null.     */    private int nextIndex;    /**     * The slot index of the record last returned by next() or previous(), or     * the record inserted by add().  dataIndex is -1 if the data record is not     * available.  If greater or equal to zero, the slot at dataIndex is always     * non-null.     */    private int dataIndex;    /**     * The iterator data last returned by next() or previous().  This value is     * set to null if dataIndex is -1, or if the state of the iterator is such     * that set() or remove() cannot be called.  For example, after add() this     * field is set to null, even though the dataIndex is still valid.     */    private Object dataObject;    /**     * Creates an iterator.     */    BlockIterator(StoredCollection coll, boolean writeAllowed, int blockSize) {        this.coll = coll;        this.writeAllowed = writeAllowed;        keys = new byte[blockSize][];        priKeys = coll.isSecondary() ? (new byte[blockSize][]) : keys;        values = new byte[blockSize][];        nextIndex = blockSize;        dataIndex = -1;        dataObject = null;    }    /**     * Copy constructor.     */    private BlockIterator(BlockIterator o) {        coll = o.coll;        writeAllowed = o.writeAllowed;        keys = copyArray(o.keys);        priKeys = coll.isSecondary() ? copyArray(o.priKeys) : keys;        values = copyArray(o.values);        nextIndex = o.nextIndex;        dataIndex = o.dataIndex;        dataObject = o.dataObject;    }    /**     * Copies an array of byte arrays.     */    private byte[][] copyArray(byte[][] a) {        byte[][] b = new byte[a.length][];        for (int i = 0; i < b.length; i += 1) {            if (a[i] != null) {                b[i] = KeyRange.copyBytes(a[i]);            }        }        return b;    }    /**     * Returns whether the element at nextIndex is available.     */    private boolean isNextAvailable() {        return (nextIndex < keys.length) &&               (keys[nextIndex] != null);    }    /**     * Returns whether the element at nextIndex-1 is available.     */    private boolean isPrevAvailable() {        return (nextIndex > 0) &&               (keys[nextIndex - 1] != null);    }    /**     * Returns the record number at the given slot position.     */    private int getRecordNumber(int i) {        if (coll.view.btreeRecNumDb) {            DataCursor cursor = null;            try {                cursor = new DataCursor(coll.view, false);                if (moveCursor(i, cursor)) {                    return cursor.getCurrentRecordNumber();                } else {                    throw new IllegalStateException();                }            } catch (DatabaseException e) {                throw StoredContainer.convertException(e);            } finally {                closeCursor(cursor);            }        } else {            DatabaseEntry entry = new DatabaseEntry(keys[i]);            return DbCompat.getRecordNumber(entry);        }    }    /**     * Sets dataObject to the iterator data for the element at dataIndex.     */    private void makeDataObject() {        int i = dataIndex;        DatabaseEntry keyEntry = new DatabaseEntry(keys[i]);        DatabaseEntry priKeyEntry = (keys != priKeys)                                    ? (new DatabaseEntry(priKeys[i]))                                    : keyEntry;        DatabaseEntry valuesEntry = new DatabaseEntry(values[i]);        dataObject = coll.makeIteratorData(this, keyEntry, priKeyEntry,                                           valuesEntry);    }    /**     * Sets all slots to null.     */    private void clearSlots() {        for (int i = 0; i < keys.length; i += 1) {            keys[i] = null;            priKeys[i] = null;            values[i] = null;        }    }    /**     * Sets a given slot using the data in the given cursor.     */    private void setSlot(int i, DataCursor cursor) {        keys[i] = KeyRange.getByteArray(cursor.getKeyThang());        if (keys != priKeys) {            priKeys[i] = KeyRange.getByteArray                (cursor.getPrimaryKeyThang());        }        values[i] = KeyRange.getByteArray(cursor.getValueThang());    }    /**     * Inserts an added record at a given slot position and shifts other slots     * accordingly.  Also adjusts nextIndex and sets dataIndex to -1.     */    private void insertSlot(int i, DataCursor cursor) {        if (i < keys.length) {            for (int j = keys.length - 1; j > i; j -= 1) {                /* Shift right. */                keys[j] = keys[j - 1];                priKeys[j] = priKeys[j - 1];                values[j] = values[j - 1];                /* Bump key in recno-renumber database. */                if (coll.view.recNumRenumber && keys[j] != null) {                    bumpRecordNumber(j);                }            }            nextIndex += 1;        } else {            if (i != keys.length) {                throw new IllegalStateException();            }            i -= 1;            for (int j = 0; j < i; j += 1) {                /* Shift left. */                keys[j] = keys[j + 1];                priKeys[j] = priKeys[j + 1];                values[j] = values[j + 1];            }        }        setSlot(i, cursor);        dataIndex = -1;    }    /**     * Increments the record number key at the given slot.     */    private void bumpRecordNumber(int i) {        DatabaseEntry entry = new DatabaseEntry(keys[i]);        DbCompat.setRecordNumber(entry,                                 DbCompat.getRecordNumber(entry) + 1);        keys[i] = entry.getData();    }    /**     * Deletes the given slot, adjusts nextIndex and sets dataIndex to -1.     */    private void deleteSlot(int i) {        for (int j = i + 1; j < keys.length; j += 1) {            keys[j - 1] = keys[j];            priKeys[j - 1] = priKeys[j];            values[j - 1] = values[j];        }        int last = keys.length - 1;        keys[last] = null;        priKeys[last] = null;        values[last] = null;        if (nextIndex > i) {            nextIndex -= 1;        }        dataIndex = -1;    }    /**     * Moves the cursor to the key/data at the given slot, and returns false     * if the reposition (search) fails.     */    private boolean moveCursor(int i, DataCursor cursor)        throws DatabaseException {        return cursor.repositionExact(keys[i], priKeys[i], values[i], false);    }    /**     * Closes the given cursor if non-null.     */    private void closeCursor(DataCursor cursor) {        if (cursor != null) {            try {                cursor.close();            } catch (DatabaseException e) {                throw StoredContainer.convertException(e);            }        }    }    // --- begin Iterator/ListIterator methods ---    public boolean hasNext() {        if (isNextAvailable()) {            return true;        }        DataCursor cursor = null;        try {            cursor = new DataCursor(coll.view, writeAllowed);            int prev = nextIndex - 1;            boolean found = false;            if (keys[prev] == null) {                /* Get the first record for an uninitialized iterator. */                OperationStatus status = cursor.getFirst(false);                if (status == OperationStatus.SUCCESS) {                    found = true;                    nextIndex = 0;                }            } else {                /* Reposition to the last known key/data pair. */                int repos = cursor.repositionRange                    (keys[prev], priKeys[prev], values[prev], false);                if (repos == DataCursor.REPOS_EXACT) {                    /*                     * The last known key/data pair was found and will now be                     * in slot zero.                     */                    found = true;                    nextIndex = 1;                    /* The data object is now in slot zero or not available. */                    if (dataIndex == prev) {                        dataIndex = 0;                    } else {                        dataIndex = -1;                        dataObject = null;                    }                } else if (repos == DataCursor.REPOS_NEXT) {                    /*                     * The last known key/data pair was not found, but the                     * following record was found and it will be in slot zero.                     */                    found = true;                    nextIndex = 0;                    /* The data object is no longer available. */                    dataIndex = -1;                    dataObject = null;                } else {                    if (repos != DataCursor.REPOS_EOF) {                        throw new IllegalStateException();                    }                }            }            if (found) {                /* Clear all slots first in case an exception occurs below. */                clearSlots();                /* Attempt to fill all slots with records. */                int i = 0;                boolean done = false;                while (!done) {                    setSlot(i, cursor);                    i += 1;                    if (i < keys.length) {                        OperationStatus status = coll.iterateDuplicates() ?                                                 cursor.getNext(false) :                                                 cursor.getNextNoDup(false);                        if (status != OperationStatus.SUCCESS) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -