diff options
author | Mark Spruiell <mes@zeroc.com> | 2009-05-18 14:03:42 -0700 |
---|---|---|
committer | Mark Spruiell <mes@zeroc.com> | 2009-05-18 14:03:42 -0700 |
commit | b30ccc77d3a9822c6ffcebf9b45945822df200bc (patch) | |
tree | 94105ea42fa81ad0b8731b05a46c7f64304dec55 /java/src/Freeze/Map.java | |
parent | Removed Freeze.UseNonmutating (diff) | |
download | ice-b30ccc77d3a9822c6ffcebf9b45945822df200bc.tar.bz2 ice-b30ccc77d3a9822c6ffcebf9b45945822df200bc.tar.xz ice-b30ccc77d3a9822c6ffcebf9b45945822df200bc.zip |
bug 252 - Freeze finalizers
bug 2552 - Update Freeze for Java5
Diffstat (limited to 'java/src/Freeze/Map.java')
-rw-r--r-- | java/src/Freeze/Map.java | 2479 |
1 files changed, 14 insertions, 2465 deletions
diff --git a/java/src/Freeze/Map.java b/java/src/Freeze/Map.java index 282a533c6e0..5769b1e2a79 100644 --- a/java/src/Freeze/Map.java +++ b/java/src/Freeze/Map.java @@ -9,2490 +9,39 @@ package Freeze; -public abstract class Map extends java.util.AbstractMap - implements java.util.SortedMap, KeyCodec +public interface Map<K, V> extends NavigableMap<K, V> { - public abstract byte[] encodeValue(Object o, Ice.Communicator communicator); - public abstract Object decodeValue(byte[] b, Ice.Communicator communicator); - - protected - Map(Connection connection, String dbName, String key, String value, - boolean createDb, java.util.Comparator comparator) - { - _connection = (ConnectionI)connection; - _dbName = dbName; - _comparator = (comparator == null) ? null : new Comparator(comparator); - - _errorPrefix = "Freeze DB DbEnv(\"" + _connection.envName() + "\") Db(\"" + dbName + "\"): "; - _trace = _connection.trace(); - - init(null, dbName, key, value, createDb, null); - } - - protected - Map(Connection connection, String dbName, java.util.Comparator comparator) - { - _connection = (ConnectionI)connection; - _dbName = dbName; - _comparator = (comparator == null) ? null : new Comparator(comparator); - - _errorPrefix = "Freeze DB DbEnv(\"" + _connection.envName() + "\") Db(\"" + dbName + "\"): "; - _trace = _connection.trace(); - } - - - protected static void - recreate(Map map, String dbName, String key, String value, - Freeze.Map.Index[] indices, java.util.Map indexComparators) - { - ConnectionI connection = map._connection; - String envName = connection.dbEnv().getEnvName(); - - if(dbName.equals(Util.catalogName()) || dbName.equals(Util.catalogIndexListName())) - { - throw new DatabaseException(errorPrefix(envName, dbName) + "You cannot recreate the \"" - + dbName + "\" database"); - } - - if(connection.trace() >= 1) - { - connection.communicator().getLogger().trace("Freeze.Map", - "Recreating \"" + dbName + "\""); - } - - Transaction tx = connection.currentTransaction(); - boolean ownTx = (tx == null); - - com.sleepycat.db.DatabaseEntry keyEntry = new com.sleepycat.db.DatabaseEntry(); - com.sleepycat.db.DatabaseEntry valueEntry = new com.sleepycat.db.DatabaseEntry(); - - com.sleepycat.db.Database oldDb = null; - MapDb newDb = null; - - for(;;) - { - try - { - if(ownTx) - { - tx = null; - tx = connection.beginTransaction(); - } - - com.sleepycat.db.Transaction txn = connection.dbTxn(); - - if(connection.trace() >= 2) - { - connection.communicator().getLogger().trace( - "Freeze.Map", "Removing all existing indices for \"" + dbName + "\""); - } - CatalogIndexList catalogIndexList = new CatalogIndexList(connection, Util.catalogIndexListName(), true); - String[] oldIndices = (String[])catalogIndexList.remove(dbName); - - - if(oldIndices != null) - { - for(int i = 0; i < oldIndices.length; ++i) - { - try - { - connection.removeMapIndex(dbName, oldIndices[i]); - } - catch(IndexNotFoundException e) - { - // - // Ignored - // - } - } - } - - // - // Rename existing database - // - String oldDbName = dbName + ".old-" + java.util.UUID.randomUUID().toString(); - - if(connection.trace() >= 2) - { - connection.communicator().getLogger().trace( - "Freeze.Map", "Renaming \"" + dbName + "\" to \"" + oldDbName + "\""); - } - - connection.dbEnv().getEnv().renameDatabase(txn, dbName, null, oldDbName); - - com.sleepycat.db.DatabaseConfig oldDbConfig = new com.sleepycat.db.DatabaseConfig(); - oldDbConfig.setType(com.sleepycat.db.DatabaseType.BTREE); - - oldDb = connection.dbEnv().getEnv().openDatabase(txn, oldDbName, null, oldDbConfig); - - newDb = new MapDb(connection, dbName, key, value, map._comparator, indices, indexComparators, true); - map.init(newDb, indices); - - - if(connection.trace() >= 2) - { - connection.communicator().getLogger().trace( - "Freeze.Map", "Writing contents of \"" + oldDbName + "\" to fresh \"" + dbName + "\""); - } - - // - // Now simply write all of oldDb into newDb - // - com.sleepycat.db.Cursor dbc = null; - try - { - dbc = oldDb.openCursor(txn, null); - - while(dbc.getNext(keyEntry, valueEntry, null) == com.sleepycat.db.OperationStatus.SUCCESS) - { - newDb.db().put(txn, keyEntry, valueEntry); - } - } - finally - { - if(dbc != null) - { - dbc.close(); - } - } - - if(connection.trace() >= 2) - { - connection.communicator().getLogger().trace( - "Freeze.Map", "Transfer complete; removing \"" + oldDbName + "\""); - } - connection.dbEnv().getEnv().removeDatabase(txn, oldDbName, null); - - if(ownTx) - { - try - { - tx.commit(); - } - finally - { - tx = null; - } - } - - break; // for (;;) - } - catch(com.sleepycat.db.DeadlockException dx) - { - if(ownTx) - { - if(connection.deadlockWarning()) - { - connection.communicator().getLogger().warning( - "Deadlock in Freeze.Map.recreate on Db \"" - + dbName + "\"; retrying ..."); - } - - // - // Ignored, try again - // - } - else - { - DeadlockException ex = new DeadlockException( - errorPrefix(envName, dbName) + "Map.recreate: " + dx.getMessage(), tx); - ex.initCause(dx); - throw ex; - } - } - catch(com.sleepycat.db.DatabaseException dx) - { - DatabaseException ex = new DatabaseException(errorPrefix(envName, dbName) + "Map.recreate: " + dx.getMessage()); - ex.initCause(dx); - throw ex; - } - catch(java.io.FileNotFoundException fne) - { - DatabaseException ex = new DatabaseException(errorPrefix(envName, dbName) + "Map.recreate: " + fne.getMessage()); - ex.initCause(fne); - throw ex; - } - finally - { - if(ownTx && tx != null) - { - try - { - tx.rollback(); - } - catch(DatabaseException de) - { - } - } - - try - { - if(newDb != null) - { - newDb.close(); - } - - if(oldDb != null) - { - try - { - oldDb.close(); - } - catch(com.sleepycat.db.DatabaseException dx) - { - DatabaseException ex = new DatabaseException( - errorPrefix(envName, dbName) + "Map.recreate: " + dx.getMessage()); - ex.initCause(dx); - throw ex; - } - } - } - finally - { - newDb = null; - oldDb = null; - } - } - } - } - - - protected void - init(Freeze.Map.Index[] indices, String dbName, - String key, String value, boolean createDb, java.util.Map indexComparators) - { - init(_connection.dbEnv().getSharedMapDb(dbName, key, value, _comparator, indices, indexComparators, createDb), - indices); - } - - protected void - init(MapDb db, Freeze.Map.Index[] indices) - { - _db = db; - _token = _connection.registerMap(this); - - if(indices != null) - { - for(int i = 0; i < indices.length; ++i) - { - _indexMap.put(indices[i].name(), indices[i]); - } - } - } - - public void - close() - { - close(false); - } - - public void - closeDb() - { - close(false); - _connection.dbEnv().removeSharedMapDb(_dbName); - } - - public Connection - getConnection() - { - return _connection; - } - // - // SortedMap methods + // Faster alternative to the standard put() method because it + // doesn't read and decode the old value. // + void fastPut(K key, V value); - public java.util.Comparator - comparator() - { - if(_comparator == null) - { - return null; - } - else - { - // - // Return's the user's comparator, not the DB comparator. - // - return _comparator.comparator(); - } - } - - public Object firstKey() - { - return firstKey(null, null); - } - - public Object lastKey() - { - return lastKey(null, null); - } - - Object firstKey(Object fromKey, Object toKey) - { - byte[] fk = fromKey == null ? null : - encodeKey(fromKey, _connection.communicator()); - - byte[] k = getFirstOrLastKey(_db.db(), _db.dbName(), fk, true); - if(k == null) - { - throw new NoSuchElementException(); - } - else - { - Object key = decodeKey(k, _connection.communicator()); - if(toKey != null && comparator().compare(key, toKey) >= 0) - { - throw new NoSuchElementException(); - } - return key; - } - } - - Object lastKey(Object fromKey, Object toKey) - { - byte[] tk = toKey == null ? null : - encodeKey(toKey, _connection.communicator()); - - byte[] k = getFirstOrLastKey(_db.db(), _db.dbName(), tk, false); - if(k == null) - { - throw new NoSuchElementException(); - } - else - { - Object key = decodeKey(k, _connection.communicator()); - if(fromKey != null && comparator().compare(fromKey, key) > 0) - { - throw new NoSuchElementException(); - } - return key; - } - } - - public java.util.SortedMap headMap(Object toKey) - { - if(toKey == null) - { - throw new NullPointerException(); - } - if(_comparator == null) - { - throw new UnsupportedOperationException(); - } - - return new SubMap(this, null, toKey); - } - - public java.util.SortedMap tailMap(Object fromKey) - { - if(fromKey == null) - { - throw new NullPointerException(); - } - if(_comparator == null) - { - throw new UnsupportedOperationException(); - } + void close(); - return new SubMap(this, fromKey, null); - } - - public java.util.SortedMap subMap(Object fromKey, Object toKey) - { - if(fromKey == null || toKey == null ) - { - throw new NullPointerException(); - } - if(_comparator == null) - { - throw new UnsupportedOperationException(); - } - return new SubMap(this, fromKey, toKey); - } - - // - // Additional non-standard xxMapForIndex methods + // Close all iterators for this map. Returns the number of + // iterators that were closed. // - public java.util.SortedMap headMapForIndex(String indexName, Object toKey) - { - if(toKey == null) - { - throw new NullPointerException(); - } - - Map.Index index = _indexMap.get(indexName); - if(index == null) - { - throw new IllegalArgumentException("Can't find index '" + indexName + "'"); - } - else if(index.comparator() == null) - { - throw new IllegalArgumentException("Index '" + indexName + "' has no user-defined comparator"); - } - return new SubMap(index, null, toKey); - } - - public java.util.SortedMap tailMapForIndex(String indexName, Object fromKey) - { - if(fromKey == null) - { - throw new NullPointerException(); - } - Map.Index index = _indexMap.get(indexName); - if(index == null) - { - throw new IllegalArgumentException("Can't find index '" + indexName + "'"); - } - else if(index.comparator() == null) - { - throw new IllegalArgumentException("Index '" + indexName + "' has no user-defined comparator"); - } - return new SubMap(index, fromKey, null); - } - - public java.util.SortedMap subMapForIndex(String indexName, Object fromKey, Object toKey) - { - if(fromKey == null || toKey == null ) - { - throw new NullPointerException(); - } - Map.Index index = _indexMap.get(indexName); - if(index == null) - { - throw new IllegalArgumentException("Can't find index '" + indexName + "'"); - } - else if(index.comparator() == null) - { - throw new IllegalArgumentException("Index '" + indexName + "' has no user-defined comparator"); - } - return new SubMap(index, fromKey, toKey); - } - - public java.util.SortedMap mapForIndex(String indexName) - { - Map.Index index = _indexMap.get(indexName); - if(index == null) - { - throw new IllegalArgumentException("Can't find index '" + indexName + "'"); - } - else if(index.comparator() == null) - { - throw new IllegalArgumentException("Index '" + indexName + "' has no user-defined comparator"); - } - return new SubMap(index, null, null); - } - - // - // Plain Map methods - // - public int - size() - { - if(_db == null) - { - DatabaseException ex = new DatabaseException(); - ex.message = _errorPrefix + "\"" + _db.dbName() + "\" has been closed"; - throw ex; - } - - // - // The number of records cannot be cached and then adjusted by - // the member functions since the map would no longer work in - // the presence of transactions - if a record is added (and - // the size adjusted) and the transaction aborted then the - // cached map size() would be incorrect. - // - - // - // TODO: DB_FAST_STAT doesn't seem to do what the - // documentation says... - // - try - { - com.sleepycat.db.StatsConfig config = new com.sleepycat.db.StatsConfig(); - // - // TODO: DB_FAST_STAT doesn't seem to do what the - // documentation says... - // - //config.setFast(true); - com.sleepycat.db.BtreeStats s = (com.sleepycat.db.BtreeStats)_db.db().getStats(null, config); - return s.getNumData(); - } - catch(com.sleepycat.db.DatabaseException e) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.stat: " + e.getMessage(); - throw ex; - } - } - - public boolean - containsValue(Object value) - { - for(;;) - { - EntryIterator p = null; - try - { - p = (EntryIterator)entrySet().iterator(); - - if(value == null) - { - while(p.hasNext()) - { - Entry e = (Entry)p.next(); - if(e.getValue() == null) - { - return true; - } - } - } - else - { - while(p.hasNext()) - { - Entry e = (Entry)p.next(); - if(value.equals(e.getValue())) - { - return true; - } - } - } - return false; - } - catch(DeadlockException e) - { - if(_connection.dbTxn() != null) - { - throw e; - } - else - { - if(_connection.deadlockWarning()) - { - _connection.communicator().getLogger().warning("Deadlock in Freeze.Map.containsValue while " + - "iterating over Db \"" + _db.dbName() + - "\"; retrying..."); - } - - // - // Try again - // - } - } - finally - { - if(p != null) - { - p.close(); - } - } - } - } - - public boolean - containsKey(Object key) - { - if(_db == null) - { - DatabaseException ex = new DatabaseException(); - ex.message = _errorPrefix + "\"" + _db.dbName() + "\" has been closed"; - throw ex; - } - - byte[] k = encodeKey(key, _connection.communicator()); - - com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k); - com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(); - dbValue.setPartial(true); - - if(_trace >= 2) - { - _connection.communicator().getLogger().trace("Freeze.Map", "checking key in Db \"" + _db.dbName() + "\""); - } - - for(;;) - { - try - { - return _db.db().get(_connection.dbTxn(), dbKey, dbValue, null) - == com.sleepycat.db.OperationStatus.SUCCESS; - } - catch(com.sleepycat.db.DeadlockException e) - { - if(_connection.dbTxn() != null) - { - DeadlockException ex = new DeadlockException( - _errorPrefix + "Db.get: " + e.getMessage(), _connection.currentTransaction()); - ex.initCause(e); - throw ex; - } - else - { - if(_connection.deadlockWarning()) - { - _connection.communicator().getLogger().warning( - "Deadlock in Freeze.Map.containsKey while " + - "reading Db \"" + _db.dbName() + - "\"; retrying..."); - } - // - // Try again - // - } - } - catch(com.sleepycat.db.DatabaseException e) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.get: " + e.getMessage(); - throw ex; - } - } - } - - public Object - get(Object key) - { - byte[] k = encodeKey(key, _connection.communicator()); - com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k); - byte[] v = getImpl(dbKey); - if(v == null) - { - return null; - } - else - { - return decodeValue(v, _connection.communicator()); - } - } - - public Object - put(Object key, Object value) - { - byte[] k = encodeKey(key, _connection.communicator()); - com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k); - byte[] v = getImpl(dbKey); - Object o = null; - if(v != null) - { - o = decodeValue(v, _connection.communicator()); - } - putImpl(dbKey, value); - return o; - } - - public Object - remove(Object key) - { - byte[] k = encodeKey(key, _connection.communicator()); - com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k); - byte[] v = getImpl(dbKey); - - if(v != null && removeImpl(dbKey)) - { - return decodeValue(v, _connection.communicator()); - } - else - { - return null; - } - } - - // - // Proprietary API calls. These are much faster than the - // corresponding Java collections API methods since the unwanted - // reads are avoided. - // - public void - fastPut(Object key, Object value) - { - byte[] k = encodeKey(key, _connection.communicator()); - com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k); - putImpl(dbKey, value); - } + int closeAllIterators(); // - // Returns true if the record was removed, false otherwise. + // Close this map and destroy the underlying Berkeley DB database. // - public boolean - fastRemove(Object key) - { - byte[] k = encodeKey(key, _connection.communicator()); - com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k); - return removeImpl(dbKey); - } - - public void - clear() - { - if(_db == null) - { - DatabaseException ex = new DatabaseException(); - ex.message = _errorPrefix + "\"" + _db.dbName() + "\" has been closed"; - throw ex; - } - - com.sleepycat.db.Transaction txn = _connection.dbTxn(); - - for(;;) - { - try - { - _db.db().truncate(txn, false); - break; - } - catch(com.sleepycat.db.DeadlockException e) - { - if(txn != null) - { - DeadlockException ex = new DeadlockException( - _errorPrefix + "Db.truncate: " + e.getMessage(), _connection.currentTransaction()); - ex.initCause(e); - throw ex; - } - else - { - if(_connection.deadlockWarning()) - { - _connection.communicator().getLogger().warning("Deadlock in Freeze.Map.clear on Db \"" + - _db.dbName() + "\"; retrying..."); - } - - // - // Try again - // - } - } - catch(com.sleepycat.db.DatabaseException e) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.truncate: " + e.getMessage(); - throw ex; - } - } - } - - public java.util.Set - entrySet() - { - if(_entrySet == null) - { - _entrySet = new java.util.AbstractSet() - { - public java.util.Iterator - iterator() - { - return new EntryIteratorImpl(null, null, null, false, false); - } - - public boolean - contains(Object o) - { - if(!(o instanceof Map.Entry)) - { - return false; - } - Map.Entry entry = (Map.Entry)o; - Object value = entry.getValue(); - - byte[] v = getImpl(entry.getDbKey()); - return v != null && valEquals(decodeValue(v, _connection.communicator()), value); - } - - public boolean - remove(Object o) - { - if(!(o instanceof Map.Entry)) - { - return false; - } - Map.Entry entry = (Map.Entry)o; - Object value = entry.getValue(); - - byte[] v = getImpl(entry.getDbKey()); - if(v != null && valEquals(decodeValue(v, _connection.communicator()), value)) - { - return removeImpl(entry.getDbKey()); - } - return false; - } - - public int - size() - { - return Map.this.size(); - } - - public void - clear() - { - Map.this.clear(); - } - }; - } - - return _entrySet; - } - - public void - closeAllIterators() - { - closeAllIteratorsExcept(null, false); - } - - - // - // Close this map and destroy the underlying Berkeley DB database - // - public void destroy() - { - if(_db == null) - { - throw new DatabaseException(_errorPrefix + "This map is closed"); - } - - String dbName = _db.dbName(); - - if(dbName.equals(Util.catalogName()) || dbName.equals(Util.catalogIndexListName())) - { - throw new DatabaseException(_errorPrefix + "You cannot destroy the \"" + dbName + "\" database"); - } - - if(_connection.currentTransaction() != null) - { - throw new DatabaseException(_errorPrefix + "You cannot destroy a database within an active transaction"); - } - - if(_trace >= 1) - { - _connection.communicator().getLogger().trace("Freeze.Map", "destroying \"" + dbName + "\""); - } - - closeDb(); - - for(;;) - { - Transaction tx = null; - try - { - tx = _connection.beginTransaction(); - com.sleepycat.db.Transaction txn = _connection.dbTxn(); - - - Catalog catalog = new Catalog(_connection, Util.catalogName(), true); - catalog.remove(dbName); - - CatalogIndexList catalogIndexList = new CatalogIndexList(_connection, Util.catalogIndexListName(), true); - catalogIndexList.remove(dbName); - - _connection.dbEnv().getEnv().removeDatabase(txn, dbName, null); - - // - // Remove all indices - // - for(String index : _indexMap.keySet()) - { - _connection.removeMapIndex(dbName, index); - - } - - tx.commit(); - - break; // for(;;) - } - catch(java.io.FileNotFoundException dx) - { - try - { - tx.rollback(); - } - catch(DatabaseException e) - { - } - - DatabaseException e = new DatabaseException(_errorPrefix + "file not found"); - e.initCause(dx); - throw e; - } - catch(com.sleepycat.db.DeadlockException dx) - { - if(_connection.deadlockWarning()) - { - _connection.communicator().getLogger().warning("Deadlock in Freeze.Map.destroy on Db \"" + - dbName + "\"; retrying..."); - } - - // - // Ignored, try again - // - } - catch(com.sleepycat.db.DatabaseException dx) - { - try - { - tx.rollback(); - } - catch(DatabaseException e) - { - } - - DatabaseException e = new DatabaseException(_errorPrefix + dx.getMessage()); - e.initCause(dx); - throw e; - } - catch(RuntimeException rx) - { - try - { - tx.rollback(); - } - catch(DatabaseException e) - { - } - - throw rx; - } - } - } - - - void - closeAllIteratorsExcept(Object except, boolean finalizing) - { - synchronized(_iteratorList) - { - java.util.Iterator p = _iteratorList.iterator(); - - while(p.hasNext()) - { - Object obj = p.next(); - if(obj != except) - { - ((EntryIteratorImpl)obj).close(finalizing); - } - } - } - } - - protected void - finalize() - { - close(true); - } - - // - // The synchronization is only needed when finalizing is true - // - void - close(boolean finalizing) - { - synchronized(_connection) - { - if(_db != null) - { - try - { - closeAllIteratorsExcept(null, finalizing); - } - finally - { - _db = null; - _connection.unregisterMap(_token); - _token = null; - } - } - } - } - - EntryIterator - createIterator(Index index, Object fromKey, Object toKey) - { - KeyCodec codec = index == null ? (KeyCodec)this : (KeyCodec)index; - - Ice.Communicator communicator = _connection.getCommunicator(); - - return new EntryIteratorImpl(index, - fromKey == null ? null : codec.encodeKey(fromKey, communicator), - toKey == null ? null : codec.encodeKey(toKey, communicator), - false, true); - } - - ConnectionI connection() - { - return _connection; - } - - private static String - errorPrefix(String envName, String dbName) - { - return "Freeze DB DbEnv(\"" + envName + "\") Db(\"" + dbName + "\"): "; - } - - private static boolean - valEquals(Object o1, Object o2) - { - return (o1 == null ? o2 == null : o1.equals(o2)); - } - - private byte[] - getFirstOrLastKey(com.sleepycat.db.Database db, String dbName, byte[] key, boolean first) - { - if(db == null) - { - DatabaseException ex = new DatabaseException(); - ex.message = _errorPrefix + "\"" + dbName + "\" has been closed"; - throw ex; - } - - if(_trace >= 2) - { - _connection.communicator().getLogger().trace("Freeze.Map", "searching Db \"" + dbName + "\""); - } - - com.sleepycat.db.DatabaseEntry dbKey = key == null ? - new com.sleepycat.db.DatabaseEntry(): - new com.sleepycat.db.DatabaseEntry(key); - - com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(); - dbValue.setPartial(true); // not interested in value - - try - { - for(;;) - { - com.sleepycat.db.Cursor dbc = null; - try - { - dbc = db.openCursor(_connection.dbTxn(), null); - com.sleepycat.db.OperationStatus status; - - if(key == null) - { - status = first ? - dbc.getFirst(dbKey, dbValue, null) : dbc.getLast(dbKey, dbValue, null); - } - else if(first) - { - status = dbc.getSearchKeyRange(dbKey, dbValue, null); - } - else - { - status = dbc.getSearchKeyRange(dbKey, dbValue, null); - - if(status == com.sleepycat.db.OperationStatus.SUCCESS) - { - // - // goto the previous pair, which must be < key - // - status = dbc.getPrevNoDup(dbKey, dbValue, null); - } - else if(status == com.sleepycat.db.OperationStatus.NOTFOUND) - { - // - // All keys < desired toKey, so we pick the largest of - // all, the last one - // - status = dbc.getLast(dbKey, dbValue, null); - } - } - - if(status == com.sleepycat.db.OperationStatus.SUCCESS) - { - return dbKey.getData(); - } - else - { - return null; - } - } - catch(com.sleepycat.db.DeadlockException dx) - { - if(_connection.dbTxn() != null) - { - DeadlockException ex = new DeadlockException( - _errorPrefix + "Dbc.getXXX: " + dx.getMessage(), _connection.currentTransaction()); - ex.initCause(dx); - throw ex; - } - else - { - if(_connection.deadlockWarning()) - { - _connection.communicator().getLogger().warning( - "Deadlock in Freeze.Map while searching \"" + db.getDatabaseName() + - "\"; retrying..."); - } - - // - // Retry - // - } - } - finally - { - if(dbc != null) - { - try - { - dbc.close(); - } - catch(com.sleepycat.db.DeadlockException dx) - { - // - // Ignored - // - } - } - } - } - } - catch(com.sleepycat.db.DatabaseException dx) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(dx); - ex.message = _errorPrefix + "Db.openCursor/Dbc.getXXX: " + dx.getMessage(); - throw ex; - } - } - - private byte[] - getImpl(com.sleepycat.db.DatabaseEntry dbKey) - { - if(_db == null) - { - DatabaseException ex = new DatabaseException(); - ex.message = _errorPrefix + "\"" + _db.dbName() + "\" has been closed"; - throw ex; - } - - com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(); - - if(_trace >= 2) - { - _connection.communicator().getLogger().trace("Freeze.Map", "reading value from Db \"" + _db.dbName() + - "\""); - } - - for(;;) - { - try - { - com.sleepycat.db.OperationStatus rc = _db.db().get(_connection.dbTxn(), dbKey, dbValue, null); - if(rc == com.sleepycat.db.OperationStatus.SUCCESS) - { - return dbValue.getData(); - } - else - { - return null; - } - } - catch(com.sleepycat.db.DeadlockException e) - { - if(_connection.dbTxn() != null) - { - DeadlockException ex = new DeadlockException( - _errorPrefix + "Db.get: " + e.getMessage(), _connection.currentTransaction()); - ex.initCause(e); - throw ex; - } - else - { - if(_connection.deadlockWarning()) - { - _connection.communicator().getLogger().warning("Deadlock in Freeze.Map.getImpl while " + - "reading Db \"" + _db.dbName() + - "\"; retrying..."); - } - - // - // Try again - // - } - } - catch(com.sleepycat.db.DatabaseException e) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.get: " + e.getMessage(); - throw ex; - } - } - } - - private void - putImpl(com.sleepycat.db.DatabaseEntry dbKey, Object value) - { - if(_db == null) - { - DatabaseException ex = new DatabaseException(); - ex.message = _errorPrefix + "\"" + _db.dbName() + "\" has been closed"; - throw ex; - } - - byte[] v = encodeValue(value, _connection.communicator()); - com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(v); - - if(_trace >= 2) - { - _connection.communicator().getLogger().trace("Freeze.Map", "writing value in Db \"" + _db.dbName() + "\""); - } - - com.sleepycat.db.Transaction txn = _connection.dbTxn(); - if(txn == null) - { - closeAllIterators(); - } - - for(;;) - { - try - { - _db.db().put(txn, dbKey, dbValue); - break; - } - catch(com.sleepycat.db.DeadlockException e) - { - if(txn != null) - { - DeadlockException ex = new DeadlockException( - _errorPrefix + "Db.put: " + e.getMessage(), _connection.currentTransaction()); - ex.initCause(e); - throw ex; - } - else - { - if(_connection.deadlockWarning()) - { - _connection.communicator().getLogger().warning("Deadlock in Freeze.Map.putImpl while " + - "writing into Db \"" + _db.dbName() + - "\"; retrying..."); - } - - // - // Try again - // - } - } - catch(com.sleepycat.db.DatabaseException e) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.put: " + e.getMessage(); - throw ex; - } - } - } - - private boolean - removeImpl(com.sleepycat.db.DatabaseEntry dbKey) - { - if(_db == null) - { - DatabaseException ex = new DatabaseException(); - ex.message = _errorPrefix + "\"" + _db.dbName() + "\" has been closed"; - throw ex; - } - - if(_trace >= 2) - { - _connection.communicator().getLogger().trace("Freeze.Map", "deleting value from Db \"" + _db.dbName() + - "\""); - } - - com.sleepycat.db.Transaction txn = _connection.dbTxn(); - if(txn == null) - { - closeAllIterators(); - } - - for(;;) - { - try - { - com.sleepycat.db.OperationStatus rc = _db.db().delete(txn, dbKey); - return (rc == com.sleepycat.db.OperationStatus.SUCCESS); - } - catch(com.sleepycat.db.DeadlockException e) - { - if(txn != null) - { - DeadlockException ex = new DeadlockException( - _errorPrefix + "Db.del: " + e.getMessage(), _connection.currentTransaction()); - ex.initCause(e); - throw ex; - } - else - { - if(_connection.deadlockWarning()) - { - _connection.communicator().getLogger().warning("Deadlock in Freeze.Map.removeImpl while " + - "writing into Db \"" + _db.dbName() + - "\"; retrying..."); - } - - // - // Try again - // - } - } - catch(com.sleepycat.db.DatabaseException e) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.del: " + e.getMessage(); - throw ex; - } - } - } - - private class Comparator implements java.util.Comparator - { - Comparator(java.util.Comparator comparator) - { - _comparator = comparator; - } - - public java.util.Comparator comparator() - { - return _comparator; - } - - public int compare(Object o1, Object o2) - { - byte[] d1 = (byte[])o1; - byte[] d2 = (byte[])o2; - - Ice.Communicator communicator = _connection.communicator(); - - return _comparator.compare(decodeKey(d1, communicator), - decodeKey(d2, communicator)); - } - - // - // The user-supplied comparator - // - private final java.util.Comparator _comparator; - } - - public abstract class Index - implements com.sleepycat.db.SecondaryKeyCreator, java.util.Comparator, KeyCodec - { - // - // Implementation details - // - public boolean - createSecondaryKey(com.sleepycat.db.SecondaryDatabase secondary, - com.sleepycat.db.DatabaseEntry key, - com.sleepycat.db.DatabaseEntry value, - com.sleepycat.db.DatabaseEntry result) - throws com.sleepycat.db.DatabaseException - { - Ice.Communicator communicator = _connection.getCommunicator(); - byte[] secondaryKey = marshalKey(value.getData()); - assert(secondaryKey != null); - - result.setData(secondaryKey); - result.setSize(secondaryKey.length); - return true; - } - - com.sleepycat.db.SecondaryDatabase - db() - { - return _db; - } - - String name() - { - return _name; - } - - protected Index(String name) - { - _name = name; - } - - void - associate(String dbName, com.sleepycat.db.Database db, - com.sleepycat.db.Transaction txn, boolean createDb, - java.util.Comparator comparator) - throws com.sleepycat.db.DatabaseException, java.io.FileNotFoundException - { - _dbName = dbName + "." + _name; - _comparator = comparator; - - assert(txn != null); - assert(_db == null); - - com.sleepycat.db.SecondaryConfig config = new com.sleepycat.db.SecondaryConfig(); - config.setAllowCreate(createDb); - config.setAllowPopulate(true); // We always populate empty indices - config.setSortedDuplicates(true); - config.setType(com.sleepycat.db.DatabaseType.BTREE); - if(_comparator != null) - { - config.setBtreeComparator(this); - } - config.setKeyCreator(this); - - Ice.Properties properties = _connection.communicator().getProperties(); - String propPrefix = "Freeze.Map." + _dbName + "."; - - int btreeMinKey = properties.getPropertyAsInt(propPrefix + "BtreeMinKey"); - if(btreeMinKey > 2) - { - if(_trace >= 1) - { - _connection.communicator().getLogger().trace( - "Freeze.Map", "Setting \"" + _dbName + "\"'s btree minkey to " + btreeMinKey); - } - config.setBtreeMinKey(btreeMinKey); - } - - boolean checksum = properties.getPropertyAsInt(propPrefix + "Checksum") > 0; - if(checksum) - { - if(_trace >= 1) - { - _connection.communicator().getLogger().trace( - "Freeze.Map", "Turning checksum on for \"" + _dbName + "\""); - } - - config.setChecksum(true); - } - - int pageSize = properties.getPropertyAsInt(propPrefix + "PageSize"); - if(pageSize > 0) - { - if(_trace >= 1) - { - _connection.communicator().getLogger().trace( - "Freeze.Map", "Setting \"" + _dbName + "\"'s pagesize to " + pageSize); - } - config.setPageSize(pageSize); - } - - _db = _connection.dbEnv().getEnv().openSecondaryDatabase(txn, _dbName, null, db, config); - } - - void init(Index from) - { - assert(_name.equals(from._name)); - assert(_db == null); - - _dbName = from._dbName; - _db = from._db; - _comparator = from._comparator; - } - - java.util.Comparator comparator() - { - return _comparator; - } - - Map parent() - { - return Map.this; - } - - Object firstKey(Object fromKey, Object toKey) - { - byte[] fk = fromKey == null ? null : - encodeKey(fromKey, _connection.communicator()); - - byte[] k = getFirstOrLastKey(_db, _dbName, fk, true); - if(k == null) - { - throw new NoSuchElementException(); - } - else - { - Object key = decodeKey(k, _connection.communicator()); - if(toKey != null && _comparator.compare(key, toKey) >= 0) - { - throw new NoSuchElementException(); - } - return key; - } - } - - Object lastKey(Object fromKey, Object toKey) - { - byte[] tk = toKey == null ? null : - encodeKey(toKey, _connection.communicator()); - - byte[] k = getFirstOrLastKey(_db, _dbName, tk, false); - if(k == null) - { - throw new NoSuchElementException(); - } - else - { - Object key = decodeKey(k, _connection.communicator()); - if(fromKey != null && _comparator.compare(fromKey, key) > 0) - { - throw new NoSuchElementException(); - } - return key; - } - } - - void close() - { - // - // close() is called by MapDb only on the "main" index - // (the one that was associated) - // - - if(_db != null) - { - try - { - _db.close(); - } - catch(com.sleepycat.db.DatabaseException dx) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(dx); - ex.message = _errorPrefix + "Db.close for index \"" + _dbName + "\": " + dx.getMessage(); - throw ex; - } - _db = null; - } - } - - public EntryIterator - untypedFind(Object key, boolean onlyDups) - { - byte[] k = encodeKey(key, _connection.communicator()); - return new EntryIteratorImpl(this, k, null, onlyDups, false); - } - - public int - untypedCount(Object key) - { - byte[] k = encodeKey(key, _connection.communicator()); - - com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k); - com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(); - - // - // When we have a custom-comparison function, Berkeley DB returns - // the key on-disk (when it finds one). We disable this behavior: - // (ref Oracle SR 5925672.992) - // - dbKey.setPartial(true); - - // - // dlen is 0, so we should not retrieve any value - // - dbValue.setPartial(true); - - try - { - for(;;) - { - com.sleepycat.db.Cursor dbc = null; - try - { - dbc = _db.openCursor(null, null); - if(dbc.getSearchKey(dbKey, dbValue, null) == com.sleepycat.db.OperationStatus.SUCCESS) - { - return dbc.count(); - } - else - { - return 0; - } - } - catch(com.sleepycat.db.DeadlockException dx) - { - if(_connection.deadlockWarning()) - { - _connection.communicator().getLogger().warning( - "Deadlock in Freeze.Map.Index.untypedCount while iterating over index \"" + _dbName + - "\"; retrying..."); - } - - // - // Retry - // - } - finally - { - if(dbc != null) - { - try - { - dbc.close(); - } - catch(com.sleepycat.db.DeadlockException dx) - { - // - // Ignored - // - } - } - } - } - } - catch(com.sleepycat.db.DatabaseException dx) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(dx); - ex.message = _errorPrefix + "Db.cursor for index \"" + _dbName + "\": " + dx.getMessage(); - throw ex; - } - } - - boolean containsKey(Object key) - { - byte[] k = encodeKey(key, _connection.communicator()); - - com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k); - com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(); - dbValue.setPartial(true); - - if(_trace >= 2) - { - _connection.communicator().getLogger().trace("Freeze.Map.Index", "checking key in Db \"" + _dbName + - "\""); - } - - for(;;) - { - try - { - return _db.get(_connection.dbTxn(), dbKey, dbValue, null) - == com.sleepycat.db.OperationStatus.SUCCESS; - } - catch(com.sleepycat.db.DeadlockException e) - { - if(_connection.dbTxn() != null) - { - DeadlockException ex = new DeadlockException( - _errorPrefix + "Db.get: " + e.getMessage(), _connection.currentTransaction()); - ex.initCause(e); - throw ex; - } - else - { - if(_connection.deadlockWarning()) - { - _connection.communicator().getLogger().warning( - "Deadlock in Freeze.Map.Index.containsKey while " + - "reading Db \"" + _dbName + "\"; retrying..."); - } - // - // Try again - // - } - } - catch(com.sleepycat.db.DatabaseException e) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.get: " + e.getMessage(); - throw ex; - } - } - } - - // - // Extracts the index key from this value - // - public abstract Object extractKey(Object value); - - protected byte[] marshalKey(byte[] value) - { - Object decodedValue = decodeValue(value, _connection.communicator()); - return encodeKey(extractKey(decodedValue), _connection.communicator()); - } - - // - // The user-supplied comparator - // - protected java.util.Comparator _comparator; - - private String _name; - private String _dbName; - private com.sleepycat.db.SecondaryDatabase _db; - } + void destroy(); /** * - * The entry iterator allows clients to explicitly close the iterator + * The entry iterator allows clients to explicitly close the iterator * and free resources allocated for the iterator as soon as possible. * **/ - public interface EntryIterator extends java.util.Iterator + public interface EntryIterator<T> extends java.util.Iterator<T> { void close(); void destroy(); // an alias for close } - class EntryIteratorImpl implements EntryIterator - { - EntryIteratorImpl(Index index, byte[] fromKey, byte[] toKey, - boolean onlyFromKeyDups, boolean skipDups) - { - _index = index; - _fromKey = fromKey; - _toKey = toKey; - _onlyFromKeyDups = onlyFromKeyDups; - _skipDups = skipDups; - - try - { - com.sleepycat.db.Transaction txn = _connection.dbTxn(); - if(txn == null) - { - // - // Start transaction - // - txn = _connection.dbEnv().getEnv().beginTransaction(null, null); - _txn = txn; - - if(_connection.txTrace() >= 1) - { - String txnId = Long.toHexString((_txn.getId() & 0x7FFFFFFF) + 0x80000000L); - - _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix + - "started transaction " + txnId + " for cursor"); - } - } - - // - // Open cursor with this transaction - // - if(index == null) - { - _cursor = _db.db().openCursor(txn, null); - } - else - { - _cursor = index.db().openSecondaryCursor(txn, null); - } - } - catch(com.sleepycat.db.DeadlockException dx) - { - dead(); - DeadlockException ex = new DeadlockException( - _errorPrefix + "EntryIterator constructor: " + dx.getMessage(), _connection.currentTransaction()); - ex.initCause(dx); - throw ex; - } - catch(com.sleepycat.db.DatabaseException dx) - { - dead(); - DatabaseException ex = new DatabaseException(); - ex.initCause(dx); - ex.message = _errorPrefix + "EntryIterator constructor: " + dx.getMessage(); - throw ex; - } - - synchronized(_iteratorList) - { - _iteratorList.addFirst(this); - java.util.Iterator p = _iteratorList.iterator(); - p.next(); - _iteratorListToken = p; - } - } - - public boolean - hasNext() - { - if(_current == null || _current == _lastReturned) - { - com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(); - com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(); - com.sleepycat.db.DatabaseEntry dbIKey = new com.sleepycat.db.DatabaseEntry(); - com.sleepycat.db.OperationStatus status = null; - - try - { - if(_index != null) - { - com.sleepycat.db.SecondaryCursor c = (com.sleepycat.db.SecondaryCursor)_cursor; - if(_current == null) - { - // - // First key - // - if(_fromKey != null) - { - dbIKey.setData(_fromKey); - status = c.getSearchKey(dbIKey, dbKey, dbValue, null); - } - else - { - status = c.getFirst(dbIKey, dbKey, dbValue, null); - } - } - else - { - if(_onlyFromKeyDups) - { - status = c.getNextDup(dbIKey, dbKey, dbValue, null); - } - else if(_skipDups) - { - status = c.getNextNoDup(dbIKey, dbKey, dbValue, null); - } - else - { - status = c.getNext(dbIKey, dbKey, dbValue, null); - } - } - } - else - { - if(_current == null && _fromKey != null) - { - dbKey.setData(_fromKey); - status = _cursor.getSearchKey(dbKey, dbValue, null); - } - else - { - status = _cursor.getNext(dbKey, dbValue, null); - } - } - } - catch(com.sleepycat.db.DeadlockException dx) - { - dead(); - DeadlockException ex = new DeadlockException( - _errorPrefix + "Dbc.get: " + dx.getMessage(), _connection.currentTransaction()); - ex.initCause(dx); - throw ex; - } - catch(com.sleepycat.db.DatabaseException dx) - { - dead(); - DatabaseException ex = new DatabaseException(); - ex.initCause(dx); - ex.message = _errorPrefix + "Dbc.get: " + dx.getMessage(); - throw ex; - } - - if(status == com.sleepycat.db.OperationStatus.SUCCESS) - { - // - // Verify it's < _toKey - // - boolean inRange = true; - if(_toKey != null) - { - if(_index != null) - { - inRange = _index.compare(dbIKey.getData(), _toKey) < 0; - } - else - { - inRange = _comparator.compare(dbKey.getData(), _toKey) < 0; - } - } - - if(inRange) - { - _current = new Entry(this, Map.this, _connection.communicator(), dbKey, - dbValue.getData(), dbIKey.getData()); - return true; - } - } - return false; - } - else - { - return true; - } - } - - public Object - next() - { - if(hasNext()) - { - _lastReturned = _current; - return _lastReturned; - } - else - { - throw new java.util.NoSuchElementException(); - } - } - - public void - remove() - { - if(_txn != null) - { - closeAllIteratorsExcept(this, false); - } - - // - // Removes the last object returned by next() - // - if(_lastReturned == null) - { - throw new IllegalStateException(); - } - - if(_lastReturned == _current) - { - try - { - if(_cursor.delete() == com.sleepycat.db.OperationStatus.KEYEMPTY) - { - throw new IllegalStateException(); - } - } - catch(com.sleepycat.db.DeadlockException e) - { - dead(); - DeadlockException ex = new DeadlockException(_errorPrefix + "Dbc.del: " + e.getMessage(), - _connection.currentTransaction()); - ex.initCause(e); - throw ex; - } - catch(com.sleepycat.db.DatabaseException e) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "Dbc.del: " + e.getMessage(); - throw ex; - } - } - else - { - // - // Duplicate the cursor and move the _lastReturned - // element to delete it (using the duplicate) - // - - // - // This works only for non-index iterators - // - if(_index != null) - { - throw new UnsupportedOperationException(); - } - - com.sleepycat.db.Cursor clone = null; - - try - { - clone = _cursor.dup(true); - - // - // Not interested in data - // - com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(); - dbValue.setPartial(true); - - com.sleepycat.db.OperationStatus rc = clone.getSearchKey(_lastReturned.getDbKey(), dbValue, null); - - if(rc == com.sleepycat.db.OperationStatus.NOTFOUND) - { - throw new IllegalStateException(); - } - if(clone.delete() == com.sleepycat.db.OperationStatus.KEYEMPTY) - { - throw new IllegalStateException(); - } - } - catch(com.sleepycat.db.DeadlockException e) - { - dead(); - DeadlockException ex = new DeadlockException(_errorPrefix + "EntryIterator.remove: " + e.getMessage(), - _connection.currentTransaction()); - ex.initCause(e); - throw ex; - } - catch(com.sleepycat.db.DatabaseException e) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "EntryIterator.remove: " + e.getMessage(); - throw ex; - } - finally - { - if(clone != null) - { - closeCursor(clone); - } - } - } - } - - // - // Extra operations. - // - public void - close() - { - close(false); - } - - // - // The synchronized is needed because this method can be called - // concurrently by Connection, Map and Map.EntryIterator finalizers. - // - synchronized void - close(boolean finalizing) - { - if(finalizing && (_cursor != null || _txn != null) && _connection.closeInFinalizeWarning()) - { - _connection.communicator().getLogger().warning( - "finalize() closing a live iterator on Map \"" + _db.dbName() + "\"; the application " + - "should have closed it earlier by calling Map.EntryIterator.close(), " + - "Map.closeAllIterators(), Map.close(), Connection.close(), or (if also " + - "leaking a transaction) Transaction.commit() or Transaction.rollback()"); - } - - if(_iteratorListToken != null) - { - synchronized(_iteratorList) - { - _iteratorListToken.remove(); - _iteratorListToken = null; - } - } - - if(_cursor != null) - { - com.sleepycat.db.Cursor cursor = _cursor; - _cursor = null; - closeCursor(cursor); - } - - if(_txn != null) - { - String txnId = null; - - try - { - if(_connection.txTrace() >= 1) - { - txnId = Long.toHexString((_txn.getId() & 0x7FFFFFFF) + 0x80000000L); - } - - _txn.commit(); - - if(_connection.txTrace() >= 1) - { - _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix + - "committed transaction " + txnId); - } - } - catch(com.sleepycat.db.DeadlockException e) - { - if(_connection.txTrace() >= 1) - { - _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix + - "failed to commit transaction " + txnId + ": " + - e.getMessage()); - } - - DeadlockException ex = new DeadlockException( - _errorPrefix + "DbTxn.commit: " + e.getMessage(), _connection.currentTransaction()); - ex.initCause(e); - throw ex; - } - catch(com.sleepycat.db.DatabaseException e) - { - if(_connection.txTrace() >= 1) - { - _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix + - "failed to commit transaction " + txnId + ": " + - e.getMessage()); - } - - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "DbTxn.commit: " + e.getMessage(); - throw ex; - } - finally - { - _txn = null; - } - } - } - - // - // An alias for close() - // - public void - destroy() - { - close(); - } - - protected void - finalize() - { - close(true); - } - - void - setValue(Map.Entry entry, Object value) - { - if(_index != null) - { - throw new UnsupportedOperationException( - _errorPrefix + "Cannot set an iterator retrieved through an index"); - } - - if(_txn != null) - { - closeAllIteratorsExcept(this, false); - } - - // - // Are we trying to update the current value? - // - if(_current == entry) - { - // - // Yes, update it directly - // - byte[] v = encodeValue(value, _connection.communicator()); - com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(v); - - try - { - _cursor.putCurrent(dbValue); - } - catch(com.sleepycat.db.DeadlockException e) - { - dead(); - DeadlockException ex = new DeadlockException(_errorPrefix + "Dbc.put: " + e.getMessage(), - _connection.currentTransaction()); - ex.initCause(e); - throw ex; - } - catch(com.sleepycat.db.DatabaseException e) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "Dbc.put: " + e.getMessage(); - throw ex; - } - } - else - { - // - // Duplicate the cursor and move the entry - // element to update it (using the duplicate cursor) - // - - com.sleepycat.db.Cursor clone = null; - - try - { - clone = _cursor.dup(true); - - // - // Not interested in data - // - com.sleepycat.db.DatabaseEntry dummy = new com.sleepycat.db.DatabaseEntry(); - dummy.setPartial(true); - - com.sleepycat.db.OperationStatus rc = clone.getSearchKey(entry.getDbKey(), dummy, null); - - if(rc == com.sleepycat.db.OperationStatus.NOTFOUND) - { - NotFoundException ex = new NotFoundException(); - ex.message = _errorPrefix + "Dbc.get: DB_NOTFOUND"; - throw ex; - } - - byte[] v = encodeValue(value, _connection.communicator()); - com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(v); - clone.putCurrent(dbValue); - } - catch(com.sleepycat.db.DeadlockException e) - { - dead(); - DeadlockException ex = new DeadlockException(_errorPrefix + "EntryIterator.setValue: " + e.getMessage(), - _connection.currentTransaction()); - ex.initCause(e); - throw ex; - } - catch(com.sleepycat.db.DatabaseException e) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "EntryIterator.setValue: " + e.getMessage(); - throw ex; - } - finally - { - if(clone != null) - { - closeCursor(clone); - } - } - } - } - - private void - closeCursor(com.sleepycat.db.Cursor cursor) - { - try - { - cursor.close(); - } - catch(com.sleepycat.db.DeadlockException e) - { - dead(); - DeadlockException ex = new DeadlockException( - _errorPrefix + "Dbc.close: " + e.getMessage(), _connection.currentTransaction()); - ex.initCause(e); - throw ex; - } - catch(com.sleepycat.db.DatabaseException e) - { - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "Dbc.close: " + e.getMessage(); - throw ex; - } - } - - private void - dead() - { - if(_cursor != null) - { - com.sleepycat.db.Cursor cursor = _cursor; - _cursor = null; - closeCursor(cursor); - } - - if(_txn != null) - { - String txnId = null; - - try - { - if(_connection.txTrace() >= 1) - { - txnId = Long.toHexString((_txn.getId() & 0x7FFFFFFF) + 0x80000000L); - } - - _txn.abort(); - - if(_connection.txTrace() >= 1) - { - _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix + - "rolled back transaction " + txnId); - } - } - catch(com.sleepycat.db.DeadlockException e) - { - if(_connection.txTrace() >= 1) - { - _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix + - "failed to roll back transaction " + txnId + - ": " + e.getMessage()); - } - - DeadlockException ex = new DeadlockException( - _errorPrefix + "DbTxn.abort: " + e.getMessage(), _connection.currentTransaction()); - ex.initCause(e); - throw ex; - } - catch(com.sleepycat.db.DatabaseException e) - { - if(_connection.txTrace() >= 1) - { - _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix + - "failed to roll back transaction " + - txnId + ": " + e.getMessage()); - } - - DatabaseException ex = new DatabaseException(); - ex.initCause(e); - ex.message = _errorPrefix + "DbTxn.abort: " + e.getMessage(); - throw ex; - } - finally - { - _txn = null; - } - } - } - - private com.sleepycat.db.Transaction _txn; - private com.sleepycat.db.Cursor _cursor; - private Entry _current; - private Entry _lastReturned; - private java.util.Iterator _iteratorListToken; - - private final Index _index; - private final byte[] _fromKey; - private final byte[] _toKey; - private final boolean _onlyFromKeyDups; - private final boolean _skipDups; - } - - static class Entry implements java.util.Map.Entry - { - public - Entry(EntryIteratorImpl iterator, Map map, Ice.Communicator communicator, - com.sleepycat.db.DatabaseEntry dbKey, byte[] valueBytes, byte[] indexBytes) - { - _iterator = iterator; - _map = map; - _communicator = communicator; - _dbKey = dbKey; - _valueBytes = valueBytes; - _indexBytes = indexBytes; - } - - public Object - getKey() - { - if(!_haveKey) - { - assert(_dbKey != null); - _key = _map.decodeKey(_dbKey.getData(), _communicator); - _haveKey = true; - } - return _key; - } - - public Object - getValue() - { - if(!_haveValue) - { - assert(_valueBytes != null); - _value = _map.decodeValue(_valueBytes, _communicator); - _haveValue = true; - // - // Not needed anymore - // - _valueBytes = null; - } - return _value; - } - - public byte[] - getIndexBytes() - { - return _indexBytes; - } - - public Object - setValue(Object value) - { - Object old = getValue(); - _iterator.setValue(this, value); - _value = value; - _haveValue = true; - return old; - } - - public boolean - equals(Object o) - { - if(!(o instanceof Map.Entry)) - { - return false; - } - Map.Entry e = (Map.Entry)o; - return eq(getKey(), e.getKey()) && eq(getValue(), e.getValue()); - } - - public int - hashCode() - { - return ((getKey() == null) ? 0 : getKey().hashCode()) ^ - ((getValue() == null) ? 0 : getValue().hashCode()); - } - - public String - toString() - { - return getKey() + "=" + getValue(); - } - - com.sleepycat.db.DatabaseEntry - getDbKey() - { - return _dbKey; - } - - private /*static*/ boolean - eq(Object o1, Object o2) - { - return (o1 == null ? o2 == null : o1.equals(o2)); - } - - private EntryIteratorImpl _iterator; - private Map _map; - private Ice.Communicator _communicator; - private com.sleepycat.db.DatabaseEntry _dbKey; - private byte[] _valueBytes; - private byte[] _indexBytes; - private Object _key; - private boolean _haveKey = false; - private Object _value; - private boolean _haveValue = false; - } - - public static class Patcher implements IceInternal.Patcher - { - public - Patcher(String type) - { - this.type = type; - } - - public void - patch(Ice.Object v) - { - value = v; - } - - public String - type() - { - return this.type; - } - - public Ice.Object - value() - { - return this.value; - } - - public String type; - public Ice.Object value; - } - - protected ConnectionI _connection; - private final Comparator _comparator; - private final String _dbName; - - protected java.util.Iterator _token; - protected MapDb _db; - protected String _errorPrefix; - protected int _trace; - - private java.util.Set _entrySet; - private LinkedList _iteratorList = new LinkedList(); - private java.util.Map<String, Map.Index> _indexMap = new java.util.HashMap(); + Connection getConnection(); + void closeDb(); } |