?? dataview.java
字號:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2000,2007 Oracle. All rights reserved. * * $Id: DataView.java,v 12.6 2007/05/04 00:28:25 mark Exp $ */package com.sleepycat.collections;import com.sleepycat.bind.EntityBinding;import com.sleepycat.bind.EntryBinding;import com.sleepycat.compat.DbCompat;import com.sleepycat.db.CursorConfig;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;import com.sleepycat.util.keyrange.KeyRange;import com.sleepycat.util.keyrange.KeyRangeException;/** * 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; CursorConfig cursorConfig; // Used for all operations via this view 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 readUncommittedAllowed; // Read-uncommited is optional in DB-CORE /* * If duplicatesView is called, dupsView will be true and dupsKey will be * the secondary key used as the "single key" range. dupRange will be set * as the range of the primary key values if subRange is subsequently * called, to further narrow the view. */ DatabaseEntry dupsKey; boolean dupsView; KeyRange dupsRange; /** * 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(); readUncommittedAllowed = DbCompat.getReadUncommitted(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; cursorConfig = CursorConfig.DEFAULT; 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(range, 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; } /** * Return a new duplicates view for a given secondary key. */ DataView duplicatesView(Object secondaryKey, EntryBinding primaryKeyBinding) throws DatabaseException, KeyRangeException { if (!isSecondary()) { throw new UnsupportedOperationException ("Only allowed for maps on secondary databases"); } if (dupsView) { throw new IllegalStateException(); } DataView view = cloneView(); view.range = subRange(view.range, secondaryKey); view.dupsKey = view.range.getSingleKey(); view.dupsView = true; view.keyBinding = primaryKeyBinding; return view; } /** * Returns a new view with a specified cursor configuration. */ DataView configuredView(CursorConfig config) { DataView view = cloneView(); view.cursorConfig = (config != null) ? DbCompat.cloneCursorConfig(config) : CursorConfig.DEFAULT; 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 { KeyRange useRange = useSubRange(); useRange = subRange (useRange, beginKey, beginInclusive, endKey, endInclusive); if (dupsView) { dupsRange = useRange; } else { range = useRange; } } /** * 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.
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -