📄 dataview.java
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2000-2004 * Sleepycat Software. All rights reserved. * * $Id: DataView.java,v 1.4 2004/08/02 18:52:05 mjc Exp $ */package com.sleepycat.collections;import com.sleepycat.bind.EntityBinding;import com.sleepycat.bind.EntryBinding;import com.sleepycat.compat.DbCompat;import com.sleepycat.db.Database;import com.sleepycat.db.DatabaseConfig;import com.sleepycat.db.DatabaseEntry;import com.sleepycat.db.DatabaseException;import com.sleepycat.db.Environment;import com.sleepycat.db.JoinConfig;import com.sleepycat.db.OperationStatus;import com.sleepycat.db.SecondaryConfig;import com.sleepycat.db.SecondaryDatabase;import com.sleepycat.db.SecondaryKeyCreator;import com.sleepycat.db.Transaction;import com.sleepycat.util.RuntimeExceptionWrapper;/** * Represents a Berkeley DB database and adds support for indices, bindings and * key ranges. * * <p>This class defines a view and takes care of reading and updating indices, * calling bindings, constraining access to a key range, etc.</p> * * @author Mark Hayes */final class DataView implements Cloneable { Database db; SecondaryDatabase secDb; CurrentTransaction currentTxn; KeyRange range; EntryBinding keyBinding; EntryBinding valueBinding; EntityBinding entityBinding; PrimaryKeyAssigner keyAssigner; SecondaryKeyCreator secKeyCreator; boolean writeAllowed; // Read-write view boolean ordered; // Not a HASH Db boolean recNumAllowed; // QUEUE, RECNO, or BTREE-RECNUM Db boolean recNumAccess; // recNumAllowed && using a rec num binding boolean btreeRecNumDb; // BTREE-RECNUM Db boolean btreeRecNumAccess; // recNumAccess && BTREE-RECNUM Db boolean recNumRenumber; // RECNO-RENUM Db boolean keysRenumbered; // recNumRenumber || btreeRecNumAccess boolean dupsAllowed; // Dups configured boolean dupsOrdered; // Sorted dups configured boolean transactional; // Db is transactional boolean dirtyReadAllowed; // Dirty-read is optional in DB-CORE boolean dirtyReadEnabled; // This view is a dirty-ready view /** * Creates a view for a given database and bindings. The initial key range * of the view will be open. */ DataView(Database database, EntryBinding keyBinding, EntryBinding valueBinding, EntityBinding entityBinding, boolean writeAllowed, PrimaryKeyAssigner keyAssigner) throws IllegalArgumentException { if (database == null) { throw new IllegalArgumentException("database is null"); } db = database; try { currentTxn = CurrentTransaction.getInstanceInternal(db.getEnvironment()); DatabaseConfig dbConfig; if (db instanceof SecondaryDatabase) { secDb = (SecondaryDatabase) database; SecondaryConfig secConfig = secDb.getSecondaryConfig(); secKeyCreator = secConfig.getKeyCreator(); dbConfig = secConfig; } else { dbConfig = db.getConfig(); } ordered = !DbCompat.isTypeHash(dbConfig); recNumAllowed = DbCompat.isTypeQueue(dbConfig) || DbCompat.isTypeRecno(dbConfig) || DbCompat.getBtreeRecordNumbers(dbConfig); recNumRenumber = DbCompat.getRenumbering(dbConfig); dupsAllowed = DbCompat.getSortedDuplicates(dbConfig) || DbCompat.getUnsortedDuplicates(dbConfig); dupsOrdered = DbCompat.getSortedDuplicates(dbConfig); transactional = currentTxn.isTxnMode() && dbConfig.getTransactional(); dirtyReadAllowed = DbCompat.getDirtyRead(dbConfig); btreeRecNumDb = recNumAllowed && DbCompat.isTypeBtree(dbConfig); range = new KeyRange(dbConfig.getBtreeComparator()); } catch (DatabaseException e) { throw new RuntimeExceptionWrapper(e); } this.writeAllowed = writeAllowed; this.keyBinding = keyBinding; this.valueBinding = valueBinding; this.entityBinding = entityBinding; this.keyAssigner = keyAssigner; if (valueBinding != null && entityBinding != null) throw new IllegalArgumentException( "both valueBinding and entityBinding are non-null"); if (keyBinding instanceof com.sleepycat.bind.RecordNumberBinding) { if (!recNumAllowed) { throw new IllegalArgumentException( "RecordNumberBinding requires DB_BTREE/DB_RECNUM, " + "DB_RECNO, or DB_QUEUE"); } recNumAccess = true; if (btreeRecNumDb) { btreeRecNumAccess = true; } } keysRenumbered = recNumRenumber || btreeRecNumAccess; } /** * Clones the view. */ private DataView cloneView() { try { return (DataView) super.clone(); } catch (CloneNotSupportedException willNeverOccur) { throw new IllegalStateException(); } } /** * Return a new key-set view derived from this view by setting the * entity and value binding to null. * * @return the derived view. */ DataView keySetView() { if (keyBinding == null) { throw new UnsupportedOperationException("must have keyBinding"); } DataView view = cloneView(); view.valueBinding = null; view.entityBinding = null; return view; } /** * Return a new value-set view derived from this view by setting the * key binding to null. * * @return the derived view. */ DataView valueSetView() { if (valueBinding == null && entityBinding == null) { throw new UnsupportedOperationException( "must have valueBinding or entityBinding"); } DataView view = cloneView(); view.keyBinding = null; return view; } /** * Return a new value-set view for single key range. * * @param singleKey the single key value. * * @return the derived view. * * @throws DatabaseException if a database problem occurs. * * @throws KeyRangeException if the specified range is not within the * current range. */ DataView valueSetView(Object singleKey) throws DatabaseException, KeyRangeException { /* * Must do subRange before valueSetView since the latter clears the * key binding needed for the former. */ KeyRange singleKeyRange = subRange(singleKey); DataView view = valueSetView(); view.range = singleKeyRange; return view; } /** * Return a new value-set view for key range, optionally changing * the key binding. */ DataView subView(Object beginKey, boolean beginInclusive, Object endKey, boolean endInclusive, EntryBinding keyBinding) throws DatabaseException, KeyRangeException { DataView view = cloneView(); view.setRange(beginKey, beginInclusive, endKey, endInclusive); if (keyBinding != null) view.keyBinding = keyBinding; return view; } /** * Returns a new view with a specified dirtyRead setting. */ DataView dirtyReadView(boolean enable) { if (!dirtyReadAllowed) return this; DataView view = cloneView(); view.dirtyReadEnabled = enable; return view; } /** * Returns the current transaction for the view or null if the environment * is non-transactional. */ CurrentTransaction getCurrentTxn() { return transactional ? currentTxn : null; } /** * Sets this view's range to a subrange with the given parameters. */ private void setRange(Object beginKey, boolean beginInclusive, Object endKey, boolean endInclusive) throws DatabaseException, KeyRangeException { range = subRange(beginKey, beginInclusive, endKey, endInclusive); } /** * Returns the key thang for a single key range, or null if a single key * range is not used. */ DatabaseEntry getSingleKeyThang() { return range.getSingleKey(); } /** * Returns the environment for the database. */ final Environment getEnv() { return currentTxn.getEnvironment(); } /** * Returns whether this is a view on a secondary database rather * than directly on a primary database. */ final boolean isSecondary() { return (secDb != null); } /** * Returns whether no records are present in the view. */ boolean isEmpty() throws DatabaseException { DataCursor cursor = new DataCursor(this, false); try { return cursor.getFirst(false) != OperationStatus.SUCCESS; } finally { cursor.close(); } } /** * Appends a value and returns the new key. If a key assigner is used * it assigns the key, otherwise a QUEUE or RECNO database is required. */ OperationStatus append(Object value, Object[] retPrimaryKey, Object[] retValue) throws DatabaseException { /* * Flags will be NOOVERWRITE if used with assigner, or APPEND * otherwise. * Requires: if value param, value or entity binding * Requires: if retPrimaryKey, primary key binding (no index). * Requires: if retValue, value or entity binding */ DatabaseEntry keyThang = new DatabaseEntry(); DatabaseEntry valueThang = new DatabaseEntry();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -