diff options
author | Bernard Normier <bernard@zeroc.com> | 2003-07-18 19:47:14 +0000 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2003-07-18 19:47:14 +0000 |
commit | 3c02842b6143c6ce9297feecd7c9497312c76da8 (patch) | |
tree | 478210bed985772e2957ee0a65b9cd3f5f390234 /java | |
parent | use lazy initialization of communicator for each request (diff) | |
download | ice-3c02842b6143c6ce9297feecd7c9497312c76da8.tar.bz2 ice-3c02842b6143c6ce9297feecd7c9497312c76da8.tar.xz ice-3c02842b6143c6ce9297feecd7c9497312c76da8.zip |
Major Freeze update
Diffstat (limited to 'java')
47 files changed, 2685 insertions, 3267 deletions
diff --git a/java/CHANGES b/java/CHANGES index 20ff92d9716..ac4e414380a 100644 --- a/java/CHANGES +++ b/java/CHANGES @@ -1,6 +1,9 @@ Changes since version 1.1.0 --------------------------- +- Major Freeze update + See corresponding entry in the Ice CHANGES file. + - Added Ice.MessageSizeMax property. This property controls the maximum message size accepted by the Ice protocol in kiloBytes. The default value is 1024 (1 MB). diff --git a/java/allTests.py b/java/allTests.py index 2448b7f15c3..d585ed5901a 100755 --- a/java/allTests.py +++ b/java/allTests.py @@ -38,7 +38,6 @@ tests = [ \ "Ice/slicing/objects", \ "Ice/custom", \ "IceXML/encoding", \ - "Freeze/cursor", \ "Freeze/dbmap", \ "Freeze/complex", \ "Freeze/evictor", \ diff --git a/java/build.xml b/java/build.xml index b57a8920b87..99f6d41e338 100644 --- a/java/build.xml +++ b/java/build.xml @@ -81,7 +81,6 @@ the Free Software Foundation. <include name="DBException.ice" /> <include name="Evictor.ice" /> <include name="ObjectRecord.ice" /> - <include name="Strategy.ice" /> </fileset> <fileset dir="${slice.dir}/IceBox"> <include name="IceBox.ice" /> diff --git a/java/demo/Freeze/bench/Client.java b/java/demo/Freeze/bench/Client.java index 66536b08a1b..764f3201e08 100644 --- a/java/demo/Freeze/bench/Client.java +++ b/java/demo/Freeze/bench/Client.java @@ -12,28 +12,27 @@ // // ********************************************************************** -class TestApp extends Freeze.Application +class TestApp extends Ice.Application { - TestApp(String dbEnvName) + TestApp(String envName) { - super(dbEnvName); + _envName = envName; } void - IntIntMapTest(Freeze.DBEnvironment dbEnv, boolean fast) + IntIntMapTest(boolean fast) { - Freeze.DB db; + IntIntMap m; + if(fast) { - db = dbEnv.openDB("IntIntMap.fast", true); + m = new IntIntMap(communicator(), _envName, "IntIntMap.fast", true); } else { - db = dbEnv.openDB("IntIntMap", true); + m = new IntIntMap(communicator(), _envName, "IntIntMap", true); } - IntIntMap m = new IntIntMap(db); - // // Populate the database. // @@ -99,7 +98,7 @@ class TestApp extends Freeze.Application System.out.println("\ttime for " + _repetitions + " " + ((fast) ? "fast " : "") + "removes: " + total + "ms"); System.out.println("\ttime per remove: " + perRecord + "ms"); - db.close(); + m.close(); } interface Generator @@ -183,11 +182,9 @@ class TestApp extends Freeze.Application } void - IntIntMapReadTest(Freeze.DBEnvironment dbEnv) + IntIntMapReadTest() { - Freeze.DB db = dbEnv.openDB("IntIntMap", true); - - IntIntMap m = new IntIntMap(db); + IntIntMap m = new IntIntMap(communicator(), _envName, "IntIntMap", true); // // Populate the database. @@ -236,15 +233,13 @@ class TestApp extends Freeze.Application System.out.println("\ttime per remove: " + perRecord + "ms"); */ - db.close(); + m.close(); } void - Struct1Struct2MapTest(Freeze.DBEnvironment dbEnv) + Struct1Struct2MapTest() { - Freeze.DB db = dbEnv.openDB("Struct1Struct2", true); - - Struct1Struct2Map m = new Struct1Struct2Map(db); + Struct1Struct2Map m = new Struct1Struct2Map(communicator(), _envName, "Struct1Struct2", true); // // Populate the database. @@ -296,15 +291,13 @@ class TestApp extends Freeze.Application System.out.println("\ttime for " + _repetitions + " removes: " + total + "ms"); System.out.println("\ttime per remove: " + perRecord + "ms"); - db.close(); + m.close(); } void - Struct1Class1MapTest(Freeze.DBEnvironment dbEnv) + Struct1Class1MapTest() { - Freeze.DB db = dbEnv.openDB("Struct1Class1", true); - - Struct1Class1Map m = new Struct1Class1Map(db); + Struct1Class1Map m = new Struct1Class1Map(communicator(), _envName, "Struct1Class1", true); // // Populate the database. @@ -356,15 +349,13 @@ class TestApp extends Freeze.Application System.out.println("\ttime for " + _repetitions + " removes: " + total + "ms"); System.out.println("\ttime per remove: " + perRecord + "ms"); - db.close(); + m.close(); } void - Struct1ObjectMapTest(Freeze.DBEnvironment dbEnv) + Struct1ObjectMapTest() { - Freeze.DB db = dbEnv.openDB("Struct1Object", true); - - Struct1ObjectMap m = new Struct1ObjectMap(db); + Struct1ObjectMap m = new Struct1ObjectMap(communicator(), _envName, "Struct1Object", true); // // Populate the database. @@ -443,32 +434,32 @@ class TestApp extends Freeze.Application System.out.println("\ttime for " + _repetitions + " removes: " + total + "ms"); System.out.println("\ttime per remove: " + perRecord + "ms"); - db.close(); + m.close(); } public int - runFreeze(String[] args, Freeze.DBEnvironment dbEnv) + run(String[] args) { System.out.println("IntIntMap (Collections API)"); - IntIntMapTest(dbEnv, false); + IntIntMapTest(false); System.out.println("IntIntMap (Fast API)"); - IntIntMapTest(dbEnv, true); + IntIntMapTest(true); System.out.println("Struct1Struct2Map"); - Struct1Struct2MapTest(dbEnv); + Struct1Struct2MapTest(); System.out.println("Struct1Class1Map"); - Struct1Class1MapTest(dbEnv); + Struct1Class1MapTest(); MyFactory factory = new MyFactory(); - factory.install(dbEnv.getCommunicator()); + factory.install(communicator()); System.out.println("Struct1ObjectMap"); - Struct1ObjectMapTest(dbEnv); + Struct1ObjectMapTest(); System.out.println("IntIntMap (read test)"); - IntIntMapReadTest(dbEnv); + IntIntMapReadTest(); return 0; } @@ -513,6 +504,7 @@ class TestApp extends Freeze.Application private int _repetitions = 10000; private StopWatch _watch = new StopWatch(); + private String _envName; } public class Client diff --git a/java/demo/Freeze/bench/build.xml b/java/demo/Freeze/bench/build.xml index ffc8343eed6..790a604109c 100644 --- a/java/demo/Freeze/bench/build.xml +++ b/java/demo/Freeze/bench/build.xml @@ -85,6 +85,10 @@ the Free Software Foundation. <target name="clean"> <delete dir="${generated.dir}"/> <delete dir="${class.dir}"/> + <delete> + <fileset dir="db" includes="log.*"/> + <fileset dir="db" includes="IntIntMap.fast,Struct1Object,IntIntMap,Struct1Class1,Struct1Struct2"/> + </delete> </target> </project> diff --git a/java/demo/Freeze/library/Collocated.java b/java/demo/Freeze/library/Collocated.java index 1eeab28e45b..23490847fee 100644 --- a/java/demo/Freeze/library/Collocated.java +++ b/java/demo/Freeze/library/Collocated.java @@ -12,29 +12,17 @@ // // ********************************************************************** -class LibraryCollocated extends Freeze.Application +class LibraryCollocated extends Ice.Application { public int - runFreeze(String[] args, Freeze.DBEnvironment dbEnv) + run(String[] args) { Ice.Properties properties = communicator().getProperties(); - - Freeze.DB dbBooks = dbEnv.openDB("books", true); - Freeze.DB dbAuthors = dbEnv.openDB("authors", true); - + // // Create an Evictor for books. // - Freeze.PersistenceStrategy strategy; - if(properties.getPropertyAsInt("Library.IdleStrategy") > 0) - { - strategy = dbBooks.createIdleStrategy(); - } - else - { - strategy = dbBooks.createEvictionStrategy(); - } - Freeze.Evictor evictor = dbBooks.createEvictor(strategy); + Freeze.Evictor evictor = Freeze.Util.createEvictor(communicator(), _envName, "books", true); int evictorSize = properties.getPropertyAsInt("Library.EvictorSize"); if(evictorSize > 0) { @@ -51,7 +39,7 @@ class LibraryCollocated extends Freeze.Application // // Create the library, and add it to the Object Adapter. // - LibraryI library = new LibraryI(dbAuthors, evictor); + LibraryI library = new LibraryI(communicator(), _envName, "authors", evictor); adapter.add(library, Ice.Util.stringToIdentity("library")); // @@ -67,13 +55,16 @@ class LibraryCollocated extends Freeze.Application adapter.deactivate(); adapter.waitForDeactivate(); + library.close(); return status; } - LibraryCollocated(String dbEnvName) + LibraryCollocated(String envName) { - super(dbEnvName); + _envName = envName; } + + private String _envName; } public class Collocated diff --git a/java/demo/Freeze/library/LibraryI.java b/java/demo/Freeze/library/LibraryI.java index 8e328da5375..72c37ce3fa1 100644 --- a/java/demo/Freeze/library/LibraryI.java +++ b/java/demo/Freeze/library/LibraryI.java @@ -223,10 +223,16 @@ class LibraryI extends _LibraryDisp } } - LibraryI(Freeze.DB db, Freeze.Evictor evictor) + LibraryI(Ice.Communicator communicator, String envName, String dbName, Freeze.Evictor evictor) { _evictor = evictor; - _authors = new StringIsbnSeqDict(db); + _authors = new StringIsbnSeqDict(communicator, envName, dbName, true); + } + + void + close() + { + _authors.close(); } private Ice.Identity diff --git a/java/demo/Freeze/library/Server.java b/java/demo/Freeze/library/Server.java index ad892ad1e73..1da96868cb6 100644 --- a/java/demo/Freeze/library/Server.java +++ b/java/demo/Freeze/library/Server.java @@ -12,29 +12,17 @@ // // ********************************************************************** -class LibraryServer extends Freeze.Application +class LibraryServer extends Ice.Application { public int - runFreeze(String[] args, Freeze.DBEnvironment dbEnv) + run(String[] args) { Ice.Properties properties = communicator().getProperties(); - Freeze.DB dbBooks = dbEnv.openDB("books", true); - Freeze.DB dbAuthors = dbEnv.openDB("authors", true); - // // Create an Evictor for books. // - Freeze.PersistenceStrategy strategy; - if(properties.getPropertyAsInt("Library.IdleStrategy") > 0) - { - strategy = dbBooks.createIdleStrategy(); - } - else - { - strategy = dbBooks.createEvictionStrategy(); - } - Freeze.Evictor evictor = dbBooks.createEvictor(strategy); + Freeze.Evictor evictor = Freeze.Util.createEvictor(communicator(), _envName, "books", true); int evictorSize = properties.getPropertyAsInt("Library.EvictorSize"); if(evictorSize > 0) { @@ -51,7 +39,7 @@ class LibraryServer extends Freeze.Application // // Create the library, and add it to the Object Adapter. // - LibraryI library = new LibraryI(dbAuthors, evictor); + LibraryI library = new LibraryI(communicator(), _envName, "authors", evictor); adapter.add(library, Ice.Util.stringToIdentity("library")); // @@ -69,13 +57,16 @@ class LibraryServer extends Freeze.Application communicator().waitForShutdown(); defaultInterrupt(); + library.close(); return 0; } - LibraryServer(String dbEnvName) + LibraryServer(String envName) { - super(dbEnvName); + _envName = envName; } + + private String _envName; } public class Server diff --git a/java/demo/Freeze/library/build.xml b/java/demo/Freeze/library/build.xml index 3b2e466feb8..07c9360c9d7 100644 --- a/java/demo/Freeze/library/build.xml +++ b/java/demo/Freeze/library/build.xml @@ -80,6 +80,10 @@ the Free Software Foundation. <target name="clean"> <delete dir="${generated.dir}"/> <delete dir="${class.dir}"/> + <delete> + <fileset dir="db" includes="log.*"/> + <fileset dir="db" includes="authors,books"/> + </delete> </target> </project> diff --git a/java/demo/Freeze/library/config b/java/demo/Freeze/library/config index f879a342312..26f0e6b48b2 100644 --- a/java/demo/Freeze/library/config +++ b/java/demo/Freeze/library/config @@ -4,6 +4,5 @@ Ice.Warn.Connections=1 #Ice.Trace.Protocol=1 Library.Proxy=library:default -p 10000 Library.EvictorSize=3 -#Library.IdleStrategy=1 Freeze.Trace.DB=1 Freeze.Trace.Evictor=2 diff --git a/java/demo/Freeze/phonebook/Collocated.java b/java/demo/Freeze/phonebook/Collocated.java index 4a1c3de8b55..6770d1a28bb 100644 --- a/java/demo/Freeze/phonebook/Collocated.java +++ b/java/demo/Freeze/phonebook/Collocated.java @@ -12,29 +12,17 @@ // // ********************************************************************** -class PhoneBookCollocated extends Freeze.Application +class PhoneBookCollocated extends Ice.Application { public int - runFreeze(String[] args, Freeze.DBEnvironment dbEnv) + run(String[] args) { Ice.Properties properties = communicator().getProperties(); - Freeze.DB dbPhoneBook = dbEnv.openDB("phonebook", true); - Freeze.DB dbContacts = dbEnv.openDB("contacts", true); - // // Create an Evictor for contacts. // - Freeze.PersistenceStrategy strategy; - if(properties.getPropertyAsInt("PhoneBook.IdleStrategy") > 0) - { - strategy = dbContacts.createIdleStrategy(); - } - else - { - strategy = dbContacts.createEvictionStrategy(); - } - Freeze.Evictor evictor = dbContacts.createEvictor(strategy); + Freeze.Evictor evictor = Freeze.Util.createEvictor(communicator(), _envName, "contacts", true); int evictorSize = properties.getPropertyAsInt("PhoneBook.EvictorSize"); if(evictorSize > 0) { @@ -51,7 +39,7 @@ class PhoneBookCollocated extends Freeze.Application // // Create the phonebook, and add it to the Object Adapter. // - PhoneBookI phoneBook = new PhoneBookI(dbPhoneBook, evictor); + PhoneBookI phoneBook = new PhoneBookI(communicator(), _envName, "phonebook", evictor); adapter.add(phoneBook, Ice.Util.stringToIdentity("phonebook")); // @@ -68,14 +56,17 @@ class PhoneBookCollocated extends Freeze.Application int status = RunParser.runParser(appName(), args, communicator()); adapter.deactivate(); adapter.waitForDeactivate(); + phoneBook.close(); return status; } - PhoneBookCollocated(String dbEnvName) + PhoneBookCollocated(String envName) { - super(dbEnvName); + _envName = envName; } + + private String _envName; } public class Collocated diff --git a/java/demo/Freeze/phonebook/PhoneBookI.java b/java/demo/Freeze/phonebook/PhoneBookI.java index e3413b37aad..bd6316d847f 100644 --- a/java/demo/Freeze/phonebook/PhoneBookI.java +++ b/java/demo/Freeze/phonebook/PhoneBookI.java @@ -235,12 +235,18 @@ class PhoneBookI extends _PhoneBookDisp } } - PhoneBookI(Freeze.DB db, Freeze.Evictor evictor) + PhoneBookI(Ice.Communicator communicator, String envName, String dbName, Freeze.Evictor evictor) { _evictor = evictor; - _nameIdentitiesDict = new NameIdentitiesDict(db); + _nameIdentitiesDict = new NameIdentitiesDict(communicator, envName, dbName, true); } + void + close() + { + _nameIdentitiesDict.close(); + } + // // It's not strictly necessary in the Java implementation to have // a private removeI implememnation since there is no problem with diff --git a/java/demo/Freeze/phonebook/Server.java b/java/demo/Freeze/phonebook/Server.java index 05adb3524cf..d5c08905aa9 100644 --- a/java/demo/Freeze/phonebook/Server.java +++ b/java/demo/Freeze/phonebook/Server.java @@ -12,29 +12,17 @@ // // ********************************************************************** -class PhoneBookServer extends Freeze.Application +class PhoneBookServer extends Ice.Application { public int - runFreeze(String[] args, Freeze.DBEnvironment dbEnv) + run(String[] args) { Ice.Properties properties = communicator().getProperties(); - Freeze.DB dbPhoneBook = dbEnv.openDB("phonebook", true); - Freeze.DB dbContacts = dbEnv.openDB("contacts", true); - // // Create an Evictor for contacts. // - Freeze.PersistenceStrategy strategy; - if(properties.getPropertyAsInt("PhoneBook.IdleStrategy") > 0) - { - strategy = dbContacts.createIdleStrategy(); - } - else - { - strategy = dbContacts.createEvictionStrategy(); - } - Freeze.Evictor evictor = dbContacts.createEvictor(strategy); + Freeze.Evictor evictor = Freeze.Util.createEvictor(communicator(), _envName, "contacts", true); int evictorSize = properties.getPropertyAsInt("PhoneBook.EvictorSize"); if(evictorSize > 0) { @@ -51,7 +39,7 @@ class PhoneBookServer extends Freeze.Application // // Create the phonebook, and add it to the Object Adapter. // - PhoneBookI phoneBook = new PhoneBookI(dbPhoneBook, evictor); + PhoneBookI phoneBook = new PhoneBookI(communicator(), _envName, "phonebook", evictor); adapter.add(phoneBook, Ice.Util.stringToIdentity("phonebook")); // @@ -70,14 +58,17 @@ class PhoneBookServer extends Freeze.Application shutdownOnInterrupt(); communicator().waitForShutdown(); defaultInterrupt(); - + + phoneBook.close(); return 0; } - PhoneBookServer(String dbEnvName) + PhoneBookServer(String envName) { - super(dbEnvName); + _envName = envName; } + + private String _envName; } public class Server @@ -86,6 +77,6 @@ public class Server main(String[] args) { PhoneBookServer app = new PhoneBookServer("db"); - app.main("demo.Freeze.phonebook.Server", args, "config"); + app.main("demo.Freeze.phonebook.Server", args); } } diff --git a/java/demo/Freeze/phonebook/build.xml b/java/demo/Freeze/phonebook/build.xml index fd3957029b6..b4a03240934 100644 --- a/java/demo/Freeze/phonebook/build.xml +++ b/java/demo/Freeze/phonebook/build.xml @@ -77,6 +77,10 @@ the Free Software Foundation. <target name="clean"> <delete dir="${generated.dir}"/> <delete dir="${class.dir}"/> + <delete> + <fileset dir="db" includes="log.*"/> + <fileset dir="db" includes="contacts,phonebook"/> + </delete> </target> </project> diff --git a/java/src/Freeze/Application.java b/java/src/Freeze/Application.java deleted file mode 100644 index 3bbf724fa81..00000000000 --- a/java/src/Freeze/Application.java +++ /dev/null @@ -1,82 +0,0 @@ -// ********************************************************************** -// -// 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; - -public abstract class Application extends Ice.Application -{ - public - Application(String dbEnvName) - { - _dbEnvName = dbEnvName; - } - - public int - run(String[] args) - { - int status; - DBEnvironment dbEnv = null; - - try - { - dbEnv = Freeze.Util.initialize(communicator(), _dbEnvName); - status = runFreeze(args, dbEnv); - } - catch(DBException ex) - { - System.err.println(appName() + ": " + ex + ": " + ex.message); - status = 1; - } - catch(Ice.LocalException ex) - { - System.err.println(appName() + ": " + ex); - ex.printStackTrace(); - status = 1; - } - catch(Exception ex) - { - System.err.println(appName() + ": unknown exception"); - ex.printStackTrace(); - status = 1; - } - - if(dbEnv != null) - { - try - { - dbEnv.close(); - } - catch(DBException ex) - { - System.err.println(appName() + ": " + ex + ": " + ex.message); - ex.printStackTrace(); - status = 1; - } - catch(Exception ex) - { - System.err.println(appName() + ": unknown exception"); - ex.printStackTrace(); - status = 1; - } - dbEnv = null; - } - - return status; - } - - public abstract int - runFreeze(String[] args, DBEnvironment dbEnv); - - private String _dbEnvName; -} diff --git a/java/src/Freeze/DBCursorI.java b/java/src/Freeze/DBCursorI.java deleted file mode 100644 index e67c6be3718..00000000000 --- a/java/src/Freeze/DBCursorI.java +++ /dev/null @@ -1,307 +0,0 @@ -// ********************************************************************** -// -// 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 DBCursorI extends Ice.LocalObjectImpl implements DBCursor -{ - public Ice.Communicator - getCommunicator() - { - // immutable - return _communicator; - } - - synchronized public void - curr(KeyHolder k, ValueHolder v) - { - if(_cursor == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(); - com.sleepycat.db.Dbt dbData = new com.sleepycat.db.Dbt(); - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "reading current value from database \"" + _name + "\""); - } - - try - { - int rc = _cursor.get(dbKey, dbData, com.sleepycat.db.Db.DB_CURRENT); - if(rc == com.sleepycat.db.Db.DB_NOTFOUND) - { - DBNotFoundException ex = new DBNotFoundException(); - ex.message = _errorPrefix + "Dbc.get: DB_NOTFOUND"; - throw ex; - } - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Dbc.get: " + e.getMessage(); - throw ex; - } - - // - // Copy the data from the read key & data - // - k.value = dbKey.get_data(); - v.value = dbData.get_data(); - } - - synchronized public void - set(byte[] v) - { - if(_cursor == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - // - // TODO: Although the API docs say that the key argument to Dbc.put() - // is ignored, an exception is raised if the Dbt object isn't initialized. - // Sleepycat has acknowledged that this is a bug. - // - com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(new byte[0]); - com.sleepycat.db.Dbt dbData = new com.sleepycat.db.Dbt(v); - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "setting current value in database \"" + _name + "\""); - } - - try - { - int rc = _cursor.put(dbKey, dbData, com.sleepycat.db.Db.DB_CURRENT); - /* Since the underlying data is btree this cannot occur. - * - if(rc == com.sleepycat.db.Db.DB_NOTFOUND) - { - DBNotFoundException ex = new DBNotFoundException(); - ex.message = _errorPrefix + "Dbc.put: DB_NOTFOUND"; - throw ex; - } - */ - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Dbc.put: " + e.getMessage(); - throw ex; - } - } - - synchronized public boolean - next() - { - if(_cursor == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(); - dbKey.set_flags(com.sleepycat.db.Db.DB_DBT_PARTIAL); - com.sleepycat.db.Dbt dbData = new com.sleepycat.db.Dbt(); - dbData.set_flags(com.sleepycat.db.Db.DB_DBT_PARTIAL); - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "moving to next value in database \"" + _name + "\""); - } - - try - { - int rc = _cursor.get(dbKey, dbData, com.sleepycat.db.Db.DB_NEXT); - if(rc == com.sleepycat.db.Db.DB_NOTFOUND) - { - return false; - } - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Dbc.get: " + e.getMessage(); - throw ex; - } - - return true; - } - - synchronized public boolean - prev() - { - if(_cursor == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(); - dbKey.set_flags(com.sleepycat.db.Db.DB_DBT_PARTIAL); - com.sleepycat.db.Dbt dbData = new com.sleepycat.db.Dbt(); - dbData.set_flags(com.sleepycat.db.Db.DB_DBT_PARTIAL); - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "moving to previous value in database \"" + _name + "\""); - } - - try - { - int rc = _cursor.get(dbKey, dbData, com.sleepycat.db.Db.DB_PREV); - if(rc == com.sleepycat.db.Db.DB_NOTFOUND) - { - return false; - } - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Dbc.get: " + e.getMessage(); - throw ex; - } - - return true; - } - - synchronized public void - del() - { - if(_cursor == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "removing the current element in database \"" + _name + "\""); - } - - try - { - int rc = _cursor.del(0); - if(rc == com.sleepycat.db.Db.DB_KEYEMPTY) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "Dbc.del: DB_KEYEMPTY"; - throw ex; - } - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Dbc.get: " + e.getMessage(); - throw ex; - } - } - - synchronized public DBCursor - _clone() - { - if(_cursor == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - com.sleepycat.db.Dbc cursor; - try - { - cursor = _cursor.dup(com.sleepycat.db.Db.DB_POSITION); - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Dbc.close: " + e.getMessage(); - throw ex; - } - return new DBCursorI(_communicator, _name, cursor); - } - - synchronized public void - close() - { - if(_cursor == null) - { - return; - } - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "closing cursor \"" + _name + "\""); - } - - try - { - _cursor.close(); - } - catch(com.sleepycat.db.DbDeadlockException e) - { - DBDeadlockException ex = new DBDeadlockException(); - ex.initCause(e); - ex.message = _errorPrefix + "Dbc.close: " + e.getMessage(); - throw ex; - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Dbc.close: " + e.getMessage(); - throw ex; - } - - _cursor = null; - } - - DBCursorI(Ice.Communicator communicator, String name, com.sleepycat.db.Dbc cursor) - { - _communicator = communicator; - _name = name; - _cursor = cursor; - _errorPrefix = "Freeze::DBCursor(\"" + _name + "\"): "; - _trace = _communicator.getProperties().getPropertyAsInt("Freeze.Trace.DB"); - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "creating cursor for \"" + _name + "\""); - } - } - - private Ice.Communicator _communicator; - private int _trace = 0; - - private String _name; - private String _errorPrefix; - - private com.sleepycat.db.Dbc _cursor; -} diff --git a/java/src/Freeze/DBEnvironmentI.java b/java/src/Freeze/DBEnvironmentI.java deleted file mode 100644 index 974e10b1e31..00000000000 --- a/java/src/Freeze/DBEnvironmentI.java +++ /dev/null @@ -1,327 +0,0 @@ -// ********************************************************************** -// -// 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 DBEnvironmentI extends Ice.LocalObjectImpl implements DBEnvironment, com.sleepycat.db.DbErrcall -{ - public String - getName() - { - // No mutex lock necessary, _name is immutable - return _name; - } - - public Ice.Communicator - getCommunicator() - { - // No mutex lock necessary, _communicator is immutable - return _communicator; - } - - synchronized public DB - openDB(String name, boolean create) - { - return openDBImpl(null, name, create); - } - - synchronized public DB - openDBWithTxn(DBTransaction t, String name, boolean create) - { - DBTransaction txn = t; - if(t == null) - { - txn = startTransaction(); - } - - DB db = openDBImpl(((DBTransactionI)txn).getTxnId(), name, create); - - if(t == null) - { - txn.commit(); - } - - return db; - } - - public DBTransaction - startTransaction() - { - return new DBTransactionI(_communicator, _dbEnv, _name); - } - - synchronized public void - close() - { - if(_dbEnv == null) - { - return; - } - - // - // Build a list of values from the iterator. The iterator - // cannot be used directly since closing each database - // modifies the content of the map (hence invalidating the - // iterator). - // - java.util.List dbs = new java.util.ArrayList(); - java.util.Iterator p = _dbMap.values().iterator(); - while(p.hasNext()) - { - dbs.add(p.next()); - } - - p = dbs.iterator(); - while(p.hasNext()) - { - DB db = (DB)p.next(); - db.close(); - } - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "closing database environment \"" + _name + "\""); - } - - try - { - _dbEnv.close(0); - } - catch(com.sleepycat.db.DbException e) - { - _dbEnv = null; - - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "DbEnv.close: " + e.getMessage(); - throw ex; - } - - _dbEnv = null; - } - - synchronized public void - sync() - { - if(_dbEnv == null) - { - return; - } - - java.util.Iterator p = _dbMap.values().iterator(); - while(p.hasNext()) - { - DB db = (DB)p.next(); - db.sync(); - } - } - - protected DB - openDBImpl(com.sleepycat.db.DbTxn txn, String name, boolean create) - { - if(_dbEnv == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - DB p = (DB)_dbMap.get(name); - if(p != null) - { - return p; - } - - com.sleepycat.db.Db db; - - try - { - db = new com.sleepycat.db.Db(_dbEnv, 0); - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.Db: " + e.getMessage(); - throw ex; - } - - try - { - return new DBI(_communicator, this, db, txn, name, create); - } - catch(DBException e) - { - try - { - db.close(0); - } - catch(com.sleepycat.db.DbException ignore) - { - } - throw e; - } - } - - synchronized protected void - add(String name, DB db) - { - _dbMap.put(name, db); - } - - synchronized protected void - remove(String name) - { - _dbMap.remove(name); - } - - synchronized protected void - eraseDB(String name) - { - // - // The database should not be open. - // - assert(_dbMap.get(name) == null); - - com.sleepycat.db.Db db; - try - { - db = new com.sleepycat.db.Db(_dbEnv, 0); - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.Db: " + e.getMessage(); - throw ex; - } - - try - { - // - // Any failure in remove will cause the database to be - // closed. - // - db.remove(name, null, 0); - } - catch(java.io.FileNotFoundException e) - { - DBNotFoundException ex = new DBNotFoundException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.remove: " + e.getMessage(); - throw ex; - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.remove: " + e.getMessage(); - throw ex; - } - } - - DBEnvironmentI(Ice.Communicator communicator, String name, boolean txn) - { - _communicator = communicator; - _name = name; - _errorPrefix = "Freeze::DBEnvironment(\"" + _name + "\"): "; - _trace = getCommunicator().getProperties().getPropertyAsInt("Freeze.Trace.DB"); - - try - { - _dbEnv = new com.sleepycat.db.DbEnv(0); - // - // This is a portability workaround. The DbEnv constructor - // is declared as throwing DbException in version 4.1.x, - // but not in earlier versions. Without a bogus throw - // statement, the compiler will complain. - // - if(_dbEnv == null) - { - throw new com.sleepycat.db.DbException(""); - } - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "DbEnv.init: " + e.getMessage(); - throw ex; - } - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "opening database environment \"" + _name + "\""); - } - - int flags = com.sleepycat.db.Db.DB_CREATE | com.sleepycat.db.Db.DB_INIT_LOCK | - com.sleepycat.db.Db.DB_INIT_MPOOL; - - if(txn) - { - flags = flags | com.sleepycat.db.Db.DB_INIT_LOG | com.sleepycat.db.Db.DB_INIT_TXN | - com.sleepycat.db.Db.DB_RECOVER; - } - - // - // Use process-private memory and mutexes. In the way we can use a - // Berkeley DB built using the POSIX thread library on Linux, like the - // Berkeley DB that comes with RedHat 9. - // - // TODO: make setting or not setting DB_PRIVATE configurable. - // When DB_PRIVATE is set, only one process can use a DB environment - // at a time. - // - - flags |= com.sleepycat.db.Db.DB_PRIVATE; - - try - { - _dbEnv.open(_name, flags, 0); //TODO: FREEZE_DB_MODE) - } - catch(java.io.FileNotFoundException e) - { - DBNotFoundException ex = new DBNotFoundException(); - ex.initCause(e); - ex.message = _errorPrefix + "DbEnv.open: " + e.getMessage(); - throw ex; - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "DbEnv.open: " + e.getMessage(); - throw ex; - } - - _dbEnv.set_errcall(this); - } - - // - // com.sleepycat.db.DbErrcall interface implementation. - // - public void - errcall(String errorPrefix, String message) - { - _communicator.getLogger().error("Freeze database error: " + _name + ": " + message); - } - - private Ice.Communicator _communicator; - private int _trace = 0; - private com.sleepycat.db.DbEnv _dbEnv; - private String _name; - private String _errorPrefix; - - private java.util.HashMap _dbMap = new java.util.HashMap(); -} diff --git a/java/src/Freeze/DBI.java b/java/src/Freeze/DBI.java deleted file mode 100644 index 155d82c7c23..00000000000 --- a/java/src/Freeze/DBI.java +++ /dev/null @@ -1,747 +0,0 @@ -// ********************************************************************** -// -// 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 DBI extends Ice.LocalObjectImpl implements DB -{ - public String - getName() - { - // No mutex lock necessary, _name is immutable - return _name; - } - - public Ice.Communicator - getCommunicator() - { - // No mutex lock necessary, _communicator is immutable - return _communicator; - } - - synchronized public long - getNumberOfRecords() - { - if(_db == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - // - // TODO: DB_FAST_STAT doesn't seem to do what the - // documentation says... - // - try - { - com.sleepycat.db.DbBtreeStat s = (com.sleepycat.db.DbBtreeStat)_db.stat(0); - return s.bt_ndata; - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.stat: " + e.getMessage(); - throw ex; - } - } - - synchronized public DBCursor - getCursor() - { - return getCursorImpl(null); - } - - synchronized public DBCursor - getCursorAtKey(byte[] key) - { - return getCursorAtKeyImpl(null, key); - } - - synchronized public void - put(byte[] key, byte[] value) - { - putImpl(null, key, value); - } - - synchronized public boolean - contains(byte[] key) - { - return containsImpl(null, key); - } - - synchronized public byte[] - get(byte[] key) - { - return getImpl(null, key); - } - - synchronized public void - del(byte[] key) - { - delImpl(null, key); - } - - synchronized public DBCursor - getCursorWithTxn(DBTransaction txn) - { - assert txn != null; - return getCursorImpl(((DBTransactionI)txn).getTxnId()); - } - - synchronized public DBCursor - getCursorAtKeyWithTxn(DBTransaction txn, byte[] key) - { - assert txn != null; - return getCursorAtKeyImpl(((DBTransactionI)txn).getTxnId(), key); - } - - synchronized public void - putWithTxn(DBTransaction txn, byte[] key, byte[] value) - { - assert txn != null; - putImpl(((DBTransactionI)txn).getTxnId(), key, value); - } - - synchronized public boolean - containsWithTxn(DBTransaction txn, byte[] key) - { - assert txn != null; - return containsImpl(((DBTransactionI)txn).getTxnId(), key); - } - - synchronized public byte[] - getWithTxn(DBTransaction txn, byte[] key) - { - assert txn != null; - return getImpl(((DBTransactionI)txn).getTxnId(), key); - } - - synchronized public void - delWithTxn(DBTransaction txn, byte[] key) - { - assert txn != null; - delImpl(((DBTransactionI)txn).getTxnId(), key); - } - - synchronized public void - clear() - { - if(_db == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - int count; // ignored - try - { - _db.truncate(null, 0); - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.truncate: " + e.getMessage(); - throw ex; - } - } - - synchronized public void - close() - { - if(_db == null) - { - return; - } - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "closing database \"" + _name + "\""); - } - - try - { - _db.close(0); - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.truncate: " + e.getMessage(); - throw ex; - } - - _dbEnvObj.remove(_name); - _dbEnvObj = null; - _db = null; - } - - synchronized public void - remove() - { - if(_db == null) - { - return; - } - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "removing database \"" + _name + "\""); - } - - // - // Remove first needs to close the database object. It's not - // possible to remove an open database. - // - try - { - _db.close(0); - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.remove: " + e.getMessage(); - throw ex; - } - - // - // Take a copy of the DBEnvironment to make cleanup easier. - // - DBEnvironmentI dbEnvCopy = _dbEnvObj; - - _dbEnvObj.remove(_name); - _dbEnvObj = null; - _db = null; - - // - // Ask the DBEnvironment to erase the database. - // - dbEnvCopy.eraseDB(_name); - } - - synchronized public void - sync() - { - if(_db == null) - { - return; - } - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "synchronizing database \"" + _name + "\""); - } - - try - { - _db.sync(0); - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.sync: " + e.getMessage(); - throw ex; - } - } - - public EvictionStrategy - createEvictionStrategy() - { - return new EvictionStrategyI(); - } - - public IdleStrategy - createIdleStrategy() - { - return new IdleStrategyI(); - } - - synchronized public Evictor - createEvictor(PersistenceStrategy strategy) - { - if(_db == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - return new EvictorI(this, strategy); - } - - DBI(Ice.Communicator communicator, DBEnvironmentI dbEnvObj, com.sleepycat.db.Db db, com.sleepycat.db.DbTxn txn, - String name, boolean create) - { - _communicator = communicator; - _dbEnvObj = dbEnvObj; - _db = db; - _name = name; - _errorPrefix = "Freeze::DB(\"" + _name + "\"): "; - _trace = _communicator.getProperties().getPropertyAsInt("Freeze.Trace.DB"); - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB","opening database \"" + _name + "\" in environment \"" + - _dbEnvObj.getName() + "\""); - } - - int flags = (create) ? com.sleepycat.db.Db.DB_CREATE : 0; - try - { - // - // The signature for the open() method changed in version 4.1. - // We use reflection to invoke it with the proper arguments. - // - java.lang.reflect.Method m; - Class[] types; - Object[] args; - if(com.sleepycat.db.Db.DB_VERSION_MAJOR > 4 || - (com.sleepycat.db.Db.DB_VERSION_MAJOR == 4 && com.sleepycat.db.Db.DB_VERSION_MINOR >= 1)) - { - types = new Class[6]; - types[0] = com.sleepycat.db.DbTxn.class; - types[1] = String.class; - types[2] = String.class; - types[3] = Integer.TYPE; - types[4] = Integer.TYPE; - types[5] = Integer.TYPE; - args = new Object[6]; - args[0] = txn; - args[1] = _name; - args[2] = null; - args[3] = new Integer(com.sleepycat.db.Db.DB_BTREE); - args[4] = new Integer(flags); - args[5] = new Integer(0); - // - // Equivalent to: - // - //_db.open(null, _name, null, com.sleepycat.db.Db.DB_BTREE, flags, 0); - } - else - { - types = new Class[5]; - types[0] = String.class; - types[1] = String.class; - types[2] = Integer.TYPE; - types[3] = Integer.TYPE; - types[4] = Integer.TYPE; - args = new Object[5]; - args[0] = _name; - args[1] = null; - args[2] = new Integer(com.sleepycat.db.Db.DB_BTREE); - args[3] = new Integer(flags); - args[4] = new Integer(0); - // - // Equivalent to: - // - //_db.open(_name, null, com.sleepycat.db.Db.DB_BTREE, flags, 0); - } - - m = com.sleepycat.db.Db.class.getDeclaredMethod("open", types); - m.invoke(_db, args); - //TODO: FREEZE_DB_MODE - } - catch(NoSuchMethodException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = "reflection error"; - throw ex; - } - catch(IllegalAccessException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = "reflection error"; - throw ex; - } - catch(IllegalArgumentException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = "reflection error"; - throw ex; - } - catch(java.lang.reflect.InvocationTargetException e) - { - Throwable t = e.getCause(); - if(t instanceof java.io.FileNotFoundException) - { - DBNotFoundException ex = new DBNotFoundException(); - ex.initCause(t); - ex.message = _errorPrefix + "Db.open: " + t.getMessage(); - throw ex; - } - else if(t instanceof com.sleepycat.db.DbException) - { - DBException ex = new DBException(); - ex.initCause(t); - ex.message = _errorPrefix + "Db.open: " + t.getMessage(); - throw ex; - } - else - { - DBException ex = new DBException(); - ex.initCause(t); - ex.message = "Db.open: unexpected exception"; - throw ex; - } - } - - _dbEnvObj.add(_name, this); - } - - private DBCursor - getCursorImpl(com.sleepycat.db.DbTxn txn) - { - if(_db == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - com.sleepycat.db.Dbc cursor; - - try - { - cursor = _db.cursor(txn, 0); - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.cursor: " + e.getMessage(); - throw ex; - } - - // - // Note that the read of the data is partial (that is the data - // will not actually be read into memory since it isn't needed - // yet). - // - com.sleepycat.db.Dbt dbData = new com.sleepycat.db.Dbt(); - dbData.set_flags(com.sleepycat.db.Db.DB_DBT_PARTIAL); - com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(); - dbKey.set_flags(com.sleepycat.db.Db.DB_DBT_PARTIAL); - - try - { - try - { - int rc = cursor.get(dbKey, dbData, com.sleepycat.db.Db.DB_FIRST); - if(rc == com.sleepycat.db.Db.DB_NOTFOUND) - { - DBNotFoundException ex = new DBNotFoundException(); - ex.message = _errorPrefix + "Dbc.get: DB_NOTFOUND"; - throw ex; - } - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Dbc.get: " + e.getMessage(); - throw ex; - } - } - catch(DBException e) - { - // - // Cleanup on failure. - // - try - { - cursor.close(); - } - catch(com.sleepycat.db.DbException ignore) - { - // Ignore - } - throw e; - } - - return new DBCursorI(_communicator, _name, cursor); - } - - private DBCursor - getCursorAtKeyImpl(com.sleepycat.db.DbTxn txn, byte[] key) - { - if(_db == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - com.sleepycat.db.Dbc cursor; - - try - { - cursor = _db.cursor(txn, 0); - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.cursor: " + e.getMessage(); - throw ex; - } - - // - // Move to the requested record - // - com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(key); - - // - // Note that the read of the data is partial (that is the data - // will not actually be read into memory since it isn't needed - // yet). - // - com.sleepycat.db.Dbt dbData = new com.sleepycat.db.Dbt(); - dbData.set_flags(com.sleepycat.db.Db.DB_DBT_PARTIAL); - - try - { - try - { - int rc = cursor.get(dbKey, dbData, com.sleepycat.db.Db.DB_SET); - if(rc == com.sleepycat.db.Db.DB_NOTFOUND) - { - DBNotFoundException ex = new DBNotFoundException(); - ex.message = _errorPrefix + "Dbc.get: DB_NOTFOUND"; - throw ex; - } - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Dbc.get: " + e.getMessage(); - throw ex; - } - } - catch(DBException e) - { - // - // Cleanup on failure. - // - try - { - cursor.close(); - } - catch(com.sleepycat.db.DbException ignore) - { - // Ignore - } - throw e; - } - - return new DBCursorI(_communicator, _name, cursor); - } - - private void - putImpl(com.sleepycat.db.DbTxn txn, byte[] key, byte[] value) - { - if(_db == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - // - // TODO: This can be optimized so that these only need to be - // allocated once. - // - com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(key); - com.sleepycat.db.Dbt dbData = new com.sleepycat.db.Dbt(value); - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "writing value in database \"" + _name + "\""); - } - - try - { - _db.put(txn, dbKey, dbData, 0); - } - catch(com.sleepycat.db.DbDeadlockException e) - { - DBDeadlockException ex = new DBDeadlockException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.put: " + e.getMessage(); - throw ex; - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.put: " + e.getMessage(); - throw ex; - } - } - - private boolean - containsImpl(com.sleepycat.db.DbTxn txn, byte[] key) - { - if(_db == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(key); - - com.sleepycat.db.Dbt dbData = new com.sleepycat.db.Dbt(); - dbData.set_flags(com.sleepycat.db.Db.DB_DBT_PARTIAL); - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "checking key in database \"" + _name + "\""); - } - - try - { - int rc =_db.get(txn, dbKey, dbData, 0); - if(rc == com.sleepycat.db.Db.DB_NOTFOUND) - { - return false; - } - else - { - assert(rc == 0); - return true; - } - } - catch(com.sleepycat.db.DbDeadlockException e) - { - DBDeadlockException ex = new DBDeadlockException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.get: " + e.getMessage(); - throw ex; - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.get: " + e.getMessage(); - throw ex; - } - } - - private byte[] - getImpl(com.sleepycat.db.DbTxn txn, byte[] key) - { - if(_db == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(key); - com.sleepycat.db.Dbt dbData = new com.sleepycat.db.Dbt(); - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "reading value from database \"" + _name + "\""); - } - - try - { - int rc =_db.get(txn, dbKey, dbData, 0); - if(rc == com.sleepycat.db.Db.DB_NOTFOUND) - { - DBNotFoundException ex = new DBNotFoundException(); - ex.message = _errorPrefix + "Db.get: DB_NOTFOUND"; - throw ex; - } - } - catch(com.sleepycat.db.DbDeadlockException e) - { - DBDeadlockException ex = new DBDeadlockException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.get: " + e.getMessage(); - throw ex; - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.get: " + e.getMessage(); - throw ex; - } - - return dbData.get_data(); - } - - private void - delImpl(com.sleepycat.db.DbTxn txn, byte[] key) - { - if(_db == null) - { - DBException ex = new DBException(); - ex.message = _errorPrefix + "\"" + _name + "\" has been closed"; - throw ex; - } - - com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(key); - - if(_trace >= 1) - { - _communicator.getLogger().trace("DB", "deleting value from database \"" + _name + "\""); - } - - try - { - int rc =_db.del(txn, dbKey, 0); - if(rc == com.sleepycat.db.Db.DB_NOTFOUND) - { - DBNotFoundException ex = new DBNotFoundException(); - ex.message = _errorPrefix + "Db.del: DB_NOTFOUND"; - throw ex; - } - } - catch(com.sleepycat.db.DbDeadlockException e) - { - DBDeadlockException ex = new DBDeadlockException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.del: " + e.getMessage(); - throw ex; - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "Db.del: " + e.getMessage(); - throw ex; - } - } - - private Ice.Communicator _communicator; - private int _trace = 0; - - private DBEnvironmentI _dbEnvObj; - private com.sleepycat.db.Db _db; - - private String _name; - private String _errorPrefix; -} diff --git a/java/src/Freeze/DBTransactionI.java b/java/src/Freeze/DBTransactionI.java deleted file mode 100644 index 1e31ad9a13a..00000000000 --- a/java/src/Freeze/DBTransactionI.java +++ /dev/null @@ -1,128 +0,0 @@ -// ********************************************************************** -// -// 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 DBTransactionI extends Ice.LocalObjectImpl implements DBTransaction -{ - public synchronized void - commit() - { - if(_tid == null) - { - String s = _errorPrefix + "transaction has already been committed or aborted"; - DBException ex = new DBException(); - ex.message = s; - throw ex; - } - - if(_trace >= 2) - { - _communicator.getLogger().trace("DB", "committing transaction for environment \"" + _name + "\""); - } - - try - { - _tid.commit(0); - } - catch(com.sleepycat.db.DbDeadlockException e) - { - DBDeadlockException ex = new DBDeadlockException(); - ex.initCause(e); - ex.message = _errorPrefix + "DbTxn.commit: " + e.getMessage(); - throw ex; - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "DbTxn.commit: " + e.getMessage(); - throw ex; - } - - _tid = null; - } - - public synchronized void - abort() - { - if(_tid == null) - { - String s = _errorPrefix + "transaction has already been committed or aborted"; - DBException ex = new DBException(); - ex.message = s; - throw ex; - } - - if(_trace >= 2) - { - _communicator.getLogger().trace("DB", "aborting transaction for environment \"" + _name + - "\" due to deadlock"); - } - - try - { - _tid.abort(); - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "DbTxn.abort: " + e.getMessage(); - throw ex; - } - - _tid = null; - } - - com.sleepycat.db.DbTxn - getTxnId() - { - return _tid; - } - - - DBTransactionI(Ice.Communicator communicator, com.sleepycat.db.DbEnv dbEnv, String name) - { - _communicator = communicator; - _name = name; - _errorPrefix = "Freeze::DBTransaction(\"" + _name + "\"): "; - _trace = _communicator.getProperties().getPropertyAsInt("Freeze.Trace.DB"); - - if(_trace >= 2) - { - _communicator.getLogger().trace("DB", "starting transaction for environment \"" + _name + "\""); - } - - try - { - _tid = dbEnv.txn_begin(null, 0); - } - catch(com.sleepycat.db.DbException e) - { - DBException ex = new DBException(); - ex.initCause(e); - ex.message = _errorPrefix + "DbEnv.txn_begin: " + e.getMessage(); - throw ex; - } - } - - private Ice.Communicator _communicator; - private int _trace = 0; - - private com.sleepycat.db.DbTxn _tid; - - private String _name; - private String _errorPrefix; -} diff --git a/java/src/Freeze/EvictionStrategyI.java b/java/src/Freeze/EvictionStrategyI.java deleted file mode 100644 index f95fe0c1f72..00000000000 --- a/java/src/Freeze/EvictionStrategyI.java +++ /dev/null @@ -1,88 +0,0 @@ -// ********************************************************************** -// -// 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; - -public final class EvictionStrategyI extends Ice.LocalObjectImpl implements EvictionStrategy -{ - public - EvictionStrategyI() - { - } - - public Ice.LocalObject - activatedObject(Ice.Identity ident, Ice.Object servant) - { - return new Cookie(); - } - - public void - destroyedObject(Ice.Identity ident, Ice.LocalObject cookie) - { - // Nothing to do - } - - public void - evictedObject(ObjectStore store, Ice.Identity ident, Ice.Object servant, Ice.LocalObject cookie) - { - // - // Only store the object's persistent state if it has been mutated. - // - Cookie c = (Cookie)cookie; - if(c.mutated) - { - store.save(ident, servant); - c.mutated = false; - } - } - - public void - savedObject(ObjectStore store, Ice.Identity ident, Ice.Object servant, Ice.LocalObject cookie, int usageCount) - { - assert(usageCount > 0); - - if(usageCount == 1) - { - Cookie c = (Cookie)cookie; - c.mutated = false; - } - } - - public void - preOperation(ObjectStore store, Ice.Identity ident, Ice.Object servant, boolean mutating, Ice.LocalObject cookie) - { - if(mutating) - { - Cookie c = (Cookie)cookie; - c.mutated = true; - } - } - - public void - postOperation(ObjectStore store, Ice.Identity ident, Ice.Object servant, boolean mutating, Ice.LocalObject cookie) - { - // Nothing to do - } - - public void - destroy() - { - // Nothing to do - } - - private static class Cookie extends Ice.LocalObjectImpl - { - boolean mutated = false; - } -} diff --git a/java/src/Freeze/EvictorI.java b/java/src/Freeze/EvictorI.java index 9a80a82122c..77b6084e3b6 100644 --- a/java/src/Freeze/EvictorI.java +++ b/java/src/Freeze/EvictorI.java @@ -14,30 +14,37 @@ package Freeze; -class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore +class EvictorI extends Ice.LocalObjectImpl implements Evictor, Runnable { - synchronized public DB - getDB() + public EvictorI(Ice.Communicator communicator, String envName, + String dbName, boolean createDb) { - if(_deactivated) - { - throw new EvictorDeactivatedException(); - } + _communicator = communicator; + _dbEnvHolder = SharedDbEnv.get(communicator, envName); + _dbEnv = _dbEnvHolder; - return _db; + init(envName, dbName, createDb); } - synchronized public PersistenceStrategy - getPersistenceStrategy() + public EvictorI(Ice.Communicator communicator, com.sleepycat.db.DbEnv dbEnv, + String dbName, boolean createDb) + { + _communicator = communicator; + _dbEnvHolder = null; + _dbEnv = dbEnv; + + init("External", dbName, createDb); + } + + protected void + finalize() { - if(_deactivated) + if(!_deactivated) { - throw new EvictorDeactivatedException(); + _communicator.getLogger().warning("evictor has not been deactivated"); } - - return _strategy; } - + synchronized public void setSize(int evictorSize) { @@ -77,6 +84,17 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore } synchronized public void + saveNow() + { + if(_deactivated) + { + throw new EvictorDeactivatedException(); + } + + saveNowNoSync(); + } + + synchronized public void createObject(Ice.Identity ident, Ice.Object servant) { if(_deactivated) @@ -85,39 +103,113 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore } // - // Copy the identity. This is necessary for add(). + // Make a copy of ident in case the user later changes it + // (used when inserting into list or map) // Ice.Identity identCopy = new Ice.Identity(); identCopy.name = ident.name; identCopy.category = ident.category; + + EvictorElement element = (EvictorElement)_evictorMap.get(ident); + if(element != null) + { + synchronized(element) + { + switch(element.status) + { + case clean: + { + element.status = modified; + addToModifiedQueue(identCopy, element); + break; + } + case created: + case modified: + { + // + // Nothing to do. + // No need to push it on the modified queue as a created resp + // modified element is either already on the queue or about + // to be saved. When saved, it becomes clean. + // + break; + } + case destroyed: + { + element.status = modified; + // + // No need to push it on the modified queue, as a destroyed element + // is either already on the queue or about to be saved. When saved, + // it becomes dead. + // + break; + } + case dead: + { + element.status = created; + addToModifiedQueue(identCopy, element); + break; + } + default: + { + assert(false); + break; + } + } + element.rec.servant = servant; + } - ObjectRecord rec = new ObjectRecord(); - rec.servant = servant; - rec.stats = new Statistics(); - rec.stats.creationTime = System.currentTimeMillis(); - rec.stats.lastSaveTime = 0; - rec.stats.avgSaveTime = 0; - - // - // Save the Ice object's initial state and add it to the queue. - // - _dict.fastPut(ident, rec); - add(identCopy, rec); - - if(_trace >= 1) + element.position.remove(); + _evictorList.addFirst(identCopy); + element.position = _evictorList.iterator(); + } + else { - _db.getCommunicator().getLogger().trace("Freeze::Evictor", - "created \"" + Ice.Util.identityToString(ident) + "\""); + // + // Create a new object + // + + ObjectRecord rec = new ObjectRecord(); + rec.servant = servant; + rec.stats = new Statistics(); + rec.stats.creationTime = System.currentTimeMillis(); + rec.stats.lastSaveTime = 0; + rec.stats.avgSaveTime = 0; + + // + // Add an Ice object with its servant to the evictor queue. + // + element = new EvictorElement(); + element.rec = rec; + element.usageCount = 0; + element.status = created; + + _evictorMap.put(identCopy, element); + _evictorList.addFirst(identCopy); + + element.position = _evictorList.iterator(); + // + // Position the iterator "on" the element. + // + element.position.next(); + + addToModifiedQueue(identCopy, element); + + // + // Evict as many elements as necessary. + // + evict(); } - // - // Evict as many elements as necessary. - // - evict(); + if(_trace >= 1) + { + _communicator.getLogger().trace("Freeze::Evictor", + "created \"" + Ice.Util.identityToString(ident) + "\""); + } } synchronized public void - saveObject(Ice.Identity ident) + destroyObject(Ice.Identity ident) { if(_deactivated) { @@ -125,46 +217,110 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore } EvictorElement element = (EvictorElement)_evictorMap.get(ident); - if(element == null) + if(element != null) { - throw new ObjectDestroyedException(); - } - assert(!element.destroyed); + synchronized(element) + { + switch(element.status) + { + case clean: + { + element.status = destroyed; - save(ident, element.rec.servant); - _strategy.savedObject(this, ident, element.rec.servant, element.strategyCookie, element.usageCount); - } + // + // Make a copy of ident in case the user later changes it + // (used when inserting into list or map) + // + Ice.Identity identCopy = new Ice.Identity(); + identCopy.name = ident.name; + identCopy.category = ident.category; + + addToModifiedQueue(identCopy, element); + break; + } + case created: + { + element.status = dead; + break; + } + case modified: + { + element.status = destroyed; + // + // Not necessary to push it on the modified queue, as a modified + // element is either on the queue already or about to be saved + // (at which point it becomes clean) + // + break; + } + case destroyed: + case dead: + { + // + // Nothing to do! + // + break; + } + default: + { + assert(false); + break; + } + } + } + } + else + { + // + // Set a real ObjectRecord in case this object gets recreated + // + ObjectRecord rec = new ObjectRecord(); + rec.servant = null; + rec.stats = new Statistics(); + rec.stats.creationTime = System.currentTimeMillis(); + rec.stats.lastSaveTime = 0; + rec.stats.avgSaveTime = 0; - synchronized public void - destroyObject(Ice.Identity ident) - { - if(_deactivated) - { - throw new EvictorDeactivatedException(); + // + // Add an Ice object with its servant to the evictor queue. + // + element = new EvictorElement(); + element.rec = rec; + element.usageCount = 0; + element.status = destroyed; + + + // + // Make a copy of ident in case the user later changes it + // (used when inserting into list or map) + // + Ice.Identity identCopy = new Ice.Identity(); + identCopy.name = ident.name; + identCopy.category = ident.category; + + _evictorMap.put(identCopy, element); + _evictorList.addFirst(identCopy); + + element.position = _evictorList.iterator(); + // + // Position the iterator "on" the element. + // + element.position.next(); + + addToModifiedQueue(identCopy, element); + + // + // Evict as many elements as necessary. + // + evict(); } - - EvictorElement element = remove(ident); - if(element != null) + + if(_trace >= 1) { - element.destroyed = true; - - // - // Notify the persistence strategy. - // - _strategy.destroyedObject(ident, element.strategyCookie); - - if(_trace >= 1) - { - _db.getCommunicator().getLogger().trace("Freeze::Evictor", "destroyed \"" + - Ice.Util.identityToString(ident) + "\""); - } + _communicator.getLogger().trace("Freeze::Evictor", "destroyed \"" + + Ice.Util.identityToString(ident) + "\""); } - - // - // Delete the Ice object from the database. - // - _dict.fastRemove(ident); } synchronized public void @@ -178,239 +334,671 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore _initializer = initializer; } - synchronized public EvictorIterator + public EvictorIterator getIterator() { - if(_deactivated) + synchronized(this) { - throw new EvictorDeactivatedException(); + if(_deactivated) + { + throw new EvictorDeactivatedException(); + } + saveNowNoSync(); } - return new EvictorIteratorI(_dict.entrySet().iterator()); + return new EvictorIteratorI(_db, _communicator, _errorPrefix); } synchronized public boolean hasObject(Ice.Identity ident) { - if(_deactivated) + synchronized(this) { - throw new EvictorDeactivatedException(); + if(_deactivated) + { + throw new EvictorDeactivatedException(); + } + + EvictorElement element = (EvictorElement)_evictorMap.get(ident); + if(element != null) + { + synchronized(element) + { + return (element.status != destroyed && element.status != dead); + } + } } - return _dict.containsKey(ident); + return dbHasObject(ident); } - synchronized public Ice.Object + public Ice.Object locate(Ice.Current current, Ice.LocalObjectHolder cookie) { - assert(_db != null); - - // - // If this operation is called on a deactivated servant locator, - // it's a bug in Ice. // - assert(!_deactivated); - - // - // First copy current.identity. This is necessary since this - // identity is later added to the evictor list (and - // potentially the map). + // Need to copy current.id, as Ice caches and reuses it // Ice.Identity ident = new Ice.Identity(); ident.name = current.id.name; ident.category = current.id.category; - - EvictorElement element = (EvictorElement)_evictorMap.get(ident); - if(element != null) + + ObjectRecord rec = null; + + for(;;) { - if(_trace >= 2) + EvictorElement element; + + synchronized(this) { - _db.getCommunicator().getLogger().trace("Freeze::Evictor", - "found \"" + Ice.Util.identityToString(ident) + - "\" in the queue"); - } - - // - // Ice object found in evictor map. Push it to the front of - // the evictor list, so that it will be evicted last. - // - element.position.remove(); - _evictorList.addFirst(ident); - element.position = _evictorList.iterator(); + // + // If this operation is called on a deactivated servant locator, + // it's a bug in Ice. + // + assert(!_deactivated); - // - // Position the iterator "on" the element. - // - element.position.next(); - } - else - { - if(_trace >= 2) + element = (EvictorElement)_evictorMap.get(ident); + + if(element != null) + { + // + // Ice object found in evictor map. Push it to the front of + // the evictor list, so that it will be evicted last. + // + element.position.remove(); + _evictorList.addFirst(ident); + element.position = _evictorList.iterator(); + // + // Position the iterator "on" the element. + // + element.position.next(); + + element.usageCount++; + cookie.value = (Ice.LocalObject)element; + + // + // Later (after releasing the mutex), check that this + // object is not dead or destroyed + // + } + else if(rec != null) + { + // + // Proceed with the object loaded in the previous loop + // + + // + // If an initializer is installed, call it now. + // + if(_initializer != null) + { + _initializer.initialize(current.adapter, ident, rec.servant); + } + + // + // Add an Ice object with its servant to the evictor queue. + // + + element = new EvictorElement(); + element.rec = rec; + element.usageCount = 1; + element.status = clean; + + _evictorMap.put(ident, element); + _evictorList.addFirst(ident); + + element.position = _evictorList.iterator(); + // + // Position the iterator "on" the element. + // + element.position.next(); + + cookie.value = (Ice.LocalObject)element; + + // + // Evict as many elements as necessary. + // + evict(); + + return rec.servant; + } + // + // Else fall to the after-sync processing + // + } + + if(element != null) { - _db.getCommunicator().getLogger().trace( - "Freeze::Evictor", - "couldn't find \"" + Ice.Util.identityToString(ident) + "\" in the queue\n" - + "loading \"" + Ice.Util.identityToString(ident) + "\" from the database"); + if(_trace >= 2) + { + _communicator.getLogger().trace("Freeze::Evictor", + "found \"" + Ice.Util.identityToString(ident) + + "\" in the queue"); + } + + // + // Return servant if object not dead or destroyed + // + synchronized(element) + { + if(element.status != destroyed && element.status != dead) + { + return element.rec.servant; + } + } + + // + // Object is destroyed or dead: clean-up + // + if(_trace >= 2) + { + _communicator.getLogger().trace("Freeze::Evictor", + "\"" + Ice.Util.identityToString(ident) + + "\" was dead or destroyed"); + } + synchronized(this) + { + element.usageCount--; + return null; + } } - - // - // Load the Ice object from the database and add a - // servant for it. - // - ObjectRecord rec = (ObjectRecord)_dict.get(ident); - if(rec == null) + else { // - // The Ice object with the given identity does not exist, - // client will get an ObjectNotExistException. + // Load object now and loop + // + + if(_trace >= 2) + { + _communicator.getLogger().trace( + "Freeze::Evictor", + "couldn't find \"" + Ice.Util.identityToString(ident) + "\" in the queue\n" + + "loading \"" + Ice.Util.identityToString(ident) + "\" from the database"); + } + + rec = getObject(ident); + + if(rec == null) + { + // + // The Ice object with the given identity does not exist, + // client will get an ObjectNotExistException. + // + return null; + } + // + // Else loop // - return null; } + } + } - // - // If an initializer is installed, call it now. - // - if(_initializer != null) + + public void + finished(Ice.Current current, Ice.Object servant, Ice.LocalObject cookie) + { + assert(servant != null); + + EvictorElement element = (EvictorElement)cookie; + boolean enqueue = false; + + if(current.mode != Ice.OperationMode.Nonmutating) + { + synchronized(element) { - _initializer.initialize(current.adapter, ident, rec.servant); + if(element.status == clean) + { + // + // Assume this operation updated the object + // + element.status = modified; + enqueue = true; + } } + } + + synchronized(this) + { + assert(!_deactivated); // - // Add the new servant to the evictor queue. + // Decrease the usage count of the evictor queue element. // - element = add(ident, rec); + assert(element.usageCount >= 1); + element.usageCount--; + + if(enqueue) + { + // + // Need to copy current.id, as Ice caches and reuses it + // + Ice.Identity ident = new Ice.Identity(); + ident.name = current.id.name; + ident.category = current.id.category; + + addToModifiedQueue(ident, element); + } + else + { + // + // Evict as many elements as necessary. + // + evict(); + } } - - // - // Increase the usage count of the evictor queue element. - // - ++element.usageCount; - - // - // Notify the persistence strategy about the operation. - // - _strategy.preOperation(this, ident, element.rec.servant, current.mode != Ice.OperationMode.Nonmutating, - element.strategyCookie); - - // - // Evict as many elements as necessary. - // - evict(); - - // - // Set the cookie and return the servant for the Ice object. - // - cookie.value = (Ice.LocalObject)element; - return element.rec.servant; } - synchronized public void - finished(Ice.Current current, Ice.Object servant, Ice.LocalObject cookie) + public void + deactivate(String category) { - assert(_db != null); - assert(servant != null); - - // - // It's possible that the locator has been deactivated already. In - // this case, _evictorSize is set to zero. - // - assert(!_deactivated || _evictorSize == 0); - - // - // Decrease the usage count of the evictor queue element. - // - EvictorElement element = (EvictorElement)cookie; - assert(element.usageCount >= 1); - --element.usageCount; - - // - // If the object has not been destroyed, notify the persistence - // strategy about the operation. - // - if(!element.destroyed) - { - _strategy.postOperation(this, current.id, servant, current.mode != Ice.OperationMode.Nonmutating, - element.strategyCookie); - } + boolean joinAndClose = false; + + synchronized(this) + { + if(!_deactivated) + { + if(_trace >= 1) + { + _communicator.getLogger().trace( + "Freeze::Evictor", + "deactivating, saving unsaved Ice objects to the database"); + } + + saveNowNoSync(); + + // + // Set the evictor size to zero, meaning that we will evict + // everything possible. + // + _evictorSize = 0; + evict(); + + _deactivated = true; + notifyAll(); + joinAndClose = true; + } + } - // - // Evict as many elements as necessary. - // - evict(); + if(joinAndClose) + { + for(;;) + { + try + { + _thread.join(); + break; + } + catch(InterruptedException ex) + { + } + } + + try + { + _db.close(0); + } + catch(com.sleepycat.db.DbException dx) + { + DBException ex = new DBException(); + ex.initCause(dx); + ex.message = _errorPrefix + "Db.close: " + dx.getMessage(); + throw ex; + } + _db = null; + if(_dbEnvHolder != null) + { + _dbEnvHolder.close(); + _dbEnvHolder = null; + } + _dbEnv = null; + } } - synchronized public void - deactivate(String category) + public void + run() { - if(!_deactivated) + for(;;) { - _deactivated = true; + java.util.List allObjects; + int saveNowThreadsSize = 0; - if(_trace >= 1) + synchronized(this) { - _db.getCommunicator().getLogger().trace("Freeze::Evictor", - "deactivating, saving unsaved Ice objects to the database"); + while((!_deactivated) && + (_saveNowThreads.size() == 0) && + (_saveSizeTrigger < 0 || _modifiedQueue.size() < _saveSizeTrigger)) + { + try + { + if(_savePeriod == 0) + { + wait(); + } + else + { + long preSave = System.currentTimeMillis(); + wait(_savePeriod); + if(System.currentTimeMillis() > preSave + _savePeriod) + { + break; + } + } + } + catch(InterruptedException ex) + { + } + } + + saveNowThreadsSize = _saveNowThreads.size(); + + if(_deactivated) + { + assert(_modifiedQueue.size() == 0); + if(saveNowThreadsSize > 0) + { + _saveNowThreads.clear(); + notifyAll(); + } + break; // for(;;) + } + + // + // Check first if there is something to do! + // + if(_modifiedQueue.size() == 0) + { + if(saveNowThreadsSize > 0) + { + _saveNowThreads.clear(); + notifyAll(); + } + continue; // for(;;) + } + + allObjects = _modifiedQueue; + _modifiedQueue = new java.util.ArrayList(); } + int size = allObjects.size(); + // - // Set the evictor size to zero, meaning that we will evict - // everything possible. + // Usage count release // - _evictorSize = 0; - evict(); + java.util.List releaseAfterStreaming = new java.util.ArrayList(); + java.util.List releaseAfterCommit = new java.util.ArrayList(); + + java.util.List streamedObjectQueue = new java.util.ArrayList(); + + long saveStart = System.currentTimeMillis(); + + // + // Stream each element + // + for(int i = 0; i < size; i++) + { + EvictorElement element = (EvictorElement)_evictorMap.get((Ice.Identity)allObjects.get(i)); + + synchronized(element) + { + ObjectRecord rec = element.rec; + + boolean streamIt = true; + byte status = element.status; + + switch(status) + { + case created: + { + element.status = clean; + releaseAfterCommit.add(element); + break; + } + case modified: + { + element.status = clean; + releaseAfterStreaming.add(element); + break; + } + case destroyed: + { + element.status = dead; + releaseAfterCommit.add(element); + break; + } + default: + { + // + // Nothing to do (could be a duplicate) + // + streamIt = false; + releaseAfterStreaming.add(element); + break; + } + } + + if(streamIt) + { + int index = streamedObjectQueue.size(); + StreamedObject obj = new StreamedObject(); + streamedObjectQueue.add(obj); + + obj.key = IdentityObjectRecordDict.encodeKeyImpl(allObjects.get(i), _communicator); + obj.status = status; + if(status != destroyed) + { + synchronized(rec.servant) + { + + obj.value = writeObjectRecordToValue(saveStart, rec); + } + } + } + } + } + + allObjects.clear(); + + if(releaseAfterStreaming.size() > 0) + { + synchronized(this) + { + for(int i = 0; i < releaseAfterStreaming.size(); i++) + { + EvictorElement element = (EvictorElement)releaseAfterStreaming.get(i); + element.usageCount--; + } + } + releaseAfterStreaming.clear(); + } + + // + // Now let's save all these streamed objects to disk using a transaction + // + + // + // Each time we get a deadlock, we reduce the number of objects to save + // per transaction + // + int txSize = streamedObjectQueue.size(); + boolean tryAgain; + + do + { + tryAgain = false; + + while(streamedObjectQueue.size() > 0) + { + if(txSize > streamedObjectQueue.size()) + { + txSize = streamedObjectQueue.size(); + } + + try + { + com.sleepycat.db.DbTxn tx = _dbEnv.txn_begin(null, 0); + try + { + for(int i = 0; i < txSize; i++) + { + StreamedObject obj = (StreamedObject) streamedObjectQueue.get(i); + + if(obj.status == destroyed) + { + // + // May not exist in the database + // + com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(obj.key); + + int err = _db.del(tx, dbKey, 0); + if(err != 0 && err != com.sleepycat.db.Db.DB_NOTFOUND) + { + // + // Bug in Freeze + // + throw new DBException(); + } + } + else + { + // + // We can't use NOOVERWRITE as some 'created' objects may + // actually be already in the database + // + + com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(obj.key); + com.sleepycat.db.Dbt dbValue = new com.sleepycat.db.Dbt(obj.value); + + int err = _db.put(tx, dbKey, dbValue, 0); + if(err != 0) + { + // + // Bug in Freeze + // + throw new DBException(); + } + } + } + } + catch(com.sleepycat.db.DbException dx) + { + tx.abort(); + throw dx; + } + tx.commit(0); + + for(int i = 0; i < txSize; i++) + { + streamedObjectQueue.remove(0); + } + + if(_trace >= 2) + { + long now = System.currentTimeMillis(); + _communicator.getLogger().trace( + "Freeze::Evictor", + "saved " + txSize + " objects in " + (now - saveStart) + " ms"); + saveStart = now; + } + } + catch(com.sleepycat.db.DbDeadlockException deadlock) + { + tryAgain = true; + txSize = (txSize + 1)/2; + } + catch(com.sleepycat.db.DbException dx) + { + DBException ex = new DBException(); + ex.initCause(dx); + ex.message = _errorPrefix + "saving: " + dx.getMessage(); + throw ex; + } + } + } while(tryAgain); + + + synchronized(this) + { + + for(int i = 0; i < releaseAfterCommit.size(); i++) + { + EvictorElement element = (EvictorElement)releaseAfterCommit.get(i); + element.usageCount--; + } + releaseAfterCommit.clear(); + + if(saveNowThreadsSize > 0) + { + for(int i = 0; i < saveNowThreadsSize; i++) + { + _saveNowThreads.remove(0); + } + notifyAll(); + } + } + + _lastSave = System.currentTimeMillis(); } } - public void - save(Ice.Identity ident, Ice.Object servant) + private void + init(String envName, String dbName, boolean createDb) { - // - // NOTE: This operation is not mutex-protected, therefore it may - // only be invoked while the evictor is already locked. For - // example, it is safe to call this operation from a persistence - // strategy implementation, iff the persistence strategy is in - // the thread context of a locked evictor operation. - // - EvictorElement element = (EvictorElement)_evictorMap.get(ident); - assert(element != null); - - // - // Update statistics before saving. - // - long now = System.currentTimeMillis(); - long diff = now - (element.rec.stats.creationTime + element.rec.stats.lastSaveTime); - if(element.rec.stats.lastSaveTime == 0) - { - element.rec.stats.lastSaveTime = diff; - element.rec.stats.avgSaveTime = diff; - } - else - { - element.rec.stats.lastSaveTime = now - element.rec.stats.creationTime; - element.rec.stats.avgSaveTime = (long)(element.rec.stats.avgSaveTime * 0.95 + diff * 0.05); - } + _trace = _communicator.getProperties().getPropertyAsInt( + "Freeze.Trace.Evictor"); - _dict.fastPut(ident, element.rec); - } + _errorPrefix = "Freeze Evictor DbEnv(\"" + envName + "\") Db(\"" + + dbName + "\") :"; - EvictorI(DB db, PersistenceStrategy strategy) - { - _db = db; - _dict = new IdentityObjectRecordDict(db); - _strategy = strategy; - _trace = _db.getCommunicator().getProperties().getPropertyAsInt("Freeze.Trace.Evictor"); - } + String propertyPrefix = "Freeze.Evictor." + envName + '.' + dbName; + + // + // By default, we save every minute or when the size of the modified + // queue reaches 10. + // - protected void - finalize() - throws Throwable - { - if(!_deactivated) - { - _db.getCommunicator().getLogger().warning("evictor has not been deactivated"); - } + _saveSizeTrigger = _communicator.getProperties().getPropertyAsIntWithDefault( + propertyPrefix + ".SaveSizeTrigger", 10); - _strategy.destroy(); + _savePeriod = _communicator.getProperties().getPropertyAsIntWithDefault( + propertyPrefix + ".SavePeriod", 60 * 1000); + + try + { + int flags = com.sleepycat.db.Db.DB_AUTO_COMMIT; + if(createDb) + { + flags |= com.sleepycat.db.Db.DB_CREATE; + } + + _db = new com.sleepycat.db.Db(_dbEnv, 0); + _db.open(null, dbName, null, com.sleepycat.db.Db.DB_BTREE, + flags, 0); + + // + // TODO: FREEZE_DB_MODE + // + } + catch(java.io.FileNotFoundException dx) + { + DBNotFoundException ex = new DBNotFoundException(); + ex.initCause(dx); + ex.message = _errorPrefix + "Db.open: " + dx.getMessage(); + throw ex; + } + catch(com.sleepycat.db.DbException dx) + { + DBException ex = new DBException(); + ex.initCause(dx); + ex.message = _errorPrefix + "Db.open: " + dx.getMessage(); + throw ex; + } + + _lastSave = System.currentTimeMillis(); + + // + // Start saving thread + // + _thread = new Thread(this); + _thread.start(); } private void @@ -432,11 +1020,6 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore // assert(ident != null && element != null); - // - // Notify the persistence strategy about the evicted object. - // - _strategy.evictedObject(this, ident, element.rec.servant, element.strategyCookie); - // // Remove element from the evictor queue. // @@ -445,7 +1028,7 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore if(_trace >= 2) { - _db.getCommunicator().getLogger().trace( + _communicator.getLogger().trace( "Freeze::Evictor", "evicted \"" + Ice.Util.identityToString(ident) + "\" from the queue\n" + "number of elements in the queue: " + @@ -453,77 +1036,205 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore } } } - - // - // If we're deactivated and there are no more elements to - // evict, it's not necessary in Java to set _db to zero to - // break cyclic dependencies. - // } - private EvictorElement - add(Ice.Identity ident, ObjectRecord rec) + private boolean + dbHasObject(Ice.Identity ident) { - // - // Ignore the request if the Ice object is already in the queue. - // - EvictorElement element = (EvictorElement)_evictorMap.get(ident); - if(element != null) + for(;;) { - return element; - } - - // - // Add an Ice object with its servant to the evictor queue. - // - _evictorList.addFirst(ident); + try + { + byte[] key = IdentityObjectRecordDict.encodeKeyImpl(ident, _communicator); + com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(key); + + // + // Keep 0 length since we're not interested in the data + // + com.sleepycat.db.Dbt dbValue = new com.sleepycat.db.Dbt(); + dbValue.set_flags(com.sleepycat.db.Db.DB_DBT_USERMEM | + com.sleepycat.db.Db.DB_DBT_PARTIAL); + + int err = _db.get(null, dbKey, dbValue, 0); + + if(err == 0) + { + return true; + } + else if(err == com.sleepycat.db.Db.DB_NOTFOUND) + { + return false; + } + else + { + assert(false); + throw new DBException(); + } + } + catch(com.sleepycat.db.DbDeadlockException deadlock) + { + // + // Ignored, try again + // + } + catch(com.sleepycat.db.DbException dx) + { + DBException ex = new DBException(); + ex.initCause(dx); + ex.message = _errorPrefix + "Db.get: " + dx.getMessage(); + throw ex; + } + } + } - element = new EvictorElement(); - element.rec = rec; - element.position = _evictorList.iterator(); - element.usageCount = 0; - element.destroyed = false; - element.strategyCookie = _strategy.activatedObject(ident, rec.servant); + private ObjectRecord + getObject(Ice.Identity ident) + { + byte[] key = IdentityObjectRecordDict.encodeKeyImpl(ident, _communicator); + com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(key); + + com.sleepycat.db.Dbt dbValue = new com.sleepycat.db.Dbt(); - // - // Position the iterator "on" the element. - // - element.position.next(); + for(;;) + { + try + { + int err = _db.get(null, dbKey, dbValue, 0); + + if(err == 0) + { + return (ObjectRecord) IdentityObjectRecordDict.decodeValueImpl( + dbValue.get_data(), _communicator); + } + else if(err == com.sleepycat.db.Db.DB_NOTFOUND) + { + return null; + } + else + { + assert(false); + throw new DBException(); + } + } + catch(com.sleepycat.db.DbDeadlockException deadlock) + { + // + // Ignored, try again + // + } + catch(com.sleepycat.db.DbException dx) + { + DBException ex = new DBException(); + ex.initCause(dx); + ex.message = _errorPrefix + "Db.get: " + dx.getMessage(); + throw ex; + } + } + } - _evictorMap.put(ident, element); - return element; + private void + addToModifiedQueue(Ice.Identity ident, EvictorElement element) + { + element.usageCount++; + _modifiedQueue.add(ident); + + if(_saveSizeTrigger >= 0 && _modifiedQueue.size() >= _saveSizeTrigger) + { + notifyAll(); + } } + + private void + saveNowNoSync() + { + Thread myself = Thread.currentThread(); - private EvictorElement - remove(Ice.Identity ident) + _saveNowThreads.add(myself); + notifyAll(); + do + { + try + { + wait(); + } + catch(InterruptedException ex) + { + } + } while(_saveNowThreads.contains(myself)); + } + + private byte[] + writeObjectRecordToValue(long saveStart, ObjectRecord rec) { // - // If the Ice object is currently in the evictor, remove it. + // Update stats first // - EvictorElement element = (EvictorElement)_evictorMap.remove(ident); - if(element != null) + Statistics stats = rec.stats; + long diff = saveStart - (stats.creationTime + stats.lastSaveTime); + if(stats.lastSaveTime == 0) { - element.position.remove(); + stats.lastSaveTime = diff; + stats.avgSaveTime = diff; } - return element; + else + { + stats.lastSaveTime = saveStart - stats.creationTime; + stats.avgSaveTime = (long)(stats.avgSaveTime * 0.95 + diff * 0.05); + } + return IdentityObjectRecordDict.encodeValueImpl(rec, _communicator); } + class StreamedObject + { + byte[] key; + byte[] value; + byte status; + }; + + class EvictorElement extends Ice.LocalObjectImpl { + byte status; ObjectRecord rec; java.util.Iterator position; int usageCount; - boolean destroyed; - Ice.LocalObject strategyCookie; }; + + // + // Clean object; can become modified or destroyed + // + private static final byte clean = 0; + + // + // New objects; can become clean, dead or destroyed + // + private static final byte created = 1; + + // + // Modified object; can become clean or destroyed + // + private static final byte modified = 2; + + // + // Being saved. Can become dead or created + // + private static final byte destroyed = 3; + + // + // Exists only in the Evictor; for example the object was created + // and later destroyed (without a save in between), or it was + // destroyed on disk but is still in use. Can become created. + // + private static final byte dead = 4; // // Map of Ice.Identity to EvictorElement // private java.util.Map _evictorMap = new java.util.HashMap(); + private int _evictorSize = 10; // - // The C++ Evictor uses std::list<Ice::Identity> which allows + // The C++ Evictor uses std::list<EvictorMap::iterator> which allows // holding of iterators across list changes. Unfortunately, Java // iterators are invalidated as soon as the underlying collection // is changed, so it's not possible to use the same technique. @@ -532,12 +1243,32 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore // private Freeze.LinkedList _evictorList = new Freeze.LinkedList(); - private int _evictorSize = 10; + // + // The _modifiedQueue contains a queue of all modified objects + // Each element in the queue "owns" a usage count, to ensure the + // pointed element remains in the map. + // + private java.util.List _modifiedQueue = new java.util.ArrayList(); + private boolean _deactivated = false; - private IdentityObjectRecordDict _dict; - - private DB _db; - private PersistenceStrategy _strategy; + + private Ice.Communicator _communicator; + private SharedDbEnv _dbEnvHolder; + private com.sleepycat.db.DbEnv _dbEnv; + private com.sleepycat.db.Db _db; private ServantInitializer _initializer; private int _trace = 0; + + // + // Threads that have requested a "saveNow" and are waiting for + // its completion + // + private java.util.List _saveNowThreads = new java.util.ArrayList(); + + private int _saveSizeTrigger; + private long _savePeriod; + private long _lastSave; + + private Thread _thread; + private String _errorPrefix; } diff --git a/java/src/Freeze/EvictorIteratorI.java b/java/src/Freeze/EvictorIteratorI.java index fdf403be19b..90df6a6d976 100644 --- a/java/src/Freeze/EvictorIteratorI.java +++ b/java/src/Freeze/EvictorIteratorI.java @@ -16,55 +16,136 @@ package Freeze; class EvictorIteratorI extends Ice.LocalObjectImpl implements EvictorIterator { - EvictorIteratorI(java.util.Iterator iterator) - { - // - // Copy the identities from the map iterator, to allow - // this iterator to continue to function even if the - // database is accessed and the map iterator is invalidated. - // - while(iterator.hasNext()) - { - java.util.Map.Entry entry = (java.util.Map.Entry)iterator.next(); - _identities.add(entry.getKey()); - } - - // - // Close the iterator explicitly. We don't want to wait for - // the garbage collection to destroy the iterator since the - // iterator consumes resources (database locks for instance). - // - ((Freeze.Map.EntryIterator)iterator).close(); - - _iterator = _identities.iterator(); - } - public boolean hasNext() { - return _iterator != null && _iterator.hasNext(); + if(_dbc == null) + { + throw new IteratorDestroyedException(); + } + + if(_current != null) + { + return true; + } + else + { + com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(); + + // + // Keep 0 length since we're not interested in the data + // + com.sleepycat.db.Dbt dbValue = new com.sleepycat.db.Dbt(); + dbValue.set_flags(com.sleepycat.db.Db.DB_DBT_USERMEM | + com.sleepycat.db.Db.DB_DBT_PARTIAL); + + try + { + if(_dbc.get(dbKey, dbValue, com.sleepycat.db.Db.DB_NEXT) == 0) + { + _current = (Ice.Identity) IdentityObjectRecordDict.decodeKeyImpl(dbKey.get_data(), _communicator); + return true; + } + else + { + return false; + } + } + catch(com.sleepycat.db.DbDeadlockException dx) + { + DBDeadlockException ex = new DBDeadlockException(); + ex.initCause(dx); + ex.message = _errorPrefix + "Dbc.get: " + dx.getMessage(); + throw ex; + } + catch(com.sleepycat.db.DbException dx) + { + DBException ex = new DBException(); + ex.initCause(dx); + ex.message = _errorPrefix + "Dbc.get: " + dx.getMessage(); + throw ex; + } + } } public Ice.Identity next() { - if(_iterator != null) - { - return (Ice.Identity)_iterator.next(); - } - else - { - throw new Freeze.NoSuchElementException(); - } + if(hasNext()) + { + Ice.Identity result = _current; + _current = null; + return result; + } + else + { + throw new NoSuchElementException(); + } } public void destroy() { - _identities = null; - _iterator = null; + if(_dbc == null) + { + throw new IteratorDestroyedException(); + } + else + { + try + { + _dbc.close(); + } + catch(com.sleepycat.db.DbDeadlockException deadlock) + { + // + // Ignored + // + } + catch(com.sleepycat.db.DbException dx) + { + DBException ex = new DBException(); + ex.initCause(dx); + ex.message = _errorPrefix + "Db.cursor: " + dx.getMessage(); + throw ex; + } + + _dbc = null; + _current = null; + _communicator = null; + } + } + + EvictorIteratorI(com.sleepycat.db.Db db, Ice.Communicator communicator, String errorPrefix) + { + _communicator = communicator; + _errorPrefix = errorPrefix; + + try + { + _dbc = db.cursor(null, 0); + } + catch(com.sleepycat.db.DbException dx) + { + DBException ex = new DBException(); + ex.initCause(dx); + ex.message = _errorPrefix + "Db.cursor: " + dx.getMessage(); + throw ex; + } } - - private java.util.ArrayList _identities = new java.util.ArrayList(); - private java.util.Iterator _iterator; + + protected void + finalize() + { + if(_dbc != null) + { + destroy(); + } + } + + + private com.sleepycat.db.Dbc _dbc; + private Ice.Identity _current = null; + private Ice.Communicator _communicator; + private String _errorPrefix; } diff --git a/java/src/Freeze/IdleStrategyI.java b/java/src/Freeze/IdleStrategyI.java deleted file mode 100644 index 7f8e6d1036c..00000000000 --- a/java/src/Freeze/IdleStrategyI.java +++ /dev/null @@ -1,112 +0,0 @@ -// ********************************************************************** -// -// 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; - -public final class IdleStrategyI extends Ice.LocalObjectImpl implements IdleStrategy -{ - public - IdleStrategyI() - { - } - - public Ice.LocalObject - activatedObject(Ice.Identity ident, Ice.Object servant) - { - return new Cookie(); - } - - public void - destroyedObject(Ice.Identity ident, Ice.LocalObject cookie) - { - // Nothing to do - } - - public void - evictedObject(ObjectStore store, Ice.Identity ident, Ice.Object servant, Ice.LocalObject cookie) - { - // - // The object must reach the idle state in order for it to be - // evicted, therefore the object should have already been saved - // by postOperation. - // - Cookie c = (Cookie)cookie; - assert(!c.mutated); - assert(c.mutatingCount == 0); - } - - public void - savedObject(ObjectStore store, Ice.Identity ident, Ice.Object servant, Ice.LocalObject cookie, int usageCount) - { - assert(usageCount > 0); - - if(usageCount == 1) - { - Cookie c = (Cookie)cookie; - c.mutated = false; - } - } - - public void - preOperation(ObjectStore store, Ice.Identity ident, Ice.Object servant, boolean mutating, Ice.LocalObject cookie) - { - Cookie c = (Cookie)cookie; - if(mutating) - { - ++c.mutatingCount; - c.mutated = true; - } - else if(c.mutatingCount == 0 && c.mutated) - { - // - // Only store the object's persistent state if the object is idle - // and it has been mutated. - // - store.save(ident, servant); - c.mutated = false; - } - } - - public void - postOperation(ObjectStore store, Ice.Identity ident, Ice.Object servant, boolean mutating, Ice.LocalObject cookie) - { - Cookie c = (Cookie)cookie; - if(mutating) - { - assert(c.mutatingCount >= 1); - --c.mutatingCount; - } - if(c.mutatingCount == 0 && c.mutated) - { - // - // Only store the object's persistent state if the object is idle - // and it has been mutated. - // - store.save(ident, servant); - c.mutated = false; - } - } - - public void - destroy() - { - // Nothing to do - } - - private static class Cookie extends Ice.LocalObjectImpl - { - int mutatingCount = 0; - boolean mutated = false; - } -} diff --git a/java/src/Freeze/Map.java b/java/src/Freeze/Map.java index 5ca1bd5560e..af0272e68f0 100644 --- a/java/src/Freeze/Map.java +++ b/java/src/Freeze/Map.java @@ -17,10 +17,62 @@ package Freeze; public abstract class Map extends java.util.AbstractMap { public - Map(DB db) + Map(Ice.Communicator communicator, String envName, String dbName, boolean createDb) { - _db = db; - _communicator = db.getCommunicator(); + _communicator = communicator; + _dbEnvHolder = SharedDbEnv.get(communicator, envName); + _dbEnv = _dbEnvHolder; + _dbName = dbName; + _errorPrefix = "Freeze DB DbEnv(\"" + envName + "\") Db(\"" + dbName + "\") :"; + + openDb(createDb); + } + + public + Map(Ice.Communicator communicator, com.sleepycat.db.DbEnv dbEnv, String dbName, boolean createDb) + { + _communicator = communicator; + _dbEnvHolder = null; + _dbEnv = dbEnv; + _dbName = dbName; + _errorPrefix = "Freeze DB DbEnv(\"External\") Db(\"" + dbName + "\") :"; + + openDb(createDb); + } + + public void + close() + { + if(_db != null) + { + try + { + _db.close(0); + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + ex.initCause(e); + ex.message = _errorPrefix + "Db.stat: " + e.getMessage(); + throw ex; + } + finally + { + _db = null; + } + } + + if(_dbEnvHolder != null) + { + try + { + _dbEnvHolder.close(); + } + finally + { + _dbEnvHolder = null; + } + } } // @@ -36,14 +88,12 @@ public abstract class Map extends java.util.AbstractMap public int size() { - // - // It's not necessary to close outstanding iterators. - // - // If it was it would be a problem - it doesn't change the Map - // - therefore open iterators should not be invalidated - // (according the Java spec). - // - // closeIterators(); + if(_db == null) + { + DBException ex = new DBException(); + ex.message = _errorPrefix + "\"" + _dbName + "\" has been closed"; + throw ex; + } // // The number of records cannot be cached and then adjusted by @@ -52,130 +102,178 @@ public abstract class Map extends java.util.AbstractMap // the size adjusted) and the transaction aborted then the // cached map size() would be incorrect. // - return (int)_db.getNumberOfRecords(); + + // + // TODO: DB_FAST_STAT doesn't seem to do what the + // documentation says... + // + try + { + com.sleepycat.db.DbBtreeStat s = (com.sleepycat.db.DbBtreeStat)_db.stat(0); + return s.bt_ndata; + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + ex.initCause(e); + ex.message = _errorPrefix + "Db.stat: " + e.getMessage(); + throw ex; + } } public boolean containsValue(Object value) { - // - // It's not necessary to close outstanding iterators. - // - // If it was it would be a problem - it doesn't change the Map - // - therefore open iterators should not be invalidated - // (according the Java spec). - // - // closeIterators(); - - EntryIterator p = (EntryIterator)entrySet().iterator(); - if(value == null) + for(;;) { - while(p.hasNext()) + EntryIterator p = null; + try { - Entry e = (Entry)p.next(); - if(e.getValue() == null) + p = (EntryIterator)entrySet().iterator(); + + if(value == null) { - return true; + while(p.hasNext()) + { + Entry e = (Entry)p.next(); + if(e.getValue() == null) + { + p.close(); + return true; + } + } + } + else + { + while(p.hasNext()) + { + Entry e = (Entry)p.next(); + if(value.equals(e.getValue())) + { + p.close(); + return true; + } + } } + return false; } - } - else - { - while(p.hasNext()) + catch(DBDeadlockException ex) + { + // + // Try again + // + } + finally { - Entry e = (Entry)p.next(); - if(value.equals(e.getValue())) + if(p != null) { - return true; + p.close(); } } } - p.close(); - - return false; } public boolean containsKey(Object key) { - // - // It's not necessary to close outstanding iterators. - // - // If it was it would be a problem - it doesn't change the Map - // - therefore open iterators should not be invalidated - // (according the Java spec). - // - //closeIterators(); + if(_db == null) + { + DBException ex = new DBException(); + ex.message = _errorPrefix + "\"" + _dbName + "\" has been closed"; + throw ex; + } byte[] k = encodeKey(key, _communicator); - return _db.contains(k); + + com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(k); + + com.sleepycat.db.Dbt dbValue = new com.sleepycat.db.Dbt(); + dbValue.set_flags(com.sleepycat.db.Db.DB_DBT_PARTIAL); + + if(_trace >= 1) + { + _communicator.getLogger().trace("DB", "checking key in database \"" + _dbName + "\""); + } + + for(;;) + { + try + { + int rc = _db.get(null, dbKey, dbValue, 0); + if(rc == com.sleepycat.db.Db.DB_NOTFOUND) + { + return false; + } + else + { + assert(rc == 0); + return true; + } + } + catch(com.sleepycat.db.DbDeadlockException e) + { + // + // Try again + // + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + ex.initCause(e); + ex.message = _errorPrefix + "Db.get: " + e.getMessage(); + throw ex; + } + } } public Object get(Object key) { - // - // It's not necessary to close outstanding iterators. - // - // If it was it would be a problem - it doesn't change the Map - // - therefore open iterators should not be invalidated - // (according the Java spec). - // - //closeIterators(); - byte[] k = encodeKey(key, _communicator); - try + com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(k); + byte[] v = getImpl(dbKey); + if(v == null) { - byte[] v = _db.get(k); - return decodeValue(v, _communicator); + return null; } - catch(DBNotFoundException e) + else { - return null; + return decodeValue(v, _communicator); } } public Object put(Object key, Object value) { - closeIterators(); - byte[] k = encodeKey(key, _communicator); - Object o; - - try + com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(k); + byte[] v = getImpl(dbKey); + Object o = null; + if(v != null) { - byte[] v = _db.get(k); o = decodeValue(v, _communicator); } - catch(DBNotFoundException e) - { - o = null; - } - byte[] v = encodeValue(value, _communicator); - _db.put(k, v); - + putImpl(dbKey, value); return o; } public Object remove(Object key) { - closeIterators(); - byte[] k = encodeKey(key, _communicator); - Object o; - try + com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(k); + byte[] v = getImpl(dbKey); + + if(v != null && removeImpl(dbKey)) { - byte[] v = _db.get(k); - o = decodeValue(v, _communicator); + return decodeValue(v, _communicator); } - catch(DBNotFoundException e) + else { - o = null; + DBNotFoundException ex = new DBNotFoundException(); + ex.message = _errorPrefix + "Db.del: DB_NOTFOUND"; + throw ex; } - _db.del(k); - return o; } // @@ -186,11 +284,9 @@ public abstract class Map extends java.util.AbstractMap public void fastPut(Object key, Object value) { - closeIterators(); - byte[] k = encodeKey(key, _communicator); - byte[] v = encodeValue(value, _communicator); - _db.put(k, v); + com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(k); + putImpl(dbKey, value); } // @@ -199,28 +295,44 @@ public abstract class Map extends java.util.AbstractMap public boolean fastRemove(Object key) { - closeIterators(); - byte[] k = encodeKey(key, _communicator); - try - { - _db.del(k); - } - catch(Freeze.DBNotFoundException e) - { - return false; - } - return true; + com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(k); + return removeImpl(dbKey); } public void clear() { - closeIterators(); + if(_db == null) + { + DBException ex = new DBException(); + ex.message = _errorPrefix + "\"" + _dbName + "\" has been closed"; + throw ex; + } - _db.clear(); + for(;;) + { + try + { + _db.truncate(null, com.sleepycat.db.Db.DB_AUTO_COMMIT); + break; + } + catch(com.sleepycat.db.DbDeadlockException e) + { + // + // Try again + // + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + ex.initCause(e); + ex.message = _errorPrefix + "Db.truncate: " + e.getMessage(); + throw ex; + } + } } - + public java.util.Set entrySet() { @@ -231,9 +343,7 @@ public abstract class Map extends java.util.AbstractMap public java.util.Iterator iterator() { - EntryIterator p = new EntryIterator(); - _iterators.add(new java.lang.ref.WeakReference(p)); - return p; + return new EntryIterator(); } public boolean @@ -246,8 +356,8 @@ public abstract class Map extends java.util.AbstractMap Map.Entry entry = (Map.Entry)o; Object value = entry.getValue(); - Entry p = getEntry(entry.getKey()); - return p != null && valEquals(p.getValue(), value); + byte[] v = getImpl(entry.getDbKey()); + return v != null && valEquals(decodeValue(v, _communicator), value); } public boolean @@ -260,13 +370,10 @@ public abstract class Map extends java.util.AbstractMap Map.Entry entry = (Map.Entry)o; Object value = entry.getValue(); - Entry p = getEntry(entry.getKey()); - if(p != null && valEquals(p.getValue(), value)) + byte[] v = getImpl(entry.getDbKey()); + if(v != null && valEquals(decodeValue(v, _communicator), value)) { - closeIterators(); - byte[] k = encodeKey(p.getKey(), _communicator); - _db.del(k); - return true; + return removeImpl(entry.getDbKey()); } return false; } @@ -288,69 +395,183 @@ public abstract class Map extends java.util.AbstractMap return _entrySet; } - // - // Because of the way that Berkeley DB cursors implement their - // locking it's necessary to ensure that all cursors are closed - // prior to doing a database operation otherwise self-deadlocks - // will occur. See "Berkeley DB Transactional Data Store locking - // conventions" section in the Berkeley DB reference guide for - // details. - // - private void - closeIterators() + protected void + finalize() { - closeIteratorsExcept(null); + close(); } - private void - closeIteratorsExcept(java.util.Iterator i) + private static boolean + valEquals(Object o1, Object o2) { - java.util.Iterator p = _iterators.iterator(); - while(p.hasNext()) + return (o1 == null ? o2 == null : o1.equals(o2)); + } + + private byte[] + getImpl(com.sleepycat.db.Dbt dbKey) + { + if(_db == null) + { + DBException ex = new DBException(); + ex.message = _errorPrefix + "\"" + _dbName + "\" has been closed"; + throw ex; + } + + com.sleepycat.db.Dbt dbValue = new com.sleepycat.db.Dbt(); + + if(_trace >= 1) { - java.lang.ref.WeakReference ref = (java.lang.ref.WeakReference)p.next(); - EntryIterator q = (EntryIterator)ref.get(); - if(q != null && q != i) + _communicator.getLogger().trace("DB", "reading value from database \"" + _dbName + "\""); + } + + for(;;) + { + try { - q.close(); + int rc = _db.get(null, dbKey, dbValue, 0); + if(rc == com.sleepycat.db.Db.DB_NOTFOUND) + { + return null; + } + else + { + return dbValue.get_data(); + } + } + catch(com.sleepycat.db.DbDeadlockException e) + { + // + // Try again + // + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + ex.initCause(e); + ex.message = _errorPrefix + "Db.get: " + e.getMessage(); + throw ex; } } + } - // - // This is more efficient than removing the list items element - // by element in the iteration loop. - // - _iterators.clear(); - if(i != null) + private void + putImpl(com.sleepycat.db.Dbt dbKey, Object value) + { + if(_db == null) { - _iterators.add(new java.lang.ref.WeakReference(i)); + DBException ex = new DBException(); + ex.message = _errorPrefix + "\"" + _dbName + "\" has been closed"; + throw ex; + } + + byte[] v = encodeValue(value, _communicator); + com.sleepycat.db.Dbt dbValue = new com.sleepycat.db.Dbt(v); + + if(_trace >= 1) + { + _communicator.getLogger().trace("DB", "writing value in database \"" + _dbName + "\""); + } + + for(;;) + { + try + { + _db.put(null, dbKey, dbValue, com.sleepycat.db.Db.DB_AUTO_COMMIT); + break; + } + catch(com.sleepycat.db.DbDeadlockException e) + { + // + // Try again + // + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + ex.initCause(e); + ex.message = _errorPrefix + "Db.put: " + e.getMessage(); + throw ex; + } } } - private Entry - getEntry(Object key) + private boolean + removeImpl(com.sleepycat.db.Dbt dbKey) { - // - // It's not necessary to close outstanding iterators. - // - // If it was it would be a problem - it doesn't change the Map - // - therefore open iterators should not be invalidated - // (according the Java spec). - // - // closeIterators(); + if(_db == null) + { + DBException ex = new DBException(); + ex.message = _errorPrefix + "\"" + _dbName + "\" has been closed"; + throw ex; + } - byte[] k = encodeKey(key, _communicator); - byte[] v = _db.get(k); + if(_trace >= 1) + { + _communicator.getLogger().trace("DB", "deleting value from database \"" + _dbName + "\""); + } - return new Entry(this, _communicator, key, v); + for(;;) + { + try + { + int rc = _db.del(null, dbKey, com.sleepycat.db.Db.DB_AUTO_COMMIT); + return (rc == 0); + } + catch(com.sleepycat.db.DbDeadlockException e) + { + // + // Try again + // + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + ex.initCause(e); + ex.message = _errorPrefix + "Db.del: " + e.getMessage(); + throw ex; + } + } } - private static boolean - valEquals(Object o1, Object o2) + private void + openDb(boolean createDb) { - return (o1 == null ? o2 == null : o1.equals(o2)); + _trace = _communicator.getProperties().getPropertyAsInt("Freeze.Trace.DB"); + + try + { + int flags = com.sleepycat.db.Db.DB_AUTO_COMMIT; + + if(createDb) + { + flags |= com.sleepycat.db.Db.DB_CREATE; + } + + _db = new com.sleepycat.db.Db(_dbEnv, 0); + _db.open(null, _dbName, null, com.sleepycat.db.Db.DB_BTREE, + flags, 0); + + // + // TODO: FREEZE_DB_MODE + // + } + catch(java.io.FileNotFoundException dx) + { + DBNotFoundException ex = new DBNotFoundException(); + ex.initCause(dx); + ex.message = _errorPrefix + "Db.open: " + dx.getMessage(); + throw ex; + } + catch(com.sleepycat.db.DbException dx) + { + DBException ex = new DBException(); + ex.initCause(dx); + ex.message = _errorPrefix + "Db.open: " + dx.getMessage(); + throw ex; + } } + /** * * The entry iterator class needs to be public to allow clients to @@ -362,76 +583,191 @@ public abstract class Map extends java.util.AbstractMap { EntryIterator() { - try - { - _cursor = _db.getCursor(); - _next = getEntry(); - } - catch(DBNotFoundException e) - { - // Database is empty. - } + if(_trace >= 3) + { + _communicator.getLogger().trace("DB", "starting transaction for cursor on database \"" + _dbName + "\""); + } + + try + { + // + // Start transaction + // + _tx = _dbEnv.txn_begin(null, 0); + + // + // Open cursor with this transaction + // + _cursor = _db.cursor(_tx, 0); + } + catch(com.sleepycat.db.DbDeadlockException dx) + { + dead(); + DBDeadlockException ex = new DBDeadlockException(); + ex.initCause(dx); + ex.message = _errorPrefix + "EntryIterator constructor: " + dx.getMessage(); + throw ex; + } + catch(com.sleepycat.db.DbException dx) + { + DBException ex = new DBException(); + ex.initCause(dx); + ex.message = _errorPrefix + "EntryIterator constructor: " + dx.getMessage(); + throw ex; + } } public boolean hasNext() { - return getNext(); + if(_current == null || _current == _lastReturned) + { + // + // Move _cursor, set _current + // + + com.sleepycat.db.Dbt dbKey = new com.sleepycat.db.Dbt(); + com.sleepycat.db.Dbt dbValue = new com.sleepycat.db.Dbt(); + + try + { + if(_cursor.get(dbKey, dbValue, com.sleepycat.db.Db.DB_NEXT) == 0) + { + _current = new Entry(this, Map.this, _communicator, dbKey, dbValue.get_data()); + return true; + } + else + { + close(); + return false; + } + } + catch(com.sleepycat.db.DbDeadlockException dx) + { + dead(); + DBDeadlockException ex = new DBDeadlockException(); + ex.initCause(dx); + ex.message = _errorPrefix + "Dbc.get: " + dx.getMessage(); + throw ex; + } + catch(com.sleepycat.db.DbException dx) + { + DBException ex = new DBException(); + ex.initCause(dx); + ex.message = _errorPrefix + "Dbc.get: " + dx.getMessage(); + throw ex; + } + } + else + { + return true; + } } - + public Object next() { - if(!getNext()) - { - throw new java.util.NoSuchElementException(); - } - assert(_next != null); - - if(_prev != null) - { - _prev.invalidateCursor(); - } - - _prev = _next; - _next = null; - return _prev; + if(hasNext()) + { + _lastReturned = _current; + return _lastReturned; + } + else + { + throw new java.util.NoSuchElementException(); + } } public void remove() { - if(_prev == null) - { - throw new IllegalStateException(); - } - - closeIteratorsExcept(this); - - // - // Clone the cursor so that error handling is simpler. - // - assert _cursor != null; - DBCursor clone = _cursor._clone(); - - try - { - clone.del(); - _prev.invalidateCursor(); - _prev = null; - _next = null; - } - finally - { - try - { - clone.close(); - } - catch(DBException ignore) - { - // Ignore - } - } + // + // Removes the last object returned by next() + // + if(_lastReturned == null) + { + throw new IllegalStateException(); + } + + if(_lastReturned == _current) + { + try + { + if(_cursor.del(0) == com.sleepycat.db.Db.DB_KEYEMPTY) + { + throw new IllegalStateException(); + } + } + catch(com.sleepycat.db.DbDeadlockException e) + { + dead(); + DBDeadlockException ex = new DBDeadlockException(); + ex.initCause(e); + ex.message = _errorPrefix + "Dbc.del: " + e.getMessage(); + throw ex; + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + 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) + // + + com.sleepycat.db.Dbc clone = null; + + try + { + clone = _cursor.dup(com.sleepycat.db.Db.DB_POSITION); + + // + // No interested in data + // + com.sleepycat.db.Dbt dbValue = new com.sleepycat.db.Dbt(); + dbValue.set_flags(com.sleepycat.db.Db.DB_DBT_USERMEM | + com.sleepycat.db.Db.DB_DBT_PARTIAL); + + int rc = clone.get(_lastReturned.getDbKey(), dbValue, com.sleepycat.db.Db.DB_SET); + + if(rc == com.sleepycat.db.Db.DB_NOTFOUND) + { + throw new IllegalStateException(); + } + if(clone.del(0) == com.sleepycat.db.Db.DB_KEYEMPTY) + { + throw new IllegalStateException(); + } + } + catch(com.sleepycat.db.DbDeadlockException e) + { + dead(); + DBDeadlockException ex = new DBDeadlockException(); + ex.initCause(e); + ex.message = _errorPrefix + "EntryIterator.remove: " + e.getMessage(); + throw ex; + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + ex.initCause(e); + ex.message = _errorPrefix + "EntryIterator.remove: " + e.getMessage(); + throw ex; + } + finally + { + if(clone != null) + { + closeCursor(clone); + } + } + } } // @@ -440,86 +776,227 @@ public abstract class Map extends java.util.AbstractMap public void close() { - DBCursor copy = _cursor; - - // - // Clear the internal iterator state. - // - _cursor = null; - _next = null; - _prev = null; - - if(copy != null) - { - copy.close(); - } - } + if(_cursor != null) + { + com.sleepycat.db.Dbc cursor = _cursor; + _cursor = null; + closeCursor(cursor); + } + + if(_tx != null) + { + if(_trace >= 3) + { + _communicator.getLogger().trace("DB", "committing transaction for cursor on database \"" + _dbName + "\""); + } - protected void + try + { + _tx.commit(0); + } + catch(com.sleepycat.db.DbDeadlockException e) + { + DBDeadlockException ex = new DBDeadlockException(); + ex.initCause(e); + ex.message = _errorPrefix + "DbTxn.commit: " + e.getMessage(); + throw ex; + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + ex.initCause(e); + ex.message = _errorPrefix + "DbTxn.commit: " + e.getMessage(); + throw ex; + } + finally + { + _tx = null; + } + } + + } + + protected void finalize() { close(); } - private Entry - getEntry() - { - assert _cursor != null; - _cursor.curr(_keyHolder, _valueHolder); - return new Entry(Map.this, _cursor, _keyHolder.value, _valueHolder.value); - } + void + setValue(Map.Entry entry, Object value) + { + // + // Are we trying to update the current value? + // + if(_current == entry) + { + // + // Yes, update it directly + // + byte[] v = encodeValue(value, _communicator); + com.sleepycat.db.Dbt dbValue = new com.sleepycat.db.Dbt(v); + + try + { + _cursor.put(entry.getDbKey(), dbValue, com.sleepycat.db.Db.DB_CURRENT); + } + catch(com.sleepycat.db.DbDeadlockException e) + { + dead(); + DBDeadlockException ex = new DBDeadlockException(); + ex.initCause(e); + ex.message = _errorPrefix + "Dbc.put: " + e.getMessage(); + throw ex; + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + 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.Dbc clone = null; - private boolean - getNext() - { - if(_next == null && _cursor != null) - { - if(_cursor.next()) - { - try - { - _next = getEntry(); - } - catch(DBNotFoundException ex) - { - // No element found. - } - } - } - return _next != null; - } + try + { + clone = _cursor.dup(com.sleepycat.db.Db.DB_POSITION); + + // + // Not interested in data + // + com.sleepycat.db.Dbt dummy = new com.sleepycat.db.Dbt(); + dummy.set_flags(com.sleepycat.db.Db.DB_DBT_USERMEM | + com.sleepycat.db.Db.DB_DBT_PARTIAL); + + int rc = clone.get(entry.getDbKey(), dummy, com.sleepycat.db.Db.DB_SET); - private DBCursor _cursor; - private Entry _next; - private Entry _prev; - private Freeze.KeyHolder _keyHolder = new Freeze.KeyHolder(); - private Freeze.ValueHolder _valueHolder = new Freeze.ValueHolder(); + if(rc == com.sleepycat.db.Db.DB_NOTFOUND) + { + DBNotFoundException ex = new DBNotFoundException(); + ex.message = _errorPrefix + "Dbc.get: DB_NOTFOUND"; + throw ex; + } + + byte[] v = encodeValue(value, _communicator); + com.sleepycat.db.Dbt dbValue = new com.sleepycat.db.Dbt(v); + clone.put(entry.getDbKey(), dbValue, com.sleepycat.db.Db.DB_CURRENT); + } + catch(com.sleepycat.db.DbDeadlockException e) + { + dead(); + DBDeadlockException ex = new DBDeadlockException(); + ex.initCause(e); + ex.message = _errorPrefix + "EntryIterator.setValue: " + e.getMessage(); + throw ex; + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + ex.initCause(e); + ex.message = _errorPrefix + "EntryIterator.setValue: " + e.getMessage(); + throw ex; + } + finally + { + if(clone != null) + { + closeCursor(clone); + } + } + } + } + + + private void + closeCursor(com.sleepycat.db.Dbc cursor) + { + try + { + cursor.close(); + } + catch(com.sleepycat.db.DbDeadlockException e) + { + dead(); + DBDeadlockException ex = new DBDeadlockException(); + ex.initCause(e); + ex.message = _errorPrefix + "Dbc.close: " + e.getMessage(); + throw ex; + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + ex.initCause(e); + ex.message = _errorPrefix + "Dbc.close: " + e.getMessage(); + throw ex; + } + } + + private void + dead() + { + if(_cursor != null) + { + com.sleepycat.db.Dbc cursor = _cursor; + _cursor = null; + closeCursor(cursor); + } + + if(_tx != null) + { + if(_trace >= 3) + { + _communicator.getLogger().trace("DB", "rolling back transaction for cursor on database \"" + _dbName + "\""); + } + + try + { + _tx.abort(); + } + catch(com.sleepycat.db.DbDeadlockException e) + { + DBDeadlockException ex = new DBDeadlockException(); + ex.initCause(e); + ex.message = _errorPrefix + "DbTxn.abort: " + e.getMessage(); + throw ex; + } + catch(com.sleepycat.db.DbException e) + { + DBException ex = new DBException(); + ex.initCause(e); + ex.message = _errorPrefix + "DbTxn.abort: " + e.getMessage(); + throw ex; + } + finally + { + _tx = null; + } + } + } + + private com.sleepycat.db.DbTxn _tx = null; + private com.sleepycat.db.Dbc _cursor = null; + private Entry _current = null; + private Entry _lastReturned = null; } static class Entry implements java.util.Map.Entry { public - Entry(Map map, DBCursor cursor, byte[] keyData, byte[] valueData) - { - _map = map; - _cursor = cursor; - _communicator = cursor.getCommunicator(); - _keyData = keyData; - _haveKey = false; - _valueData = valueData; - _haveValue = false; - } - - public - Entry(Map map, Ice.Communicator communicator, Object key, byte[] valueData) + Entry(Map.EntryIterator iterator, Map map, Ice.Communicator communicator, com.sleepycat.db.Dbt dbKey, byte[] valueBytes) { - _map = map; - _cursor = null; - _communicator = communicator; - _key = key; - _haveKey = true; - _valueData = valueData; - _haveValue = false; + _iterator = iterator; + _map = map; + _communicator = communicator; + _dbKey = dbKey; + _valueBytes = valueBytes; } public Object @@ -527,8 +1004,8 @@ public abstract class Map extends java.util.AbstractMap { if(!_haveKey) { - assert(_keyData != null); - _key = _map.decodeKey(_keyData, _communicator); + assert(_dbKey != null); + _key = _map.decodeKey(_dbKey.get_data(), _communicator); _haveKey = true; } return _key; @@ -539,9 +1016,13 @@ public abstract class Map extends java.util.AbstractMap { if(!_haveValue) { - assert(_valueData != null); - _value = _map.decodeValue(_valueData, _communicator); + assert(_valueBytes != null); + _value = _map.decodeValue(_valueBytes, _communicator); _haveValue = true; + // + // Not needed anymore + // + _valueBytes = null; } return _value; } @@ -549,17 +1030,9 @@ public abstract class Map extends java.util.AbstractMap public Object setValue(Object value) { - Object old = getValue(); - if(_cursor != null) - { - byte[] v = _map.encodeValue(value, _communicator); - _cursor.set(v); - } - else - { - _map.put(getKey(), value); // Invalidates iterators. - } - _value = value; + Object old = getValue(); + _iterator.setValue(this, value); + _value = value; _haveValue = true; return old; } @@ -588,11 +1061,10 @@ public abstract class Map extends java.util.AbstractMap return getKey() + "=" + getValue(); } - void - invalidateCursor() - { - _cursor = null; - } + com.sleepycat.db.Dbt getDbKey() + { + return _dbKey; + } private /*static*/ boolean eq(Object o1, Object o2) @@ -600,19 +1072,23 @@ public abstract class Map extends java.util.AbstractMap return (o1 == null ? o2 == null : o1.equals(o2)); } - private Map _map; - private DBCursor _cursor; - private Ice.Communicator _communicator; - private Object _key; - private byte[] _keyData; - private boolean _haveKey; - private Object _value; - private byte[] _valueData; - private boolean _haveValue; + private Map.EntryIterator _iterator = null; + private Map _map = null; + private Ice.Communicator _communicator = null; + private com.sleepycat.db.Dbt _dbKey = null; + private byte[] _valueBytes = null; + private Object _key = null; + private boolean _haveKey = false; + private Object _value = null; + private boolean _haveValue = false; } - private java.util.Set _entrySet; - private DB _db; - private Ice.Communicator _communicator; - private java.util.List _iterators = new java.util.LinkedList(); + private java.util.Set _entrySet = null; + private SharedDbEnv _dbEnvHolder = null; + private com.sleepycat.db.DbEnv _dbEnv = null; + private com.sleepycat.db.Db _db = null; + private String _dbName = null; + private Ice.Communicator _communicator = null; + private String _errorPrefix = null; + private int _trace = 0; } 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(); +} + diff --git a/java/src/Freeze/Util.java b/java/src/Freeze/Util.java index 35bda9949ce..a1f46c3ac90 100644 --- a/java/src/Freeze/Util.java +++ b/java/src/Freeze/Util.java @@ -16,16 +16,17 @@ package Freeze; public class Util { - public static DBEnvironment - initialize(Ice.Communicator communicator, String name) + + public static Evictor + createEvictor(Ice.Communicator communicator, String envName, String dbName, boolean createDb) { - return new DBEnvironmentI(communicator, name, false); - } + return new EvictorI(communicator, envName, dbName, createDb); + } - public static DBEnvironment - initializeWithTxn(Ice.Communicator communicator, String name) + public static Evictor + createEvictor(Ice.Communicator communicator, com.sleepycat.db.DbEnv dbEnv, String dbName, boolean createDb) { - return new DBEnvironmentI(communicator, name, true); - } + return new EvictorI(communicator, dbEnv, dbName, createDb); + } } diff --git a/java/src/Ice/PropertiesI.java b/java/src/Ice/PropertiesI.java index 14a6fc61fcb..6929a31924e 100644 --- a/java/src/Ice/PropertiesI.java +++ b/java/src/Ice/PropertiesI.java @@ -523,7 +523,8 @@ final class PropertiesI extends LocalObjectImpl implements Properties private static final String _freezeProps[] = { "Trace.DB", - "Trace.Evictor" + "Trace.Evictor", + "Evictor.*" }; private static final class ValidProps diff --git a/java/src/IceBox/ServiceManagerI.java b/java/src/IceBox/ServiceManagerI.java index ef8715d3025..1a93a70df4b 100644 --- a/java/src/IceBox/ServiceManagerI.java +++ b/java/src/IceBox/ServiceManagerI.java @@ -286,7 +286,7 @@ public final class ServiceManagerI extends _ServiceManagerDisp // IceBox::Service // Service s = (Service)info.service; - info.dbEnv = null; + info.envName = null; s.start(service, communicator, serviceArgs); } catch(ClassCastException e) @@ -299,10 +299,9 @@ public final class ServiceManagerI extends _ServiceManagerDisp // FreezeService fs = (FreezeService)info.service; - info.dbEnv = Freeze.Util.initialize(communicator, - properties.getProperty("IceBox.DBEnvName." + service)); + info.envName = properties.getProperty("IceBox.DBEnvName." + service); - fs.start(service, communicator, serviceArgs, info.dbEnv); + fs.start(service, communicator, serviceArgs, info.envName); } _services.put(service, info); } @@ -351,22 +350,6 @@ public final class ServiceManagerI extends _ServiceManagerDisp pw.flush(); _logger.warning("ServiceManager: exception in stop for service " + name + "\n" + sw.toString()); } - - if(info.dbEnv != null) - { - try - { - info.dbEnv.sync(); - } - catch(Exception e) - { - java.io.StringWriter sw = new java.io.StringWriter(); - java.io.PrintWriter pw = new java.io.PrintWriter(sw); - e.printStackTrace(pw); - pw.flush(); - _logger.warning("ServiceManager: exception in stop for service " + name + "\n" + sw.toString()); - } - } } // @@ -397,22 +380,6 @@ public final class ServiceManagerI extends _ServiceManagerDisp _logger.warning("ServiceManager: exception in stop for service " + name + "\n" + sw.toString()); } } - - if(info.dbEnv != null) - { - try - { - info.dbEnv.close(); - } - catch(Exception e) - { - java.io.StringWriter sw = new java.io.StringWriter(); - java.io.PrintWriter pw = new java.io.PrintWriter(sw); - e.printStackTrace(pw); - pw.flush(); - _logger.warning("ServiceManager: exception in stop for service " + name + "\n" + sw.toString()); - } - } if(info.communicator != null) { @@ -438,12 +405,11 @@ public final class ServiceManagerI extends _ServiceManagerDisp { public ServiceBase service; public Ice.Communicator communicator = null; - Freeze.DBEnvironment dbEnv; + String envName; } private Ice.Application _server; private Ice.Logger _logger; private String[] _argv; // Filtered server argument vector private java.util.HashMap _services = new java.util.HashMap(); - private java.util.HashMap _dbEnvs = new java.util.HashMap(); } diff --git a/java/test/Freeze/build.xml b/java/test/Freeze/build.xml index 52539f330da..2447c1069d6 100644 --- a/java/test/Freeze/build.xml +++ b/java/test/Freeze/build.xml @@ -17,7 +17,7 @@ the Free Software Foundation. <ant dir="cursor"/> <ant dir="dbmap"/> <ant dir="complex"/> - <ant dir="evictor"/> + <ant dir="evictor"/> </target> <target name="clean"> diff --git a/java/test/Freeze/complex/Client.java b/java/test/Freeze/complex/Client.java index df34f1a40b2..7e1dd4a308e 100644 --- a/java/test/Freeze/complex/Client.java +++ b/java/test/Freeze/complex/Client.java @@ -27,11 +27,11 @@ public class Client } } - private static int - validate(DB db) + private int + validate(String dbName) throws DBException { - Complex.ComplexDict m = new Complex.ComplexDict(db); + Complex.ComplexDict m = new Complex.ComplexDict(_communicator, _envName, dbName, true); try { @@ -64,11 +64,13 @@ public class Client test(false); } + m.close(); + return 0; } - private static int - populate(DB db) + private int + populate(String dbName) throws DBException { String[] expressions = @@ -80,7 +82,7 @@ public class Client "10+(10+(20+(8*(2*(3*2+4+5+6)))))" }; - Complex.ComplexDict m = new Complex.ComplexDict(db); + Complex.ComplexDict m = new Complex.ComplexDict(_communicator, _envName, dbName, true); try { @@ -104,6 +106,7 @@ public class Client test(false); } + m.close(); return 0; } @@ -115,40 +118,45 @@ public class Client System.out.println("--dbdir Location of the database directory."); } - private static int - run(String[] args, DB db) + private int + run(String[] args, String dbName) throws DBException { // // Register a factory for the node types. // - Ice.Communicator communicator = db.getCommunicator(); Ice.ObjectFactory factory = new Complex.ObjectFactoryI(); - communicator.addObjectFactory(factory, "::Complex::NumberNode"); - communicator.addObjectFactory(factory, "::Complex::AddNode"); - communicator.addObjectFactory(factory, "::Complex::MultiplyNode"); + _communicator.addObjectFactory(factory, "::Complex::NumberNode"); + _communicator.addObjectFactory(factory, "::Complex::AddNode"); + _communicator.addObjectFactory(factory, "::Complex::MultiplyNode"); if(args.length != 0 && args[0].equals("populate")) { - return populate(db); + return populate(dbName); } if(args.length != 0 && args[0].equals("validate")) { - return validate(db); + return validate(dbName); } usage(progName); return 0; } + private + Client(Ice.Communicator communicator, String envName) + { + _communicator = communicator; + _envName = envName; + } + + static public void main(String[] args) { int status; Ice.Communicator communicator = null; - DBEnvironment dbEnv = null; - DB db = null; - String dbEnvDir = "db"; + String envName = "db"; try { @@ -166,9 +174,9 @@ public class Client System.exit(1); } - dbEnvDir = args[i+1]; - dbEnvDir += "/"; - dbEnvDir += "db"; + envName = args[i+1]; + envName += "/"; + envName += "db"; // // Consume arguments @@ -191,9 +199,8 @@ public class Client holder.value = args; communicator = Ice.Util.initialize(holder); args = holder.value; - dbEnv = Freeze.Util.initialize(communicator, dbEnvDir); - db = dbEnv.openDB("test", true); - status = run(args, db); + Client client = new Client(communicator, envName); + status = client.run(args, "test"); } catch(Exception ex) { @@ -202,44 +209,6 @@ public class Client status = 1; } - if(db != null) - { - try - { - db.close(); - } - catch(DBException ex) - { - System.err.println(progName + ": " + ex + ": " + ex.message); - status = 1; - } - dbEnv = null; - } - - if(dbEnv != null) - { - try - { - dbEnv.close(); - } - catch(DBException ex) - { - System.err.println(progName + ": " + ex + ": " + ex.message); - status = 1; - } - catch(Ice.LocalException ex) - { - System.err.println(progName + ": " + ex); - status = 1; - } - catch(Exception ex) - { - System.err.println(progName + ": unknown exception: " + ex); - status = 1; - } - dbEnv = null; - } - if(communicator != null) { try @@ -255,4 +224,8 @@ public class Client System.exit(status); } + + private Ice.Communicator _communicator; + private String _envName; + } diff --git a/java/test/Freeze/complex/build.xml b/java/test/Freeze/complex/build.xml index dfdc70193db..9b12eb59f1e 100644 --- a/java/test/Freeze/complex/build.xml +++ b/java/test/Freeze/complex/build.xml @@ -60,6 +60,10 @@ the Free Software Foundation. <target name="clean"> <delete dir="${class.dir}"/> <delete dir="${generated.dir}"/> + <delete> + <fileset dir="db" includes="log.*"/> + <fileset dir="db" includes="test"/> + </delete> </target> </project> diff --git a/java/test/Freeze/cursor/build.xml b/java/test/Freeze/cursor/build.xml index 55c69b2b8ad..a9b4e96eeb0 100644 --- a/java/test/Freeze/cursor/build.xml +++ b/java/test/Freeze/cursor/build.xml @@ -32,7 +32,8 @@ the Free Software Foundation. classpath="${lib.dir}" debug="${debug}"/> </target> - <target name="all" depends="compile"/> + + <target name="all"/> <target name="clean"> <delete dir="${class.dir}"/> diff --git a/java/test/Freeze/dbmap/Client.java b/java/test/Freeze/dbmap/Client.java index 86e617b5bee..ec206d47e2b 100644 --- a/java/test/Freeze/dbmap/Client.java +++ b/java/test/Freeze/dbmap/Client.java @@ -32,6 +32,7 @@ public class Client Object o = p.next(); test(entrySet.contains(o)); } + ((Freeze.Map.EntryIterator)p).close(); } } catch(Exception ex) @@ -71,7 +72,7 @@ public class Client } private static int - run(String[] args, java.util.Map m, DB db) + run(String[] args, java.util.Map m) throws DBException { // @@ -208,8 +209,6 @@ public class Client } } - ((Freeze.Map.EntryIterator)p).close(); - test(m.size() == 23); test(m.get(new Byte((byte)'b')) == null); test(m.get(new Byte((byte)'n')) == null); @@ -262,8 +261,6 @@ public class Client } } - ((Freeze.Map.EntryIterator)p).close(); - test(m.size() == 26); test(m.get(new Byte((byte)'b')) != null); test(m.get(new Byte((byte)'n')) != null); @@ -287,21 +284,6 @@ public class Client System.out.println("ok"); } - /** - * - * TODO: BENOIT: Re-enable this test. The stress test is disabled for now. It exposes - * many self dead locks. I believe this is caused by how we setup the database environment, - * i.e.: with all the flags to enable Berkeley DB Transactional support. However since we - * don't use transactions in the code this leads to deadlocks. If we specify DB_INIT_TXN we - * should use transactions (http://www.sleepycat.com/docs/ref/transapp/env_open.html). - * - * There's also some details at http://www.sleepycat.com/docs/ref/lock/notxn.html. - * - * Two solutions: - * - * - use transactions. - * - use BerkeleyDB Concurrent Data Store product instead. - * { System.out.print(" testing concurrent access... "); System.out.flush(); @@ -313,14 +295,7 @@ public class Client // for(int i = 0; i < 10; ++i) { - if(m instanceof ByteIntMapXML) - { - l.add(new StressThread(new ByteIntMapXML(db))); - } - else - { - l.add(new StressThread(new ByteIntMapBinary(db))); - } + l.add(new StressThread(m)); } // @@ -354,7 +329,6 @@ public class Client System.out.println("ok"); } - */ return 0; } @@ -364,9 +338,8 @@ public class Client { int status; Ice.Communicator communicator = null; - DBEnvironment dbEnv = null; - String dbEnvDir = "db"; - DB xmlDB = null, binaryDB = null; + String envName = "db"; + try { @@ -376,100 +349,37 @@ public class Client args = holder.value; if(args.length > 0) { - dbEnvDir = args[0]; - dbEnvDir += "/"; - dbEnvDir += "db"; + envName = args[0]; + envName += "/"; + envName += "db"; } - dbEnv = Freeze.Util.initialize(communicator, dbEnvDir); - xmlDB = dbEnv.openDB("xml", true); - ByteIntMapXML xml = new ByteIntMapXML(xmlDB); + + ByteIntMapXML xml = new ByteIntMapXML(communicator, envName, "xml", true); System.out.println("testing XML encoding..."); - status = run(args, xml, xmlDB); + status = run(args, xml); + xml.close(); if(status == 0) { - binaryDB = dbEnv.openDB("binary", true); - ByteIntMapBinary binary = new ByteIntMapBinary(binaryDB); + ByteIntMapBinary binary = new ByteIntMapBinary(communicator, envName, "binary", true); System.out.println("testing binary encoding..."); - status = run(args, binary, binaryDB); + status = run(args, binary); + binary.close(); } } - catch(Exception ex) + catch(DBException ex) { - ex.printStackTrace(); - System.err.println(ex); + System.err.println(args[0] + ": " + ex + ": " + ex.message); status = 1; } - - if(xmlDB != null) - { - try - { - xmlDB.close(); - } - catch(DBException ex) - { - System.err.println(args[0] + ": " + ex + ": " + ex.message); - status = 1; - } - catch(Ice.LocalException ex) - { - System.err.println(args[0] + ": " + ex); - status = 1; - } - catch(Exception ex) - { - System.err.println(args[0] + ": unknown exception: " + ex); - status = 1; - } - xmlDB = null; - } - - if(binaryDB != null) - { - try - { - binaryDB.close(); - } - catch(DBException ex) - { - System.err.println(args[0] + ": " + ex + ": " + ex.message); - status = 1; - } - catch(Ice.LocalException ex) - { - System.err.println(args[0] + ": " + ex); - status = 1; - } - catch(Exception ex) - { - System.err.println(args[0] + ": unknown exception: " + ex); - status = 1; - } - binaryDB = null; - } - - if(dbEnv != null) + catch(Ice.LocalException ex) { - try - { - dbEnv.close(); - } - catch(DBException ex) - { - System.err.println(args[0] + ": " + ex + ": " + ex.message); - status = 1; - } - catch(Ice.LocalException ex) - { - System.err.println(args[0] + ": " + ex); - status = 1; - } - catch(Exception ex) - { - System.err.println(args[0] + ": unknown exception: " + ex); - status = 1; - } - dbEnv = null; + System.err.println(args[0] + ": " + ex); + status = 1; + } + catch(Exception ex) + { + System.err.println(args[0] + ": unknown exception: " + ex); + status = 1; } if(communicator != null) diff --git a/java/test/Freeze/dbmap/build.xml b/java/test/Freeze/dbmap/build.xml index 5bafaa122aa..30cd47ceed7 100644 --- a/java/test/Freeze/dbmap/build.xml +++ b/java/test/Freeze/dbmap/build.xml @@ -54,6 +54,10 @@ the Free Software Foundation. <target name="clean"> <delete dir="${class.dir}"/> <delete dir="${generated.dir}"/> + <delete> + <fileset dir="db" includes="log.*"/> + <fileset dir="db" includes="binary,xml"/> + </delete> </target> </project> diff --git a/java/test/Freeze/evictor/Client.java b/java/test/Freeze/evictor/Client.java index b9613759063..f7f4434eb55 100644 --- a/java/test/Freeze/evictor/Client.java +++ b/java/test/Freeze/evictor/Client.java @@ -44,343 +44,165 @@ public class Client test(base != null); Test.RemoteEvictorFactoryPrx factory = Test.RemoteEvictorFactoryPrxHelper.checkedCast(base); - // - // Test EvictionStrategy - // - { - System.out.print("testing EvictionStrategy... "); - System.out.flush(); - - final int size = 5; - - Test.RemoteEvictorPrx evictor = factory.createEvictor("EvictionStrategy", Test.Strategy.Eviction); - evictor.setSize(size); - - // - // Create the same number of servants as the evictor size - // (i.e., don't exceed queue size). Servants should be - // saved immediately. - // - Test.ServantPrx[] servants = new Test.ServantPrx[size]; - for(int i = 0; i < size; i++) - { - servants[i] = evictor.createServant(i, i); - test(evictor.getLastSavedValue() == i); - } - - // - // Evict and verify values. - // - evictor.setSize(0); - evictor.setSize(size); - evictor.clearLastSavedValue(); - for(int i = 0; i < size; i++) - { - test(servants[i].getValue() == i); - } - - // - // Mutate servants. - // - for(int i = 0; i < size; i++) - { + + System.out.print("testing Freeze Evictor... "); + System.out.flush(); + + final int size = 5; + + Test.RemoteEvictorPrx evictor = factory.createEvictor("Test"); + evictor.setSize(size); + + // + // Create some servants and verify they did not get saved + // + Test.ServantPrx[] servants = new Test.ServantPrx[size]; + for(int i = 0; i < size; i++) + { + servants[i] = evictor.createServant(i, i); + test(evictor.getLastSavedValue() == -1); + } + + // + // Save and verify + // + evictor.saveNow(); + test(evictor.getLastSavedValue() == size - 1); + + // + // Evict and verify values. + // + evictor.setSize(0); + evictor.setSize(size); + evictor.clearLastSavedValue(); + for(int i = 0; i < size; i++) + { + test(servants[i].getValue() == i); + } + + // + // Mutate servants. + // + for(int i = 0; i < size; i++) + { servants[i].setValue(i + 100); - } - - // - // Servants should not be saved yet. - // - test(evictor.getLastSavedValue() == -1); - for(int i = 0; i < size; i++) - { - test(servants[i].getValue() == i + 100); - } - - // - // Evict and verify values. - // - evictor.setSize(0); - evictor.setSize(size); - for(int i = 0; i < size; i++) - { - test(servants[i].getValue() == i + 100); - } - - // - // Destroy servants and verify ObjectNotExistException. - // - for(int i = 0; i < size; i++) - { - servants[i].destroy(); - try - { - servants[i].getValue(); - test(false); - } - catch(Ice.ObjectNotExistException ex) - { - // Expected - } - } - - // - // Allocate space for size+1 servants. - // - servants = new Test.ServantPrx[size + 1]; - - // - // Recreate servants. - // - for(int i = 0; i < size; i++) - { - servants[i] = evictor.createServant(i, i); - } - - // - // Deactivate and recreate evictor, to ensure that servants - // are restored properly after database close and reopen. - // - evictor.deactivate(); - evictor = factory.createEvictor("EvictionStrategy", Test.Strategy.Eviction); - evictor.setSize(size); - for(int i = 0; i < size; i++) - { - servants[i] = evictor.getServant(i); - test(servants[i].getValue() == i); - } - - // - // No servants should have been evicted yet. - // - test(evictor.getLastEvictedValue() == -1); - - // - // Create new servant - should cause eviction. - // - servants[size] = evictor.createServant(size, size); - test(evictor.getLastEvictedValue() == 0); - - // - // Restore the evicted servant, which evicts another - // servant, and so on. - // - for(int i = 0; i <= size; i++) - { - test(servants[i].getValue() == i); - test(evictor.getLastEvictedValue() == (i + 1) % (size + 1)); - } - - // - // Destroy new servant and verify eviction no longer occurs. - // - servants[size].destroy(); - evictor.clearLastEvictedValue(); - for(int i = 0; i < size; i++) - { - test(servants[i].getValue() == i); - } - test(evictor.getLastEvictedValue() == -1); + } + + // + // Servants should not be saved yet. + // + test(evictor.getLastSavedValue() == -1); + for(int i = 0; i < size; i++) + { + test(servants[i].getValue() == i + 100); + } + + evictor.saveNow(); + + // + // Test saving while busy + // + + AMI_Servant_setValueAsyncI setCB = new AMI_Servant_setValueAsyncI(); + for(int i = 0; i < size; i++) + { + evictor.clearLastSavedValue(); + // + // Start a mutating operation so that the object is not idle. + // + servants[i].setValueAsync_async(setCB, i + 300); - // - // Test explicit saves // - for(int i = 0; i < size; i++) + // Wait for setValueAsync to be dispatched. + // + try { - servants[i].saveValue(i + 1); - test(evictor.getLastSavedValue() == i + 1); + Thread.sleep(100); } + catch(InterruptedException ex) + { + } + // + // Object should not have been modified or saved yet. + // + test(servants[i].getValue() == i + 100); + test(evictor.getLastSavedValue() == -1); + // + // This operation modifies the object state but is not saved + // because the setValueAsync operation is still pending. + // + servants[i].setValue(i + 200); + test(servants[i].getValue() == i + 200); + test(evictor.getLastSavedValue() == -1); + + evictor.saveNow(); + test(evictor.getLastSavedValue() == i + 200); - // - // Clean up. - // - for(int i = 0; i < size; i++) - { - servants[i].destroy(); - } - - evictor.deactivate(); - System.out.println("ok"); - } - - // - // Test IdleStrategy - // - { - System.out.print("testing IdleStrategy... "); - System.out.flush(); - - final int size = 5; - - Test.RemoteEvictorPrx evictor = factory.createEvictor("IdleStrategy", Test.Strategy.Idle); - evictor.setSize(size); - - // - // Create the same number of servants as the evictor size - // (i.e., don't exceed queue size). Servants should be - // saved immediately. - // - Test.ServantPrx[] servants = new Test.ServantPrx[size]; - for(int i = 0; i < size; i++) - { - servants[i] = evictor.createServant(i, i); - test(evictor.getLastSavedValue() == i); - } - - // - // Evict and verify values. - // - evictor.setSize(0); - evictor.setSize(size); - for(int i = 0; i < size; i++) - { - test(servants[i].getValue() == i); - } - - // - // Mutate servants and verify they have been saved. - // - for(int i = 0; i < size; i++) - { - servants[i].setValue(i + 100); - test(evictor.getLastSavedValue() == i + 100); - } - - // - // Evict and verify values. - // - evictor.setSize(0); - evictor.setSize(size); - for(int i = 0; i < size; i++) - { - test(servants[i].getValue() == i + 100); - } - - // - // No servants should have been saved yet. - // - test(evictor.getLastSavedValue() == -1); - - // - // Test idle behavior. - // - AMI_Servant_setValueAsyncI setCB = new AMI_Servant_setValueAsyncI(); - for(int i = 0; i < size; i++) - { - // - // Start a mutating operation so that the object is not idle. - // - servants[i].setValueAsync_async(setCB, i + 300); - // - // Wait for setValueAsync to be dispatched. - // - try - { - Thread.sleep(100); - } - catch(InterruptedException ex) - { - } - // - // Object should not have been modified or saved yet. - // - test(servants[i].getValue() == i + 100); - test(evictor.getLastSavedValue() == -1); - // - // This operation modifies the object state but is not saved - // because the setValueAsync operation is still pending. - // - servants[i].setValue(i + 200); - test(servants[i].getValue() == i + 200); - test(evictor.getLastSavedValue() == -1); - // - // Force the response to setValueAsync, which should cause - // the object to be saved. - // - servants[i].releaseAsync(); - test(servants[i].getValue() == i + 300); - test(evictor.getLastSavedValue() == i + 300); - } - - // - // Destroy servants and verify ObjectNotExistException. - // - for(int i = 0; i < size; i++) - { - servants[i].destroy(); - try - { - servants[i].getValue(); - test(false); - } - catch(Ice.ObjectNotExistException ex) - { - // Expected - } - } - - // - // Allocate space for size+1 servants. - // - servants = new Test.ServantPrx[size + 1]; - - // - // Recreate servants. - // - for(int i = 0; i < size; i++) - { - servants[i] = evictor.createServant(i, i); - } - - // - // Deactivate and recreate evictor, to ensure that servants - // are restored properly after database close and reopen. - // - evictor.deactivate(); - evictor = factory.createEvictor("IdleStrategy", Test.Strategy.Idle); - evictor.setSize(size); - for(int i = 0; i < size; i++) - { - servants[i] = evictor.getServant(i); - test(servants[i].getValue() == i); - } - - // - // No servants should have been saved yet. - // - test(evictor.getLastSavedValue() == -1); - - // - // Create new servant - should cause eviction but no - // servants should be saved. - // - servants[size] = evictor.createServant(size, size); - test(evictor.getLastSavedValue() == size); - test(evictor.getLastEvictedValue() != -1); - - // - // Restore the evicted servant, which evicts another - // servant, and so on. - // - for(int i = 0; i <= size; i++) - { - test(servants[i].getValue() == i); - test(evictor.getLastEvictedValue() == (i + 1) % (size + 1)); - } - test(evictor.getLastSavedValue() == -1); - - // - // Clean up. - // - for(int i = 0; i <= size; i++) - { - servants[i].destroy(); - } - - evictor.deactivate(); - System.out.println("ok"); - } - + // + // Force the response to setValueAsync + // + servants[i].releaseAsync(); + test(servants[i].getValue() == i + 300); + test(evictor.getLastSavedValue() == i + 200); + evictor.saveNow(); + test(evictor.getLastSavedValue() == i + 300); + } + + // + // Destroy servants and verify ObjectNotExistException. + // + for(int i = 0; i < size; i++) + { + servants[i].destroy(); + try + { + servants[i].getValue(); + test(false); + } + catch(Ice.ObjectNotExistException ex) + { + // Expected + } + } + + // + // Allocate space for size+1 servants. + // + servants = new Test.ServantPrx[size + 1]; + + // + // Recreate servants. + // + for(int i = 0; i < size; i++) + { + servants[i] = evictor.createServant(i, i); + } + + // + // Deactivate and recreate evictor, to ensure that servants + // are restored properly after database close and reopen. + // + evictor.deactivate(); + evictor = factory.createEvictor("Test"); + evictor.setSize(size); + for(int i = 0; i < size; i++) + { + servants[i] = evictor.getServant(i); + test(servants[i].getValue() == i); + } + + // + // Clean up. + // + for(int i = 0; i < size; i++) + { + servants[i].destroy(); + } + + evictor.deactivate(); + System.out.println("ok"); + factory.shutdown(); return 0; diff --git a/java/test/Freeze/evictor/RemoteEvictorFactoryI.java b/java/test/Freeze/evictor/RemoteEvictorFactoryI.java index e8d9bc3abd3..7917a776146 100644 --- a/java/test/Freeze/evictor/RemoteEvictorFactoryI.java +++ b/java/test/Freeze/evictor/RemoteEvictorFactoryI.java @@ -14,10 +14,10 @@ public final class RemoteEvictorFactoryI extends Test._RemoteEvictorFactoryDisp { - RemoteEvictorFactoryI(Ice.ObjectAdapter adapter, Freeze.DBEnvironment dbEnv) + RemoteEvictorFactoryI(Ice.ObjectAdapter adapter, String envName) { _adapter = adapter; - _dbEnv = dbEnv; + _envName = envName; } static class Initializer extends Ice.LocalObjectImpl implements Freeze.ServantInitializer @@ -40,23 +40,11 @@ public final class RemoteEvictorFactoryI extends Test._RemoteEvictorFactoryDisp } public Test.RemoteEvictorPrx - createEvictor(String name, Test.Strategy s, Ice.Current current) + createEvictor(String name, Ice.Current current) { - Freeze.DB db = _dbEnv.openDB(name, true); + Freeze.Evictor evictor = Freeze.Util.createEvictor(_adapter.getCommunicator(), _envName, name, true); - Freeze.PersistenceStrategy delegate; - if(s == Test.Strategy.Eviction) - { - delegate = db.createEvictionStrategy(); - } - else - { - delegate = db.createIdleStrategy(); - } - StrategyI strategy = new StrategyI(delegate); - Freeze.Evictor evictor = db.createEvictor(strategy); - - RemoteEvictorI remoteEvictor = new RemoteEvictorI(_adapter, name, db, strategy, evictor); + RemoteEvictorI remoteEvictor = new RemoteEvictorI(_adapter, name, evictor); evictor.installServantInitializer(new Initializer(remoteEvictor, evictor)); return Test.RemoteEvictorPrxHelper.uncheckedCast(_adapter.add(remoteEvictor, Ice.Util.stringToIdentity(name))); } @@ -64,9 +52,9 @@ public final class RemoteEvictorFactoryI extends Test._RemoteEvictorFactoryDisp public void shutdown(Ice.Current current) { - _dbEnv.getCommunicator().shutdown(); + _adapter.getCommunicator().shutdown(); } private Ice.ObjectAdapter _adapter; - private Freeze.DBEnvironment _dbEnv; + private String _envName; } diff --git a/java/test/Freeze/evictor/RemoteEvictorI.java b/java/test/Freeze/evictor/RemoteEvictorI.java index 67a88df28e4..72264d54f37 100644 --- a/java/test/Freeze/evictor/RemoteEvictorI.java +++ b/java/test/Freeze/evictor/RemoteEvictorI.java @@ -14,12 +14,10 @@ public final class RemoteEvictorI extends Test._RemoteEvictorDisp { - RemoteEvictorI(Ice.ObjectAdapter adapter, String category, Freeze.DB db, StrategyI strategy, Freeze.Evictor evictor) + RemoteEvictorI(Ice.ObjectAdapter adapter, String category, Freeze.Evictor evictor) { _adapter = adapter; _category = category; - _db = db; - _strategy = strategy; _evictor = evictor; Ice.Communicator communicator = adapter.getCommunicator(); _evictorAdapter = communicator.createObjectAdapterWithEndpoints(Ice.Util.generateUUID(), "default"); @@ -58,7 +56,6 @@ public final class RemoteEvictorI extends Test._RemoteEvictorDisp getLastSavedValue(Ice.Current current) { int result = _lastSavedValue; - _lastSavedValue = -1; return result; } @@ -68,16 +65,10 @@ public final class RemoteEvictorI extends Test._RemoteEvictorDisp _lastSavedValue = -1; } - public int - getLastEvictedValue(Ice.Current current) - { - return _strategy.getLastEvictedValue(); - } - - public void - clearLastEvictedValue(Ice.Current current) + public + void saveNow(Ice.Current current) { - _strategy.clearLastEvictedValue(); + _evictor.saveNow(); } public void @@ -86,7 +77,6 @@ public final class RemoteEvictorI extends Test._RemoteEvictorDisp _evictorAdapter.deactivate(); _evictorAdapter.waitForDeactivate(); _adapter.remove(Ice.Util.stringToIdentity(_category)); - _db.close(); } void @@ -97,8 +87,6 @@ public final class RemoteEvictorI extends Test._RemoteEvictorDisp private Ice.ObjectAdapter _adapter; private String _category; - private Freeze.DB _db; - private StrategyI _strategy; private Freeze.Evictor _evictor; private Ice.ObjectAdapter _evictorAdapter; private int _lastSavedValue; diff --git a/java/test/Freeze/evictor/ServantI.java b/java/test/Freeze/evictor/ServantI.java index 44d3d84b9d5..80bd32120bd 100644 --- a/java/test/Freeze/evictor/ServantI.java +++ b/java/test/Freeze/evictor/ServantI.java @@ -51,13 +51,6 @@ public final class ServantI extends Test.Servant } public void - saveValue(int value, Ice.Current current) - { - this.value = value; - _evictor.saveObject(current.id); - } - - public void setValueAsync_async(Test.AMD_Servant_setValueAsync __cb, int value, Ice.Current current) { _setValueAsyncCB = __cb; diff --git a/java/test/Freeze/evictor/Server.java b/java/test/Freeze/evictor/Server.java index e38f6a6b18c..c1c29fa088f 100644 --- a/java/test/Freeze/evictor/Server.java +++ b/java/test/Freeze/evictor/Server.java @@ -30,13 +30,13 @@ public class Server } static int - run(String[] args, Ice.Communicator communicator, Freeze.DBEnvironment dbEnv) + run(String[] args, Ice.Communicator communicator, String envName) { communicator.getProperties().setProperty("Evictor.Endpoints", "default -p 12345 -t 2000"); Ice.ObjectAdapter adapter = communicator.createObjectAdapter("Evictor"); - RemoteEvictorFactoryI factory = new RemoteEvictorFactoryI(adapter, dbEnv); + RemoteEvictorFactoryI factory = new RemoteEvictorFactoryI(adapter, envName); adapter.add(factory, Ice.Util.stringToIdentity("factory")); Ice.ObjectFactory servantFactory = new ServantFactory(); @@ -54,8 +54,7 @@ public class Server { int status = 0; Ice.Communicator communicator = null; - Freeze.DBEnvironment dbEnv = null; - String dbEnvDir = "db"; + String envName = "db"; try { @@ -65,12 +64,10 @@ public class Server args = holder.value; if(args.length > 0) { - dbEnvDir = args[0]; - dbEnvDir += "/"; - dbEnvDir += "db"; + envName = args[0]; + envName += "/db"; } - dbEnv = Freeze.Util.initialize(communicator, dbEnvDir); - status = run(args, communicator, dbEnv); + status = run(args, communicator, envName); } catch(Ice.LocalException ex) { @@ -78,11 +75,6 @@ public class Server status = 1; } - if(dbEnv != null) - { - dbEnv.close(); - } - if(communicator != null) { try diff --git a/java/test/Freeze/evictor/StrategyI.java b/java/test/Freeze/evictor/StrategyI.java deleted file mode 100644 index 3083d1fc33a..00000000000 --- a/java/test/Freeze/evictor/StrategyI.java +++ /dev/null @@ -1,86 +0,0 @@ -// ********************************************************************** -// -// 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. -// -// ********************************************************************** - -public final class StrategyI extends Ice.LocalObjectImpl implements Freeze.PersistenceStrategy -{ - public - StrategyI(Freeze.PersistenceStrategy delegate) - { - _delegate = delegate; - } - - public Ice.LocalObject - activatedObject(Ice.Identity ident, Ice.Object servant) - { - return _delegate.activatedObject(ident, servant); - } - - public void - destroyedObject(Ice.Identity ident, Ice.LocalObject cookie) - { - _delegate.destroyedObject(ident, cookie); - } - - public void - evictedObject(Freeze.ObjectStore store, Ice.Identity ident, Ice.Object servant, Ice.LocalObject cookie) - { - Test.Servant s = (Test.Servant)servant; - _lastEvictedValue = s.getValue(null); - - _delegate.evictedObject(store, ident, servant, cookie); - } - - public void - savedObject(Freeze.ObjectStore store, Ice.Identity ident, Ice.Object servant, Ice.LocalObject cookie, int usageCount) - { - _delegate.savedObject(store, ident, servant, cookie, usageCount); - } - - public void - preOperation(Freeze.ObjectStore store, Ice.Identity ident, Ice.Object servant, boolean mutating, - Ice.LocalObject cookie) - { - _delegate.preOperation(store, ident, servant, mutating, cookie); - } - - public void - postOperation(Freeze.ObjectStore store, Ice.Identity ident, Ice.Object servant, boolean mutating, - Ice.LocalObject cookie) - { - _delegate.postOperation(store, ident, servant, mutating, cookie); - } - - public void - destroy() - { - _delegate.destroy(); - } - - int - getLastEvictedValue() - { - int result = _lastEvictedValue; - _lastEvictedValue = -1; - return result; - } - - void - clearLastEvictedValue() - { - _lastEvictedValue = -1; - } - - private Freeze.PersistenceStrategy _delegate; - private int _lastEvictedValue = -1; -} diff --git a/java/test/Freeze/evictor/Test.ice b/java/test/Freeze/evictor/Test.ice index 4850f02fec0..e7ba8d797e6 100644 --- a/java/test/Freeze/evictor/Test.ice +++ b/java/test/Freeze/evictor/Test.ice @@ -21,12 +21,9 @@ module Test class Servant { nonmutating int getValue(); - void setValue(int value); - ["ami", "amd"] void setValueAsync(int value); - - void saveValue(int value); + ["ami", "amd"] void setValueAsync(int value); nonmutating void releaseAsync(); void destroy(); @@ -41,20 +38,13 @@ interface RemoteEvictor Servant* getServant(int id); nonmutating int getLastSavedValue(); void clearLastSavedValue(); - nonmutating int getLastEvictedValue(); - void clearLastEvictedValue(); + void saveNow(); void deactivate(); }; -enum Strategy -{ - Eviction, - Idle -}; - interface RemoteEvictorFactory { - RemoteEvictor* createEvictor(string name, Strategy s); + RemoteEvictor* createEvictor(string name); void shutdown(); }; diff --git a/java/test/Freeze/evictor/build.xml b/java/test/Freeze/evictor/build.xml index 5bfe855c4a7..bd0717fc53c 100644 --- a/java/test/Freeze/evictor/build.xml +++ b/java/test/Freeze/evictor/build.xml @@ -52,6 +52,10 @@ the Free Software Foundation. <target name="clean"> <delete dir="${generated.dir}"/> <delete dir="${class.dir}"/> + <delete> + <fileset dir="db" includes="log.*"/> + <fileset dir="db" includes="Test"/> + </delete> </target> </project> diff --git a/java/test/Freeze/evictor/config b/java/test/Freeze/evictor/config new file mode 100644 index 00000000000..f00c7ebae94 --- /dev/null +++ b/java/test/Freeze/evictor/config @@ -0,0 +1,10 @@ +# +# Disable automatic saves +# +Freeze.Evictor.db.Test.SaveSizeTrigger=-1 +Freeze.Evictor.db.Test.SavePeriod=0 +Freeze.Trace.DB=1 +Freeze.Trace.Evictor=1 + + + diff --git a/java/test/Freeze/evictor/run.py b/java/test/Freeze/evictor/run.py index dad7059a4e2..1a04746f4ae 100755 --- a/java/test/Freeze/evictor/run.py +++ b/java/test/Freeze/evictor/run.py @@ -29,8 +29,10 @@ name = os.path.join("Freeze", "evictor") testdir = os.path.join(toplevel, "test", name) os.environ["CLASSPATH"] = os.path.join(testdir, "classes") + TestUtil.sep + os.getenv("CLASSPATH", "") +testOptions = " --Ice.Config=" + testdir + "/config "; + dbdir = os.path.join(testdir, "db") TestUtil.cleanDbDir(dbdir) -TestUtil.clientServerTestWithOptions(" " + testdir, "") +TestUtil.clientServerTestWithOptions(" " + testdir, testOptions) sys.exit(0) diff --git a/java/test/IcePack/deployer/FreezeService.java b/java/test/IcePack/deployer/FreezeService.java index 658a19dbf40..2d61fc06a36 100644 --- a/java/test/IcePack/deployer/FreezeService.java +++ b/java/test/IcePack/deployer/FreezeService.java @@ -15,11 +15,9 @@ public class FreezeService extends Ice.LocalObjectImpl implements IceBox.FreezeService { public void - start(String name, Ice.Communicator communicator, String[] args, Freeze.DBEnvironment dbEnv) + start(String name, Ice.Communicator communicator, String[] args, String envName) throws IceBox.FailureException { - Freeze.DB db = dbEnv.openDB("testdb", true); - Ice.Properties properties = communicator.getProperties(); Ice.ObjectAdapter adapter = communicator.createObjectAdapter(name); diff --git a/java/test/IcePack/deployer/build.xml b/java/test/IcePack/deployer/build.xml index b8e5c337f26..51828a3840a 100644 --- a/java/test/IcePack/deployer/build.xml +++ b/java/test/IcePack/deployer/build.xml @@ -52,6 +52,12 @@ the Free Software Foundation. <target name="clean"> <delete dir="${generated.dir}"/> <delete dir="${class.dir}"/> + <delete> + <fileset dir="db/node/db" includes="log.*"/> + <fileset dir="db/node/db" includes="serveradapters,servers"/> + <fileset dir="db/registry" includes="log.*"/> + <fileset dir="db/registry" includes="adapter,adapterregistry,noderegistry,objectregistry,objectregistry-types,serverregistry"/> + </delete> </target> </project> diff --git a/java/test/IcePack/simple/build.xml b/java/test/IcePack/simple/build.xml index 8005dcf78fb..1a6485244b1 100644 --- a/java/test/IcePack/simple/build.xml +++ b/java/test/IcePack/simple/build.xml @@ -52,6 +52,12 @@ the Free Software Foundation. <target name="clean"> <delete dir="${generated.dir}"/> <delete dir="${class.dir}"/> + <delete> + <fileset dir="db/node/db" includes="log.*"/> + <fileset dir="db/node/db" includes="serveradapters,servers"/> + <fileset dir="db/registry" includes="log.*"/> + <fileset dir="db/registry" includes="adapter,adapterregistry,noderegistry,objectregistry,objectregistry-types,serverregistry"/> + </delete> </target> </project> |