summaryrefslogtreecommitdiff
path: root/java/src/Freeze/SharedDbEnv.java
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2003-07-18 19:47:14 +0000
committerBernard Normier <bernard@zeroc.com>2003-07-18 19:47:14 +0000
commit3c02842b6143c6ce9297feecd7c9497312c76da8 (patch)
tree478210bed985772e2957ee0a65b9cd3f5f390234 /java/src/Freeze/SharedDbEnv.java
parentuse lazy initialization of communicator for each request (diff)
downloadice-3c02842b6143c6ce9297feecd7c9497312c76da8.tar.bz2
ice-3c02842b6143c6ce9297feecd7c9497312c76da8.tar.xz
ice-3c02842b6143c6ce9297feecd7c9497312c76da8.zip
Major Freeze update
Diffstat (limited to 'java/src/Freeze/SharedDbEnv.java')
-rw-r--r--java/src/Freeze/SharedDbEnv.java368
1 files changed, 368 insertions, 0 deletions
diff --git a/java/src/Freeze/SharedDbEnv.java b/java/src/Freeze/SharedDbEnv.java
new file mode 100644
index 00000000000..0c94c1e3a7b
--- /dev/null
+++ b/java/src/Freeze/SharedDbEnv.java
@@ -0,0 +1,368 @@
+// **********************************************************************
+//
+// Copyright (c) 2003
+// ZeroC, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved.
+//
+// Ice is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation.
+//
+// **********************************************************************
+
+package Freeze;
+
+class SharedDbEnv extends com.sleepycat.db.DbEnv implements com.sleepycat.db.DbErrcall, Runnable
+{
+ public static SharedDbEnv
+ get(Ice.Communicator communicator, String envName)
+ {
+ MapKey key = new MapKey(envName, communicator);
+
+ synchronized(_map)
+ {
+ SharedDbEnv result = (SharedDbEnv) _map.get(key);
+ if(result == null)
+ {
+ try
+ {
+ result = new SharedDbEnv(key);
+ }
+ catch(com.sleepycat.db.DbException dx)
+ {
+ DBException ex = new DBException();
+ ex.initCause(dx);
+ ex.message = errorPrefix(envName) + "creation: " + dx.getMessage();
+ throw ex;
+ }
+
+ Object previousValue = _map.put(key, result);
+ assert(previousValue == null);
+ }
+ else
+ {
+ result._refCount++;
+ }
+ return result;
+ }
+ }
+
+ public String
+ getEnvName()
+ {
+ return _key.envName;
+ }
+
+ public Ice.Communicator
+ getCommunicator()
+ {
+ return _key.communicator;
+ }
+
+ public void
+ close()
+ {
+ synchronized(_map)
+ {
+ if(--_refCount == 0)
+ {
+ //
+ // Remove from map
+ //
+ Object value = _map.remove(_key);
+ assert(value == this);
+
+ //
+ // Join thread
+ //
+ synchronized(this)
+ {
+ _done = true;
+ notify();
+ }
+
+ for(;;)
+ {
+ try
+ {
+ _thread.join();
+ break;
+ }
+ catch(InterruptedException ex)
+ {
+ }
+ }
+
+ if(_trace >= 1)
+ {
+ _key.communicator.getLogger().trace("DB", "closing database environment \"" + _key.envName + "\"");
+ }
+
+ //
+ // Keep lock to prevent somebody else to re-open this DbEnv
+ // before it's closed.
+ //
+ try
+ {
+ super.close(0);
+ }
+ catch(com.sleepycat.db.DbException dx)
+ {
+ DBException ex = new DBException();
+ ex.initCause(dx);
+ ex.message = errorPrefix(_key.envName) + "close: " + dx.getMessage();
+ throw ex;
+ }
+ }
+ }
+ }
+
+
+ synchronized public void
+ deleteOldLogs()
+ {
+ try
+ {
+ String[] list = log_archive(com.sleepycat.db.Db.DB_ARCH_ABS);
+
+ for(int i = 0; i < list.length; i++)
+ {
+ //
+ // Remove each file
+ //
+ java.io.File file = new java.io.File(list[i]);
+ boolean ok = file.delete();
+ if(!ok)
+ {
+ _key.communicator.getLogger().warning(
+ "could not delete file \"" + list[i] + "\"");
+ }
+ }
+ }
+ catch(com.sleepycat.db.DbException dx)
+ {
+ DBException ex = new DBException();
+ ex.initCause(dx);
+ ex.message = errorPrefix(_key.envName) + "log_archive: " + dx.getMessage();
+ throw ex;
+ }
+ }
+
+ synchronized public void
+ moveOldLogs()
+ {
+ //
+ // Not yet implemented
+ //
+ assert(false);
+ }
+
+ public void
+ run()
+ {
+ for(;;)
+ {
+ synchronized(this)
+ {
+ while(!_done)
+ {
+ try
+ {
+ wait(_checkpointPeriod);
+ }
+ catch(InterruptedException ex)
+ {
+ continue;
+ }
+ //
+ // Loop
+ //
+ }
+ if(_done)
+ {
+ return;
+ }
+ }
+
+ try
+ {
+ txn_checkpoint(_kbyte, 0, 0);
+ }
+ catch(com.sleepycat.db.DbException dx)
+ {
+ _key.communicator.getLogger().warning(
+ "checkpoint on DbEnv \"" + _key.envName + "\" raised DbException: "
+ + dx.getMessage());
+ }
+
+ if(_autoDelete)
+ {
+ try
+ {
+ deleteOldLogs();
+ }
+ catch(DBException ex)
+ {
+ _key.communicator.getLogger().warning(
+ "checkpoint on DbEnv \"" + _key.envName + "\" raised DBException: "
+ + ex.getMessage());
+ }
+
+ }
+ }
+ }
+
+ public void
+ errcall(String errorPrefix, String message)
+ {
+ _key.communicator.getLogger().error("Freeze database error in DbEnv \"" + _key.envName + "\" :" + message);
+ }
+
+ protected void
+ finalize()
+ {
+ assert(_refCount == 0);
+ }
+
+ private SharedDbEnv(MapKey key) throws com.sleepycat.db.DbException
+ {
+ super(0);
+ _key = key;
+
+ Ice.Properties properties = key.communicator.getProperties();
+ _trace = properties.getPropertyAsInt("Freeze.Trace.DB");
+
+ if(_trace >= 1)
+ {
+ _key.communicator.getLogger().trace("DB", "opening database environment \"" + _key.envName + "\"");
+ }
+
+ String propertyPrefix = "Freeze." + _key.envName;
+
+ set_errcall(this);
+
+ //
+ // Deadlock detection
+ //
+ set_lk_detect(com.sleepycat.db.Db.DB_LOCK_MINLOCKS);
+
+ //
+ // Async tx
+ //
+ set_flags(com.sleepycat.db.Db.DB_TXN_NOSYNC, true);
+
+ int flags = com.sleepycat.db.Db.DB_INIT_LOCK |
+ com.sleepycat.db.Db.DB_INIT_LOG |
+ com.sleepycat.db.Db.DB_INIT_MPOOL |
+ com.sleepycat.db.Db.DB_INIT_TXN;
+
+ if(properties.getPropertyAsInt(
+ propertyPrefix + ".DbRecoverFatal") != 0)
+ {
+ flags |= com.sleepycat.db.Db.DB_RECOVER_FATAL |
+ com.sleepycat.db.Db.DB_CREATE;
+ }
+ else
+ {
+ flags |= com.sleepycat.db.Db. DB_RECOVER |
+ com.sleepycat.db.Db.DB_CREATE;
+ }
+
+ if(properties.getPropertyAsIntWithDefault(
+ propertyPrefix + ".DbPrivate", 1) != 0)
+ {
+ flags |= com.sleepycat.db.Db.DB_PRIVATE;
+ }
+
+ String dbHome = properties.getPropertyWithDefault(
+ propertyPrefix + ".DbHome", _key.envName);
+
+ //
+ // TODO: FREEZE_DB_MODE
+ //
+
+ try
+ {
+ open(dbHome, flags, 0);
+ }
+ catch(java.io.FileNotFoundException dx)
+ {
+ DBNotFoundException ex = new DBNotFoundException();
+ ex.initCause(dx);
+ ex.message = errorPrefix(_key.envName) + "open: " + dx.getMessage();
+ throw ex;
+ }
+
+ //
+ // Default checkpoint period is every 10 minutes
+ //
+ _checkpointPeriod = properties.getPropertyAsIntWithDefault(
+ propertyPrefix + ".CheckpointPeriod", 10) * 60 * 1000;
+
+ _kbyte = properties.getPropertyAsInt(
+ propertyPrefix + ".PeriodicCheckpointMinSize");
+
+ _autoDelete = (properties.getPropertyAsIntWithDefault(
+ propertyPrefix + ".OldLogsAutoDelete", 1) != 0);
+
+ _thread = new Thread(this);
+ _thread.start();
+
+ _refCount = 1;
+ }
+
+ private static String
+ errorPrefix(String envName)
+ {
+ return "DbEnv(\"" + envName + "\"): ";
+ }
+
+ private static class MapKey
+ {
+ final String envName;
+ final Ice.Communicator communicator;
+
+ MapKey(String envName, Ice.Communicator communicator)
+ {
+ this.envName = envName;
+ this.communicator = communicator;
+ }
+
+ public boolean
+ equals(Object o)
+ {
+ try
+ {
+ MapKey k = (MapKey)o;
+ return (communicator == k.communicator) && envName.equals(k.envName);
+ }
+ catch(ClassCastException ex)
+ {
+ communicator.getLogger().trace("DB", "equals cast failed");
+ return false;
+ }
+ }
+
+ public int hashCode()
+ {
+ return envName.hashCode() ^ communicator.hashCode();
+ }
+ }
+
+ private MapKey _key;
+ private int _refCount = 0;
+ private boolean _done = false;
+ private int _trace = 0;
+ private long _checkpointPeriod = 0;
+ private int _kbyte = 0;
+ private boolean _autoDelete = false;
+ private Thread _thread;
+
+ //
+ // Hash map of (MapKey, SharedDbEnv)
+ //
+ private static java.util.Map _map = new java.util.HashMap();
+}
+