summaryrefslogtreecommitdiff
path: root/java/src/Freeze/SharedDbEnv.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/Freeze/SharedDbEnv.java')
-rw-r--r--java/src/Freeze/SharedDbEnv.java402
1 files changed, 237 insertions, 165 deletions
diff --git a/java/src/Freeze/SharedDbEnv.java b/java/src/Freeze/SharedDbEnv.java
index d8dabe8a385..807b7ac88b7 100644
--- a/java/src/Freeze/SharedDbEnv.java
+++ b/java/src/Freeze/SharedDbEnv.java
@@ -23,34 +23,81 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
result = (SharedDbEnv)_map.get(key);
if(result == null)
{
+ result = new SharedDbEnv(key, dbEnv);
+
+ Object previousValue = _map.put(key, result);
+ assert(previousValue == null);
+ }
+ else
+ {
+ result._refCount++;
+ }
+ }
+
+ return result;
+ }
+
+ //
+ // Returns a shared map Db; the caller should NOT close this Db.
+ //
+ MapDb getSharedMapDb(String dbName, String key, String value,
+ java.util.Comparator comparator, Map.Index[] indices, java.util.Map indexComparators,
+ boolean createDb)
+ {
+ if(dbName.equals(_catalog.dbName()))
+ {
+ _catalog.checkTypes(key, value);
+ return _catalog;
+ }
+ else if(dbName.equals(_catalogIndexList.dbName()))
+ {
+ _catalogIndexList.checkTypes(key, value);
+ return _catalogIndexList;
+ }
+
+ synchronized(_sharedDbMap)
+ {
+ MapDb db = _sharedDbMap.get(dbName);
+ if(db == null)
+ {
+ ConnectionI insertConnection = (ConnectionI)Util.createConnection(_key.communicator, _key.envName);
+
try
{
- result = new SharedDbEnv(key, dbEnv);
+ db = new MapDb(insertConnection, dbName, key, value, comparator, indices, indexComparators, createDb);
}
- catch(com.sleepycat.db.DatabaseException dx)
+ finally
{
- DatabaseException ex = new DatabaseException();
- ex.initCause(dx);
- ex.message = errorPrefix(envName) + "creation: " + dx.getMessage();
- throw ex;
+ insertConnection.close();
}
- Object previousValue = _map.put(key, result);
+ Object previousValue = _sharedDbMap.put(dbName, db);
assert(previousValue == null);
}
else
{
- result._refCount++;
+ db.checkTypes(key, value);
+ db.connectIndices(indices);
}
+ return db;
}
+ }
- //
- // Make sure the result if fully initialized
- //
- result.init();
- return result;
+ //
+ // Tell SharedDbEnv to close and remove this Shared Db from the map
+ //
+ void removeSharedMapDb(String dbName)
+ {
+ synchronized(_sharedDbMap)
+ {
+ MapDb db = _sharedDbMap.remove(dbName);
+ if(db != null)
+ {
+ db.close();
+ }
+ }
}
-
+
public String
getEnvName()
{
@@ -68,20 +115,7 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
{
return _dbEnv;
}
-
- public SharedDb
- getCatalog()
- {
- return _catalog;
- }
-
- public SharedDb
- getCatalogIndexList()
- {
- return _catalogIndexList;
- }
-
-
+
public void
close()
{
@@ -96,66 +130,9 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
assert(value == this);
//
- // Join thread
- //
- synchronized(this)
- {
- _done = true;
- notify();
- }
-
- for(;;)
- {
- if(_thread != null)
- {
- try
- {
- _thread.join();
- _thread = null;
- break;
- }
- catch(InterruptedException ex)
- {
- }
- }
- }
-
- //
- // Release catalogs
- //
- if(_catalog != null)
- {
- _catalog.close();
- _catalog = null;
- }
-
- if(_catalogIndexList != null)
- {
- _catalogIndexList.close();
- _catalogIndexList = null;
- }
-
- if(_trace >= 1)
- {
- _key.communicator.getLogger().trace("Freeze.DbEnv", "closing database environment \"" +
- _key.envName + "\"");
- }
-
- //
- // Keep lock to prevent somebody else from re-opening this DbEnv
- // before it's closed.
+ // Cleanup with _map locked to prevent concurrent cleanup of the same dbEnv
//
- try
- {
- _dbEnv.close();
- }
- catch(com.sleepycat.db.DatabaseException dx)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(dx);
- ex.message = errorPrefix(_key.envName) + "close: " + dx.getMessage();
- throw ex;
- }
+ cleanup();
}
}
}
@@ -287,7 +264,6 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
private
SharedDbEnv(MapKey key, com.sleepycat.db.Environment dbEnv)
- throws com.sleepycat.db.DatabaseException
{
_key = key;
_dbEnv = dbEnv;
@@ -296,104 +272,198 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
Ice.Properties properties = key.communicator.getProperties();
_trace = properties.getPropertyAsInt("Freeze.Trace.DbEnv");
- if(_ownDbEnv)
+ try
{
- com.sleepycat.db.EnvironmentConfig config = new com.sleepycat.db.EnvironmentConfig();
+ if(_ownDbEnv)
+ {
+ com.sleepycat.db.EnvironmentConfig config = new com.sleepycat.db.EnvironmentConfig();
+
+ config.setErrorHandler(this);
+ config.setInitializeLocking(true);
+ config.setInitializeLogging(true);
+ config.setInitializeCache(true);
+ config.setAllowCreate(true);
+ config.setTransactional(true);
- config.setErrorHandler(this);
- config.setInitializeLocking(true);
- config.setInitializeLogging(true);
- config.setInitializeCache(true);
- config.setAllowCreate(true);
- config.setTransactional(true);
+ //
+ // Deadlock detection
+ //
+ config.setLockDetectMode(com.sleepycat.db.LockDetectMode.YOUNGEST);
- //
- // Deadlock detection
- //
- config.setLockDetectMode(com.sleepycat.db.LockDetectMode.YOUNGEST);
+ String propertyPrefix = "Freeze.DbEnv." + _key.envName;
+ if(properties.getPropertyAsInt(propertyPrefix + ".DbRecoverFatal") != 0)
+ {
+ config.setRunFatalRecovery(true);
+ }
+ else
+ {
+ config.setRunRecovery(true);
+ }
- String propertyPrefix = "Freeze.DbEnv." + _key.envName;
- if(properties.getPropertyAsInt(propertyPrefix + ".DbRecoverFatal") != 0)
+ if(properties.getPropertyAsIntWithDefault(propertyPrefix + ".DbPrivate", 1) != 0)
+ {
+ config.setPrivate(true);
+ }
+
+ if(properties.getPropertyAsIntWithDefault(propertyPrefix + ".OldLogsAutoDelete", 1) != 0)
+ {
+ config.setLogAutoRemove(true);
+ }
+
+ if(_trace >= 1)
+ {
+ _key.communicator.getLogger().trace("Freeze.DbEnv", "opening database environment \"" +
+ _key.envName + "\"");
+ }
+
+ try
+ {
+ String dbHome = properties.getPropertyWithDefault(propertyPrefix + ".DbHome", _key.envName);
+ java.io.File home = new java.io.File(dbHome);
+ _dbEnv = new com.sleepycat.db.Environment(home, config);
+ }
+ catch(java.io.FileNotFoundException dx)
+ {
+ NotFoundException ex = new NotFoundException();
+ ex.initCause(dx);
+ ex.message = errorPrefix(_key.envName) + "open: " + dx.getMessage();
+ throw ex;
+ }
+
+ //
+ // Default checkpoint period is every 120 seconds
+ //
+ _checkpointPeriod =
+ properties.getPropertyAsIntWithDefault(propertyPrefix + ".CheckpointPeriod", 120) * 1000;
+
+ _kbyte = properties.getPropertyAsIntWithDefault(propertyPrefix + ".PeriodicCheckpointMinSize", 0);
+
+ String threadName;
+ String programName = properties.getProperty("Ice.ProgramName");
+ if(programName.length() > 0)
+ {
+ threadName = programName + "-";
+ }
+ else
+ {
+ threadName = "";
+ }
+ threadName += "FreezeCheckpointThread(" + _key.envName + ")";
+
+ if(_checkpointPeriod > 0)
+ {
+ _thread = new Thread(this, threadName);
+ _thread.start();
+ }
+ }
+
+ _catalog = new MapDb(_key.communicator, _key.envName, Util.catalogName(), "string", "::Freeze::CatalogData", _dbEnv);
+ _catalogIndexList = new MapDb(_key.communicator, _key.envName, Util.catalogIndexListName(),
+ "string", "::Ice::StringSeq", _dbEnv);
+ }
+ catch(com.sleepycat.db.DatabaseException dx)
+ {
+ cleanup();
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(dx);
+ ex.message = errorPrefix(_key.envName) + "creation: " + dx.getMessage();
+ throw ex;
+ }
+ catch(java.lang.RuntimeException ex)
+ {
+ cleanup();
+ throw ex;
+ }
+
+ _refCount = 1;
+ }
+
+ private void
+ cleanup()
+ {
+ //
+ // Join thread
+ //
+ synchronized(this)
+ {
+ _done = true;
+ notify();
+ }
+
+ for(;;)
+ {
+ if(_thread != null)
{
- config.setRunFatalRecovery(true);
+ try
+ {
+ _thread.join();
+ _thread = null;
+ break;
+ }
+ catch(InterruptedException ex)
+ {
+ }
}
- else
+ }
+
+ //
+ // Release catalogs
+ //
+ if(_catalog != null)
+ {
+ try
{
- config.setRunRecovery(true);
+ _catalog.close();
}
-
- if(properties.getPropertyAsIntWithDefault(propertyPrefix + ".DbPrivate", 1) != 0)
+ finally
{
- config.setPrivate(true);
+ _catalog = null;
}
-
- if(properties.getPropertyAsIntWithDefault(propertyPrefix + ".OldLogsAutoDelete", 1) != 0)
+ }
+
+ if(_catalogIndexList != null)
+ {
+ try
{
- config.setLogAutoRemove(true);
+ _catalogIndexList.close();
}
-
- if(_trace >= 1)
+ finally
{
- _key.communicator.getLogger().trace("Freeze.DbEnv", "opening database environment \"" +
- _key.envName + "\"");
+ _catalogIndexList = null;
}
-
- //
- // TODO: FREEZE_DB_MODE
- //
-
+ }
+
+ //
+ // Close Dbs
+ //
+ for(MapDb db: _sharedDbMap.values())
+ {
+ db.close();
+ }
+
+ if(_trace >= 1)
+ {
+ _key.communicator.getLogger().trace("Freeze.DbEnv", "closing database environment \"" +
+ _key.envName + "\"");
+ }
+
+ if(_ownDbEnv && _dbEnv != null)
+ {
try
{
- String dbHome = properties.getPropertyWithDefault(propertyPrefix + ".DbHome", _key.envName);
- java.io.File home = new java.io.File(dbHome);
- _dbEnv = new com.sleepycat.db.Environment(home, config);
+ _dbEnv.close();
}
- catch(java.io.FileNotFoundException dx)
+ catch(com.sleepycat.db.DatabaseException dx)
{
- NotFoundException ex = new NotFoundException();
+ DatabaseException ex = new DatabaseException();
ex.initCause(dx);
- ex.message = errorPrefix(_key.envName) + "open: " + dx.getMessage();
+ ex.message = errorPrefix(_key.envName) + "close: " + dx.getMessage();
throw ex;
}
-
- //
- // Default checkpoint period is every 120 seconds
- //
- _checkpointPeriod =
- properties.getPropertyAsIntWithDefault(propertyPrefix + ".CheckpointPeriod", 120) * 1000;
-
- _kbyte = properties.getPropertyAsIntWithDefault(propertyPrefix + ".PeriodicCheckpointMinSize", 0);
-
- String threadName;
- String programName = properties.getProperty("Ice.ProgramName");
- if(programName.length() > 0)
+ finally
{
- threadName = programName + "-";
+ _dbEnv = null;
}
- else
- {
- threadName = "";
- }
- threadName += "FreezeCheckpointThread(" + _key.envName + ")";
-
- if(_checkpointPeriod > 0)
- {
- _thread = new Thread(this, threadName);
- _thread.start();
- }
- }
-
- _refCount = 1;
- }
-
- private synchronized void
- init()
- {
- if(_catalog == null)
- {
- SharedDb[] catalogs = SharedDb.openCatalogs(this);
- _catalog = catalogs[0];
- _catalogIndexList = catalogs[1];
}
}
@@ -438,8 +508,8 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
private MapKey _key;
private com.sleepycat.db.Environment _dbEnv;
private boolean _ownDbEnv;
- private SharedDb _catalog;
- private SharedDb _catalogIndexList;
+ private MapDb _catalog;
+ private MapDb _catalogIndexList;
private int _refCount = 0; // protected by _map!
private boolean _done = false;
private int _trace = 0;
@@ -449,6 +519,8 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
private java.util.Map _ctxMap = new java.util.HashMap();
+ private java.util.Map<String, MapDb> _sharedDbMap = new java.util.HashMap<String, MapDb>();
+
//
// Hash map of (MapKey, SharedDbEnv)
//