summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2009-05-18 14:03:42 -0700
committerMark Spruiell <mes@zeroc.com>2009-05-18 14:03:42 -0700
commitb30ccc77d3a9822c6ffcebf9b45945822df200bc (patch)
tree94105ea42fa81ad0b8731b05a46c7f64304dec55 /java
parentRemoved Freeze.UseNonmutating (diff)
downloadice-b30ccc77d3a9822c6ffcebf9b45945822df200bc.tar.bz2
ice-b30ccc77d3a9822c6ffcebf9b45945822df200bc.tar.xz
ice-b30ccc77d3a9822c6ffcebf9b45945822df200bc.zip
bug 252 - Freeze finalizers
bug 2552 - Update Freeze for Java5
Diffstat (limited to 'java')
-rw-r--r--java/build.xml53
-rw-r--r--java/config/common.xml24
-rw-r--r--java/demo/Freeze/bench/Client.java86
-rw-r--r--java/demo/Freeze/bench/build.xml2
-rw-r--r--java/demo/Freeze/casino/build.xml2
-rw-r--r--java/demo/Freeze/library/Grammar.java14
-rw-r--r--java/demo/Freeze/library/LibraryI.java6
-rw-r--r--java/demo/Freeze/library/Parser.java36
-rw-r--r--java/demo/Freeze/library/build.xml2
-rw-r--r--java/demo/Freeze/phonebook/Grammar.java16
-rw-r--r--java/demo/Freeze/phonebook/build.xml2
-rw-r--r--java/demo/Freeze/transform/Create.java21
-rw-r--r--java/demo/Freeze/transform/Read.java44
-rw-r--r--java/demo/Freeze/transform/ReadNew.java51
-rw-r--r--java/demo/Freeze/transform/Recreate.java21
-rw-r--r--java/demo/Freeze/transform/build.xml2
-rw-r--r--java/demo/book/freeze_filesystem/build.xml2
-rw-r--r--java/src/Freeze/BackgroundSaveEvictorI.java354
-rw-r--r--java/src/Freeze/ConnectionI.java119
-rw-r--r--java/src/Freeze/EvictorElement.java2
-rw-r--r--java/src/Freeze/EvictorI.java161
-rw-r--r--java/src/Freeze/EvictorIteratorI.java59
-rw-r--r--java/src/Freeze/Index.java87
-rw-r--r--java/src/Freeze/LinkedList.java50
-rw-r--r--java/src/Freeze/Map.java2479
-rw-r--r--java/src/Freeze/MapDb.java134
-rw-r--r--java/src/Freeze/MapIndex.java22
-rw-r--r--java/src/Freeze/MapInternal/EntryI.java131
-rw-r--r--java/src/Freeze/MapInternal/Index.java708
-rw-r--r--java/src/Freeze/MapInternal/IndexedSubMap.java869
-rw-r--r--java/src/Freeze/MapInternal/IteratorI.java422
-rw-r--r--java/src/Freeze/MapInternal/IteratorModel.java25
-rw-r--r--java/src/Freeze/MapInternal/KeyCodec.java (renamed from java/src/Freeze/KeyCodec.java)8
-rw-r--r--java/src/Freeze/MapInternal/MapI.java1571
-rw-r--r--java/src/Freeze/MapInternal/Search.java238
-rw-r--r--java/src/Freeze/MapInternal/SubMap.java695
-rw-r--r--java/src/Freeze/MapInternal/TraceLevels.java28
-rw-r--r--java/src/Freeze/NavigableMap.java42
-rw-r--r--java/src/Freeze/ObjectStore.java116
-rw-r--r--java/src/Freeze/SharedDbEnv.java55
-rw-r--r--java/src/Freeze/SubMap.java476
-rw-r--r--java/src/Freeze/TransactionI.java31
-rw-r--r--java/src/Freeze/TransactionalEvictorContext.java90
-rw-r--r--java/src/Freeze/TransactionalEvictorI.java891
-rw-r--r--java/src/Freeze/Util.java42
-rw-r--r--java/src/IceGridGUI/BareBonesBrowserLaunch.java7
-rw-r--r--java/src/IceInternal/PropertyNames.java3
-rw-r--r--java/test/Freeze/complex/Client.java37
-rw-r--r--java/test/Freeze/complex/Parser.java12
-rw-r--r--java/test/Freeze/dbmap/Client.java1796
-rw-r--r--java/test/Freeze/evictor/AccountI.java23
-rw-r--r--java/test/Freeze/evictor/Client.java185
-rw-r--r--java/test/Freeze/evictor/FacetI.java2
-rw-r--r--java/test/Freeze/evictor/RemoteEvictorFactoryI.java3
-rw-r--r--java/test/Freeze/evictor/RemoteEvictorI.java11
-rw-r--r--java/test/Freeze/evictor/ServantI.java2
-rw-r--r--java/test/Freeze/evictor/Server.java10
57 files changed, 7665 insertions, 4715 deletions
diff --git a/java/build.xml b/java/build.xml
index d6f73fca9b6..798ef767aba 100644
--- a/java/build.xml
+++ b/java/build.xml
@@ -169,10 +169,9 @@
<depend srcdir="${generated.dir}:${src.dir}" destdir="${lib.dir}" cache="${cache.dir}"/>
<javac srcdir="${generated.dir}:${src.dir}" destdir="${lib.dir}"
source="1.5" debug="${debug}"
- excludes="IceGridGUI/**"
+ excludes="IceGridGUI/**,Freeze/**,ant/**"
includes="**"
- deprecation="on"
- classpathref="db.classpath">
+ deprecation="on">
<compilerarg value="${javac.lint}"/>
</javac>
</target>
@@ -187,7 +186,27 @@
<exclude name="*.jar"/>
<manifest>
<attribute name="Built-By" value="ZeroC, Inc."/>
- <attribute name="Class-Path" value="Freeze.jar"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name="freeze-compile" depends="ice-compile">
+ <mkdir dir="${lib.dir}"/>
+ <javac srcdir="${generated.dir}:${src.dir}" destdir="${lib.dir}"
+ source="1.5" debug="${debug}"
+ includes="Freeze/**"
+ deprecation="on"
+ classpathref="db.classpath">
+ <compilerarg value="${javac.lint}"/>
+ </javac>
+ </target>
+
+ <target name="freeze-jar" depends="freeze-compile">
+ <jar jarfile="${lib.dir}/Freeze.jar" basedir="${lib.dir}">
+ <include name="Freeze/**"/>
+ <manifest>
+ <attribute name="Built-By" value="ZeroC, Inc."/>
+ <attribute name="Class-Path" value="db.jar db-${db.version}.jar /usr/share/java/db-${db.version}.jar ../db.jar"/>
</manifest>
</jar>
</target>
@@ -196,7 +215,6 @@
<mkdir dir="${generated.test.dir}"/>
<!-- Create the output directory for generated code -->
<slice2java outputdir="${generated.test.dir}" dependencyfile="${generated.test.dir}/.depend.Test">
- <meta value="${java2metadata}"/>
<includepath>
<pathelement path="${slice.dir}" />
</includepath>
@@ -302,7 +320,6 @@
<includepath>
<pathelement path="${slice.dir}" />
</includepath>
- <meta value="${java2metadata}"/>
<fileset dir="test/Freeze/evictor">
<include name="Test.ice" />
</fileset>
@@ -310,7 +327,6 @@
<!-- test/Freeze/complex -->
<slice2freezej outputdir="${generated.test.dir}" dependencyfile="${generated.test.dir}/.depend.Test">
- <meta value="${java2metadata}"/>
<dict name="test.Freeze.complex.Complex.ComplexDict" key="Complex::Key" value="Complex::Node"/>
<fileset dir="test/Freeze/complex">
<include name="Complex.ice" />
@@ -319,12 +335,10 @@
<!-- test/Freeze/dbmap -->
<slice2freezej outputdir="${generated.test.dir}" dependencyfile="${generated.test.dir}/.depend.Test">
- <meta value="${java2metadata}"/>
<dict name="test.Freeze.dbmap.ByteIntMap" key="byte" value="int"/>
<dictindex name="test.Freeze.dbmap.ByteIntMap"/>
</slice2freezej>
<slice2freezej ice="on" outputdir="${generated.test.dir}">
- <meta value="${java2metadata}"/>
<includepath>
<pathelement path="${slice.dir}" />
</includepath>
@@ -332,7 +346,6 @@
<dict name="test.Freeze.dbmap.IntIdentityMap" key="int" value="Ice::Identity"/>
</slice2freezej>
<slice2freezej ice="on" outputdir="${generated.test.dir}">
- <meta value="${java2metadata}"/>
<includepath>
<pathelement path="${slice.dir}" />
</includepath>
@@ -341,7 +354,6 @@
<dictindex name="test.Freeze.dbmap.IntIdentityMapWithIndex" member="category"/>
</slice2freezej>
<slice2freezej ice="on" outputdir="${generated.test.dir}">
- <meta value="${java2metadata}"/>
<includepath>
<pathelement path="${slice.dir}" />
</includepath>
@@ -351,7 +363,6 @@
</slice2freezej>
<slice2java stream="on" outputdir="${generated.test.dir}" dependencyfile="${generated.test.dir}/.depend.Test">
- <meta value="${java2metadata}"/>
<includepath>
<pathelement path="${slice.dir}" />
</includepath>
@@ -364,7 +375,6 @@
</slice2java>
<slice2java checksum="test.Ice.checksum.Test.SliceChecksums" outputdir="${generated.test.dir}" dependencyfile="${generated.test.dir}/.depend.Test">
- <meta value="${java2metadata}"/>
<includepath>
<pathelement path="${slice.dir}" />
</includepath>
@@ -375,7 +385,6 @@
</slice2java>
<slice2java outputdir="${generated.test.dir}" dependencyfile="${generated.test.dir}/.depend.Test">
- <meta value="${java2metadata}"/>
<includepath>
<pathelement path="${slice.dir}" />
<pathelement path="test/Ice/packagemd" />
@@ -388,7 +397,6 @@
</slice2java>
<slice2java checksum="test.Ice.checksum.server.Test.SliceChecksums" outputdir="${generated.test.dir}" dependencyfile="${generated.test.dir}/.depend.Test">
- <meta value="${java2metadata}"/>
<includepath>
<pathelement path="${slice.dir}" />
</includepath>
@@ -399,12 +407,12 @@
</slice2java>
</target>
- <target name="test-compile" depends="ice-compile,test-generate">
+ <target name="test-compile" depends="freeze-compile,test-generate">
<mkdir dir="${lib.dir}"/>
<mkdir dir="${cache.dir}"/>
<depend srcdir="." destdir="${lib.dir}" cache="${cache.dir}"/>
<javac srcdir=".:${generated.test.dir}" destdir="${lib.dir}" source="1.5" debug="${debug}" deprecation="on"
- classpathref="db.classpath">
+ classpathref="freeze.classpath">
<exclude name="${generated.test.dir}/**"/>
<include name="test/**"/>
<exclude name="test/Ice/translator/"/>
@@ -415,7 +423,6 @@
<target name="test-jar" depends="test-compile">
<jar jarfile="${lib.dir}/IceTest.jar" basedir="${lib.dir}">
<include name="test/**"/>
- <exclude name="test/Freeze/**"/>
<manifest>
<attribute name="Built-By" value="ZeroC, Inc."/>
<attribute name="Class-Path" value="Ice.jar"/>
@@ -423,16 +430,6 @@
</jar>
</target>
- <target name="freeze-jar" depends="ice-compile">
- <jar jarfile="${lib.dir}/Freeze.jar" basedir="${lib.dir}">
- <include name="Freeze/**"/>
- <manifest>
- <attribute name="Built-By" value="ZeroC, Inc."/>
- <attribute name="Class-Path" value="db.jar db-${db.version}.jar /usr/share/java/db-${db.version}.jar ../db.jar"/>
- </manifest>
- </jar>
- </target>
-
<target name="icegridadmin-compile" depends="ice-compile">
<javac srcdir="${src.dir}" destdir="${lib.dir}"
source="1.5" debug="${debug}"
diff --git a/java/config/common.xml b/java/config/common.xml
index 0dd06f436e9..223d7007ef7 100644
--- a/java/config/common.xml
+++ b/java/config/common.xml
@@ -192,7 +192,7 @@
</condition>
<path id="db.classpath">
- <pathelement path="${db.jar.file}"/>
+ <pathelement location="${db.jar.file}"/>
</path>
<target name="config-init-warn" if="ice.warn.duplicate.translator">
@@ -238,7 +238,27 @@
</condition>
<path id="ice.classpath">
- <fileset file="${dist.jar.file}"/>
+ <pathelement location="${dist.jar.file}"/>
+ </path>
+
+ <!-- Set freeze.classpath with the distribution Freeze.jar file -->
+ <condition property="freeze.jar.file" value="${dist.lib.dir}/Freeze-${ice.version}.jar">
+ <and>
+ <not><isset property="freeze.jar.file"/></not>
+ <available file="${dist.lib.dir}/Freeze-${ice.version}.jar"/>
+ </and>
+ </condition>
+
+ <condition property="freeze.jar.file" value="${dist.lib.dir}/Freeze.jar">
+ <and>
+ <not><isset property="freeze.jar.file"/></not>
+ <available file="${dist.lib.dir}/Freeze.jar"/>
+ </and>
+ </condition>
+
+ <path id="freeze.classpath">
+ <pathelement location="${freeze.jar.file}"/>
+ <path refid="db.classpath"/>
</path>
<condition property="certs.dir" value="${ice.top.dir}/certs" else="${ice.top.dir}/../certs">
diff --git a/java/demo/Freeze/bench/Client.java b/java/demo/Freeze/bench/Client.java
index 946dae1c76d..8a795cb63ee 100644
--- a/java/demo/Freeze/bench/Client.java
+++ b/java/demo/Freeze/bench/Client.java
@@ -12,7 +12,7 @@ import Demo.*;
class Client extends Ice.Application
{
void
- IntIntMapTest(Freeze.Map m, boolean fast)
+ IntIntMapTest(Freeze.Map<Integer, Integer> m, boolean fast)
{
//
// Populate the database.
@@ -23,14 +23,14 @@ class Client extends Ice.Application
{
for(int i = 0; i < _repetitions; ++i)
{
- m.fastPut(new Integer(i), new Integer(i));
+ m.fastPut(i, i);
}
}
else
{
for(int i = 0; i < _repetitions; ++i)
{
- m.put(new Integer(i), new Integer(i));
+ m.put(i, i);
}
}
tx.commit();
@@ -47,7 +47,7 @@ class Client extends Ice.Application
_watch.start();
for(int i = 0; i < _repetitions; ++i)
{
- Integer n = (Integer)m.get(new Integer(i));
+ Integer n = m.get(i);
test(n.intValue() == i);
}
total = _watch.stop();
@@ -65,20 +65,19 @@ class Client extends Ice.Application
_watch.start();
for(int i = 0; i < _repetitions; ++i)
{
- java.util.Iterator p = indexedM.findByValue(i);
+ java.util.Iterator<java.util.Map.Entry<Integer, Integer>> p = indexedM.findByValue(i);
test(p.hasNext());
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
- test(((Integer)e.getKey()).intValue() == i);
+ java.util.Map.Entry<Integer, Integer> e = p.next();
+ test(e.getKey().intValue() == i);
m.closeAllIterators();
}
total = _watch.stop();
perRecord = total / _repetitions;
-
+
System.out.println("\ttime for " + _repetitions + " indexed reads: " + total + "ms");
System.out.println("\ttime per indexed read: " + perRecord + "ms");
}
-
//
// Remove each record.
//
@@ -88,14 +87,14 @@ class Client extends Ice.Application
{
for(int i = 0; i < _repetitions; ++i)
{
- test(m.fastRemove(new Integer(i)));
+ test(m.fastRemove(i));
}
}
else
{
for(int i = 0; i < _repetitions; ++i)
{
- Integer n = (Integer)m.remove(new Integer(i));
+ Integer n = m.remove(i);
test(n.intValue() == i);
}
}
@@ -163,7 +162,7 @@ class Client extends Ice.Application
public String
toString()
{
- return new Integer((_max - _min)+1).toString();
+ return new Integer((_max - _min) + 1).toString();
}
private int _min;
@@ -172,20 +171,19 @@ class Client extends Ice.Application
}
void
- generatedRead(Freeze.Map m, int reads, Generator gen)
+ generatedRead(Freeze.Map<Integer, Integer> m, int reads, Generator gen)
{
_watch.start();
for(int i = 0; i < reads; ++i)
{
int key = gen.next();
- Integer n = (Integer)m.get(new Integer(key));
+ Integer n = m.get(key);
test(n.intValue() == key);
}
double total = _watch.stop();
double perRecord = total / reads;
- System.out.println("\ttime for " + reads + " reads of " + gen + " records: " +
- total + "ms");
+ System.out.println("\ttime for " + reads + " reads of " + gen + " records: " + total + "ms");
System.out.println("\ttime per read: " + perRecord + "ms");
if(m instanceof IndexedIntIntMap)
@@ -195,23 +193,23 @@ class Client extends Ice.Application
for(int i = 0; i < reads; ++i)
{
int val = gen.next();
- java.util.Iterator p = indexedM.findByValue(val);
+ java.util.Iterator<java.util.Map.Entry<Integer, Integer>> p = indexedM.findByValue(val);
test(p.hasNext());
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
- test(((Integer)e.getKey()).intValue() == val);
+ java.util.Map.Entry<Integer, Integer> e = p.next();
+ test(e.getKey().intValue() == val);
m.closeAllIterators();
}
total = _watch.stop();
perRecord = total / reads;
-
- System.out.println("\ttime for " + reads + " reverse (indexed) reads of " + gen + " records: " +
- total + "ms");
+
+ System.out.println("\ttime for " + reads + " reverse (indexed) reads of " + gen + " records: " + total +
+ "ms");
System.out.println("\ttime per reverse (indexed) read: " + perRecord + "ms");
}
}
void
- IntIntMapReadTest(Freeze.Map m)
+ IntIntMapReadTest(Freeze.Map<Integer, Integer> m)
{
//
// Populate the database.
@@ -220,7 +218,7 @@ class Client extends Ice.Application
Freeze.Transaction tx = _connection.beginTransaction();
for(int i = 0; i < _repetitions; ++i)
{
- m.fastPut(new Integer(i), new Integer(i));
+ m.fastPut(i, i);
}
tx.commit();
double total = _watch.stop();
@@ -252,7 +250,7 @@ class Client extends Ice.Application
_watch.start();
for(int i = 0; i < _repetitions; ++i)
{
- test(m.fastRemove(new Integer(i)));
+ test(m.fastRemove(i));
}
total = _watch.stop();
perRecord = total / _repetitions;
@@ -265,7 +263,7 @@ class Client extends Ice.Application
}
void
- Struct1Struct2MapTest(Freeze.Map m)
+ Struct1Struct2MapTest(Freeze.Map<Struct1, Struct2> m)
{
//
// Populate the database.
@@ -295,7 +293,7 @@ class Client extends Ice.Application
for(int i = 0; i < _repetitions; ++i)
{
s1.l = i;
- Struct2 ns2 = (Struct2)m.get(s1);
+ Struct2 ns2 = m.get(s1);
test(ns2.s.equals(new Integer(i).toString()));
}
total = _watch.stop();
@@ -304,7 +302,6 @@ class Client extends Ice.Application
System.out.println("\ttime for " + _repetitions + " reads: " + total + "ms");
System.out.println("\ttime per read: " + perRecord + "ms");
-
//
// Optional index test
//
@@ -316,20 +313,20 @@ class Client extends Ice.Application
for(int i = 0; i < _repetitions; ++i)
{
String s = (new Integer(i)).toString();
- java.util.Iterator p = indexedM.findByS(s);
+ java.util.Iterator<java.util.Map.Entry<Struct1, Struct2>> p = indexedM.findByS(s);
test(p.hasNext());
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
- test(((Struct1)e.getKey()).l == i);
+ java.util.Map.Entry<Struct1, Struct2> e = p.next();
+ test(e.getKey().l == i);
m.closeAllIterators();
}
for(int i = 0; i < _repetitions; ++i)
{
s1.l = i;
- java.util.Iterator p = indexedM.findByS1(s1);
+ java.util.Iterator<java.util.Map.Entry<Struct1, Struct2>> p = indexedM.findByS1(s1);
test(p.hasNext());
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
- test(((Struct1)e.getKey()).l == i);
+ java.util.Map.Entry<Struct1, Struct2> e = p.next();
+ test(e.getKey().l == i);
m.closeAllIterators();
}
total = _watch.stop();
@@ -360,7 +357,7 @@ class Client extends Ice.Application
}
void
- Struct1Class1MapTest(Freeze.Map m)
+ Struct1Class1MapTest(Freeze.Map<Struct1, Class1> m)
{
//
// Populate the database.
@@ -389,7 +386,7 @@ class Client extends Ice.Application
for(int i = 0; i < _repetitions; ++i)
{
s1.l = i;
- Class1 nc1 = (Class1)m.get(s1);
+ Class1 nc1 = m.get(s1);
test(nc1.s.equals(new Integer(i).toString()));
}
total = _watch.stop();
@@ -398,7 +395,6 @@ class Client extends Ice.Application
System.out.println("\ttime for " + _repetitions + " reads: " + total + "ms");
System.out.println("\ttime per read: " + perRecord + "ms");
-
//
// Optional index test
//
@@ -410,10 +406,10 @@ class Client extends Ice.Application
for(int i = 0; i < _repetitions; ++i)
{
String s = (new Integer(i)).toString();
- java.util.Iterator p = indexedM.findByS(s);
+ java.util.Iterator<java.util.Map.Entry<Struct1, Class1>> p = indexedM.findByS(s);
test(p.hasNext());
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
- test(((Struct1)e.getKey()).l == i);
+ java.util.Map.Entry<Struct1, Class1> e = p.next();
+ test(e.getKey().l == i);
m.closeAllIterators();
}
@@ -445,7 +441,7 @@ class Client extends Ice.Application
}
void
- Struct1ObjectMapTest(Freeze.Map m)
+ Struct1ObjectMapTest(Freeze.Map<Struct1, Ice.Object> m)
{
//
// Populate the database.
@@ -460,7 +456,7 @@ class Client extends Ice.Application
for(int i = 0; i < _repetitions; ++i)
{
s1.l = i;
- Object o;
+ Ice.Object o;
if((i % 2) == 0)
{
o = c2;
@@ -489,7 +485,7 @@ class Client extends Ice.Application
{
s1.l = i;
- Object o = m.get(s1);
+ Ice.Object o = m.get(s1);
Class1 nc1;
if((i % 2) == 0)
@@ -530,7 +526,7 @@ class Client extends Ice.Application
m.close();
}
-
+
public int
run(String[] args)
{
@@ -559,7 +555,7 @@ class Client extends Ice.Application
System.out.println("Struct1Struct2Map with index");
Struct1Struct2MapTest(new IndexedStruct1Struct2Map(_connection, "IndexedStruct1Struct2", true));
-
+
System.out.println("Struct1Class1Map");
Struct1Class1MapTest(new Struct1Class1Map(_connection, "Struct1Class1", true));
diff --git a/java/demo/Freeze/bench/build.xml b/java/demo/Freeze/bench/build.xml
index 3b81ad1637b..1bbdc29419a 100644
--- a/java/demo/Freeze/bench/build.xml
+++ b/java/demo/Freeze/bench/build.xml
@@ -56,7 +56,7 @@
<exclude name="${generated.dir}/**"/>
<classpath>
<path refid="ice.classpath"/>
- <path refid="db.classpath"/>
+ <path refid="freeze.classpath"/>
</classpath>
<compilerarg value="${javac.lint}"/>
</javac>
diff --git a/java/demo/Freeze/casino/build.xml b/java/demo/Freeze/casino/build.xml
index 99e67437810..72f8f9dc214 100644
--- a/java/demo/Freeze/casino/build.xml
+++ b/java/demo/Freeze/casino/build.xml
@@ -35,7 +35,7 @@
<exclude name="${generated.dir}/**"/>
<classpath>
<path refid="ice.classpath"/>
- <path refid="db.classpath"/>
+ <path refid="freeze.classpath"/>
</classpath>
<compilerarg value="${javac.lint}"/>
</javac>
diff --git a/java/demo/Freeze/library/Grammar.java b/java/demo/Freeze/library/Grammar.java
index c261cc0921e..1541c3b3b36 100644
--- a/java/demo/Freeze/library/Grammar.java
+++ b/java/demo/Freeze/library/Grammar.java
@@ -53,7 +53,7 @@ class Grammar
}
else if(_token.type == Token.TOK_ADD_BOOK)
{
- java.util.List s = strings();
+ java.util.List<String> s = strings();
if(_token.type != Token.TOK_SEMI)
{
throw new ParseError("Expected ';'");
@@ -62,7 +62,7 @@ class Grammar
}
else if(_token.type == Token.TOK_FIND_ISBN)
{
- java.util.List s = strings();
+ java.util.List<String> s = strings();
if(_token.type != Token.TOK_SEMI)
{
throw new ParseError("Expected ';'");
@@ -71,7 +71,7 @@ class Grammar
}
else if(_token.type == Token.TOK_FIND_AUTHORS)
{
- java.util.List s = strings();
+ java.util.List<String> s = strings();
if(_token.type != Token.TOK_SEMI)
{
throw new ParseError("Expected ';'");
@@ -100,7 +100,7 @@ class Grammar
}
else if(_token.type == Token.TOK_RENT_BOOK)
{
- java.util.List s = strings();
+ java.util.List<String> s = strings();
if(_token.type != Token.TOK_SEMI)
{
throw new ParseError("Expected ';'");
@@ -128,7 +128,7 @@ class Grammar
}
else if(_token.type == Token.TOK_SET_EVICTOR_SIZE)
{
- java.util.List s = strings();
+ java.util.List<String> s = strings();
if(_token.type != Token.TOK_SEMI)
{
throw new ParseError("Expected ';'");
@@ -157,10 +157,10 @@ class Grammar
}
}
- private java.util.List
+ private java.util.List<String>
strings()
{
- java.util.List l = new java.util.ArrayList();
+ java.util.List<String> l = new java.util.ArrayList<String>();
while(true)
{
_token = _scanner.nextToken();
diff --git a/java/demo/Freeze/library/LibraryI.java b/java/demo/Freeze/library/LibraryI.java
index ca09c0fb908..9035731ac7f 100644
--- a/java/demo/Freeze/library/LibraryI.java
+++ b/java/demo/Freeze/library/LibraryI.java
@@ -55,7 +55,7 @@ class LibraryI extends _LibraryDisp
//
// Add the isbn number to the authors map.
//
- String[] isbnSeq = (String[])_authors.get(description.authors);
+ String[] isbnSeq = _authors.get(description.authors);
int length = (isbnSeq == null) ? 0 : isbnSeq.length;
String[] newIsbnSeq = new String[length+1];
@@ -111,7 +111,7 @@ class LibraryI extends _LibraryDisp
// Lookup all books that match the given authors, and
// return them to the caller.
//
- String[] isbnSeq = (String[])_authors.get(authors);
+ String[] isbnSeq = _authors.get(authors);
int length = (isbnSeq == null) ? 0 : isbnSeq.length;
BookPrx[] books = new BookPrx[length];
@@ -156,7 +156,7 @@ class LibraryI extends _LibraryDisp
{
try
{
- String[] isbnSeq = (String[])_authors.get(description.authors);
+ String[] isbnSeq = _authors.get(description.authors);
assert isbnSeq != null;
diff --git a/java/demo/Freeze/library/Parser.java b/java/demo/Freeze/library/Parser.java
index 8d2c5256f70..8d11881eb71 100644
--- a/java/demo/Freeze/library/Parser.java
+++ b/java/demo/Freeze/library/Parser.java
@@ -35,21 +35,21 @@ class Parser
}
void
- addBook(java.util.List args)
+ addBook(java.util.List<String> args)
{
if(args.size() != 3)
{
error("`add' requires at exactly three arguments (type `help' for more info)");
return;
}
-
+
try
{
BookDescription desc = new BookDescription();
- desc.isbn = (String)args.get(0);
- desc.title = (String)args.get(1);
- desc.authors = (String)args.get(2);
-
+ desc.isbn = args.get(0);
+ desc.title = args.get(1);
+ desc.authors = args.get(2);
+
BookPrx book = _library.createBook(desc);
System.out.println("added new book with isbn " + desc.isbn);
}
@@ -68,20 +68,20 @@ class Parser
}
void
- findIsbn(java.util.List args)
+ findIsbn(java.util.List<String> args)
{
if(args.size() != 1)
{
error("`isbn' requires exactly one argument (type `help' for more info)");
return;
}
-
+
try
{
_foundBooks = null;
_current = 0;
- BookPrx book = _library.findByIsbn((String)args.get(0));
+ BookPrx book = _library.findByIsbn(args.get(0));
if(book == null)
{
System.out.println("no book with that ISBN number exists.");
@@ -104,17 +104,17 @@ class Parser
}
void
- findAuthors(java.util.List args)
+ findAuthors(java.util.List<String> args)
{
if(args.size() != 1)
{
error("`authors' requires exactly one argument (type `help' for more info)");
return;
}
-
+
try
{
- _foundBooks = _library.findByAuthors((String)args.get(0));
+ _foundBooks = _library.findByAuthors(args.get(0));
_current = 0;
System.out.println("number of books found: " + _foundBooks.length);
printCurrent();
@@ -138,7 +138,7 @@ class Parser
}
printCurrent();
}
-
+
void
printCurrent()
{
@@ -181,7 +181,7 @@ class Parser
}
void
- rentCurrent(java.util.List args)
+ rentCurrent(java.util.List<String> args)
{
if(args.size() != 1)
{
@@ -193,8 +193,8 @@ class Parser
{
if(_foundBooks != null && _current != _foundBooks.length)
{
- _foundBooks[_current].rentBook((String)args.get(0));
- System.out.println("the book is now rented by `" + (String)args.get(0) + "'");
+ _foundBooks[_current].rentBook(args.get(0));
+ System.out.println("the book is now rented by `" + args.get(0) + "'");
}
else
{
@@ -274,7 +274,7 @@ class Parser
}
void
- setEvictorSize(java.util.List args)
+ setEvictorSize(java.util.List<String> args)
{
if(args.size() != 1)
{
@@ -282,7 +282,7 @@ class Parser
return;
}
- String s = (String)args.get(0);
+ String s = args.get(0);
try
{
_library.setEvictorSize(Integer.parseInt(s));
diff --git a/java/demo/Freeze/library/build.xml b/java/demo/Freeze/library/build.xml
index dc8d213a27f..7e67186a72d 100644
--- a/java/demo/Freeze/library/build.xml
+++ b/java/demo/Freeze/library/build.xml
@@ -44,7 +44,7 @@
<exclude name="${generated.dir}/**"/>
<classpath>
<path refid="ice.classpath"/>
- <path refid="db.classpath"/>
+ <path refid="freeze.classpath"/>
</classpath>
<compilerarg value="${javac.lint}"/>
</javac>
diff --git a/java/demo/Freeze/phonebook/Grammar.java b/java/demo/Freeze/phonebook/Grammar.java
index 803966e4977..26ba2198ad2 100644
--- a/java/demo/Freeze/phonebook/Grammar.java
+++ b/java/demo/Freeze/phonebook/Grammar.java
@@ -53,7 +53,7 @@ class Grammar
}
else if(_token.type == Token.TOK_ADD_CONTACTS)
{
- java.util.List s = strings();
+ java.util.List<String> s = strings();
if(_token.type != Token.TOK_SEMI)
{
throw new ParseError("Expected ';'");
@@ -62,7 +62,7 @@ class Grammar
}
else if(_token.type == Token.TOK_FIND_CONTACTS)
{
- java.util.List s = strings();
+ java.util.List<String> s = strings();
if(_token.type != Token.TOK_SEMI)
{
throw new ParseError("Expected ';'");
@@ -91,7 +91,7 @@ class Grammar
}
else if(_token.type == Token.TOK_SET_CURRENT_NAME)
{
- java.util.List s = strings();
+ java.util.List<String> s = strings();
if(_token.type != Token.TOK_SEMI)
{
throw new ParseError("Expected ';'");
@@ -100,7 +100,7 @@ class Grammar
}
else if(_token.type == Token.TOK_SET_CURRENT_ADDRESS)
{
- java.util.List s = strings();
+ java.util.List<String> s = strings();
if(_token.type != Token.TOK_SEMI)
{
throw new ParseError("Expected ';'");
@@ -109,7 +109,7 @@ class Grammar
}
else if(_token.type == Token.TOK_SET_CURRENT_PHONE)
{
- java.util.List s = strings();
+ java.util.List<String> s = strings();
if(_token.type != Token.TOK_SEMI)
{
throw new ParseError("Expected ';'");
@@ -128,7 +128,7 @@ class Grammar
}
else if(_token.type == Token.TOK_SET_EVICTOR_SIZE)
{
- java.util.List s = strings();
+ java.util.List<String> s = strings();
if(_token.type != Token.TOK_SEMI)
{
throw new ParseError("Expected ';'");
@@ -157,10 +157,10 @@ class Grammar
}
}
- private java.util.List
+ private java.util.List<String>
strings()
{
- java.util.List l = new java.util.ArrayList();
+ java.util.List<String> l = new java.util.ArrayList<String>();
while(true)
{
_token = _scanner.nextToken();
diff --git a/java/demo/Freeze/phonebook/build.xml b/java/demo/Freeze/phonebook/build.xml
index 6af5e9f1b60..88b7a9ef591 100644
--- a/java/demo/Freeze/phonebook/build.xml
+++ b/java/demo/Freeze/phonebook/build.xml
@@ -41,7 +41,7 @@
<exclude name="${generated.dir}/**"/>
<classpath>
<path refid="ice.classpath"/>
- <path refid="db.classpath"/>
+ <path refid="freeze.classpath"/>
</classpath>
<compilerarg value="${javac.lint}"/>
</javac>
diff --git a/java/demo/Freeze/transform/Create.java b/java/demo/Freeze/transform/Create.java
index 231730c52b4..d55f9301c4e 100644
--- a/java/demo/Freeze/transform/Create.java
+++ b/java/demo/Freeze/transform/Create.java
@@ -22,35 +22,32 @@ class Create extends Ice.Application
}
final String[] names = { "don", "ed", "frank", "gary", "arnold", "bob", "carlos" };
- final String[] phoneNumbers = { "(777)777-7777", "(666)666-6666", "(555)555-5555 x123",
+ final String[] phoneNumbers = { "(777)777-7777", "(666)666-6666", "(555)555-5555 x123",
"(444)444-4444", "(333)333-3333 x1234", "(222)222-2222", "(111)111-1111" };
Connection connection = Util.createConnection(communicator(), "db");
- final java.util.Comparator less =
- new java.util.Comparator()
+ final java.util.Comparator<String> less = new java.util.Comparator<String>()
{
- public int compare(Object o1, Object o2)
+ public int compare(String s1, String s2)
{
- if(o1 == o2)
+ if(s1 == s2)
{
return 0;
}
- else if(o1 == null)
+ else if(s1 == null)
{
- return -((Comparable)o2).compareTo(o1);
+ return -s2.compareTo(s1);
}
else
{
- return ((Comparable)o1).compareTo(o2);
+ return s1.compareTo(s2);
}
}
};
- java.util.Map indexComparators = new java.util.HashMap();
- indexComparators.put("phoneNumber", less);
+ Contacts.IndexComparators indexComparators = new Contacts.IndexComparators(less);
Contacts contacts = new Contacts(connection, "contacts", true, less, indexComparators);
-
//
// Create a bunch of contacts within one transaction, and commit it
@@ -73,7 +70,7 @@ class Create extends Ice.Application
}
System.out.println(names.length + " contacts were successfully created or updated");
-
+
return 0;
}
diff --git a/java/demo/Freeze/transform/Read.java b/java/demo/Freeze/transform/Read.java
index 995cf531409..efab503377d 100644
--- a/java/demo/Freeze/transform/Read.java
+++ b/java/demo/Freeze/transform/Read.java
@@ -23,54 +23,44 @@ class Read extends Ice.Application
Connection connection = Util.createConnection(communicator(), "db");
- final java.util.Comparator less =
- new java.util.Comparator()
+ final java.util.Comparator<String> less = new java.util.Comparator<String>()
{
- public int compare(Object o1, Object o2)
+ public int compare(String s1, String s2)
{
- if(o1 == o2)
+ if(s1 == s2)
{
return 0;
}
- else if(o1 == null)
+ else if(s1 == null)
{
- return -((Comparable)o2).compareTo(o1);
+ return -s2.compareTo(s1);
}
else
{
- return ((Comparable)o1).compareTo(o2);
+ return s1.compareTo(s2);
}
}
};
- java.util.Map indexComparators = new java.util.HashMap();
- indexComparators.put("phoneNumber", less);
-
try
{
+ Contacts.IndexComparators indexComparators = new Contacts.IndexComparators(less);
Contacts contacts = new Contacts(connection, "contacts", false, less, indexComparators);
-
+
System.out.println("All contacts (default order)");
- java.util.Iterator p = contacts.entrySet().iterator();
- while(p.hasNext())
+ for(java.util.Map.Entry<String, ContactData> entry : contacts.entrySet())
{
- java.util.Map.Entry entry = (java.util.Map.Entry)p.next();
- System.out.println((String)entry.getKey() + ":\t\t"
- + ((ContactData)entry.getValue()).phoneNumber);
+ System.out.println(entry.getKey() + ":\t\t" + entry.getValue().phoneNumber);
}
-
+
System.out.println("\nAll contacts (ordered by phone number)");
- java.util.SortedMap phoneNumberMap = contacts.mapForIndex("phoneNumber");
- p = phoneNumberMap.values().iterator();
- while(p.hasNext())
+ java.util.SortedMap<String, java.util.Set<java.util.Map.Entry<String, ContactData>>> phoneNumberMap =
+ contacts.mapForPhoneNumber();
+ for(java.util.Set<java.util.Map.Entry<String, ContactData>> entries : phoneNumberMap.values())
{
- java.util.Set entries = (java.util.Set)p.next();
- java.util.Iterator q = entries.iterator();
- while(q.hasNext())
+ for(java.util.Map.Entry<String, ContactData> entry : entries)
{
- java.util.Map.Entry entry = (java.util.Map.Entry)q.next();
- System.out.println((String)entry.getKey() + ":\t\t"
- + ((ContactData)entry.getValue()).phoneNumber);
+ System.out.println(entry.getKey() + ":\t\t" + entry.getValue().phoneNumber);
}
}
}
@@ -78,7 +68,7 @@ class Read extends Ice.Application
{
connection.close();
}
-
+
return 0;
}
diff --git a/java/demo/Freeze/transform/ReadNew.java b/java/demo/Freeze/transform/ReadNew.java
index 96ba48150a5..30add0aa939 100644
--- a/java/demo/Freeze/transform/ReadNew.java
+++ b/java/demo/Freeze/transform/ReadNew.java
@@ -23,60 +23,47 @@ class ReadNew extends Ice.Application
Connection connection = Util.createConnection(communicator(), "dbnew");
- final java.util.Comparator less =
- new java.util.Comparator()
+ final java.util.Comparator<String> less = new java.util.Comparator<String>()
{
- public int compare(Object o1, Object o2)
+ public int compare(String s1, String s2)
{
- if(o1 == o2)
+ if(s1 == s2)
{
return 0;
}
- else if(o1 == null)
+ else if(s1 == null)
{
- return -((Comparable)o2).compareTo(o1);
+ return -s2.compareTo(s1);
}
else
{
- return ((Comparable)o1).compareTo(o2);
+ return s1.compareTo(s2);
}
}
};
- java.util.Map indexComparators = new java.util.HashMap();
- indexComparators.put("phoneNumber", less);
-
try
{
+ NewContacts.IndexComparators indexComparators = new NewContacts.IndexComparators(less);
boolean createDb = true;
NewContacts contacts = new NewContacts(connection, "contacts", createDb, less, indexComparators);
-
+
System.out.println("All contacts (default order)");
- java.util.Iterator p = contacts.entrySet().iterator();
- while(p.hasNext())
+ for(java.util.Map.Entry<String, NewContactData> entry : contacts.entrySet())
{
- java.util.Map.Entry entry = (java.util.Map.Entry)p.next();
- NewContactData data = (NewContactData)entry.getValue();
-
- System.out.println((String)entry.getKey() + ":\t\t"
- + data.phoneNumber + " " + data.emailAddress);
+ NewContactData data = entry.getValue();
+ System.out.println(entry.getKey() + ":\t\t" + data.phoneNumber + " " + data.emailAddress);
}
-
+
System.out.println("\nAll contacts (ordered by phone number)");
- java.util.SortedMap phoneNumberMap = contacts.mapForIndex("phoneNumber");
- p = phoneNumberMap.values().iterator();
- while(p.hasNext())
+ java.util.SortedMap<String, java.util.Set<java.util.Map.Entry<String, NewContactData>>> phoneNumberMap =
+ contacts.mapForPhoneNumber();
+ for(java.util.Set<java.util.Map.Entry<String, NewContactData>> entries : phoneNumberMap.values())
{
- java.util.Set entries = (java.util.Set)p.next();
- java.util.Iterator q = entries.iterator();
- while(q.hasNext())
+ for(java.util.Map.Entry<String, NewContactData> entry : entries)
{
- java.util.Map.Entry entry = (java.util.Map.Entry)q.next();
- NewContactData data = (NewContactData)entry.getValue();
-
- System.out.println((String)entry.getKey() + ":\t\t"
- + data.phoneNumber + " " + data.emailAddress);
-
+ NewContactData data = entry.getValue();
+ System.out.println(entry.getKey() + ":\t\t" + data.phoneNumber + " " + data.emailAddress);
}
}
}
@@ -84,7 +71,7 @@ class ReadNew extends Ice.Application
{
connection.close();
}
-
+
return 0;
}
diff --git a/java/demo/Freeze/transform/Recreate.java b/java/demo/Freeze/transform/Recreate.java
index fe0bece7663..33a0298d8df 100644
--- a/java/demo/Freeze/transform/Recreate.java
+++ b/java/demo/Freeze/transform/Recreate.java
@@ -23,40 +23,37 @@ class Recreate extends Ice.Application
Connection connection = Util.createConnection(communicator(), "dbnew");
- final java.util.Comparator less =
- new java.util.Comparator()
+ final java.util.Comparator<String> less = new java.util.Comparator<String>()
{
- public int compare(Object o1, Object o2)
+ public int compare(String s1, String s2)
{
- if(o1 == o2)
+ if(s1 == s2)
{
return 0;
}
- else if(o1 == null)
+ else if(s1 == null)
{
- return -((Comparable)o2).compareTo(o1);
+ return -s2.compareTo(s1);
}
else
{
- return ((Comparable)o1).compareTo(o2);
+ return s1.compareTo(s2);
}
}
};
- java.util.Map indexComparators = new java.util.HashMap();
- indexComparators.put("phoneNumber", less);
-
try
{
+ NewContacts.IndexComparators indexComparators = new NewContacts.IndexComparators(less);
NewContacts.recreate(connection, "contacts", less, indexComparators);
}
finally
{
connection.close();
}
-
+
System.out.println("Recreated contacts database successfully!");
-
+
return 0;
}
diff --git a/java/demo/Freeze/transform/build.xml b/java/demo/Freeze/transform/build.xml
index b7a3a940420..786ed1ca1ce 100644
--- a/java/demo/Freeze/transform/build.xml
+++ b/java/demo/Freeze/transform/build.xml
@@ -43,7 +43,7 @@
<exclude name="${generated.dir}/**"/>
<classpath>
<path refid="ice.classpath"/>
- <path refid="db.classpath"/>
+ <path refid="freeze.classpath"/>
</classpath>
<compilerarg value="${javac.lint}"/>
</javac>
diff --git a/java/demo/book/freeze_filesystem/build.xml b/java/demo/book/freeze_filesystem/build.xml
index 96671a6a95c..8010bd22527 100644
--- a/java/demo/book/freeze_filesystem/build.xml
+++ b/java/demo/book/freeze_filesystem/build.xml
@@ -35,7 +35,7 @@
<exclude name="${generated.dir}/**"/>
<classpath>
<path refid="ice.classpath"/>
- <path refid="db.classpath"/>
+ <path refid="freeze.classpath"/>
</classpath>
<compilerarg value="${javac.lint}"/>
</javac>
diff --git a/java/src/Freeze/BackgroundSaveEvictorI.java b/java/src/Freeze/BackgroundSaveEvictorI.java
index 11bdbe289e3..d7649788530 100644
--- a/java/src/Freeze/BackgroundSaveEvictorI.java
+++ b/java/src/Freeze/BackgroundSaveEvictorI.java
@@ -20,22 +20,22 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
// Clean object; can become modified or destroyed
//
static final byte clean = 0;
-
+
//
// New object; can become clean, dead or destroyed
//
static final byte created = 1;
-
+
//
// Modified object; can become clean or destroyed
//
static final byte modified = 2;
-
+
//
// Being saved. Can become dead or created
//
static final byte destroyed = 3;
-
+
//
// Exists only in the SaveAsyncEvictor; for example the object was created
// and later destroyed (without a save in between), or it was
@@ -58,7 +58,8 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
assert timeout > 0;
}
- public synchronized void run()
+ public synchronized void
+ run()
{
while(!_done)
{
@@ -91,7 +92,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
if(IceInternal.Time.currentMonotonicTimeMillis() - startTime >= _timeout)
{
_communicator.getLogger().error(_errorPrefix +
- "Fatal error: streaming watch dog thread timed out.");
+ "Fatal error: streaming watch dog thread timed out");
Util.handleFatalError(BackgroundSaveEvictorI.this, _communicator, null);
}
@@ -99,19 +100,22 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
}
- synchronized void activate()
+ synchronized void
+ activate()
{
_active = true;
notify();
}
-
- synchronized void deactivate()
+
+ synchronized void
+ deactivate()
{
_active = false;
notify();
}
- synchronized void terminate()
+ synchronized void
+ terminate()
{
_done = true;
notify();
@@ -122,23 +126,21 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
private boolean _active = false;
}
-
- BackgroundSaveEvictorI(Ice.ObjectAdapter adapter, String envName, String filename,
+ BackgroundSaveEvictorI(Ice.ObjectAdapter adapter, String envName, String filename,
ServantInitializer initializer, Index[] indices, boolean createDb)
{
this(adapter, envName, null, filename, initializer, indices, createDb);
}
-
- BackgroundSaveEvictorI(Ice.ObjectAdapter adapter, String envName, com.sleepycat.db.Environment dbEnv,
+ BackgroundSaveEvictorI(Ice.ObjectAdapter adapter, String envName, com.sleepycat.db.Environment dbEnv,
String filename, ServantInitializer initializer, Index[] indices, boolean createDb)
{
super(adapter, envName, dbEnv, filename, null, initializer, indices, createDb);
- String propertyPrefix = "Freeze.Evictor." + envName + '.' + filename;
-
- //
- // By default, we save every minute or when the size of the modified
+ String propertyPrefix = "Freeze.Evictor." + envName + '.' + filename;
+
+ //
+ // By default, we save every minute or when the size of the modified
// queue reaches 10.
//
@@ -158,12 +160,12 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
_maxTxSize = 100;
}
-
+
//
// Start threads
//
String savingThreadName;
-
+
String programName = _communicator.getProperties().getProperty("Ice.ProgramName");
if(programName.length() > 0)
{
@@ -191,13 +193,12 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
_thread = new Thread(this, savingThreadName);
_thread.start();
}
-
-
+
public Ice.ObjectPrx
addFacet(Ice.Object servant, Ice.Identity ident, String facet)
{
checkIdentity(ident);
-
+
if(facet == null)
{
facet = "";
@@ -211,42 +212,41 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
if(store == null)
{
NotFoundException ex = new NotFoundException();
- ex.message = _errorPrefix + "addFacet: could not open database for facet '"
- + facet + "'";
+ ex.message = _errorPrefix + "addFacet: could not open database for facet '" + facet + "'";
throw ex;
}
boolean alreadyThere = false;
-
+
for(;;)
{
//
// Create a new entry
//
-
+
EvictorElement element = new EvictorElement(ident, store);
element.status = dead;
element.rec = new ObjectRecord();
element.rec.stats = new Statistics();
-
+
Object o = store.cache().putIfAbsent(ident, element);
-
+
if(o != null)
{
element = (EvictorElement)o;
}
-
+
synchronized(this)
- {
+ {
if(element.stale)
{
//
// Try again
- //
+ //
continue;
}
fixEvictPosition(element);
-
+
synchronized(element)
{
switch(element.status)
@@ -257,12 +257,12 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
alreadyThere = true;
break;
- }
+ }
case destroyed:
{
element.status = modified;
element.rec.servant = servant;
-
+
//
// No need to push it on the modified queue, as a destroyed object
// is either already on the queue or about to be saved. When saved,
@@ -274,12 +274,12 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
element.status = created;
ObjectRecord rec = element.rec;
-
+
rec.servant = servant;
rec.stats.creationTime = IceInternal.Time.currentMonotonicTimeMillis();
rec.stats.lastSaveTime = 0;
rec.stats.avgSaveTime = 0;
-
+
addToModifiedQueue(element);
break;
}
@@ -293,7 +293,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
break; // for(;;)
}
-
+
if(alreadyThere)
{
Ice.AlreadyRegisteredException ex = new Ice.AlreadyRegisteredException();
@@ -305,7 +305,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
throw ex;
}
-
+
if(_trace >= 1)
{
String objString = "object \"" + _communicator.identityToString(ident) + "\"";
@@ -313,11 +313,11 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
objString += " with facet \"" + facet + "\"";
}
-
+
_communicator.getLogger().trace("Freeze.Evictor", "added " + objString + " to Db \"" + _filename +
"\"");
}
-
+
Ice.ObjectPrx obj = _adapter.createProxy(ident);
if(facet.length() > 0)
{
@@ -346,10 +346,10 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
ObjectStore store = findStore(facet, false);
Ice.Object servant = null;
-
+
if(store != null)
{
- for(;;)
+ for(;;)
{
//
// Retrieve object
@@ -363,10 +363,10 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
//
// Try again
- //
+ //
continue;
}
-
+
fixEvictPosition(element);
synchronized(element)
{
@@ -398,7 +398,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
// (at which point it becomes clean)
//
break;
- }
+ }
case destroyed:
case dead:
{
@@ -411,11 +411,11 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
}
}
-
+
if(element.keepCount > 0)
{
assert servant != null;
-
+
element.keepCount = 0;
//
// Add to front of evictor queue
@@ -432,10 +432,10 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
}
}
- break; // for(;;)
+ break; // for(;;)
}
}
-
+
if(servant == null)
{
Ice.NotRegisteredException ex = new Ice.NotRegisteredException();
@@ -447,7 +447,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
throw ex;
}
-
+
if(_trace >= 1)
{
String objString = "object \"" + _communicator.identityToString(ident) + "\"";
@@ -455,7 +455,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
objString += " with facet \"" + facet + "\"";
}
-
+
_communicator.getLogger().trace("Freeze.Evictor", "removed " + objString + " from Db \"" + _filename +
"\"");
}
@@ -466,7 +466,6 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
_deactivateController.unlock();
}
}
-
public void
keep(Ice.Identity ident)
@@ -487,7 +486,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
try
{
boolean notThere = false;
-
+
ObjectStore store = findStore(facet, false);
if(store == null)
{
@@ -503,7 +502,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
notThere = true;
break;
}
-
+
synchronized(this)
{
if(element.stale)
@@ -513,7 +512,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
//
continue;
}
-
+
synchronized(element)
{
if(element.status == destroyed || element.status == dead)
@@ -522,11 +521,11 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
break;
}
}
-
+
//
// Found!
//
-
+
if(element.keepCount == 0)
{
if(element.usageCount < 0)
@@ -553,7 +552,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
}
}
-
+
if(notThere)
{
Ice.NotRegisteredException ex = new Ice.NotRegisteredException();
@@ -597,11 +596,11 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
synchronized(this)
{
- EvictorElement element = (EvictorElement) store.cache().getIfPinned(ident);
+ EvictorElement element = (EvictorElement)store.cache().getIfPinned(ident);
if(element != null)
{
assert !element.stale;
- if(element.keepCount > 0)
+ if(element.keepCount > 0)
{
if(--element.keepCount == 0)
{
@@ -628,7 +627,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
}
}
-
+
Ice.NotRegisteredException ex = new Ice.NotRegisteredException();
ex.kindOfObject = "servant";
ex.id = _communicator.identityToString(ident);
@@ -636,7 +635,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
ex.id += " -f " + IceUtilInternal.StringUtil.escapeString(facet, "");
}
-
+
throw ex;
}
finally
@@ -644,7 +643,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
_deactivateController.unlock();
}
}
-
+
public boolean
hasFacet(Ice.Identity ident, String facet)
{
@@ -659,19 +658,19 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
ObjectStore store = findStore(facet, false);
-
+
if(store == null)
{
return false;
}
synchronized(this)
- {
+ {
EvictorElement element = (EvictorElement)store.cache().getIfPinned(ident);
if(element != null)
{
- assert !element.stale;
-
+ assert !element.stale;
+
synchronized(element)
{
return element.status != dead && element.status != destroyed;
@@ -686,7 +685,6 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
}
-
protected boolean
hasAnotherFacet(Ice.Identity ident, String facet)
{
@@ -694,36 +692,33 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
try
{
//
- // If the object exists in another store, throw FacetNotExistException
+ // If the object exists in another store, throw FacetNotExistException
// instead of returning null (== ObjectNotExistException)
- //
- java.util.Map storeMapCopy;
+ //
+ java.util.Map<String, ObjectStore> storeMapCopy;
synchronized(this)
{
- storeMapCopy = new java.util.HashMap(_storeMap);
- }
-
- java.util.Iterator p = storeMapCopy.entrySet().iterator();
- while(p.hasNext())
+ storeMapCopy = new java.util.HashMap<String, ObjectStore>(_storeMap);
+ }
+
+ for(java.util.Map.Entry<String, ObjectStore> entry : storeMapCopy.entrySet())
{
- java.util.Map.Entry entry = (java.util.Map.Entry) p.next();
-
//
// Do not check facet
//
if(!facet.equals(entry.getKey()))
{
- ObjectStore store = (ObjectStore)entry.getValue();
+ ObjectStore store = entry.getValue();
boolean inCache = false;
-
+
synchronized(this)
{
EvictorElement element = (EvictorElement)store.cache().getIfPinned(ident);
if(element != null)
{
inCache = true;
- assert !element.stale;
-
+ assert !element.stale;
+
synchronized(element)
{
if(element.status != dead && element.status != destroyed)
@@ -740,7 +735,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
return true;
}
}
- }
+ }
}
return false;
}
@@ -750,22 +745,20 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
}
-
- protected Object
+ protected Object
createEvictorElement(Ice.Identity ident, ObjectRecord rec, ObjectStore store)
{
EvictorElement elt = new EvictorElement(ident, store);
elt.rec = rec;
return elt;
}
-
+
protected Ice.Object
locateImpl(Ice.Current current, Ice.LocalObjectHolder cookie)
{
_deactivateController.lock();
try
{
-
cookie.value = null;
ObjectStore store = findStore(current.facet, false);
@@ -794,7 +787,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
synchronized(this)
- {
+ {
if(element.stale)
{
//
@@ -805,8 +798,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
synchronized(element)
{
- if(element.status == destroyed ||
- element.status == dead)
+ if(element.status == destroyed || element.status == dead)
{
if(_trace >= 2)
{
@@ -836,7 +828,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
return element.rec.servant;
}
}
- }
+ }
}
finally
{
@@ -853,9 +845,9 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
if(cookie != null)
{
EvictorElement element = (EvictorElement)cookie;
-
+
boolean enqueue = false;
-
+
if((servant.ice_operationAttributes(current.operation) & 0x1) != 0)
{
synchronized(element)
@@ -864,27 +856,27 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
//
// Assume this operation updated the object
- //
+ //
element.status = modified;
enqueue = true;
}
}
}
-
+
synchronized(this)
{
//
- // Only elements with a usageCount == 0 can become stale and we own
+ // Only elements with a usageCount == 0 can become stale and we own
// one count!
- //
+ //
assert !element.stale;
assert element.usageCount >= 1;
-
+
//
// Decrease the usage count of the evictor queue element.
//
element.usageCount--;
-
+
if(enqueue)
{
addToModifiedQueue(element);
@@ -904,7 +896,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
_deactivateController.unlock();
}
}
-
+
public void
deactivate(String category)
{
@@ -922,11 +914,11 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
//
_evictorSize = 0;
evict();
-
+
_savingThreadDone = true;
notifyAll();
}
-
+
try
{
_thread.join();
@@ -934,20 +926,20 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
catch(InterruptedException ex)
{
}
-
+
if(_watchDogThread != null)
{
_watchDogThread.terminate();
-
+
try
{
_watchDogThread.join();
}
catch(InterruptedException ex)
{
- }
+ }
}
-
+
closeDbEnv();
}
finally
@@ -956,7 +948,6 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
}
}
-
public void
run()
@@ -965,11 +956,11 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
for(;;)
{
- java.util.List allObjects;
- java.util.List deadObjects = new java.util.LinkedList();
+ java.util.List<EvictorElement> allObjects;
+ java.util.List<EvictorElement> deadObjects = new java.util.LinkedList<EvictorElement>();
int saveNowThreadsSize = 0;
-
+
synchronized(this)
{
while(!_savingThreadDone &&
@@ -996,16 +987,16 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
}
}
-
+
saveNowThreadsSize = _saveNowThreads.size();
-
+
if(_savingThreadDone)
{
assert(_modifiedQueue.size() == 0);
assert(saveNowThreadsSize == 0);
break; // for(;;)
}
-
+
//
// Check first if there is something to do!
//
@@ -1018,35 +1009,35 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
continue; // for(;;)
}
-
+
allObjects = _modifiedQueue;
- _modifiedQueue = new java.util.ArrayList();
+ _modifiedQueue = new java.util.ArrayList<EvictorElement>();
}
-
+
int size = allObjects.size();
-
- java.util.List streamedObjectQueue = new java.util.ArrayList();
-
+
+ java.util.List<StreamedObject> streamedObjectQueue = new java.util.ArrayList<StreamedObject>();
+
long streamStart = IceInternal.Time.currentMonotonicTimeMillis();
-
+
//
// Stream each element
//
for(int i = 0; i < size; i++)
{
- EvictorElement element = (EvictorElement)allObjects.get(i);
-
+ EvictorElement element = allObjects.get(i);
+
boolean tryAgain;
-
+
do
{
tryAgain = false;
Ice.Object servant = null;
-
+
synchronized(element)
{
byte status = element.status;
-
+
switch(status)
{
case created:
@@ -1054,7 +1045,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
servant = element.rec.servant;
break;
- }
+ }
case destroyed:
{
streamedObjectQueue.add(stream(element, streamStart));
@@ -1062,7 +1053,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
element.status = dead;
deadObjects.add(element);
break;
- }
+ }
case dead:
{
deadObjects.add(element);
@@ -1077,7 +1068,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
}
}
-
+
if(servant != null)
{
//
@@ -1098,7 +1089,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
synchronized(element)
{
byte status = element.status;
-
+
switch(status)
{
case created:
@@ -1119,11 +1110,11 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
case destroyed:
{
streamedObjectQueue.add(stream(element, streamStart));
-
+
element.status = dead;
deadObjects.add(element);
break;
- }
+ }
case dead:
{
deadObjects.add(element);
@@ -1142,18 +1133,18 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
} while(tryAgain);
}
-
+
if(_trace >= 1)
{
long now = IceInternal.Time.currentMonotonicTimeMillis();
_communicator.getLogger().trace("Freeze.Evictor", "streamed " + streamedObjectQueue.size() +
" objects in " + (now - streamStart) + " ms");
}
-
+
//
// 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
@@ -1163,20 +1154,20 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
txSize = _maxTxSize;
}
-
+
boolean tryAgain;
-
+
do
{
tryAgain = false;
-
+
while(streamedObjectQueue.size() > 0)
{
if(txSize > streamedObjectQueue.size())
{
txSize = streamedObjectQueue.size();
}
-
+
long saveStart = IceInternal.Time.currentMonotonicTimeMillis();
String txnId = null;
@@ -1186,20 +1177,20 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
if(_txTrace >= 1)
{
- txnId = Long.toHexString((tx.getId() & 0x7FFFFFFF) + 0x80000000L);
+ txnId = Long.toHexString((tx.getId() & 0x7FFFFFFF) + 0x80000000L);
_communicator.getLogger().trace("Freeze.Evictor", _errorPrefix +
"started transaction " + txnId + " in saving thread");
}
try
- {
+ {
for(int i = 0; i < txSize; i++)
{
- StreamedObject obj = (StreamedObject) streamedObjectQueue.get(i);
+ StreamedObject obj = streamedObjectQueue.get(i);
obj.store.save(obj.key, obj.value, obj.status, tx);
}
-
+
com.sleepycat.db.Transaction toCommit = tx;
tx = null;
toCommit.commit();
@@ -1222,12 +1213,12 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
}
}
-
+
for(int i = 0; i < txSize; i++)
{
streamedObjectQueue.remove(0);
}
-
+
if(_trace >= 1)
{
long now = IceInternal.Time.currentMonotonicTimeMillis();
@@ -1239,10 +1230,11 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
if(_deadlockWarning)
{
- _communicator.getLogger().warning("Deadlock in Freeze.BackgroundSaveEvictorI.run while writing " +
- "into Db \"" + _filename + "\"; retrying...");
+ _communicator.getLogger().warning(
+ "Deadlock in Freeze.BackgroundSaveEvictorI.run while writing " +
+ "into Db \"" + _filename + "\"; retrying...");
}
-
+
tryAgain = true;
txSize = (txSize + 1)/2;
}
@@ -1253,27 +1245,24 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
ex.message = _errorPrefix + "saving: " + dx.getMessage();
throw ex;
}
- }
+ }
} while(tryAgain);
-
+
synchronized(this)
- {
+ {
//
// Release usage count
//
for(int i = 0; i < allObjects.size(); i++)
- {
- EvictorElement element = (EvictorElement) allObjects.get(i);
+ {
+ EvictorElement element = allObjects.get(i);
assert element.usageCount > 0;
element.usageCount--;
}
allObjects.clear();
- java.util.Iterator p = deadObjects.iterator();
- while(p.hasNext())
+ for(EvictorElement element : deadObjects)
{
- EvictorElement element = (EvictorElement) p.next();
-
//
// Can be stale when there are duplicates on the deadObjects list
//
@@ -1323,19 +1312,19 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
{
assert Thread.holdsLock(this);
- java.util.Iterator p = _evictorList.riterator();
+ java.util.Iterator<EvictorElement> p = _evictorList.riterator();
while(p.hasNext() && _currentEvictorSize > _evictorSize)
{
//
// Get the last unused element from the evictor queue.
//
- EvictorElement element = (EvictorElement)p.next();
+ EvictorElement element = p.next();
if(element.usageCount == 0)
{
//
// Fine, servant is not in use (and not in the modifiedQueue)
//
-
+
assert !element.stale;
assert element.keepCount == 0;
assert element.evictPosition != null;
@@ -1351,8 +1340,8 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
_communicator.getLogger().trace("Freeze.Evictor", "evicting " + objString + " from the queue; " +
"number of elements in the queue: " + _currentEvictorSize);
- }
-
+ }
+
//
// Remove last unused element from the evictor queue.
//
@@ -1360,7 +1349,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
element.store.cache().unpin(element.identity);
p.remove();
element.evictPosition = null;
- _currentEvictorSize--;
+ _currentEvictorSize--;
}
}
}
@@ -1374,7 +1363,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
synchronized private void
saveNow()
- {
+ {
Thread myself = Thread.currentThread();
_saveNowThreads.add(myself);
@@ -1392,7 +1381,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
while(_saveNowThreads.contains(myself));
}
- private void
+ private void
fixEvictPosition(EvictorElement element)
{
assert Thread.holdsLock(this);
@@ -1404,7 +1393,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
if(element.usageCount < 0)
{
assert element.evictPosition == null;
-
+
//
// New object
//
@@ -1432,7 +1421,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
assert !element.stale;
assert element.keepCount == 0;
-
+
element.evictPosition.remove();
_currentEvictorSize--;
element.stale = true;
@@ -1446,7 +1435,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
element.usageCount++;
_modifiedQueue.add(element);
-
+
if(_saveSizeTrigger >= 0 && _modifiedQueue.size() >= _saveSizeTrigger)
{
notifyAll();
@@ -1459,13 +1448,13 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
assert Thread.holdsLock(element);
assert element.status != dead;
-
+
StreamedObject obj = new StreamedObject();
obj.status = element.status;
obj.store = element.store;
obj.key = ObjectStore.marshalKey(element.identity, _communicator);
-
+
if(element.status != destroyed)
{
updateStats(element.rec.stats, streamStart);
@@ -1473,7 +1462,7 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
}
return obj;
}
-
+
static private class EvictorElement
{
EvictorElement(Ice.Identity identity, ObjectStore store)
@@ -1481,18 +1470,18 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
this.identity = identity;
this.store = store;
}
-
+
final ObjectStore store;
final Ice.Identity identity;
-
+
//
// Protected by SaveAsyncEvictor
//
- java.util.Iterator evictPosition = null;
+ java.util.Iterator<EvictorElement> evictPosition = null;
int usageCount = -1;
int keepCount = 0;
boolean stale = false;
-
+
//
// Protected by this
//
@@ -1500,7 +1489,6 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
byte status = clean;
}
-
static private class StreamedObject
{
byte[] key = null;
@@ -1508,11 +1496,11 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
byte status = dead;
ObjectStore store = null;
}
-
+
//
// List of EvictorElement with stable iterators
//
- private final Freeze.LinkedList _evictorList = new Freeze.LinkedList();
+ private final Freeze.LinkedList<EvictorElement> _evictorList = new Freeze.LinkedList<EvictorElement>();
private int _currentEvictorSize = 0;
//
@@ -1520,16 +1508,16 @@ class BackgroundSaveEvictorI extends EvictorI implements BackgroundSaveEvictor,
// Each element in the queue "owns" a usage count, to ensure the
// elements containing them remain in the map.
//
- private java.util.List _modifiedQueue = new java.util.ArrayList();
-
- private boolean _savingThreadDone = false;
- private WatchDogThread _watchDogThread = null;
+ private java.util.List<EvictorElement> _modifiedQueue = new java.util.ArrayList<EvictorElement>();
+
+ private boolean _savingThreadDone = false;
+ private WatchDogThread _watchDogThread = null;
//
// Threads that have requested a "saveNow" and are waiting for
// its completion
//
- private final java.util.List _saveNowThreads = new java.util.ArrayList();
+ private final java.util.List<Thread> _saveNowThreads = new java.util.ArrayList<Thread>();
private int _saveSizeTrigger;
private int _maxTxSize;
diff --git a/java/src/Freeze/ConnectionI.java b/java/src/Freeze/ConnectionI.java
index 9b403b345bb..94fd8cfb656 100644
--- a/java/src/Freeze/ConnectionI.java
+++ b/java/src/Freeze/ConnectionI.java
@@ -9,9 +9,8 @@
package Freeze;
-class ConnectionI implements Connection
+public class ConnectionI implements Connection
{
-
public Transaction
beginTransaction()
{
@@ -37,7 +36,7 @@ class ConnectionI implements Connection
{
throw new DatabaseException("Closed connection");
}
-
+
try
{
_dbEnv.getEnv().removeDatabase(dbTxn(), mapName + "." + indexName, null);
@@ -60,42 +59,11 @@ class ConnectionI implements Connection
}
}
-
public void
close()
{
- close(false);
- }
-
- public Ice.Communicator
- getCommunicator()
- {
- return _communicator;
- }
-
- public String
- getName()
- {
- return _envName;
- }
-
- protected void
- finalize()
- {
- close(true);
- }
-
- void
- close(boolean finalizing)
- {
if(_transaction != null)
{
- if(finalizing)
- {
- _communicator.getLogger().warning
- ("Finalizing Connection on DbEnv \"" + _envName + "\" with active transaction");
- }
-
try
{
_transaction.rollback();
@@ -108,16 +76,11 @@ class ConnectionI implements Connection
}
}
-
- synchronized(this)
+ java.util.Iterator<Map> p = _mapList.iterator();
+ while(p.hasNext())
{
- java.util.Iterator p = _mapList.iterator();
- while(p.hasNext())
- {
- ((Map) p.next()).close(finalizing);
- }
+ p.next().close();
}
-
if(_dbEnv != null)
{
@@ -132,17 +95,40 @@ class ConnectionI implements Connection
}
}
+ public Ice.Communicator
+ getCommunicator()
+ {
+ return _communicator;
+ }
+
+ public String
+ getName()
+ {
+ return _envName;
+ }
+
+ protected void
+ finalize()
+ throws Throwable
+ {
+ if(_dbEnv != null)
+ {
+ _logger.warning("leaked Connection for DbEnv \"" + _envName + "\"");
+ }
+ super.finalize();
+ }
+
ConnectionI(SharedDbEnv dbEnv)
{
_dbEnv = dbEnv;
_communicator = dbEnv.getCommunicator();
+ _logger = _communicator.getLogger();
_envName = dbEnv.getEnvName();
_trace = _communicator.getProperties().getPropertyAsInt("Freeze.Trace.Map");
_txTrace = _communicator.getProperties().getPropertyAsInt("Freeze.Trace.Transaction");
-
+
Ice.Properties properties = _communicator.getProperties();
_deadlockWarning = properties.getPropertyAsInt("Freeze.Warn.Deadlocks") > 0;
- _closeInFinalizeWarning = properties.getPropertyAsIntWithDefault("Freeze.Warn.CloseInFinalize", 1) > 0;
}
ConnectionI(Ice.Communicator communicator, String envName, com.sleepycat.db.Environment dbEnv)
@@ -150,31 +136,26 @@ class ConnectionI implements Connection
this(SharedDbEnv.get(communicator, envName, dbEnv));
}
-
- //
- // The synchronization is only needed only during finalization
- //
-
- synchronized void
+ public void
closeAllIterators()
{
- java.util.Iterator p = _mapList.iterator();
+ java.util.Iterator<Map> p = _mapList.iterator();
while(p.hasNext())
{
- ((Map) p.next()).closeAllIterators();
+ p.next().closeAllIterators();
}
}
- synchronized java.util.Iterator
+ public java.util.Iterator
registerMap(Map map)
{
_mapList.addFirst(map);
- java.util.Iterator p = _mapList.iterator();
+ java.util.Iterator<Map> p = _mapList.iterator();
p.next();
return p;
}
- synchronized void
+ public void
unregisterMap(java.util.Iterator p)
{
p.remove();
@@ -186,7 +167,7 @@ class ConnectionI implements Connection
_transaction = null;
}
- com.sleepycat.db.Transaction
+ public com.sleepycat.db.Transaction
dbTxn()
{
if(_transaction == null)
@@ -199,61 +180,55 @@ class ConnectionI implements Connection
}
}
- SharedDbEnv
+ public SharedDbEnv
dbEnv()
{
return _dbEnv;
}
- String
+ public String
envName()
{
return _envName;
}
- Ice.Communicator
+ public Ice.Communicator
communicator()
{
return _communicator;
}
- final int
+ public final int
trace()
{
return _trace;
}
- final int
+ public final int
txTrace()
{
return _txTrace;
}
- final boolean
+ public final boolean
deadlockWarning()
{
return _deadlockWarning;
}
- final boolean
- closeInFinalizeWarning()
- {
- return _closeInFinalizeWarning;
- }
-
- private String errorPrefix()
+ private String
+ errorPrefix()
{
return "DbEnv(\"" + _envName + "\"): ";
}
-
private Ice.Communicator _communicator;
+ private Ice.Logger _logger;
private SharedDbEnv _dbEnv;
private String _envName;
private TransactionI _transaction;
- private LinkedList _mapList = new Freeze.LinkedList();
+ private LinkedList<Map> _mapList = new LinkedList<Map>();
private int _trace;
private int _txTrace;
private boolean _deadlockWarning;
- private boolean _closeInFinalizeWarning;
}
diff --git a/java/src/Freeze/EvictorElement.java b/java/src/Freeze/EvictorElement.java
index 67e28c49135..e0c366f78d1 100644
--- a/java/src/Freeze/EvictorElement.java
+++ b/java/src/Freeze/EvictorElement.java
@@ -50,7 +50,7 @@ class EvictorElement
//
// Protected by EvictorI
//
- java.util.Iterator evictPosition = null;
+ java.util.Iterator<EvictorElement> evictPosition = null;
int usageCount = -1;
int keepCount = 0;
boolean stale = false;
diff --git a/java/src/Freeze/EvictorI.java b/java/src/Freeze/EvictorI.java
index c032894a4d0..6be4de9e7db 100644
--- a/java/src/Freeze/EvictorI.java
+++ b/java/src/Freeze/EvictorI.java
@@ -20,13 +20,15 @@ abstract class EvictorI implements Evictor
//
class DeactivateController
{
- synchronized void activate()
+ synchronized void
+ activate()
{
assert !_activated;
_activated = true;
}
- synchronized void lock()
+ synchronized void
+ lock()
{
assert _activated;
@@ -37,7 +39,8 @@ abstract class EvictorI implements Evictor
_guardCount++;
}
- synchronized void unlock()
+ synchronized void
+ unlock()
{
assert _activated;
@@ -51,13 +54,15 @@ abstract class EvictorI implements Evictor
notifyAll();
}
}
-
- synchronized boolean deactivated()
+
+ synchronized boolean
+ deactivated()
{
return !_activated || _deactivated;
}
-
- synchronized boolean deactivate()
+
+ synchronized boolean
+ deactivate()
{
assert _activated;
@@ -65,7 +70,7 @@ abstract class EvictorI implements Evictor
{
return false;
}
-
+
if(_deactivating)
{
//
@@ -91,9 +96,8 @@ abstract class EvictorI implements Evictor
{
if(_trace >= 1)
{
- _communicator.getLogger().trace(
- "Freeze.Evictor", "Waiting for " + _guardCount +
- " threads to complete before starting deactivation.");
+ _communicator.getLogger().trace("Freeze.Evictor", "Waiting for " + _guardCount +
+ " threads to complete before starting deactivation.");
}
try
@@ -114,7 +118,8 @@ abstract class EvictorI implements Evictor
}
}
- synchronized void deactivationComplete()
+ synchronized void
+ deactivationComplete()
{
if(_trace >= 1)
{
@@ -135,7 +140,6 @@ abstract class EvictorI implements Evictor
static final String defaultDb = "$default";
static final String indexPrefix = "$index:";
-
public Ice.ObjectPrx
add(Ice.Object servant, Ice.Identity ident)
{
@@ -161,7 +165,7 @@ abstract class EvictorI implements Evictor
// Special ice_ping() handling
//
if(current.operation != null && current.operation.equals("ice_ping"))
- {
+ {
if(hasFacet(current.id, current.facet))
{
if(_trace >= 3)
@@ -170,6 +174,7 @@ abstract class EvictorI implements Evictor
"Freeze.Evictor", "ice_ping found \"" + _communicator.identityToString(current.id) +
"\" with facet \"" + current.facet + "\"");
}
+
cookie.value = null;
return _pingObject;
}
@@ -181,7 +186,7 @@ abstract class EvictorI implements Evictor
"Freeze.Evictor", "ice_ping raises FacetNotExistException for \"" +
_communicator.identityToString(current.id) + "\" with facet \"" + current.facet + "\"");
}
-
+
throw new Ice.FacetNotExistException();
}
else
@@ -192,13 +197,13 @@ abstract class EvictorI implements Evictor
"Freeze.Evictor", "ice_ping will raise ObjectNotExistException for \"" +
_communicator.identityToString(current.id) + "\" with facet \"" + current.facet + "\"");
}
-
+
return null;
}
}
-
+
Ice.Object result = locateImpl(current, cookie);
-
+
if(result == null)
{
if(hasAnotherFacet(current.id, current.facet))
@@ -222,12 +227,12 @@ abstract class EvictorI implements Evictor
{
return;
}
-
+
//
// Update the evictor size.
//
_evictorSize = evictorSize;
-
+
//
// Evict as many elements as necessary.
//
@@ -238,14 +243,13 @@ abstract class EvictorI implements Evictor
_deactivateController.unlock();
}
}
-
+
synchronized public int
getSize()
- {
+ {
return _evictorSize;
}
-
public EvictorIterator
getIterator(String facet, int batchSize)
{
@@ -268,53 +272,38 @@ abstract class EvictorI implements Evictor
abstract protected boolean hasAnotherFacet(Ice.Identity ident, String facet);
abstract protected Object createEvictorElement(Ice.Identity ident, ObjectRecord rec, ObjectStore store);
-
- abstract protected Ice.Object locateImpl(Ice.Current current, Ice.LocalObjectHolder cookie);
-
- abstract protected void evict();
+ abstract protected Ice.Object locateImpl(Ice.Current current, Ice.LocalObjectHolder cookie);
- synchronized protected void
- finalize()
- {
- if(!_deactivateController.deactivated())
- {
- _communicator.getLogger().warning("Freeze evictor " + toString() + " has not been deactivated");
- deactivate("");
- }
- }
+ abstract protected void evict();
protected void
closeDbEnv()
{
assert _dbEnv != null;
- java.util.Iterator p = _storeMap.values().iterator();
- while(p.hasNext())
+ for(ObjectStore store : _storeMap.values())
{
- ObjectStore store = (ObjectStore)p.next();
store.close();
}
_dbEnv.close();
_dbEnv = null;
}
-
protected synchronized ObjectStore
findStore(String facet, boolean createIt)
{
- ObjectStore os = (ObjectStore)_storeMap.get(facet);
+ ObjectStore os = _storeMap.get(facet);
if(os == null && createIt)
{
- String facetType = (String)_facetTypes.get(facet);
- os = new ObjectStore(facet, facetType, true, this, new java.util.LinkedList(), false);
-
+ String facetType = _facetTypes.get(facet);
+ os = new ObjectStore(facet, facetType, true, this, new java.util.LinkedList<Index>(), false);
_storeMap.put(facet, os);
}
return os;
}
- protected void
+ protected void
initialize(Ice.Identity ident, String facet, Ice.Object servant)
{
if(_initializer != null)
@@ -323,37 +312,39 @@ abstract class EvictorI implements Evictor
}
}
- protected EvictorI(Ice.ObjectAdapter adapter, String envName, com.sleepycat.db.Environment dbEnv, String filename,
- java.util.Map facetTypes, ServantInitializer initializer, Index[] indices, boolean createDb)
+ protected
+ EvictorI(Ice.ObjectAdapter adapter, String envName, com.sleepycat.db.Environment dbEnv, String filename,
+ java.util.Map<String, String> facetTypes, ServantInitializer initializer, Index[] indices,
+ boolean createDb)
{
_adapter = adapter;
_communicator = adapter.getCommunicator();
_initializer = initializer;
_filename = filename;
_createDb = createDb;
- _facetTypes = facetTypes == null ? new java.util.HashMap() : new java.util.HashMap(facetTypes);
-
+ _facetTypes = facetTypes == null ? new java.util.HashMap<String, String>() :
+ new java.util.HashMap<String, String>(facetTypes);
+
_dbEnv = SharedDbEnv.get(_communicator, envName, dbEnv);
_trace = _communicator.getProperties().getPropertyAsInt("Freeze.Trace.Evictor");
_txTrace = _communicator.getProperties().getPropertyAsInt("Freeze.Trace.Transaction");
_deadlockWarning = _communicator.getProperties().getPropertyAsInt("Freeze.Warn.Deadlocks") != 0;
-
+
_errorPrefix = "Freeze Evictor DbEnv(\"" + envName + "\") Db(\"" + _filename + "\"): ";
String propertyPrefix = "Freeze.Evictor." + envName + '.' + _filename;
-
+
boolean populateEmptyIndices =
- _communicator.getProperties().getPropertyAsIntWithDefault(propertyPrefix +
- ".PopulateEmptyIndices", 0) != 0;
-
+ _communicator.getProperties().getPropertyAsIntWithDefault(propertyPrefix + ".PopulateEmptyIndices", 0) != 0;
+
//
// Instantiate all Dbs in 2 steps:
// (1) iterate over the indices and create ObjectStore with indices
// (2) open ObjectStores without indices
//
- java.util.List dbs = allDbs();
+ java.util.List<String> dbs = allDbs();
//
// Add default db in case it's not there
//
@@ -364,10 +355,10 @@ abstract class EvictorI implements Evictor
for(int i = 0; i < indices.length; ++i)
{
String facet = indices[i].facet();
-
+
if(_storeMap.get(facet) == null)
{
- java.util.List storeIndices = new java.util.LinkedList();
+ java.util.List<Index> storeIndices = new java.util.LinkedList<Index>();
for(int j = i; j < indices.length; ++j)
{
if(indices[j].facet().equals(facet))
@@ -375,40 +366,38 @@ abstract class EvictorI implements Evictor
storeIndices.add(indices[j]);
}
}
-
- String facetType = (String)_facetTypes.get(facet);
- ObjectStore store = new ObjectStore(facet, facetType,_createDb, this, storeIndices,
+
+ String facetType = _facetTypes.get(facet);
+ ObjectStore store = new ObjectStore(facet, facetType,_createDb, this, storeIndices,
populateEmptyIndices);
_storeMap.put(facet, store);
}
}
}
-
- java.util.Iterator p = dbs.iterator();
- while(p.hasNext())
+
+ for(String facet : dbs)
{
- String facet = (String) p.next();
if(facet.equals(defaultDb))
{
facet = "";
}
-
+
if(_storeMap.get(facet) == null)
{
- String facetType = (String)_facetTypes.get(facet);
+ String facetType = _facetTypes.get(facet);
+
+ ObjectStore store = new ObjectStore(facet, facetType, _createDb, this,
+ new java.util.LinkedList<Index>(), populateEmptyIndices);
- ObjectStore store = new ObjectStore(facet, facetType, _createDb, this, new java.util.LinkedList(),
- populateEmptyIndices);
-
_storeMap.put(facet, store);
}
}
_deactivateController.activate();
}
-
- protected EvictorI(Ice.ObjectAdapter adapter, String envName, String filename, java.util.Map facetTypes,
- ServantInitializer initializer, Index[] indices, boolean createDb)
+ protected
+ EvictorI(Ice.ObjectAdapter adapter, String envName, String filename, java.util.Map<String, String> facetTypes,
+ ServantInitializer initializer, Index[] indices, boolean createDb)
{
this(adapter, envName, null, filename, facetTypes, initializer, indices, createDb);
}
@@ -465,7 +454,7 @@ abstract class EvictorI implements Evictor
deadlockWarning()
{
return _deadlockWarning;
- }
+ }
final int
trace()
@@ -473,11 +462,11 @@ abstract class EvictorI implements Evictor
return _trace;
}
- private java.util.List
+ private java.util.List<String>
allDbs()
{
- java.util.List result = new java.util.LinkedList();
-
+ java.util.List<String> result = new java.util.LinkedList<String>();
+
com.sleepycat.db.Database db = null;
com.sleepycat.db.Cursor dbc = null;
@@ -503,7 +492,7 @@ abstract class EvictorI implements Evictor
// Assumes Berkeley-DB encodes the db names in UTF-8!
//
String dbName = new String(key.getData(), 0, key.getSize(), "UTF8");
-
+
if(!dbName.startsWith(indexPrefix))
{
result.add(dbName);
@@ -576,17 +565,12 @@ abstract class EvictorI implements Evictor
throw e;
}
}
-
-
protected int _evictorSize = 10;
- //
- // Map of string (facet) to ObjectStore
- //
- protected final java.util.Map _storeMap = new java.util.HashMap();
- private final java.util.Map _facetTypes;
-
+ protected final java.util.Map<String, ObjectStore> _storeMap = new java.util.HashMap<String, ObjectStore>();
+ private final java.util.Map<String, String> _facetTypes;
+
protected final Ice.ObjectAdapter _adapter;
protected final Ice.Communicator _communicator;
@@ -601,11 +585,10 @@ abstract class EvictorI implements Evictor
protected int _txTrace = 0;
protected String _errorPrefix;
-
- protected boolean _deadlockWarning;
-
+
+ protected boolean _deadlockWarning;
+
protected DeactivateController _deactivateController = new DeactivateController();
private Ice.Object _pingObject = new PingObject();
-
}
diff --git a/java/src/Freeze/EvictorIteratorI.java b/java/src/Freeze/EvictorIteratorI.java
index 98bacdde010..be011a906c7 100644
--- a/java/src/Freeze/EvictorIteratorI.java
+++ b/java/src/Freeze/EvictorIteratorI.java
@@ -14,7 +14,7 @@ class EvictorIteratorI implements EvictorIterator
public boolean
hasNext()
{
- if(_batchIterator != null && _batchIterator.hasNext())
+ if(_batchIterator != null && _batchIterator.hasNext())
{
return true;
}
@@ -30,69 +30,66 @@ class EvictorIteratorI implements EvictorIterator
{
if(hasNext())
{
- return (Ice.Identity)_batchIterator.next();
+ return _batchIterator.next();
}
else
{
throw new NoSuchElementException();
}
}
-
+
EvictorIteratorI(ObjectStore store, TransactionI tx, int batchSize)
{
_store = store;
_more = (store != null);
_batchSize = batchSize;
_tx = tx;
-
+
assert batchSize > 0;
_key.setReuseBuffer(true);
//
- // dlen is 0, so we should not retrieve any value
- //
+ // dlen is 0, so we should not retrieve any value
+ //
_value.setPartial(true);
}
- private java.util.Iterator
+ private java.util.Iterator<Ice.Identity>
nextBatch()
{
EvictorI.DeactivateController deactivateController = _store.evictor().deactivateController();
deactivateController.lock();
-
+
com.sleepycat.db.Transaction txn = _tx == null ? null : _tx.dbTxn();
-
+
try
{
-
if(!_more)
{
return null;
}
-
- java.util.List evictorElements = null;
-
+
Ice.Communicator communicator = _store.communicator();
-
+
byte[] firstKey = null;
if(_key.getSize() > 0)
{
firstKey = new byte[_key.getSize()];
System.arraycopy(_key.getData(), 0, firstKey, 0, firstKey.length);
}
-
+
for(;;)
{
com.sleepycat.db.Cursor dbc = null;
-
- _batch = new java.util.ArrayList();
-
+
+ _batch = new java.util.ArrayList<Ice.Identity>();
+
try
{
//
// Move to the first record
- //
+ //
boolean range = false;
if(firstKey != null)
{
@@ -102,9 +99,9 @@ class EvictorIteratorI implements EvictorIterator
//
range = true;
}
-
+
dbc = _store.db().openCursor(txn, null);
-
+
boolean done = false;
do
{
@@ -118,11 +115,11 @@ class EvictorIteratorI implements EvictorIterator
status = dbc.getNext(_key, _value, null);
}
_more = (status == com.sleepycat.db.OperationStatus.SUCCESS);
-
+
if(_more)
{
range = false;
-
+
if(_batch.size() < _batchSize)
{
Ice.Identity ident = ObjectStore.unmarshalKey(_key.getData(), communicator);
@@ -138,7 +135,7 @@ class EvictorIteratorI implements EvictorIterator
}
}
while(!done && _more);
-
+
break; // for (;;)
}
catch(com.sleepycat.db.DeadlockException dx)
@@ -146,10 +143,10 @@ class EvictorIteratorI implements EvictorIterator
if(_store.evictor().deadlockWarning())
{
communicator.getLogger().warning("Deadlock in Freeze.EvictorIteratorI.load while " +
- "iterating over Db \"" + _store.evictor().filename() + "/" + _store.dbName() +
- "\"");
+ "iterating over Db \"" + _store.evictor().filename() + "/" +
+ _store.dbName() + "\"");
}
-
+
if(_tx == null)
{
if(firstKey != null)
@@ -162,7 +159,7 @@ class EvictorIteratorI implements EvictorIterator
{
_key.setSize(0);
}
-
+
//
// Retry
//
@@ -209,7 +206,7 @@ class EvictorIteratorI implements EvictorIterator
}
}
}
-
+
if(_batch.size() == 0)
{
return null;
@@ -228,10 +225,10 @@ class EvictorIteratorI implements EvictorIterator
private final ObjectStore _store;
private final TransactionI _tx;
private final int _batchSize;
- private java.util.Iterator _batchIterator;
+ private java.util.Iterator<Ice.Identity> _batchIterator;
private final com.sleepycat.db.DatabaseEntry _key = new com.sleepycat.db.DatabaseEntry();
private final com.sleepycat.db.DatabaseEntry _value = new com.sleepycat.db.DatabaseEntry();
- private java.util.List _batch = null;
+ private java.util.List<Ice.Identity> _batch = null;
private boolean _more = true;
}
diff --git a/java/src/Freeze/Index.java b/java/src/Freeze/Index.java
index 86fb253f3bc..8a98ca8e9d3 100644
--- a/java/src/Freeze/Index.java
+++ b/java/src/Freeze/Index.java
@@ -14,7 +14,7 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
//
// Implementation details
//
-
+
public boolean
createSecondaryKey(com.sleepycat.db.SecondaryDatabase secondary,
com.sleepycat.db.DatabaseEntry key,
@@ -53,15 +53,15 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
return _facet;
}
- protected Index(String name, String facet)
+ protected
+ Index(String name, String facet)
{
_name = name;
_facet = facet;
}
- protected abstract byte[]
- marshalKey(Ice.Object servant);
-
+ protected abstract byte[] marshalKey(Ice.Object servant);
+
protected Ice.Identity[]
untypedFindFirst(byte[] k, int firstN)
{
@@ -70,42 +70,43 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
try
{
com.sleepycat.db.DatabaseEntry key = new com.sleepycat.db.DatabaseEntry(k);
-
+
+ //
// When we have a custom-comparison function, Berkeley DB returns
// the key on-disk (when it finds one). We disable this behavior:
// (ref Oracle SR 5925672.992)
//
key.setPartial(true);
-
+
com.sleepycat.db.DatabaseEntry pkey = new com.sleepycat.db.DatabaseEntry();
com.sleepycat.db.DatabaseEntry value = new com.sleepycat.db.DatabaseEntry();
//
- // dlen is 0, so we should not retrieve any value
- //
+ // dlen is 0, so we should not retrieve any value
+ //
value.setPartial(true);
-
+
Ice.Communicator communicator = _store.communicator();
TransactionI transaction = _store.evictor().beforeQuery();
com.sleepycat.db.Transaction tx = transaction == null ? null : transaction.dbTxn();
- java.util.List identities;
-
+ java.util.List<Ice.Identity> identities;
+
for(;;)
{
com.sleepycat.db.SecondaryCursor dbc = null;
- identities = new java.util.ArrayList();
-
+ identities = new java.util.ArrayList<Ice.Identity>();
+
try
{
//
// Move to the first record
- //
+ //
dbc = _db.openSecondaryCursor(tx, null);
boolean first = true;
-
+
boolean found;
-
+
do
{
com.sleepycat.db.OperationStatus status;
@@ -117,9 +118,9 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
{
status = dbc.getNextDup(key, pkey, value, null);
}
-
+
found = status == com.sleepycat.db.OperationStatus.SUCCESS;
-
+
if(found)
{
Ice.Identity ident = ObjectStore.unmarshalKey(pkey.getData(), communicator);
@@ -128,7 +129,7 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
}
}
while((firstN <= 0 || identities.size() < firstN) && found);
-
+
break; // for(;;)
}
catch(com.sleepycat.db.DeadlockException dx)
@@ -139,7 +140,7 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
"iterating over Db \"" + _store.evictor().filename() +
"/" + _dbName + "\"");
}
-
+
if(tx != null)
{
DeadlockException ex = new DeadlockException(
@@ -147,7 +148,7 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
ex.initCause(dx);
throw ex;
}
-
+
//
// Otherwise retry
//
@@ -186,11 +187,11 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
}
}
}
-
+
if(identities.size() != 0)
{
Ice.Identity[] result = new Ice.Identity[identities.size()];
- return (Ice.Identity[])identities.toArray(result);
+ return identities.toArray(result);
}
else
{
@@ -202,7 +203,7 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
deactivateController.unlock();
}
}
-
+
protected Ice.Identity[]
untypedFind(byte[] key)
{
@@ -216,29 +217,29 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
deactivateController.lock();
try
{
-
com.sleepycat.db.DatabaseEntry key = new com.sleepycat.db.DatabaseEntry(k);
-
+
+ //
// When we have a custom-comparison function, Berkeley DB returns
// the key on-disk (when it finds one). We disable this behavior:
// (ref Oracle SR 5925672.992)
//
key.setPartial(true);
-
+
com.sleepycat.db.DatabaseEntry value = new com.sleepycat.db.DatabaseEntry();
//
- // dlen is 0, so we should not retrieve any value
- //
+ // dlen is 0, so we should not retrieve any value
+ //
value.setPartial(true);
TransactionI transaction = _store.evictor().beforeQuery();
com.sleepycat.db.Transaction tx = transaction == null ? null : transaction.dbTxn();
-
+
for(;;)
{
com.sleepycat.db.Cursor dbc = null;
try
{
- dbc = _db.openCursor(tx, null);
+ dbc = _db.openCursor(tx, null);
if(dbc.getSearchKey(key, value, null) == com.sleepycat.db.OperationStatus.SUCCESS)
{
return dbc.count();
@@ -254,8 +255,7 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
{
_store.communicator().getLogger().warning("Deadlock in Freeze.Index.untypedCount while " +
"iterating over Db \"" +
- _store.evictor().filename() + "/" + _dbName +
- "\"");
+ _store.evictor().filename() + "/" + _dbName + "\"");
}
if(tx != null)
@@ -309,20 +309,20 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
deactivateController.unlock();
}
}
-
+
protected final Ice.Communicator
communicator()
{
return _store.communicator();
}
-
+
void
associate(ObjectStore store, com.sleepycat.db.Transaction txn, boolean createDb, boolean populateIndex)
throws com.sleepycat.db.DatabaseException, java.io.FileNotFoundException
{
assert(txn != null);
_store = store;
-
+
_dbName = EvictorI.indexPrefix + store.dbName() + "." + _name;
com.sleepycat.db.SecondaryConfig config = new com.sleepycat.db.SecondaryConfig();
@@ -334,18 +334,19 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
Ice.Properties properties = store.evictor().communicator().getProperties();
String propPrefix = "Freeze.Evictor." + store.evictor().filename() + ".";
-
+
int btreeMinKey = properties.getPropertyAsInt(propPrefix + _dbName + ".BtreeMinKey");
if(btreeMinKey > 2)
{
if(store.evictor().trace() >= 1)
{
store.evictor().communicator().getLogger().trace(
- "Freeze.Evictor", "Setting \"" + store.evictor().filename() + "." + _dbName + "\"'s btree minkey to " + btreeMinKey);
+ "Freeze.Evictor", "Setting \"" + store.evictor().filename() + "." + _dbName +
+ "\"'s btree minkey to " + btreeMinKey);
}
config.setBtreeMinKey(btreeMinKey);
}
-
+
boolean checksum = properties.getPropertyAsInt(propPrefix + "Checksum") > 0;
if(checksum)
{
@@ -354,7 +355,7 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
//
config.setChecksum(true);
}
-
+
//
// Can't change page size
//
@@ -379,10 +380,10 @@ public abstract class Index implements com.sleepycat.db.SecondaryKeyCreator
ex.message = _store.evictor().errorPrefix() + "Db.close: " + dx.getMessage();
throw ex;
}
- _db = null;
+ _db = null;
}
}
-
+
private final String _name;
private final String _facet;
private String _dbName;
diff --git a/java/src/Freeze/LinkedList.java b/java/src/Freeze/LinkedList.java
index c4457255527..36ef4e8cb50 100644
--- a/java/src/Freeze/LinkedList.java
+++ b/java/src/Freeze/LinkedList.java
@@ -20,7 +20,7 @@ package Freeze;
// retained over structural changes to the list itself (similar to an
// STL list).
//
-public class LinkedList
+public class LinkedList<T>
{
public
LinkedList()
@@ -28,7 +28,7 @@ public class LinkedList
_header.next = _header.previous = _header;
}
- public java.lang.Object
+ public T
getFirst()
{
if(_size == 0)
@@ -39,7 +39,7 @@ public class LinkedList
return _header.next.element;
}
- public java.lang.Object
+ public T
getLast()
{
if(_size == 0)
@@ -51,11 +51,11 @@ public class LinkedList
}
public void
- addFirst(java.lang.Object o)
+ addFirst(T o)
{
addBefore(o, _header.next);
}
-
+
public boolean
isEmpty()
{
@@ -68,19 +68,19 @@ public class LinkedList
return _size;
}
- public java.util.Iterator
+ public java.util.Iterator<T>
iterator()
{
return new ForwardIterator();
}
- public java.util.Iterator
+ public java.util.Iterator<T>
riterator()
{
return new ReverseIterator();
}
- private class ForwardIterator implements java.util.Iterator
+ private class ForwardIterator implements java.util.Iterator<T>
{
public boolean
hasNext()
@@ -88,7 +88,7 @@ public class LinkedList
return _next != null;
}
- public java.lang.Object
+ public T
next()
{
if(_next == null)
@@ -133,11 +133,11 @@ public class LinkedList
_current = null;
}
- private Entry _current;
- private Entry _next;
+ private Entry<T> _current;
+ private Entry<T> _next;
}
- private class ReverseIterator implements java.util.Iterator
+ private class ReverseIterator implements java.util.Iterator<T>
{
public boolean
hasNext()
@@ -145,7 +145,7 @@ public class LinkedList
return _next != null;
}
- public java.lang.Object
+ public T
next()
{
if(_next == null)
@@ -190,17 +190,17 @@ public class LinkedList
_current = null;
}
- private Entry _current;
- private Entry _next;
+ private Entry<T> _current;
+ private Entry<T> _next;
}
- private static class Entry
+ private static class Entry<T>
{
- java.lang.Object element;
- Entry next;
- Entry previous;
+ T element;
+ Entry<T> next;
+ Entry<T> previous;
- Entry(java.lang.Object element, Entry next, Entry previous)
+ Entry(T element, Entry<T> next, Entry<T> previous)
{
this.element = element;
this.next = next;
@@ -208,10 +208,10 @@ public class LinkedList
}
}
- private Entry
- addBefore(java.lang.Object o, Entry e)
+ private Entry<T>
+ addBefore(T o, Entry<T> e)
{
- Entry newEntry = new Entry(o, e, e.previous);
+ Entry<T> newEntry = new Entry<T>(o, e, e.previous);
newEntry.previous.next = newEntry;
newEntry.next.previous = newEntry;
_size++;
@@ -219,7 +219,7 @@ public class LinkedList
}
private void
- remove(Entry e)
+ remove(Entry<T> e)
{
if(e == _header)
{
@@ -231,6 +231,6 @@ public class LinkedList
_size--;
}
- private Entry _header = new Entry(null, null, null);
+ private Entry<T> _header = new Entry<T>(null, null, null);
private int _size = 0;
}
diff --git a/java/src/Freeze/Map.java b/java/src/Freeze/Map.java
index 282a533c6e0..5769b1e2a79 100644
--- a/java/src/Freeze/Map.java
+++ b/java/src/Freeze/Map.java
@@ -9,2490 +9,39 @@
package Freeze;
-public abstract class Map extends java.util.AbstractMap
- implements java.util.SortedMap, KeyCodec
+public interface Map<K, V> extends NavigableMap<K, V>
{
- public abstract byte[] encodeValue(Object o, Ice.Communicator communicator);
- public abstract Object decodeValue(byte[] b, Ice.Communicator communicator);
-
- protected
- Map(Connection connection, String dbName, String key, String value,
- boolean createDb, java.util.Comparator comparator)
- {
- _connection = (ConnectionI)connection;
- _dbName = dbName;
- _comparator = (comparator == null) ? null : new Comparator(comparator);
-
- _errorPrefix = "Freeze DB DbEnv(\"" + _connection.envName() + "\") Db(\"" + dbName + "\"): ";
- _trace = _connection.trace();
-
- init(null, dbName, key, value, createDb, null);
- }
-
- protected
- Map(Connection connection, String dbName, java.util.Comparator comparator)
- {
- _connection = (ConnectionI)connection;
- _dbName = dbName;
- _comparator = (comparator == null) ? null : new Comparator(comparator);
-
- _errorPrefix = "Freeze DB DbEnv(\"" + _connection.envName() + "\") Db(\"" + dbName + "\"): ";
- _trace = _connection.trace();
- }
-
-
- protected static void
- recreate(Map map, String dbName, String key, String value,
- Freeze.Map.Index[] indices, java.util.Map indexComparators)
- {
- ConnectionI connection = map._connection;
- String envName = connection.dbEnv().getEnvName();
-
- if(dbName.equals(Util.catalogName()) || dbName.equals(Util.catalogIndexListName()))
- {
- throw new DatabaseException(errorPrefix(envName, dbName) + "You cannot recreate the \""
- + dbName + "\" database");
- }
-
- if(connection.trace() >= 1)
- {
- connection.communicator().getLogger().trace("Freeze.Map",
- "Recreating \"" + dbName + "\"");
- }
-
- Transaction tx = connection.currentTransaction();
- boolean ownTx = (tx == null);
-
- com.sleepycat.db.DatabaseEntry keyEntry = new com.sleepycat.db.DatabaseEntry();
- com.sleepycat.db.DatabaseEntry valueEntry = new com.sleepycat.db.DatabaseEntry();
-
- com.sleepycat.db.Database oldDb = null;
- MapDb newDb = null;
-
- for(;;)
- {
- try
- {
- if(ownTx)
- {
- tx = null;
- tx = connection.beginTransaction();
- }
-
- com.sleepycat.db.Transaction txn = connection.dbTxn();
-
- if(connection.trace() >= 2)
- {
- connection.communicator().getLogger().trace(
- "Freeze.Map", "Removing all existing indices for \"" + dbName + "\"");
- }
- CatalogIndexList catalogIndexList = new CatalogIndexList(connection, Util.catalogIndexListName(), true);
- String[] oldIndices = (String[])catalogIndexList.remove(dbName);
-
-
- if(oldIndices != null)
- {
- for(int i = 0; i < oldIndices.length; ++i)
- {
- try
- {
- connection.removeMapIndex(dbName, oldIndices[i]);
- }
- catch(IndexNotFoundException e)
- {
- //
- // Ignored
- //
- }
- }
- }
-
- //
- // Rename existing database
- //
- String oldDbName = dbName + ".old-" + java.util.UUID.randomUUID().toString();
-
- if(connection.trace() >= 2)
- {
- connection.communicator().getLogger().trace(
- "Freeze.Map", "Renaming \"" + dbName + "\" to \"" + oldDbName + "\"");
- }
-
- connection.dbEnv().getEnv().renameDatabase(txn, dbName, null, oldDbName);
-
- com.sleepycat.db.DatabaseConfig oldDbConfig = new com.sleepycat.db.DatabaseConfig();
- oldDbConfig.setType(com.sleepycat.db.DatabaseType.BTREE);
-
- oldDb = connection.dbEnv().getEnv().openDatabase(txn, oldDbName, null, oldDbConfig);
-
- newDb = new MapDb(connection, dbName, key, value, map._comparator, indices, indexComparators, true);
- map.init(newDb, indices);
-
-
- if(connection.trace() >= 2)
- {
- connection.communicator().getLogger().trace(
- "Freeze.Map", "Writing contents of \"" + oldDbName + "\" to fresh \"" + dbName + "\"");
- }
-
- //
- // Now simply write all of oldDb into newDb
- //
- com.sleepycat.db.Cursor dbc = null;
- try
- {
- dbc = oldDb.openCursor(txn, null);
-
- while(dbc.getNext(keyEntry, valueEntry, null) == com.sleepycat.db.OperationStatus.SUCCESS)
- {
- newDb.db().put(txn, keyEntry, valueEntry);
- }
- }
- finally
- {
- if(dbc != null)
- {
- dbc.close();
- }
- }
-
- if(connection.trace() >= 2)
- {
- connection.communicator().getLogger().trace(
- "Freeze.Map", "Transfer complete; removing \"" + oldDbName + "\"");
- }
- connection.dbEnv().getEnv().removeDatabase(txn, oldDbName, null);
-
- if(ownTx)
- {
- try
- {
- tx.commit();
- }
- finally
- {
- tx = null;
- }
- }
-
- break; // for (;;)
- }
- catch(com.sleepycat.db.DeadlockException dx)
- {
- if(ownTx)
- {
- if(connection.deadlockWarning())
- {
- connection.communicator().getLogger().warning(
- "Deadlock in Freeze.Map.recreate on Db \""
- + dbName + "\"; retrying ...");
- }
-
- //
- // Ignored, try again
- //
- }
- else
- {
- DeadlockException ex = new DeadlockException(
- errorPrefix(envName, dbName) + "Map.recreate: " + dx.getMessage(), tx);
- ex.initCause(dx);
- throw ex;
- }
- }
- catch(com.sleepycat.db.DatabaseException dx)
- {
- DatabaseException ex = new DatabaseException(errorPrefix(envName, dbName) + "Map.recreate: " + dx.getMessage());
- ex.initCause(dx);
- throw ex;
- }
- catch(java.io.FileNotFoundException fne)
- {
- DatabaseException ex = new DatabaseException(errorPrefix(envName, dbName) + "Map.recreate: " + fne.getMessage());
- ex.initCause(fne);
- throw ex;
- }
- finally
- {
- if(ownTx && tx != null)
- {
- try
- {
- tx.rollback();
- }
- catch(DatabaseException de)
- {
- }
- }
-
- try
- {
- if(newDb != null)
- {
- newDb.close();
- }
-
- if(oldDb != null)
- {
- try
- {
- oldDb.close();
- }
- catch(com.sleepycat.db.DatabaseException dx)
- {
- DatabaseException ex = new DatabaseException(
- errorPrefix(envName, dbName) + "Map.recreate: " + dx.getMessage());
- ex.initCause(dx);
- throw ex;
- }
- }
- }
- finally
- {
- newDb = null;
- oldDb = null;
- }
- }
- }
- }
-
-
- protected void
- init(Freeze.Map.Index[] indices, String dbName,
- String key, String value, boolean createDb, java.util.Map indexComparators)
- {
- init(_connection.dbEnv().getSharedMapDb(dbName, key, value, _comparator, indices, indexComparators, createDb),
- indices);
- }
-
- protected void
- init(MapDb db, Freeze.Map.Index[] indices)
- {
- _db = db;
- _token = _connection.registerMap(this);
-
- if(indices != null)
- {
- for(int i = 0; i < indices.length; ++i)
- {
- _indexMap.put(indices[i].name(), indices[i]);
- }
- }
- }
-
- public void
- close()
- {
- close(false);
- }
-
- public void
- closeDb()
- {
- close(false);
- _connection.dbEnv().removeSharedMapDb(_dbName);
- }
-
- public Connection
- getConnection()
- {
- return _connection;
- }
-
//
- // SortedMap methods
+ // Faster alternative to the standard put() method because it
+ // doesn't read and decode the old value.
//
+ void fastPut(K key, V value);
- public java.util.Comparator
- comparator()
- {
- if(_comparator == null)
- {
- return null;
- }
- else
- {
- //
- // Return's the user's comparator, not the DB comparator.
- //
- return _comparator.comparator();
- }
- }
-
- public Object firstKey()
- {
- return firstKey(null, null);
- }
-
- public Object lastKey()
- {
- return lastKey(null, null);
- }
-
- Object firstKey(Object fromKey, Object toKey)
- {
- byte[] fk = fromKey == null ? null :
- encodeKey(fromKey, _connection.communicator());
-
- byte[] k = getFirstOrLastKey(_db.db(), _db.dbName(), fk, true);
- if(k == null)
- {
- throw new NoSuchElementException();
- }
- else
- {
- Object key = decodeKey(k, _connection.communicator());
- if(toKey != null && comparator().compare(key, toKey) >= 0)
- {
- throw new NoSuchElementException();
- }
- return key;
- }
- }
-
- Object lastKey(Object fromKey, Object toKey)
- {
- byte[] tk = toKey == null ? null :
- encodeKey(toKey, _connection.communicator());
-
- byte[] k = getFirstOrLastKey(_db.db(), _db.dbName(), tk, false);
- if(k == null)
- {
- throw new NoSuchElementException();
- }
- else
- {
- Object key = decodeKey(k, _connection.communicator());
- if(fromKey != null && comparator().compare(fromKey, key) > 0)
- {
- throw new NoSuchElementException();
- }
- return key;
- }
- }
-
- public java.util.SortedMap headMap(Object toKey)
- {
- if(toKey == null)
- {
- throw new NullPointerException();
- }
- if(_comparator == null)
- {
- throw new UnsupportedOperationException();
- }
-
- return new SubMap(this, null, toKey);
- }
-
- public java.util.SortedMap tailMap(Object fromKey)
- {
- if(fromKey == null)
- {
- throw new NullPointerException();
- }
- if(_comparator == null)
- {
- throw new UnsupportedOperationException();
- }
+ void close();
- return new SubMap(this, fromKey, null);
- }
-
- public java.util.SortedMap subMap(Object fromKey, Object toKey)
- {
- if(fromKey == null || toKey == null )
- {
- throw new NullPointerException();
- }
- if(_comparator == null)
- {
- throw new UnsupportedOperationException();
- }
- return new SubMap(this, fromKey, toKey);
- }
-
-
//
- // Additional non-standard xxMapForIndex methods
+ // Close all iterators for this map. Returns the number of
+ // iterators that were closed.
//
- public java.util.SortedMap headMapForIndex(String indexName, Object toKey)
- {
- if(toKey == null)
- {
- throw new NullPointerException();
- }
-
- Map.Index index = _indexMap.get(indexName);
- if(index == null)
- {
- throw new IllegalArgumentException("Can't find index '" + indexName + "'");
- }
- else if(index.comparator() == null)
- {
- throw new IllegalArgumentException("Index '" + indexName + "' has no user-defined comparator");
- }
- return new SubMap(index, null, toKey);
- }
-
- public java.util.SortedMap tailMapForIndex(String indexName, Object fromKey)
- {
- if(fromKey == null)
- {
- throw new NullPointerException();
- }
- Map.Index index = _indexMap.get(indexName);
- if(index == null)
- {
- throw new IllegalArgumentException("Can't find index '" + indexName + "'");
- }
- else if(index.comparator() == null)
- {
- throw new IllegalArgumentException("Index '" + indexName + "' has no user-defined comparator");
- }
- return new SubMap(index, fromKey, null);
- }
-
- public java.util.SortedMap subMapForIndex(String indexName, Object fromKey, Object toKey)
- {
- if(fromKey == null || toKey == null )
- {
- throw new NullPointerException();
- }
- Map.Index index = _indexMap.get(indexName);
- if(index == null)
- {
- throw new IllegalArgumentException("Can't find index '" + indexName + "'");
- }
- else if(index.comparator() == null)
- {
- throw new IllegalArgumentException("Index '" + indexName + "' has no user-defined comparator");
- }
- return new SubMap(index, fromKey, toKey);
- }
-
- public java.util.SortedMap mapForIndex(String indexName)
- {
- Map.Index index = _indexMap.get(indexName);
- if(index == null)
- {
- throw new IllegalArgumentException("Can't find index '" + indexName + "'");
- }
- else if(index.comparator() == null)
- {
- throw new IllegalArgumentException("Index '" + indexName + "' has no user-defined comparator");
- }
- return new SubMap(index, null, null);
- }
-
- //
- // Plain Map methods
- //
- public int
- size()
- {
- if(_db == null)
- {
- DatabaseException ex = new DatabaseException();
- ex.message = _errorPrefix + "\"" + _db.dbName() + "\" has been closed";
- throw ex;
- }
-
- //
- // The number of records cannot be cached and then adjusted by
- // the member functions since the map would no longer work in
- // the presence of transactions - if a record is added (and
- // the size adjusted) and the transaction aborted then the
- // cached map size() would be incorrect.
- //
-
- //
- // TODO: DB_FAST_STAT doesn't seem to do what the
- // documentation says...
- //
- try
- {
- com.sleepycat.db.StatsConfig config = new com.sleepycat.db.StatsConfig();
- //
- // TODO: DB_FAST_STAT doesn't seem to do what the
- // documentation says...
- //
- //config.setFast(true);
- com.sleepycat.db.BtreeStats s = (com.sleepycat.db.BtreeStats)_db.db().getStats(null, config);
- return s.getNumData();
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "Db.stat: " + e.getMessage();
- throw ex;
- }
- }
-
- public boolean
- containsValue(Object value)
- {
- for(;;)
- {
- EntryIterator p = null;
- try
- {
- p = (EntryIterator)entrySet().iterator();
-
- if(value == null)
- {
- while(p.hasNext())
- {
- Entry e = (Entry)p.next();
- if(e.getValue() == null)
- {
- return true;
- }
- }
- }
- else
- {
- while(p.hasNext())
- {
- Entry e = (Entry)p.next();
- if(value.equals(e.getValue()))
- {
- return true;
- }
- }
- }
- return false;
- }
- catch(DeadlockException e)
- {
- if(_connection.dbTxn() != null)
- {
- throw e;
- }
- else
- {
- if(_connection.deadlockWarning())
- {
- _connection.communicator().getLogger().warning("Deadlock in Freeze.Map.containsValue while " +
- "iterating over Db \"" + _db.dbName() +
- "\"; retrying...");
- }
-
- //
- // Try again
- //
- }
- }
- finally
- {
- if(p != null)
- {
- p.close();
- }
- }
- }
- }
-
- public boolean
- containsKey(Object key)
- {
- if(_db == null)
- {
- DatabaseException ex = new DatabaseException();
- ex.message = _errorPrefix + "\"" + _db.dbName() + "\" has been closed";
- throw ex;
- }
-
- byte[] k = encodeKey(key, _connection.communicator());
-
- com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
- com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
- dbValue.setPartial(true);
-
- if(_trace >= 2)
- {
- _connection.communicator().getLogger().trace("Freeze.Map", "checking key in Db \"" + _db.dbName() + "\"");
- }
-
- for(;;)
- {
- try
- {
- return _db.db().get(_connection.dbTxn(), dbKey, dbValue, null)
- == com.sleepycat.db.OperationStatus.SUCCESS;
- }
- catch(com.sleepycat.db.DeadlockException e)
- {
- if(_connection.dbTxn() != null)
- {
- DeadlockException ex = new DeadlockException(
- _errorPrefix + "Db.get: " + e.getMessage(), _connection.currentTransaction());
- ex.initCause(e);
- throw ex;
- }
- else
- {
- if(_connection.deadlockWarning())
- {
- _connection.communicator().getLogger().warning(
- "Deadlock in Freeze.Map.containsKey while " +
- "reading Db \"" + _db.dbName() +
- "\"; retrying...");
- }
- //
- // Try again
- //
- }
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "Db.get: " + e.getMessage();
- throw ex;
- }
- }
- }
-
- public Object
- get(Object key)
- {
- byte[] k = encodeKey(key, _connection.communicator());
- com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
- byte[] v = getImpl(dbKey);
- if(v == null)
- {
- return null;
- }
- else
- {
- return decodeValue(v, _connection.communicator());
- }
- }
-
- public Object
- put(Object key, Object value)
- {
- byte[] k = encodeKey(key, _connection.communicator());
- com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
- byte[] v = getImpl(dbKey);
- Object o = null;
- if(v != null)
- {
- o = decodeValue(v, _connection.communicator());
- }
- putImpl(dbKey, value);
- return o;
- }
-
- public Object
- remove(Object key)
- {
- byte[] k = encodeKey(key, _connection.communicator());
- com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
- byte[] v = getImpl(dbKey);
-
- if(v != null && removeImpl(dbKey))
- {
- return decodeValue(v, _connection.communicator());
- }
- else
- {
- return null;
- }
- }
-
- //
- // Proprietary API calls. These are much faster than the
- // corresponding Java collections API methods since the unwanted
- // reads are avoided.
- //
- public void
- fastPut(Object key, Object value)
- {
- byte[] k = encodeKey(key, _connection.communicator());
- com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
- putImpl(dbKey, value);
- }
+ int closeAllIterators();
//
- // Returns true if the record was removed, false otherwise.
+ // Close this map and destroy the underlying Berkeley DB database.
//
- public boolean
- fastRemove(Object key)
- {
- byte[] k = encodeKey(key, _connection.communicator());
- com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
- return removeImpl(dbKey);
- }
-
- public void
- clear()
- {
- if(_db == null)
- {
- DatabaseException ex = new DatabaseException();
- ex.message = _errorPrefix + "\"" + _db.dbName() + "\" has been closed";
- throw ex;
- }
-
- com.sleepycat.db.Transaction txn = _connection.dbTxn();
-
- for(;;)
- {
- try
- {
- _db.db().truncate(txn, false);
- break;
- }
- catch(com.sleepycat.db.DeadlockException e)
- {
- if(txn != null)
- {
- DeadlockException ex = new DeadlockException(
- _errorPrefix + "Db.truncate: " + e.getMessage(), _connection.currentTransaction());
- ex.initCause(e);
- throw ex;
- }
- else
- {
- if(_connection.deadlockWarning())
- {
- _connection.communicator().getLogger().warning("Deadlock in Freeze.Map.clear on Db \"" +
- _db.dbName() + "\"; retrying...");
- }
-
- //
- // Try again
- //
- }
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "Db.truncate: " + e.getMessage();
- throw ex;
- }
- }
- }
-
- public java.util.Set
- entrySet()
- {
- if(_entrySet == null)
- {
- _entrySet = new java.util.AbstractSet()
- {
- public java.util.Iterator
- iterator()
- {
- return new EntryIteratorImpl(null, null, null, false, false);
- }
-
- public boolean
- contains(Object o)
- {
- if(!(o instanceof Map.Entry))
- {
- return false;
- }
- Map.Entry entry = (Map.Entry)o;
- Object value = entry.getValue();
-
- byte[] v = getImpl(entry.getDbKey());
- return v != null && valEquals(decodeValue(v, _connection.communicator()), value);
- }
-
- public boolean
- remove(Object o)
- {
- if(!(o instanceof Map.Entry))
- {
- return false;
- }
- Map.Entry entry = (Map.Entry)o;
- Object value = entry.getValue();
-
- byte[] v = getImpl(entry.getDbKey());
- if(v != null && valEquals(decodeValue(v, _connection.communicator()), value))
- {
- return removeImpl(entry.getDbKey());
- }
- return false;
- }
-
- public int
- size()
- {
- return Map.this.size();
- }
-
- public void
- clear()
- {
- Map.this.clear();
- }
- };
- }
-
- return _entrySet;
- }
-
- public void
- closeAllIterators()
- {
- closeAllIteratorsExcept(null, false);
- }
-
-
- //
- // Close this map and destroy the underlying Berkeley DB database
- //
- public void destroy()
- {
- if(_db == null)
- {
- throw new DatabaseException(_errorPrefix + "This map is closed");
- }
-
- String dbName = _db.dbName();
-
- if(dbName.equals(Util.catalogName()) || dbName.equals(Util.catalogIndexListName()))
- {
- throw new DatabaseException(_errorPrefix + "You cannot destroy the \"" + dbName + "\" database");
- }
-
- if(_connection.currentTransaction() != null)
- {
- throw new DatabaseException(_errorPrefix + "You cannot destroy a database within an active transaction");
- }
-
- if(_trace >= 1)
- {
- _connection.communicator().getLogger().trace("Freeze.Map", "destroying \"" + dbName + "\"");
- }
-
- closeDb();
-
- for(;;)
- {
- Transaction tx = null;
- try
- {
- tx = _connection.beginTransaction();
- com.sleepycat.db.Transaction txn = _connection.dbTxn();
-
-
- Catalog catalog = new Catalog(_connection, Util.catalogName(), true);
- catalog.remove(dbName);
-
- CatalogIndexList catalogIndexList = new CatalogIndexList(_connection, Util.catalogIndexListName(), true);
- catalogIndexList.remove(dbName);
-
- _connection.dbEnv().getEnv().removeDatabase(txn, dbName, null);
-
- //
- // Remove all indices
- //
- for(String index : _indexMap.keySet())
- {
- _connection.removeMapIndex(dbName, index);
-
- }
-
- tx.commit();
-
- break; // for(;;)
- }
- catch(java.io.FileNotFoundException dx)
- {
- try
- {
- tx.rollback();
- }
- catch(DatabaseException e)
- {
- }
-
- DatabaseException e = new DatabaseException(_errorPrefix + "file not found");
- e.initCause(dx);
- throw e;
- }
- catch(com.sleepycat.db.DeadlockException dx)
- {
- if(_connection.deadlockWarning())
- {
- _connection.communicator().getLogger().warning("Deadlock in Freeze.Map.destroy on Db \"" +
- dbName + "\"; retrying...");
- }
-
- //
- // Ignored, try again
- //
- }
- catch(com.sleepycat.db.DatabaseException dx)
- {
- try
- {
- tx.rollback();
- }
- catch(DatabaseException e)
- {
- }
-
- DatabaseException e = new DatabaseException(_errorPrefix + dx.getMessage());
- e.initCause(dx);
- throw e;
- }
- catch(RuntimeException rx)
- {
- try
- {
- tx.rollback();
- }
- catch(DatabaseException e)
- {
- }
-
- throw rx;
- }
- }
- }
-
-
- void
- closeAllIteratorsExcept(Object except, boolean finalizing)
- {
- synchronized(_iteratorList)
- {
- java.util.Iterator p = _iteratorList.iterator();
-
- while(p.hasNext())
- {
- Object obj = p.next();
- if(obj != except)
- {
- ((EntryIteratorImpl)obj).close(finalizing);
- }
- }
- }
- }
-
- protected void
- finalize()
- {
- close(true);
- }
-
- //
- // The synchronization is only needed when finalizing is true
- //
- void
- close(boolean finalizing)
- {
- synchronized(_connection)
- {
- if(_db != null)
- {
- try
- {
- closeAllIteratorsExcept(null, finalizing);
- }
- finally
- {
- _db = null;
- _connection.unregisterMap(_token);
- _token = null;
- }
- }
- }
- }
-
- EntryIterator
- createIterator(Index index, Object fromKey, Object toKey)
- {
- KeyCodec codec = index == null ? (KeyCodec)this : (KeyCodec)index;
-
- Ice.Communicator communicator = _connection.getCommunicator();
-
- return new EntryIteratorImpl(index,
- fromKey == null ? null : codec.encodeKey(fromKey, communicator),
- toKey == null ? null : codec.encodeKey(toKey, communicator),
- false, true);
- }
-
- ConnectionI connection()
- {
- return _connection;
- }
-
- private static String
- errorPrefix(String envName, String dbName)
- {
- return "Freeze DB DbEnv(\"" + envName + "\") Db(\"" + dbName + "\"): ";
- }
-
- private static boolean
- valEquals(Object o1, Object o2)
- {
- return (o1 == null ? o2 == null : o1.equals(o2));
- }
-
- private byte[]
- getFirstOrLastKey(com.sleepycat.db.Database db, String dbName, byte[] key, boolean first)
- {
- if(db == null)
- {
- DatabaseException ex = new DatabaseException();
- ex.message = _errorPrefix + "\"" + dbName + "\" has been closed";
- throw ex;
- }
-
- if(_trace >= 2)
- {
- _connection.communicator().getLogger().trace("Freeze.Map", "searching Db \"" + dbName + "\"");
- }
-
- com.sleepycat.db.DatabaseEntry dbKey = key == null ?
- new com.sleepycat.db.DatabaseEntry():
- new com.sleepycat.db.DatabaseEntry(key);
-
- com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
- dbValue.setPartial(true); // not interested in value
-
- try
- {
- for(;;)
- {
- com.sleepycat.db.Cursor dbc = null;
- try
- {
- dbc = db.openCursor(_connection.dbTxn(), null);
- com.sleepycat.db.OperationStatus status;
-
- if(key == null)
- {
- status = first ?
- dbc.getFirst(dbKey, dbValue, null) : dbc.getLast(dbKey, dbValue, null);
- }
- else if(first)
- {
- status = dbc.getSearchKeyRange(dbKey, dbValue, null);
- }
- else
- {
- status = dbc.getSearchKeyRange(dbKey, dbValue, null);
-
- if(status == com.sleepycat.db.OperationStatus.SUCCESS)
- {
- //
- // goto the previous pair, which must be < key
- //
- status = dbc.getPrevNoDup(dbKey, dbValue, null);
- }
- else if(status == com.sleepycat.db.OperationStatus.NOTFOUND)
- {
- //
- // All keys < desired toKey, so we pick the largest of
- // all, the last one
- //
- status = dbc.getLast(dbKey, dbValue, null);
- }
- }
-
- if(status == com.sleepycat.db.OperationStatus.SUCCESS)
- {
- return dbKey.getData();
- }
- else
- {
- return null;
- }
- }
- catch(com.sleepycat.db.DeadlockException dx)
- {
- if(_connection.dbTxn() != null)
- {
- DeadlockException ex = new DeadlockException(
- _errorPrefix + "Dbc.getXXX: " + dx.getMessage(), _connection.currentTransaction());
- ex.initCause(dx);
- throw ex;
- }
- else
- {
- if(_connection.deadlockWarning())
- {
- _connection.communicator().getLogger().warning(
- "Deadlock in Freeze.Map while searching \"" + db.getDatabaseName() +
- "\"; retrying...");
- }
-
- //
- // Retry
- //
- }
- }
- finally
- {
- if(dbc != null)
- {
- try
- {
- dbc.close();
- }
- catch(com.sleepycat.db.DeadlockException dx)
- {
- //
- // Ignored
- //
- }
- }
- }
- }
- }
- catch(com.sleepycat.db.DatabaseException dx)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(dx);
- ex.message = _errorPrefix + "Db.openCursor/Dbc.getXXX: " + dx.getMessage();
- throw ex;
- }
- }
-
- private byte[]
- getImpl(com.sleepycat.db.DatabaseEntry dbKey)
- {
- if(_db == null)
- {
- DatabaseException ex = new DatabaseException();
- ex.message = _errorPrefix + "\"" + _db.dbName() + "\" has been closed";
- throw ex;
- }
-
- com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
-
- if(_trace >= 2)
- {
- _connection.communicator().getLogger().trace("Freeze.Map", "reading value from Db \"" + _db.dbName() +
- "\"");
- }
-
- for(;;)
- {
- try
- {
- com.sleepycat.db.OperationStatus rc = _db.db().get(_connection.dbTxn(), dbKey, dbValue, null);
- if(rc == com.sleepycat.db.OperationStatus.SUCCESS)
- {
- return dbValue.getData();
- }
- else
- {
- return null;
- }
- }
- catch(com.sleepycat.db.DeadlockException e)
- {
- if(_connection.dbTxn() != null)
- {
- DeadlockException ex = new DeadlockException(
- _errorPrefix + "Db.get: " + e.getMessage(), _connection.currentTransaction());
- ex.initCause(e);
- throw ex;
- }
- else
- {
- if(_connection.deadlockWarning())
- {
- _connection.communicator().getLogger().warning("Deadlock in Freeze.Map.getImpl while " +
- "reading Db \"" + _db.dbName() +
- "\"; retrying...");
- }
-
- //
- // Try again
- //
- }
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "Db.get: " + e.getMessage();
- throw ex;
- }
- }
- }
-
- private void
- putImpl(com.sleepycat.db.DatabaseEntry dbKey, Object value)
- {
- if(_db == null)
- {
- DatabaseException ex = new DatabaseException();
- ex.message = _errorPrefix + "\"" + _db.dbName() + "\" has been closed";
- throw ex;
- }
-
- byte[] v = encodeValue(value, _connection.communicator());
- com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(v);
-
- if(_trace >= 2)
- {
- _connection.communicator().getLogger().trace("Freeze.Map", "writing value in Db \"" + _db.dbName() + "\"");
- }
-
- com.sleepycat.db.Transaction txn = _connection.dbTxn();
- if(txn == null)
- {
- closeAllIterators();
- }
-
- for(;;)
- {
- try
- {
- _db.db().put(txn, dbKey, dbValue);
- break;
- }
- catch(com.sleepycat.db.DeadlockException e)
- {
- if(txn != null)
- {
- DeadlockException ex = new DeadlockException(
- _errorPrefix + "Db.put: " + e.getMessage(), _connection.currentTransaction());
- ex.initCause(e);
- throw ex;
- }
- else
- {
- if(_connection.deadlockWarning())
- {
- _connection.communicator().getLogger().warning("Deadlock in Freeze.Map.putImpl while " +
- "writing into Db \"" + _db.dbName() +
- "\"; retrying...");
- }
-
- //
- // Try again
- //
- }
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "Db.put: " + e.getMessage();
- throw ex;
- }
- }
- }
-
- private boolean
- removeImpl(com.sleepycat.db.DatabaseEntry dbKey)
- {
- if(_db == null)
- {
- DatabaseException ex = new DatabaseException();
- ex.message = _errorPrefix + "\"" + _db.dbName() + "\" has been closed";
- throw ex;
- }
-
- if(_trace >= 2)
- {
- _connection.communicator().getLogger().trace("Freeze.Map", "deleting value from Db \"" + _db.dbName() +
- "\"");
- }
-
- com.sleepycat.db.Transaction txn = _connection.dbTxn();
- if(txn == null)
- {
- closeAllIterators();
- }
-
- for(;;)
- {
- try
- {
- com.sleepycat.db.OperationStatus rc = _db.db().delete(txn, dbKey);
- return (rc == com.sleepycat.db.OperationStatus.SUCCESS);
- }
- catch(com.sleepycat.db.DeadlockException e)
- {
- if(txn != null)
- {
- DeadlockException ex = new DeadlockException(
- _errorPrefix + "Db.del: " + e.getMessage(), _connection.currentTransaction());
- ex.initCause(e);
- throw ex;
- }
- else
- {
- if(_connection.deadlockWarning())
- {
- _connection.communicator().getLogger().warning("Deadlock in Freeze.Map.removeImpl while " +
- "writing into Db \"" + _db.dbName() +
- "\"; retrying...");
- }
-
- //
- // Try again
- //
- }
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "Db.del: " + e.getMessage();
- throw ex;
- }
- }
- }
-
- private class Comparator implements java.util.Comparator
- {
- Comparator(java.util.Comparator comparator)
- {
- _comparator = comparator;
- }
-
- public java.util.Comparator comparator()
- {
- return _comparator;
- }
-
- public int compare(Object o1, Object o2)
- {
- byte[] d1 = (byte[])o1;
- byte[] d2 = (byte[])o2;
-
- Ice.Communicator communicator = _connection.communicator();
-
- return _comparator.compare(decodeKey(d1, communicator),
- decodeKey(d2, communicator));
- }
-
- //
- // The user-supplied comparator
- //
- private final java.util.Comparator _comparator;
- }
-
- public abstract class Index
- implements com.sleepycat.db.SecondaryKeyCreator, java.util.Comparator, KeyCodec
- {
- //
- // Implementation details
- //
- public boolean
- createSecondaryKey(com.sleepycat.db.SecondaryDatabase secondary,
- com.sleepycat.db.DatabaseEntry key,
- com.sleepycat.db.DatabaseEntry value,
- com.sleepycat.db.DatabaseEntry result)
- throws com.sleepycat.db.DatabaseException
- {
- Ice.Communicator communicator = _connection.getCommunicator();
- byte[] secondaryKey = marshalKey(value.getData());
- assert(secondaryKey != null);
-
- result.setData(secondaryKey);
- result.setSize(secondaryKey.length);
- return true;
- }
-
- com.sleepycat.db.SecondaryDatabase
- db()
- {
- return _db;
- }
-
- String name()
- {
- return _name;
- }
-
- protected Index(String name)
- {
- _name = name;
- }
-
- void
- associate(String dbName, com.sleepycat.db.Database db,
- com.sleepycat.db.Transaction txn, boolean createDb,
- java.util.Comparator comparator)
- throws com.sleepycat.db.DatabaseException, java.io.FileNotFoundException
- {
- _dbName = dbName + "." + _name;
- _comparator = comparator;
-
- assert(txn != null);
- assert(_db == null);
-
- com.sleepycat.db.SecondaryConfig config = new com.sleepycat.db.SecondaryConfig();
- config.setAllowCreate(createDb);
- config.setAllowPopulate(true); // We always populate empty indices
- config.setSortedDuplicates(true);
- config.setType(com.sleepycat.db.DatabaseType.BTREE);
- if(_comparator != null)
- {
- config.setBtreeComparator(this);
- }
- config.setKeyCreator(this);
-
- Ice.Properties properties = _connection.communicator().getProperties();
- String propPrefix = "Freeze.Map." + _dbName + ".";
-
- int btreeMinKey = properties.getPropertyAsInt(propPrefix + "BtreeMinKey");
- if(btreeMinKey > 2)
- {
- if(_trace >= 1)
- {
- _connection.communicator().getLogger().trace(
- "Freeze.Map", "Setting \"" + _dbName + "\"'s btree minkey to " + btreeMinKey);
- }
- config.setBtreeMinKey(btreeMinKey);
- }
-
- boolean checksum = properties.getPropertyAsInt(propPrefix + "Checksum") > 0;
- if(checksum)
- {
- if(_trace >= 1)
- {
- _connection.communicator().getLogger().trace(
- "Freeze.Map", "Turning checksum on for \"" + _dbName + "\"");
- }
-
- config.setChecksum(true);
- }
-
- int pageSize = properties.getPropertyAsInt(propPrefix + "PageSize");
- if(pageSize > 0)
- {
- if(_trace >= 1)
- {
- _connection.communicator().getLogger().trace(
- "Freeze.Map", "Setting \"" + _dbName + "\"'s pagesize to " + pageSize);
- }
- config.setPageSize(pageSize);
- }
-
- _db = _connection.dbEnv().getEnv().openSecondaryDatabase(txn, _dbName, null, db, config);
- }
-
- void init(Index from)
- {
- assert(_name.equals(from._name));
- assert(_db == null);
-
- _dbName = from._dbName;
- _db = from._db;
- _comparator = from._comparator;
- }
-
- java.util.Comparator comparator()
- {
- return _comparator;
- }
-
- Map parent()
- {
- return Map.this;
- }
-
- Object firstKey(Object fromKey, Object toKey)
- {
- byte[] fk = fromKey == null ? null :
- encodeKey(fromKey, _connection.communicator());
-
- byte[] k = getFirstOrLastKey(_db, _dbName, fk, true);
- if(k == null)
- {
- throw new NoSuchElementException();
- }
- else
- {
- Object key = decodeKey(k, _connection.communicator());
- if(toKey != null && _comparator.compare(key, toKey) >= 0)
- {
- throw new NoSuchElementException();
- }
- return key;
- }
- }
-
- Object lastKey(Object fromKey, Object toKey)
- {
- byte[] tk = toKey == null ? null :
- encodeKey(toKey, _connection.communicator());
-
- byte[] k = getFirstOrLastKey(_db, _dbName, tk, false);
- if(k == null)
- {
- throw new NoSuchElementException();
- }
- else
- {
- Object key = decodeKey(k, _connection.communicator());
- if(fromKey != null && _comparator.compare(fromKey, key) > 0)
- {
- throw new NoSuchElementException();
- }
- return key;
- }
- }
-
- void close()
- {
- //
- // close() is called by MapDb only on the "main" index
- // (the one that was associated)
- //
-
- if(_db != null)
- {
- try
- {
- _db.close();
- }
- catch(com.sleepycat.db.DatabaseException dx)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(dx);
- ex.message = _errorPrefix + "Db.close for index \"" + _dbName + "\": " + dx.getMessage();
- throw ex;
- }
- _db = null;
- }
- }
-
- public EntryIterator
- untypedFind(Object key, boolean onlyDups)
- {
- byte[] k = encodeKey(key, _connection.communicator());
- return new EntryIteratorImpl(this, k, null, onlyDups, false);
- }
-
- public int
- untypedCount(Object key)
- {
- byte[] k = encodeKey(key, _connection.communicator());
-
- com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
- com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
-
- //
- // When we have a custom-comparison function, Berkeley DB returns
- // the key on-disk (when it finds one). We disable this behavior:
- // (ref Oracle SR 5925672.992)
- //
- dbKey.setPartial(true);
-
- //
- // dlen is 0, so we should not retrieve any value
- //
- dbValue.setPartial(true);
-
- try
- {
- for(;;)
- {
- com.sleepycat.db.Cursor dbc = null;
- try
- {
- dbc = _db.openCursor(null, null);
- if(dbc.getSearchKey(dbKey, dbValue, null) == com.sleepycat.db.OperationStatus.SUCCESS)
- {
- return dbc.count();
- }
- else
- {
- return 0;
- }
- }
- catch(com.sleepycat.db.DeadlockException dx)
- {
- if(_connection.deadlockWarning())
- {
- _connection.communicator().getLogger().warning(
- "Deadlock in Freeze.Map.Index.untypedCount while iterating over index \"" + _dbName +
- "\"; retrying...");
- }
-
- //
- // Retry
- //
- }
- finally
- {
- if(dbc != null)
- {
- try
- {
- dbc.close();
- }
- catch(com.sleepycat.db.DeadlockException dx)
- {
- //
- // Ignored
- //
- }
- }
- }
- }
- }
- catch(com.sleepycat.db.DatabaseException dx)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(dx);
- ex.message = _errorPrefix + "Db.cursor for index \"" + _dbName + "\": " + dx.getMessage();
- throw ex;
- }
- }
-
- boolean containsKey(Object key)
- {
- byte[] k = encodeKey(key, _connection.communicator());
-
- com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
- com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
- dbValue.setPartial(true);
-
- if(_trace >= 2)
- {
- _connection.communicator().getLogger().trace("Freeze.Map.Index", "checking key in Db \"" + _dbName +
- "\"");
- }
-
- for(;;)
- {
- try
- {
- return _db.get(_connection.dbTxn(), dbKey, dbValue, null)
- == com.sleepycat.db.OperationStatus.SUCCESS;
- }
- catch(com.sleepycat.db.DeadlockException e)
- {
- if(_connection.dbTxn() != null)
- {
- DeadlockException ex = new DeadlockException(
- _errorPrefix + "Db.get: " + e.getMessage(), _connection.currentTransaction());
- ex.initCause(e);
- throw ex;
- }
- else
- {
- if(_connection.deadlockWarning())
- {
- _connection.communicator().getLogger().warning(
- "Deadlock in Freeze.Map.Index.containsKey while " +
- "reading Db \"" + _dbName + "\"; retrying...");
- }
- //
- // Try again
- //
- }
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "Db.get: " + e.getMessage();
- throw ex;
- }
- }
- }
-
- //
- // Extracts the index key from this value
- //
- public abstract Object extractKey(Object value);
-
- protected byte[] marshalKey(byte[] value)
- {
- Object decodedValue = decodeValue(value, _connection.communicator());
- return encodeKey(extractKey(decodedValue), _connection.communicator());
- }
-
- //
- // The user-supplied comparator
- //
- protected java.util.Comparator _comparator;
-
- private String _name;
- private String _dbName;
- private com.sleepycat.db.SecondaryDatabase _db;
- }
+ void destroy();
/**
*
- * The entry iterator allows clients to explicitly close the iterator
+ * The entry iterator allows clients to explicitly close the iterator
* and free resources allocated for the iterator as soon as possible.
*
**/
- public interface EntryIterator extends java.util.Iterator
+ public interface EntryIterator<T> extends java.util.Iterator<T>
{
void close();
void destroy(); // an alias for close
}
- class EntryIteratorImpl implements EntryIterator
- {
- EntryIteratorImpl(Index index, byte[] fromKey, byte[] toKey,
- boolean onlyFromKeyDups, boolean skipDups)
- {
- _index = index;
- _fromKey = fromKey;
- _toKey = toKey;
- _onlyFromKeyDups = onlyFromKeyDups;
- _skipDups = skipDups;
-
- try
- {
- com.sleepycat.db.Transaction txn = _connection.dbTxn();
- if(txn == null)
- {
- //
- // Start transaction
- //
- txn = _connection.dbEnv().getEnv().beginTransaction(null, null);
- _txn = txn;
-
- if(_connection.txTrace() >= 1)
- {
- String txnId = Long.toHexString((_txn.getId() & 0x7FFFFFFF) + 0x80000000L);
-
- _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix +
- "started transaction " + txnId + " for cursor");
- }
- }
-
- //
- // Open cursor with this transaction
- //
- if(index == null)
- {
- _cursor = _db.db().openCursor(txn, null);
- }
- else
- {
- _cursor = index.db().openSecondaryCursor(txn, null);
- }
- }
- catch(com.sleepycat.db.DeadlockException dx)
- {
- dead();
- DeadlockException ex = new DeadlockException(
- _errorPrefix + "EntryIterator constructor: " + dx.getMessage(), _connection.currentTransaction());
- ex.initCause(dx);
- throw ex;
- }
- catch(com.sleepycat.db.DatabaseException dx)
- {
- dead();
- DatabaseException ex = new DatabaseException();
- ex.initCause(dx);
- ex.message = _errorPrefix + "EntryIterator constructor: " + dx.getMessage();
- throw ex;
- }
-
- synchronized(_iteratorList)
- {
- _iteratorList.addFirst(this);
- java.util.Iterator p = _iteratorList.iterator();
- p.next();
- _iteratorListToken = p;
- }
- }
-
- public boolean
- hasNext()
- {
- if(_current == null || _current == _lastReturned)
- {
- com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry();
- com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
- com.sleepycat.db.DatabaseEntry dbIKey = new com.sleepycat.db.DatabaseEntry();
- com.sleepycat.db.OperationStatus status = null;
-
- try
- {
- if(_index != null)
- {
- com.sleepycat.db.SecondaryCursor c = (com.sleepycat.db.SecondaryCursor)_cursor;
- if(_current == null)
- {
- //
- // First key
- //
- if(_fromKey != null)
- {
- dbIKey.setData(_fromKey);
- status = c.getSearchKey(dbIKey, dbKey, dbValue, null);
- }
- else
- {
- status = c.getFirst(dbIKey, dbKey, dbValue, null);
- }
- }
- else
- {
- if(_onlyFromKeyDups)
- {
- status = c.getNextDup(dbIKey, dbKey, dbValue, null);
- }
- else if(_skipDups)
- {
- status = c.getNextNoDup(dbIKey, dbKey, dbValue, null);
- }
- else
- {
- status = c.getNext(dbIKey, dbKey, dbValue, null);
- }
- }
- }
- else
- {
- if(_current == null && _fromKey != null)
- {
- dbKey.setData(_fromKey);
- status = _cursor.getSearchKey(dbKey, dbValue, null);
- }
- else
- {
- status = _cursor.getNext(dbKey, dbValue, null);
- }
- }
- }
- catch(com.sleepycat.db.DeadlockException dx)
- {
- dead();
- DeadlockException ex = new DeadlockException(
- _errorPrefix + "Dbc.get: " + dx.getMessage(), _connection.currentTransaction());
- ex.initCause(dx);
- throw ex;
- }
- catch(com.sleepycat.db.DatabaseException dx)
- {
- dead();
- DatabaseException ex = new DatabaseException();
- ex.initCause(dx);
- ex.message = _errorPrefix + "Dbc.get: " + dx.getMessage();
- throw ex;
- }
-
- if(status == com.sleepycat.db.OperationStatus.SUCCESS)
- {
- //
- // Verify it's < _toKey
- //
- boolean inRange = true;
- if(_toKey != null)
- {
- if(_index != null)
- {
- inRange = _index.compare(dbIKey.getData(), _toKey) < 0;
- }
- else
- {
- inRange = _comparator.compare(dbKey.getData(), _toKey) < 0;
- }
- }
-
- if(inRange)
- {
- _current = new Entry(this, Map.this, _connection.communicator(), dbKey,
- dbValue.getData(), dbIKey.getData());
- return true;
- }
- }
- return false;
- }
- else
- {
- return true;
- }
- }
-
- public Object
- next()
- {
- if(hasNext())
- {
- _lastReturned = _current;
- return _lastReturned;
- }
- else
- {
- throw new java.util.NoSuchElementException();
- }
- }
-
- public void
- remove()
- {
- if(_txn != null)
- {
- closeAllIteratorsExcept(this, false);
- }
-
- //
- // Removes the last object returned by next()
- //
- if(_lastReturned == null)
- {
- throw new IllegalStateException();
- }
-
- if(_lastReturned == _current)
- {
- try
- {
- if(_cursor.delete() == com.sleepycat.db.OperationStatus.KEYEMPTY)
- {
- throw new IllegalStateException();
- }
- }
- catch(com.sleepycat.db.DeadlockException e)
- {
- dead();
- DeadlockException ex = new DeadlockException(_errorPrefix + "Dbc.del: " + e.getMessage(),
- _connection.currentTransaction());
- ex.initCause(e);
- throw ex;
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "Dbc.del: " + e.getMessage();
- throw ex;
- }
- }
- else
- {
- //
- // Duplicate the cursor and move the _lastReturned
- // element to delete it (using the duplicate)
- //
-
- //
- // This works only for non-index iterators
- //
- if(_index != null)
- {
- throw new UnsupportedOperationException();
- }
-
- com.sleepycat.db.Cursor clone = null;
-
- try
- {
- clone = _cursor.dup(true);
-
- //
- // Not interested in data
- //
- com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
- dbValue.setPartial(true);
-
- com.sleepycat.db.OperationStatus rc = clone.getSearchKey(_lastReturned.getDbKey(), dbValue, null);
-
- if(rc == com.sleepycat.db.OperationStatus.NOTFOUND)
- {
- throw new IllegalStateException();
- }
- if(clone.delete() == com.sleepycat.db.OperationStatus.KEYEMPTY)
- {
- throw new IllegalStateException();
- }
- }
- catch(com.sleepycat.db.DeadlockException e)
- {
- dead();
- DeadlockException ex = new DeadlockException(_errorPrefix + "EntryIterator.remove: " + e.getMessage(),
- _connection.currentTransaction());
- ex.initCause(e);
- throw ex;
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "EntryIterator.remove: " + e.getMessage();
- throw ex;
- }
- finally
- {
- if(clone != null)
- {
- closeCursor(clone);
- }
- }
- }
- }
-
- //
- // Extra operations.
- //
- public void
- close()
- {
- close(false);
- }
-
- //
- // The synchronized is needed because this method can be called
- // concurrently by Connection, Map and Map.EntryIterator finalizers.
- //
- synchronized void
- close(boolean finalizing)
- {
- if(finalizing && (_cursor != null || _txn != null) && _connection.closeInFinalizeWarning())
- {
- _connection.communicator().getLogger().warning(
- "finalize() closing a live iterator on Map \"" + _db.dbName() + "\"; the application " +
- "should have closed it earlier by calling Map.EntryIterator.close(), " +
- "Map.closeAllIterators(), Map.close(), Connection.close(), or (if also " +
- "leaking a transaction) Transaction.commit() or Transaction.rollback()");
- }
-
- if(_iteratorListToken != null)
- {
- synchronized(_iteratorList)
- {
- _iteratorListToken.remove();
- _iteratorListToken = null;
- }
- }
-
- if(_cursor != null)
- {
- com.sleepycat.db.Cursor cursor = _cursor;
- _cursor = null;
- closeCursor(cursor);
- }
-
- if(_txn != null)
- {
- String txnId = null;
-
- try
- {
- if(_connection.txTrace() >= 1)
- {
- txnId = Long.toHexString((_txn.getId() & 0x7FFFFFFF) + 0x80000000L);
- }
-
- _txn.commit();
-
- if(_connection.txTrace() >= 1)
- {
- _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix +
- "committed transaction " + txnId);
- }
- }
- catch(com.sleepycat.db.DeadlockException e)
- {
- if(_connection.txTrace() >= 1)
- {
- _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix +
- "failed to commit transaction " + txnId + ": " +
- e.getMessage());
- }
-
- DeadlockException ex = new DeadlockException(
- _errorPrefix + "DbTxn.commit: " + e.getMessage(), _connection.currentTransaction());
- ex.initCause(e);
- throw ex;
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- if(_connection.txTrace() >= 1)
- {
- _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix +
- "failed to commit transaction " + txnId + ": " +
- e.getMessage());
- }
-
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "DbTxn.commit: " + e.getMessage();
- throw ex;
- }
- finally
- {
- _txn = null;
- }
- }
- }
-
- //
- // An alias for close()
- //
- public void
- destroy()
- {
- close();
- }
-
- protected void
- finalize()
- {
- close(true);
- }
-
- void
- setValue(Map.Entry entry, Object value)
- {
- if(_index != null)
- {
- throw new UnsupportedOperationException(
- _errorPrefix + "Cannot set an iterator retrieved through an index");
- }
-
- if(_txn != null)
- {
- closeAllIteratorsExcept(this, false);
- }
-
- //
- // Are we trying to update the current value?
- //
- if(_current == entry)
- {
- //
- // Yes, update it directly
- //
- byte[] v = encodeValue(value, _connection.communicator());
- com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(v);
-
- try
- {
- _cursor.putCurrent(dbValue);
- }
- catch(com.sleepycat.db.DeadlockException e)
- {
- dead();
- DeadlockException ex = new DeadlockException(_errorPrefix + "Dbc.put: " + e.getMessage(),
- _connection.currentTransaction());
- ex.initCause(e);
- throw ex;
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "Dbc.put: " + e.getMessage();
- throw ex;
- }
- }
- else
- {
- //
- // Duplicate the cursor and move the entry
- // element to update it (using the duplicate cursor)
- //
-
- com.sleepycat.db.Cursor clone = null;
-
- try
- {
- clone = _cursor.dup(true);
-
- //
- // Not interested in data
- //
- com.sleepycat.db.DatabaseEntry dummy = new com.sleepycat.db.DatabaseEntry();
- dummy.setPartial(true);
-
- com.sleepycat.db.OperationStatus rc = clone.getSearchKey(entry.getDbKey(), dummy, null);
-
- if(rc == com.sleepycat.db.OperationStatus.NOTFOUND)
- {
- NotFoundException ex = new NotFoundException();
- ex.message = _errorPrefix + "Dbc.get: DB_NOTFOUND";
- throw ex;
- }
-
- byte[] v = encodeValue(value, _connection.communicator());
- com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(v);
- clone.putCurrent(dbValue);
- }
- catch(com.sleepycat.db.DeadlockException e)
- {
- dead();
- DeadlockException ex = new DeadlockException(_errorPrefix + "EntryIterator.setValue: " + e.getMessage(),
- _connection.currentTransaction());
- ex.initCause(e);
- throw ex;
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "EntryIterator.setValue: " + e.getMessage();
- throw ex;
- }
- finally
- {
- if(clone != null)
- {
- closeCursor(clone);
- }
- }
- }
- }
-
- private void
- closeCursor(com.sleepycat.db.Cursor cursor)
- {
- try
- {
- cursor.close();
- }
- catch(com.sleepycat.db.DeadlockException e)
- {
- dead();
- DeadlockException ex = new DeadlockException(
- _errorPrefix + "Dbc.close: " + e.getMessage(), _connection.currentTransaction());
- ex.initCause(e);
- throw ex;
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "Dbc.close: " + e.getMessage();
- throw ex;
- }
- }
-
- private void
- dead()
- {
- if(_cursor != null)
- {
- com.sleepycat.db.Cursor cursor = _cursor;
- _cursor = null;
- closeCursor(cursor);
- }
-
- if(_txn != null)
- {
- String txnId = null;
-
- try
- {
- if(_connection.txTrace() >= 1)
- {
- txnId = Long.toHexString((_txn.getId() & 0x7FFFFFFF) + 0x80000000L);
- }
-
- _txn.abort();
-
- if(_connection.txTrace() >= 1)
- {
- _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix +
- "rolled back transaction " + txnId);
- }
- }
- catch(com.sleepycat.db.DeadlockException e)
- {
- if(_connection.txTrace() >= 1)
- {
- _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix +
- "failed to roll back transaction " + txnId +
- ": " + e.getMessage());
- }
-
- DeadlockException ex = new DeadlockException(
- _errorPrefix + "DbTxn.abort: " + e.getMessage(), _connection.currentTransaction());
- ex.initCause(e);
- throw ex;
- }
- catch(com.sleepycat.db.DatabaseException e)
- {
- if(_connection.txTrace() >= 1)
- {
- _connection.communicator().getLogger().trace("Freeze.Map", _errorPrefix +
- "failed to roll back transaction " +
- txnId + ": " + e.getMessage());
- }
-
- DatabaseException ex = new DatabaseException();
- ex.initCause(e);
- ex.message = _errorPrefix + "DbTxn.abort: " + e.getMessage();
- throw ex;
- }
- finally
- {
- _txn = null;
- }
- }
- }
-
- private com.sleepycat.db.Transaction _txn;
- private com.sleepycat.db.Cursor _cursor;
- private Entry _current;
- private Entry _lastReturned;
- private java.util.Iterator _iteratorListToken;
-
- private final Index _index;
- private final byte[] _fromKey;
- private final byte[] _toKey;
- private final boolean _onlyFromKeyDups;
- private final boolean _skipDups;
- }
-
- static class Entry implements java.util.Map.Entry
- {
- public
- Entry(EntryIteratorImpl iterator, Map map, Ice.Communicator communicator,
- com.sleepycat.db.DatabaseEntry dbKey, byte[] valueBytes, byte[] indexBytes)
- {
- _iterator = iterator;
- _map = map;
- _communicator = communicator;
- _dbKey = dbKey;
- _valueBytes = valueBytes;
- _indexBytes = indexBytes;
- }
-
- public Object
- getKey()
- {
- if(!_haveKey)
- {
- assert(_dbKey != null);
- _key = _map.decodeKey(_dbKey.getData(), _communicator);
- _haveKey = true;
- }
- return _key;
- }
-
- public Object
- getValue()
- {
- if(!_haveValue)
- {
- assert(_valueBytes != null);
- _value = _map.decodeValue(_valueBytes, _communicator);
- _haveValue = true;
- //
- // Not needed anymore
- //
- _valueBytes = null;
- }
- return _value;
- }
-
- public byte[]
- getIndexBytes()
- {
- return _indexBytes;
- }
-
- public Object
- setValue(Object value)
- {
- Object old = getValue();
- _iterator.setValue(this, value);
- _value = value;
- _haveValue = true;
- return old;
- }
-
- public boolean
- equals(Object o)
- {
- if(!(o instanceof Map.Entry))
- {
- return false;
- }
- Map.Entry e = (Map.Entry)o;
- return eq(getKey(), e.getKey()) && eq(getValue(), e.getValue());
- }
-
- public int
- hashCode()
- {
- return ((getKey() == null) ? 0 : getKey().hashCode()) ^
- ((getValue() == null) ? 0 : getValue().hashCode());
- }
-
- public String
- toString()
- {
- return getKey() + "=" + getValue();
- }
-
- com.sleepycat.db.DatabaseEntry
- getDbKey()
- {
- return _dbKey;
- }
-
- private /*static*/ boolean
- eq(Object o1, Object o2)
- {
- return (o1 == null ? o2 == null : o1.equals(o2));
- }
-
- private EntryIteratorImpl _iterator;
- private Map _map;
- private Ice.Communicator _communicator;
- private com.sleepycat.db.DatabaseEntry _dbKey;
- private byte[] _valueBytes;
- private byte[] _indexBytes;
- private Object _key;
- private boolean _haveKey = false;
- private Object _value;
- private boolean _haveValue = false;
- }
-
- public static class Patcher implements IceInternal.Patcher
- {
- public
- Patcher(String type)
- {
- this.type = type;
- }
-
- public void
- patch(Ice.Object v)
- {
- value = v;
- }
-
- public String
- type()
- {
- return this.type;
- }
-
- public Ice.Object
- value()
- {
- return this.value;
- }
-
- public String type;
- public Ice.Object value;
- }
-
- protected ConnectionI _connection;
- private final Comparator _comparator;
- private final String _dbName;
-
- protected java.util.Iterator _token;
- protected MapDb _db;
- protected String _errorPrefix;
- protected int _trace;
-
- private java.util.Set _entrySet;
- private LinkedList _iteratorList = new LinkedList();
- private java.util.Map<String, Map.Index> _indexMap = new java.util.HashMap();
+ Connection getConnection();
+ void closeDb();
}
diff --git a/java/src/Freeze/MapDb.java b/java/src/Freeze/MapDb.java
index 1089d32c027..0d90b85bfb1 100644
--- a/java/src/Freeze/MapDb.java
+++ b/java/src/Freeze/MapDb.java
@@ -14,19 +14,18 @@ package Freeze;
// share the very same MapDb object; SharedDbEnv manages these shared MapDb objects.
//
-class MapDb
-{
-
- MapDb(ConnectionI connection, String dbName, String key, String value,
- java.util.Comparator comparator, Map.Index[] indices, java.util.Map indexComparators,
- boolean createDb)
- {
+public class MapDb
+{
+ public
+ MapDb(ConnectionI connection, String dbName, String key, String value, java.util.Comparator comparator,
+ MapIndex[] indices, boolean createDb)
+ {
_communicator = connection.communicator();
_dbName = dbName;
_errorPrefix = "Freeze DB DbEnv(\"" + connection.dbEnv().getEnvName() + "\") Db(\"" + dbName + "\"): ";
_indices = indices;
_trace = connection.trace();
-
+
Catalog catalog = new Catalog(connection, Util.catalogName(), true);
CatalogData catalogData = (CatalogData)catalog.get(_dbName);
if(catalogData != null)
@@ -44,10 +43,9 @@ class MapDb
_key = key;
_value = value;
}
-
+
com.sleepycat.db.DatabaseConfig config = new com.sleepycat.db.DatabaseConfig();
-
-
+
config.setAllowCreate(createDb);
config.setType(com.sleepycat.db.DatabaseType.BTREE);
@@ -57,7 +55,7 @@ class MapDb
}
Ice.Properties properties = _communicator.getProperties();
String propPrefix = "Freeze.Map." + _dbName + ".";
-
+
int btreeMinKey = properties.getPropertyAsInt(propPrefix + "BtreeMinKey");
if(btreeMinKey > 2)
{
@@ -68,26 +66,24 @@ class MapDb
}
config.setBtreeMinKey(btreeMinKey);
}
-
+
boolean checksum = properties.getPropertyAsInt(propPrefix + "Checksum") > 0;
if(checksum)
{
if(_trace >= 1)
{
- _communicator.getLogger().trace(
- "Freeze.Map", "Turning checksum on for \"" + _dbName + "\"");
+ _communicator.getLogger().trace("Freeze.Map", "Turning checksum on for \"" + _dbName + "\"");
}
-
+
config.setChecksum(true);
}
-
+
int pageSize = properties.getPropertyAsInt(propPrefix + "PageSize");
if(pageSize > 0)
{
if(_trace >= 1)
{
- _communicator.getLogger().trace(
- "Freeze.Map", "Setting \"" + _dbName + "\"'s pagesize to " + pageSize);
+ _communicator.getLogger().trace("Freeze.Map", "Setting \"" + _dbName + "\"'s pagesize to " + pageSize);
}
config.setPageSize(pageSize);
}
@@ -109,36 +105,29 @@ class MapDb
tx = null;
tx = connection.beginTransaction();
}
-
+
com.sleepycat.db.Transaction txn = Util.getTxn(tx);
-
+
_db = connection.dbEnv().getEnv().openDatabase(txn, _dbName, null, config);
-
+
String[] oldIndices = null;
java.util.List<String> newIndices = new java.util.LinkedList<String>();
-
+
CatalogIndexList catalogIndexList = new CatalogIndexList(connection, Util.catalogIndexListName(), true);
-
+
if(createDb)
{
- oldIndices = (String[])catalogIndexList.get(_dbName);
+ oldIndices = catalogIndexList.get(_dbName);
}
-
-
+
if(_indices != null)
{
- for(int i = 0; i < _indices.length; ++i)
+ for(MapIndex i : _indices)
{
- String indexName = _indices[i].name();
-
- java.util.Comparator indexComparator = null;
- if(indexComparators != null)
- {
- indexComparator = (java.util.Comparator)indexComparators.get(indexName);
- }
-
- _indices[i].associate(_dbName, _db, txn, createDb, indexComparator);
-
+ String indexName = i.name();
+
+ i.associate(_dbName, _db, txn, createDb);
+
if(createDb)
{
if(oldIndices != null)
@@ -153,7 +142,7 @@ class MapDb
}
}
}
-
+
if(catalogData == null)
{
catalogData = new CatalogData();
@@ -162,29 +151,28 @@ class MapDb
catalogData.value = value;
catalog.put(_dbName, catalogData);
}
-
+
if(createDb)
{
boolean indexRemoved = false;
-
+
if(oldIndices != null)
{
//
// Remove old indices and write the new ones
//
- for(int i = 0; i < oldIndices.length; ++i)
+ for(String index : oldIndices)
{
- String index = oldIndices[i];
if(index != null)
{
if(_trace >= 1)
{
- _communicator.getLogger().trace(
- "Freeze.Map", "removing old index \"" + index + "\" on Db \"" + _dbName + "\"");
+ _communicator.getLogger().trace("Freeze.Map", "removing old index \"" + index +
+ "\" on Db \"" + _dbName + "\"");
}
-
+
indexRemoved = true;
-
+
try
{
connection.removeMapIndex(_dbName, index);
@@ -192,21 +180,21 @@ class MapDb
catch(IndexNotFoundException ife)
{
// Ignored
-
+
if(_trace >= 1)
{
- _communicator.getLogger().trace(
- "Freeze.Map", "index \"" + index + "\" on Db \"" + _dbName + "\" does not exist");
+ _communicator.getLogger().trace("Freeze.Map", "index \"" + index +
+ "\" on Db \"" + _dbName + "\" does not exist");
}
}
}
}
}
-
+
int oldSize = oldIndices == null ? 0 : oldIndices.length;
-
+
if(indexRemoved || newIndices.size() != oldSize)
- {
+ {
if(newIndices.size() == 0)
{
catalogIndexList.remove(_dbName);
@@ -215,7 +203,6 @@ class MapDb
_communicator.getLogger().trace(
"Freeze.Map", "Removed catalogIndexList entry for Db \"" + _dbName + "\"");
}
-
}
else
{
@@ -253,12 +240,11 @@ class MapDb
catch(com.sleepycat.db.DeadlockException dx)
{
if(ownTx)
- {
+ {
if(connection.deadlockWarning())
{
- connection.communicator().getLogger().warning(
- "Deadlock in Freeze.Shared.Shared on Db \""
- + _dbName + "\"; retrying ...");
+ connection.communicator().getLogger().warning("Deadlock in Freeze.Shared.Shared on Db \"" +
+ _dbName + "\"; retrying ...");
}
tx = null;
}
@@ -293,23 +279,22 @@ class MapDb
}
}
}
-
//
// The constructor for catalogs
//
- MapDb(Ice.Communicator communicator, String envName, String dbName, String key, String value,
+ MapDb(Ice.Communicator communicator, String envName, String dbName, String key, String value,
com.sleepycat.db.Environment dbEnv)
throws com.sleepycat.db.DatabaseException
- {
+ {
_communicator = communicator;
_dbName = dbName;
_errorPrefix = "Freeze DB DbEnv(\"" + envName + "\") Db(\"" + dbName + "\"): ";
_key = key;
_value = value;
_trace = _communicator.getProperties().getPropertyAsInt("Freeze.Trace.Map");
-
+
if(_trace >= 1)
{
_communicator.getLogger().trace("Freeze.Map", "opening Db \"" + _dbName + "\"");
@@ -336,7 +321,8 @@ class MapDb
}
}
- void close()
+ public void
+ close()
{
if(_trace >= 1)
{
@@ -365,9 +351,8 @@ class MapDb
}
}
-
void
- connectIndices(Map.Index[] indices)
+ connectIndices(MapIndex[] indices)
{
if(indices != null)
{
@@ -385,22 +370,21 @@ class MapDb
{
if(_indices != null)
{
- for(int i = 0; i < _indices.length; ++i)
+ for(MapIndex i : _indices)
{
- _indices[i].close();
+ i.close();
}
_indices = null;
}
}
-
- com.sleepycat.db.Database
+ public com.sleepycat.db.Database
db()
{
return _db;
}
- String
+ public String
dbName()
{
return _dbName;
@@ -411,14 +395,12 @@ class MapDb
{
if(!key.equals(_key))
{
- throw new DatabaseException(_errorPrefix + _dbName + "'s key type is " + _key +
- ", not " + key);
+ throw new DatabaseException(_errorPrefix + _dbName + "'s key type is " + _key + ", not " + key);
}
-
+
if(!value.equals(_value))
{
- throw new DatabaseException(_errorPrefix + _dbName + "'s value type is " + _value +
- ", not " + value);
+ throw new DatabaseException(_errorPrefix + _dbName + "'s value type is " + _value + ", not " + value);
}
}
@@ -429,5 +411,5 @@ class MapDb
private String _key;
private String _value;
private final int _trace;
- private Map.Index[] _indices;
+ private MapIndex[] _indices;
}
diff --git a/java/src/Freeze/MapIndex.java b/java/src/Freeze/MapIndex.java
new file mode 100644
index 00000000000..9bab3d4e5bf
--- /dev/null
+++ b/java/src/Freeze/MapIndex.java
@@ -0,0 +1,22 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Freeze;
+
+public interface MapIndex
+{
+ String name();
+
+ void associate(String dbName, com.sleepycat.db.Database db, com.sleepycat.db.Transaction txn, boolean createDb)
+ throws com.sleepycat.db.DatabaseException, java.io.FileNotFoundException;
+
+ void init(MapIndex i);
+
+ void close();
+}
diff --git a/java/src/Freeze/MapInternal/EntryI.java b/java/src/Freeze/MapInternal/EntryI.java
new file mode 100644
index 00000000000..29fa155e83d
--- /dev/null
+++ b/java/src/Freeze/MapInternal/EntryI.java
@@ -0,0 +1,131 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Freeze.MapInternal;
+
+class EntryI<K, V> implements java.util.Map.Entry<K, V>
+{
+ public
+ EntryI(MapI<K, V> map, K key, com.sleepycat.db.DatabaseEntry dbKey, byte[] valueBytes, byte[] indexBytes)
+ {
+ _map = map;
+ _dbKey = dbKey;
+ _valueBytes = valueBytes;
+ _indexBytes = indexBytes;
+ _communicator = map.connection().getCommunicator();
+ _key = key;
+ _haveKey = key != null;
+ }
+
+ public K
+ getKey()
+ {
+ if(!_haveKey)
+ {
+ assert(_dbKey != null);
+ _key = _map.decodeKey(_dbKey.getData(), _communicator);
+ _haveKey = true;
+ }
+ return _key;
+ }
+
+ public V
+ getValue()
+ {
+ if(!_haveValue)
+ {
+ assert(_valueBytes != null);
+ _value = _map.decodeValue(_valueBytes, _communicator);
+ _haveValue = true;
+ //
+ // Not needed anymore
+ //
+ _valueBytes = null;
+ }
+ return _value;
+ }
+
+ public byte[]
+ getIndexBytes()
+ {
+ return _indexBytes;
+ }
+
+ public V
+ setValue(V value)
+ {
+ V old = getValue();
+ if(_iterator != null)
+ {
+ _iterator.setValue(this, value);
+ }
+ else
+ {
+ _map.putImpl(_dbKey, value);
+ }
+ _value = value;
+ _haveValue = true;
+ return old;
+ }
+
+ public boolean
+ equals(Object o)
+ {
+ if(!(o instanceof EntryI))
+ {
+ return false;
+ }
+ @SuppressWarnings("unchecked")
+ EntryI<K, V> e = (EntryI<K, V>)o;
+ return eq(getKey(), e.getKey()) && eq(getValue(), e.getValue());
+ }
+
+ public int
+ hashCode()
+ {
+ return ((getKey() == null) ? 0 : getKey().hashCode()) ^
+ ((getValue() == null) ? 0 : getValue().hashCode());
+ }
+
+ public String
+ toString()
+ {
+ return getKey() + "=" + getValue();
+ }
+
+ void
+ iterator(IteratorI<K, V> iterator)
+ {
+ _iterator = iterator;
+ }
+
+ com.sleepycat.db.DatabaseEntry
+ getDbKey()
+ {
+ return _dbKey;
+ }
+
+ private static boolean
+ eq(Object o1, Object o2)
+ {
+ return (o1 == null ? o2 == null : o1.equals(o2));
+ }
+
+ private MapI<K, V> _map;
+ private com.sleepycat.db.DatabaseEntry _dbKey;
+ private byte[] _valueBytes;
+ private byte[] _indexBytes;
+
+ private Ice.Communicator _communicator;
+ private K _key;
+ private boolean _haveKey = false;
+ private V _value;
+ private boolean _haveValue = false;
+ private IteratorI<K, V> _iterator;
+}
diff --git a/java/src/Freeze/MapInternal/Index.java b/java/src/Freeze/MapInternal/Index.java
new file mode 100644
index 00000000000..d95813a7058
--- /dev/null
+++ b/java/src/Freeze/MapInternal/Index.java
@@ -0,0 +1,708 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Freeze.MapInternal;
+
+import Freeze.DatabaseException;
+import Freeze.DeadlockException;
+import Freeze.ConnectionI;
+import Freeze.Map;
+import Freeze.MapIndex;
+import Freeze.NavigableMap;
+
+public abstract class Index<K, V, I>
+ implements MapIndex, com.sleepycat.db.SecondaryKeyCreator, java.util.Comparator<byte[]>, KeyCodec<I>
+{
+ protected
+ Index(MapI<K, V> map, String name, java.util.Comparator<I> comparator)
+ {
+ _map = map;
+ _name = name;
+ _comparator = comparator;
+ }
+
+ //
+ // Subclasses define this so that we can extract the index key from a value.
+ //
+ protected abstract I extractKey(V value);
+
+ //
+ // MapIndex methods
+ //
+
+ public String
+ name()
+ {
+ return _name;
+ }
+
+ public void
+ associate(String dbName, com.sleepycat.db.Database db, com.sleepycat.db.Transaction txn, boolean createDb)
+ throws com.sleepycat.db.DatabaseException, java.io.FileNotFoundException
+ {
+ _dbName = dbName + "." + _name;
+ _trace = new TraceLevels(_map.connection(), _dbName);
+
+ assert(txn != null);
+ assert(_db == null);
+
+ com.sleepycat.db.SecondaryConfig config = new com.sleepycat.db.SecondaryConfig();
+ config.setAllowCreate(createDb);
+ config.setAllowPopulate(true); // We always populate empty indices
+ config.setSortedDuplicates(true);
+ config.setType(com.sleepycat.db.DatabaseType.BTREE);
+ if(_comparator != null)
+ {
+ config.setBtreeComparator(this);
+ }
+ config.setKeyCreator(this);
+
+ Ice.Properties properties = _map.connection().getCommunicator().getProperties();
+ String propPrefix = "Freeze.Map." + _dbName + ".";
+
+ int btreeMinKey = properties.getPropertyAsInt(propPrefix + "BtreeMinKey");
+ if(btreeMinKey > 2)
+ {
+ if(_trace.level >= 1)
+ {
+ _trace.logger.trace("Freeze.Map", "Setting \"" + _dbName + "\"'s btree minkey to " + btreeMinKey);
+ }
+ config.setBtreeMinKey(btreeMinKey);
+ }
+
+ boolean checksum = properties.getPropertyAsInt(propPrefix + "Checksum") > 0;
+ if(checksum)
+ {
+ if(_trace.level >= 1)
+ {
+ _trace.logger.trace("Freeze.Map", "Turning checksum on for \"" + _dbName + "\"");
+ }
+ config.setChecksum(true);
+ }
+
+ int pageSize = properties.getPropertyAsInt(propPrefix + "PageSize");
+ if(pageSize > 0)
+ {
+ if(_trace.level >= 1)
+ {
+ _trace.logger.trace("Freeze.Map", "Setting \"" + _dbName + "\"'s pagesize to " + pageSize);
+ }
+ config.setPageSize(pageSize);
+ }
+
+ _db = _map.connection().dbEnv().getEnv().openSecondaryDatabase(txn, _dbName, null, db, config);
+ }
+
+ public void
+ init(MapIndex f)
+ {
+ @SuppressWarnings("unchecked")
+ Index<K, V, I> from = (Index<K, V, I>)f;
+
+ assert(_name.equals(from._name));
+ assert(_db == null);
+
+ _dbName = from._dbName;
+ _db = from._db;
+ _comparator = from._comparator;
+ _trace = _map.traceLevels();
+ }
+
+ public void
+ close()
+ {
+ //
+ // close() is called by MapDb only on the "main" index
+ // (the one that was associated)
+ //
+
+ if(_db != null)
+ {
+ try
+ {
+ _db.close();
+ }
+ catch(com.sleepycat.db.DatabaseException dx)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(dx);
+ ex.message = _trace.errorPrefix + "Db.close for index \"" + _dbName + "\": " + dx.getMessage();
+ throw ex;
+ }
+ _db = null;
+ }
+ }
+
+ //
+ // SecondaryKeyCreator methods
+ //
+
+ public boolean
+ createSecondaryKey(com.sleepycat.db.SecondaryDatabase secondary,
+ com.sleepycat.db.DatabaseEntry key,
+ com.sleepycat.db.DatabaseEntry value,
+ com.sleepycat.db.DatabaseEntry result)
+ throws com.sleepycat.db.DatabaseException
+ {
+ Ice.Communicator communicator = _map.connection().getCommunicator();
+ byte[] secondaryKey = marshalKey(value.getData());
+ assert(secondaryKey != null);
+
+ result.setData(secondaryKey);
+ result.setSize(secondaryKey.length);
+ return true;
+ }
+
+ //
+ // java.util.Comparator<byte[]> methods
+ //
+
+ public int
+ compare(byte[] k1, byte[] k2)
+ {
+ assert(_comparator != null);
+ Ice.Communicator communicator = _map.connection().getCommunicator();
+ return _comparator.compare(decodeKey(k1, communicator), decodeKey(k2, communicator));
+ }
+
+ private class FindModel implements IteratorModel<K, V>
+ {
+ FindModel(I key, boolean onlyDups)
+ {
+ _fromKey = key;
+ _onlyDups = onlyDups;
+ }
+
+ public String
+ dbName()
+ {
+ return Index.this.dbName();
+ }
+
+ public TraceLevels
+ traceLevels()
+ {
+ return _trace;
+ }
+
+ public com.sleepycat.db.Cursor
+ openCursor()
+ throws com.sleepycat.db.DatabaseException
+ {
+ return _db.openSecondaryCursor(_map.connection().dbTxn(), null);
+ }
+
+ public EntryI<K, V>
+ firstEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException
+ {
+ return Index.this.findFirstEntry(cursor, _fromKey);
+ }
+
+ public EntryI<K, V>
+ nextEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException
+ {
+ return Index.this.findNextEntry(cursor, _onlyDups);
+ }
+
+ private final I _fromKey;
+ private final boolean _onlyDups;
+ }
+
+ public IteratorI<K, V>
+ find(I key, boolean onlyDups)
+ {
+ return new IteratorI<K, V>(_map, new FindModel(key, onlyDups));
+ }
+
+ public IteratorI<K, V>
+ find(I key)
+ {
+ return find(key, true);
+ }
+
+ public int
+ count(I key)
+ {
+ byte[] k = encodeKey(key, _map.connection().getCommunicator());
+
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+
+ //
+ // When we have a custom-comparison function, Berkeley DB returns
+ // the key on-disk (when it finds one). We disable this behavior:
+ // (ref Oracle SR 5925672.992)
+ //
+ dbKey.setPartial(true);
+
+ //
+ // dlen is 0, so we should not retrieve any value
+ //
+ dbValue.setPartial(true);
+
+ try
+ {
+ for(;;)
+ {
+ com.sleepycat.db.Cursor dbc = null;
+ try
+ {
+ dbc = _db.openCursor(null, null);
+ if(dbc.getSearchKey(dbKey, dbValue, null) == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ return dbc.count();
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ catch(com.sleepycat.db.DeadlockException dx)
+ {
+ if(_trace.deadlockWarning)
+ {
+ _trace.logger.warning("Deadlock in Freeze.MapIndex.count while iterating over index \"" +
+ _dbName + "\"; retrying...");
+ }
+
+ //
+ // Retry
+ //
+ }
+ finally
+ {
+ if(dbc != null)
+ {
+ try
+ {
+ dbc.close();
+ }
+ catch(com.sleepycat.db.DeadlockException dx)
+ {
+ //
+ // Ignored
+ //
+ }
+ }
+ }
+ }
+ }
+ catch(com.sleepycat.db.DatabaseException dx)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(dx);
+ ex.message = _trace.errorPrefix + "Db.cursor for index \"" + _dbName + "\": " + dx.getMessage();
+ throw ex;
+ }
+ }
+
+ //
+ // Used by subclasses to implement headMapForXXX.
+ //
+ public NavigableMap<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ createHeadMap(I toKey, boolean inclusive)
+ {
+ if(toKey == null)
+ {
+ throw new NullPointerException();
+ }
+
+ if(_comparator == null)
+ {
+ throw new UnsupportedOperationException("Index '" + _name + "' has no user-defined comparator");
+ }
+
+ return new IndexedSubMap<K, V, I>(this, null, false, toKey, inclusive);
+ }
+
+ //
+ // Used by subclasses to implement tailMapForXXX.
+ //
+ public NavigableMap<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ createTailMap(I fromKey, boolean inclusive)
+ {
+ if(fromKey == null)
+ {
+ throw new NullPointerException();
+ }
+
+ if(_comparator == null)
+ {
+ throw new UnsupportedOperationException("Index '" + _name + "' has no user-defined comparator");
+ }
+
+ return new IndexedSubMap<K, V, I>(this, fromKey, inclusive, null, false);
+ }
+
+ //
+ // Used by subclasses to implement subMapForXXX.
+ //
+ public NavigableMap<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ createSubMap(I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ {
+ if(fromKey == null || toKey == null )
+ {
+ throw new NullPointerException();
+ }
+
+ if(_comparator == null)
+ {
+ throw new UnsupportedOperationException("Index '" + _name + "' has no user-defined comparator");
+ }
+
+ return new IndexedSubMap<K, V, I>(this, fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ //
+ // Used by subclasses to implement mapForXXX.
+ //
+ public NavigableMap<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ createMap()
+ {
+ if(_comparator == null)
+ {
+ throw new UnsupportedOperationException("Index '" + _name + "' has no user-defined comparator");
+ }
+
+ return new IndexedSubMap<K, V, I>(this, null, false, null, false);
+ }
+
+ com.sleepycat.db.SecondaryDatabase
+ db()
+ {
+ return _db;
+ }
+
+ String
+ dbName()
+ {
+ return _dbName;
+ }
+
+ TraceLevels
+ traceLevels()
+ {
+ return _trace;
+ }
+
+ java.util.Comparator<I>
+ comparator()
+ {
+ return _comparator;
+ }
+
+ MapI<K, V>
+ parent()
+ {
+ return _map;
+ }
+
+ boolean
+ containsKey(Object o)
+ {
+ @SuppressWarnings("unchecked")
+ I key = (I)o;
+
+ byte[] k = encodeKey(key, _map.connection().getCommunicator());
+
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+ dbValue.setPartial(true);
+
+ if(_trace.level >= 2)
+ {
+ _trace.logger.trace("Freeze.MapIndex", "checking key in Db \"" + _dbName + "\"");
+ }
+
+ for(;;)
+ {
+ try
+ {
+ return _db.get(_map.connection().dbTxn(), dbKey, dbValue, null) ==
+ com.sleepycat.db.OperationStatus.SUCCESS;
+ }
+ catch(com.sleepycat.db.DeadlockException e)
+ {
+ if(_map.connection().dbTxn() != null)
+ {
+ DeadlockException ex = new DeadlockException(
+ _trace.errorPrefix + "Db.get: " + e.getMessage(), _map.connection().currentTransaction());
+ ex.initCause(e);
+ throw ex;
+ }
+ else
+ {
+ if(_trace.deadlockWarning)
+ {
+ _trace.logger.warning("Deadlock in Freeze.MapIndex.containsKey while " + "reading Db \"" +
+ _dbName + "\"; retrying...");
+ }
+ //
+ // Try again
+ //
+ }
+ }
+ catch(com.sleepycat.db.DatabaseException e)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(e);
+ ex.message = _trace.errorPrefix + "Db.get: " + e.getMessage();
+ throw ex;
+ }
+ }
+ }
+
+ //
+ // Used by the iterator created by the findByXXX methods.
+ //
+ EntryI<K, V>
+ findFirstEntry(com.sleepycat.db.Cursor cursor, I fromKey)
+ throws com.sleepycat.db.DatabaseException
+ {
+ com.sleepycat.db.SecondaryCursor c = (com.sleepycat.db.SecondaryCursor)cursor;
+
+ assert(fromKey != null);
+ byte[] k = encodeKey(fromKey, _map.connection().getCommunicator());
+
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbIKey = new com.sleepycat.db.DatabaseEntry(k);
+
+ if(c.getSearchKey(dbIKey, dbKey, dbValue, null) == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ return new EntryI<K, V>(_map, null, dbKey, dbValue.getData(), dbIKey.getData());
+ }
+
+ return null;
+ }
+
+ //
+ // Used by the iterator created by the findByXXX methods.
+ //
+ EntryI<K, V>
+ findNextEntry(com.sleepycat.db.Cursor cursor, boolean onlyDups)
+ throws com.sleepycat.db.DatabaseException
+ {
+ com.sleepycat.db.SecondaryCursor c = (com.sleepycat.db.SecondaryCursor)cursor;
+
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbIKey = new com.sleepycat.db.DatabaseEntry();
+
+ com.sleepycat.db.OperationStatus status;
+
+ if(onlyDups)
+ {
+ status = c.getNextDup(dbIKey, dbKey, dbValue, null);
+ }
+ else
+ {
+ status = c.getNext(dbIKey, dbKey, dbValue, null);
+ }
+
+ if(status == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ return new EntryI<K, V>(_map, null, dbKey, dbValue.getData(), dbIKey.getData());
+ }
+
+ return null;
+ }
+
+ //
+ // Used by IndexedSubMap for ascending maps.
+ //
+ EntryI<K, V>
+ firstEntry(com.sleepycat.db.Cursor cursor, I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ throws com.sleepycat.db.DatabaseException
+ {
+ com.sleepycat.db.SecondaryCursor c = (com.sleepycat.db.SecondaryCursor)cursor;
+
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbIKey = new com.sleepycat.db.DatabaseEntry();
+
+ com.sleepycat.db.OperationStatus status;
+
+ if(fromKey != null)
+ {
+ byte[] k = encodeKey(fromKey, _map.connection().getCommunicator());
+ dbIKey.setData(k);
+ dbIKey.setReuseBuffer(false);
+
+ status = c.getSearchKeyRange(dbIKey, dbKey, dbValue, null);
+
+ if(status == com.sleepycat.db.OperationStatus.SUCCESS && !fromInclusive)
+ {
+ int cmp = compare(dbIKey.getData(), k);
+ assert(cmp >= 0);
+ if(cmp == 0)
+ {
+ status = c.getNextNoDup(dbIKey, dbKey, dbValue, null);
+ }
+ }
+ }
+ else
+ {
+ status = c.getFirst(dbIKey, dbKey, dbValue, null);
+ }
+
+ if(status == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ return newEntry(dbIKey, dbKey, dbValue, fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ return null;
+ }
+
+ //
+ // Used by IndexedSubMap for ascending maps.
+ //
+ EntryI<K, V>
+ nextEntry(com.sleepycat.db.Cursor cursor, I toKey, boolean toInclusive)
+ throws com.sleepycat.db.DatabaseException
+ {
+ com.sleepycat.db.SecondaryCursor c = (com.sleepycat.db.SecondaryCursor)cursor;
+
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbIKey = new com.sleepycat.db.DatabaseEntry();
+
+ if(c.getNextNoDup(dbIKey, dbKey, dbValue, null) == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ return newEntry(dbIKey, dbKey, dbValue, null, false, toKey, toInclusive);
+ }
+
+ return null;
+ }
+
+ //
+ // Used by IndexedSubMap for descending maps.
+ //
+ EntryI<K, V>
+ lastEntry(com.sleepycat.db.Cursor cursor, I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ throws com.sleepycat.db.DatabaseException
+ {
+ com.sleepycat.db.SecondaryCursor c = (com.sleepycat.db.SecondaryCursor)cursor;
+
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbIKey = new com.sleepycat.db.DatabaseEntry();
+
+ com.sleepycat.db.OperationStatus status;
+
+ if(fromKey != null)
+ {
+ byte[] k = encodeKey(fromKey, _map.connection().getCommunicator());
+ dbIKey.setData(k);
+ dbIKey.setReuseBuffer(false);
+
+ status = c.getSearchKeyRange(dbIKey, dbKey, dbValue, null);
+
+ if(status == com.sleepycat.db.OperationStatus.SUCCESS && !fromInclusive)
+ {
+ int cmp = compare(dbIKey.getData(), k);
+ assert(cmp >= 0);
+ if(cmp == 0)
+ {
+ status = c.getPrevNoDup(dbIKey, dbKey, dbValue, null);
+ }
+ }
+ }
+ else
+ {
+ status = c.getLast(dbIKey, dbKey, dbValue, null);
+ }
+
+ if(status == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ return newEntry(dbIKey, dbKey, dbValue, toKey, toInclusive, fromKey, fromInclusive);
+ }
+
+ return null;
+ }
+
+ //
+ // Used by IndexedSubMap for descending maps.
+ //
+ EntryI<K, V>
+ previousEntry(com.sleepycat.db.Cursor cursor, I toKey, boolean toInclusive)
+ throws com.sleepycat.db.DatabaseException
+ {
+ com.sleepycat.db.SecondaryCursor c = (com.sleepycat.db.SecondaryCursor)cursor;
+
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbIKey = new com.sleepycat.db.DatabaseEntry();
+
+ if(c.getPrevNoDup(dbIKey, dbKey, dbValue, null) == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ return newEntry(dbIKey, dbKey, dbValue, toKey, toInclusive, null, false);
+ }
+
+ return null;
+ }
+
+ //
+ // marshalKey may be overridden by subclasses as an optimization.
+ //
+ protected byte[]
+ marshalKey(byte[] value)
+ {
+ V decodedValue = _map.decodeValue(value, _map.connection().getCommunicator());
+ return encodeKey(extractKey(decodedValue), _map.connection().getCommunicator());
+ }
+
+ private EntryI<K, V>
+ newEntry(com.sleepycat.db.DatabaseEntry dbIKey, com.sleepycat.db.DatabaseEntry dbKey,
+ com.sleepycat.db.DatabaseEntry dbValue, I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ {
+ I key = null;
+ if(fromKey != null || toKey != null)
+ {
+ key = decodeKey(dbIKey.getData(), _map.connection().getCommunicator());
+ if(!checkRange(key, fromKey, fromInclusive, toKey, toInclusive))
+ {
+ return null;
+ }
+ }
+
+ return new EntryI<K, V>(_map, null, dbKey, dbValue.getData(), dbIKey.getData());
+ }
+
+ private boolean
+ checkRange(I key, I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ {
+ if(fromKey != null)
+ {
+ int cmp = _comparator.compare(key, fromKey);
+ if((fromInclusive && cmp < 0) || (!fromInclusive && cmp <= 0))
+ {
+ return false;
+ }
+ }
+ if(toKey != null)
+ {
+ int cmp = _comparator.compare(key, toKey);
+ if((toInclusive && cmp > 0) || (!toInclusive && cmp >= 0))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private MapI<K, V> _map;
+ private String _name;
+ private java.util.Comparator<I> _comparator;
+ private TraceLevels _trace;
+ private String _dbName;
+ private com.sleepycat.db.SecondaryDatabase _db;
+}
diff --git a/java/src/Freeze/MapInternal/IndexedSubMap.java b/java/src/Freeze/MapInternal/IndexedSubMap.java
new file mode 100644
index 00000000000..313308b80dd
--- /dev/null
+++ b/java/src/Freeze/MapInternal/IndexedSubMap.java
@@ -0,0 +1,869 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Freeze.MapInternal;
+
+import Freeze.ConnectionI;
+import Freeze.DatabaseException;
+import Freeze.Map;
+import Freeze.NavigableMap;
+
+//
+// Indexed submap of a Freeze Map or of another submap
+//
+class IndexedSubMap<K, V, I>
+ extends java.util.AbstractMap<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ implements NavigableMap<I, java.util.Set<java.util.Map.Entry<K, V>>>
+{
+ private class Value extends java.util.AbstractSet<java.util.Map.Entry<K, V>>
+ {
+ public java.util.Iterator<java.util.Map.Entry<K, V>>
+ iterator()
+ {
+ return _index.find(_myKey, true);
+ }
+
+ public int
+ size()
+ {
+ return _index.count(_myKey);
+ }
+
+ public boolean
+ equals(Object o)
+ {
+ if(o instanceof IndexedSubMap.Value)
+ {
+ IndexedSubMap.Value v = (IndexedSubMap.Value)o;
+ return v._myKey.equals(_myKey);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public int
+ hashCode()
+ {
+ return _myKey.hashCode();
+ }
+
+ private
+ Value(I key)
+ {
+ _myKey = key;
+ }
+
+ private I
+ getKey()
+ {
+ return _myKey;
+ }
+
+ private I _myKey;
+ }
+
+ private class Entry implements java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ {
+ public I
+ getKey()
+ {
+ return _value.getKey();
+ }
+
+ public java.util.Set<java.util.Map.Entry<K, V>>
+ getValue()
+ {
+ return _value;
+ }
+
+ public java.util.Set<java.util.Map.Entry<K, V>>
+ setValue(java.util.Set<java.util.Map.Entry<K, V>> value)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean
+ equals(Object o)
+ {
+ if(o instanceof IndexedSubMap.Entry)
+ {
+ IndexedSubMap.Entry e = (IndexedSubMap.Entry)o;
+ return e._value.equals(_value);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public int
+ hashCode()
+ {
+ return _value.hashCode();
+ }
+
+ IndexedSubMap<K, V, I>
+ parent()
+ {
+ return IndexedSubMap.this;
+ }
+
+ private
+ Entry(I key)
+ {
+ _value = new Value(key);
+ }
+
+ private Value _value;
+ }
+
+ private class Iterator
+ implements Map.EntryIterator<java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>>
+ {
+ public boolean
+ hasNext()
+ {
+ return _iterator.hasNext();
+ }
+
+ public java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ next()
+ {
+ EntryI<K, V> entry = (EntryI<K, V>)_iterator.next();
+ return new Entry(_index.decodeKey(entry.getIndexBytes(), _map.connection().getCommunicator()));
+ }
+
+ public void
+ remove()
+ {
+ _iterator.remove();
+ }
+
+ public void
+ close()
+ {
+ _iterator.close();
+ }
+
+ public void
+ destroy()
+ {
+ close();
+ }
+
+ private
+ Iterator()
+ {
+ assert(_index != null);
+ _iterator = new IteratorI<K, V>(_map, _view);
+ }
+
+ Map.EntryIterator<java.util.Map.Entry<K, V>> _iterator;
+ }
+
+ IndexedSubMap(Index<K, V, I> index, I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ {
+ _map = index.parent();
+ _index = index;
+ _view = new AscendingView(fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ private
+ IndexedSubMap(Index<K, V, I> index, View v)
+ {
+ _map = index.parent();
+ _index = index;
+ _view = v;
+ }
+
+ //
+ // NavigableMap methods
+ //
+
+ public boolean
+ fastRemove(I key)
+ {
+ if(!_view.inRange(key, true))
+ {
+ return false;
+ }
+
+ //
+ // Not yet implemented
+ //
+ throw new UnsupportedOperationException();
+ }
+
+ public java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ firstEntry()
+ {
+ return _view.first();
+ }
+
+ public java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ lastEntry()
+ {
+ return _view.last();
+ }
+
+ public java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ ceilingEntry(I key)
+ {
+ return _view.ceiling(key);
+ }
+
+ public java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ floorEntry(I key)
+ {
+ return _view.floor(key);
+ }
+
+ public java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ higherEntry(I key)
+ {
+ return _view.higher(key);
+ }
+
+ public java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ lowerEntry(I key)
+ {
+ return _view.lower(key);
+ }
+
+ public I
+ ceilingKey(I key)
+ {
+ Entry e = _view.ceiling(key);
+ return e != null ? e.getKey() : null;
+ }
+
+ public I
+ floorKey(I key)
+ {
+ Entry e = _view.floor(key);
+ return e != null ? e.getKey() : null;
+ }
+
+ public I
+ higherKey(I key)
+ {
+ Entry e = _view.higher(key);
+ return e != null ? e.getKey() : null;
+ }
+
+ public I
+ lowerKey(I key)
+ {
+ Entry e = _view.lower(key);
+ return e != null ? e.getKey() : null;
+ }
+
+ public java.util.Set<I>
+ descendingKeySet()
+ {
+ return descendingMap().keySet();
+ }
+
+ public NavigableMap<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ descendingMap()
+ {
+ if(_descendingMap == null)
+ {
+ View v = _view.descendingView();
+ _descendingMap = new IndexedSubMap<K, V, I>(_index, v);
+ }
+ return _descendingMap;
+ }
+
+ public NavigableMap<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ headMap(I toKey, boolean inclusive)
+ {
+ if(toKey == null)
+ {
+ throw new NullPointerException();
+ }
+ View v = _view.subView(null, false, toKey, inclusive);
+ return new IndexedSubMap<K, V, I>(_index, v);
+ }
+
+ public NavigableMap<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ subMap(I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ {
+ if(fromKey == null || toKey == null)
+ {
+ throw new NullPointerException();
+ }
+ View v = _view.subView(fromKey, fromInclusive, toKey, toInclusive);
+ return new IndexedSubMap<K, V, I>(_index, v);
+ }
+
+ public NavigableMap<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ tailMap(I fromKey, boolean inclusive)
+ {
+ if(fromKey == null)
+ {
+ throw new NullPointerException();
+ }
+ View v = _view.subView(fromKey, inclusive, null, false);
+ return new IndexedSubMap<K, V, I>(_index, v);
+ }
+
+ public java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ pollFirstEntry()
+ {
+ //
+ // Not yet implemented
+ //
+ throw new UnsupportedOperationException();
+ }
+
+ public java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ pollLastEntry()
+ {
+ //
+ // Not yet implemented
+ //
+ throw new UnsupportedOperationException();
+ }
+
+ //
+ // SortedMap methods
+ //
+
+ public java.util.Comparator<? super I>
+ comparator()
+ {
+ return _view.comparator();
+ }
+
+ public I
+ firstKey()
+ {
+ Entry e = _view.first();
+ if(e == null)
+ {
+ throw new java.util.NoSuchElementException();
+ }
+ return e.getKey();
+ }
+
+ public I
+ lastKey()
+ {
+ Entry e = _view.last();
+ if(e == null)
+ {
+ throw new java.util.NoSuchElementException();
+ }
+ return e.getKey();
+ }
+
+ public java.util.SortedMap<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ headMap(I toKey)
+ {
+ return headMap(toKey, false);
+ }
+
+ public java.util.SortedMap<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ tailMap(I fromKey)
+ {
+ return tailMap(fromKey, true);
+ }
+
+ public java.util.SortedMap<I, java.util.Set<java.util.Map.Entry<K, V>>>
+ subMap(I fromKey, I toKey)
+ {
+ return subMap(fromKey, true, toKey, false);
+ }
+
+ //
+ // Map methods
+ //
+
+ public java.util.Set<java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>>
+ entrySet()
+ {
+ if(_entrySet == null)
+ {
+ _entrySet = new java.util.AbstractSet<java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>>()
+ {
+ public java.util.Iterator<java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>>
+ iterator()
+ {
+ return new Iterator();
+ }
+
+ public boolean
+ contains(Object o)
+ {
+ if(o instanceof IndexedSubMap.Entry)
+ {
+ IndexedSubMap.Entry e = (IndexedSubMap.Entry)o;
+ return e.parent() == IndexedSubMap.this && _index.containsKey(e.getKey());
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public boolean
+ remove(Object o)
+ {
+ //
+ // Not yet implemented, should remove all objects that
+ // match this index-key
+ //
+ throw new UnsupportedOperationException();
+ }
+
+ public int
+ size()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean
+ isEmpty()
+ {
+ try
+ {
+ firstKey();
+ return false;
+ }
+ catch(java.util.NoSuchElementException e)
+ {
+ return true;
+ }
+ }
+ };
+ }
+ return _entrySet;
+ }
+
+ //
+ // Put is not implemented (you have to put in the main map view)
+ //
+
+ public boolean
+ constainsKey(Object key)
+ {
+ @SuppressWarnings("unchecked")
+ I k = (I)key;
+ if(!_view.inRange(k, true))
+ {
+ return false;
+ }
+
+ return _index.containsKey(key);
+ }
+
+ public java.util.Set<java.util.Map.Entry<K, V>>
+ get(Object key)
+ {
+ @SuppressWarnings("unchecked")
+ I k = (I)key;
+ if(!_view.inRange(k, true))
+ {
+ return null;
+ }
+
+ if(_index.containsKey(k))
+ {
+ return new Value(k);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public java.util.Set<java.util.Map.Entry<K, V>>
+ remove(Object key)
+ {
+ @SuppressWarnings("unchecked")
+ I k = (I)key;
+ if(!_view.inRange(k, true))
+ {
+ return null;
+ }
+
+ //
+ // Not yet implemented
+ //
+ throw new UnsupportedOperationException();
+ }
+
+ private Entry
+ entrySearch(Search.Type type, byte[] key)
+ {
+ if(type != Search.Type.FIRST && type != Search.Type.LAST && key == null)
+ {
+ throw new NullPointerException();
+ }
+
+ if(_index.db() == null)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.message = _index.traceLevels().errorPrefix + "\"" + _index.dbName() + "\" has been closed";
+ throw ex;
+ }
+
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(key);
+
+ if(Search.search(type, _map.connection(), _index.dbName(), _index.db(), dbKey, null, _index, _view,
+ _index.traceLevels()))
+ {
+ I k = _index.decodeKey(dbKey.getData(), _map.connection().getCommunicator());
+ return new Entry(k);
+ }
+
+ return null;
+ }
+
+ private abstract class View implements IteratorModel<K, V>, Search.KeyValidator
+ {
+ protected
+ View(java.util.Comparator<? super I> comparator, I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ {
+ _comparator = comparator;
+ _fromKey = fromKey;
+ _fromInclusive = fromInclusive;
+ _toKey = toKey;
+ _toInclusive = toInclusive;
+
+ //
+ // Validate the key range.
+ //
+ if(_fromKey != null && _toKey != null)
+ {
+ int cmp = comparator.compare(_fromKey, _toKey);
+ if(cmp > 0 || (cmp == 0 && !(_fromInclusive && _toInclusive)))
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+
+ protected
+ View(View v, java.util.Comparator<? super I> comparator, I fromKey, boolean fromInclusive, I toKey,
+ boolean toInclusive)
+ {
+ this(comparator, fromKey, fromInclusive, toKey, toInclusive);
+
+ //
+ // Verify that the key range is correct with respect to the original view.
+ //
+ if(!v.inRange(_fromKey, _fromInclusive) || !v.inRange(_toKey, _toInclusive))
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ abstract Search.Type mapSearchType(Search.Type type);
+ abstract View copy(I fromKey, boolean fromInclusive, I toKey, boolean toInclusive);
+ abstract View descendingView();
+
+ final Entry
+ first()
+ {
+ Search.Type type;
+ byte[] key = null;
+ if(_fromKey != null)
+ {
+ type = _fromInclusive ? mapSearchType(Search.Type.CEILING) : mapSearchType(Search.Type.HIGHER);
+ key = fromKeyBytes();
+ }
+ else
+ {
+ type = mapSearchType(Search.Type.FIRST);
+ }
+ return entrySearch(type, key);
+ }
+
+ final Entry
+ last()
+ {
+ Search.Type type;
+ byte[] key = null;
+ if(_toKey != null)
+ {
+ type = _toInclusive ? mapSearchType(Search.Type.FLOOR) : mapSearchType(Search.Type.LOWER);
+ key = toKeyBytes();
+ }
+ else
+ {
+ type = mapSearchType(Search.Type.LAST);
+ }
+ return entrySearch(type, key);
+ }
+
+ final Entry
+ ceiling(I key)
+ {
+ byte[] k = _index.encodeKey(key, _map.connection().getCommunicator());
+ return entrySearch(mapSearchType(Search.Type.CEILING), k);
+ }
+
+ final Entry
+ floor(I key)
+ {
+ byte[] k = _index.encodeKey(key, _map.connection().getCommunicator());
+ return entrySearch(mapSearchType(Search.Type.FLOOR), k);
+ }
+
+ final Entry
+ higher(I key)
+ {
+ byte[] k = _index.encodeKey(key, _map.connection().getCommunicator());
+ return entrySearch(mapSearchType(Search.Type.HIGHER), k);
+ }
+
+ final Entry
+ lower(I key)
+ {
+ byte[] k = _index.encodeKey(key, _map.connection().getCommunicator());
+ return entrySearch(mapSearchType(Search.Type.LOWER), k);
+ }
+
+ final View
+ subView(I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ {
+ if(fromKey == null)
+ {
+ fromKey = _fromKey;
+ fromInclusive = _fromInclusive;
+ }
+ if(toKey == null)
+ {
+ toKey = _toKey;
+ toInclusive = _toInclusive;
+ }
+ return copy(fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ //
+ // IteratorModel methods (partial)
+ //
+
+ final public String
+ dbName()
+ {
+ return _index.dbName();
+ }
+
+ final public TraceLevels
+ traceLevels()
+ {
+ return _index.traceLevels();
+ }
+
+ final public com.sleepycat.db.Cursor
+ openCursor()
+ throws com.sleepycat.db.DatabaseException
+ {
+ return _index.db().openSecondaryCursor(_map.connection().dbTxn(), null);
+ }
+
+ //
+ // Search.KeyValidator methods
+ //
+
+ final public boolean
+ keyInRange(byte[] key)
+ {
+ I k = _index.decodeKey(key, _map.connection().getCommunicator());
+ return inRange(k, true);
+ }
+
+ final boolean
+ inRange(I key, boolean inclusive)
+ {
+ return !tooLow(key, inclusive, _fromKey, _fromInclusive) &&
+ !tooHigh(key, inclusive, _toKey, _toInclusive);
+ }
+
+ final java.util.Comparator<? super I>
+ comparator()
+ {
+ return _comparator;
+ }
+
+ final protected byte[]
+ fromKeyBytes()
+ {
+ if(_fromKey != null && _fromKeyBytes == null)
+ {
+ _fromKeyBytes = _index.encodeKey(_fromKey, _map.connection().getCommunicator());
+ }
+ return _fromKeyBytes;
+ }
+
+ final protected byte[]
+ toKeyBytes()
+ {
+ if(_toKey != null && _toKeyBytes == null)
+ {
+ _toKeyBytes = _index.encodeKey(_toKey, _map.connection().getCommunicator());
+ }
+ return _toKeyBytes;
+ }
+
+ final protected boolean
+ tooLow(I key, boolean inclusive, I targetKey, boolean targetInclusive)
+ {
+ if(key != null && targetKey != null)
+ {
+ int cmp = comparator().compare(key, targetKey);
+ if(cmp < 0 || (cmp == 0 && inclusive && !targetInclusive))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ final protected boolean
+ tooHigh(I key, boolean inclusive, I targetKey, boolean targetInclusive)
+ {
+ if(key != null && targetKey != null)
+ {
+ int cmp = comparator().compare(key, targetKey);
+ if(cmp > 0 || (cmp == 0 && inclusive && !targetInclusive))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ final java.util.Comparator<? super I> _comparator;
+ final I _fromKey;
+ final boolean _fromInclusive;
+ final I _toKey;
+ final boolean _toInclusive;
+ private byte[] _fromKeyBytes;
+ private byte[] _toKeyBytes;
+ }
+
+ private class AscendingView extends View
+ {
+ AscendingView(I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ {
+ super(_index.comparator(), fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ AscendingView(View v, I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ {
+ super(v, _index.comparator(), fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ //
+ // View methods
+ //
+
+ Search.Type
+ mapSearchType(Search.Type type)
+ {
+ return type;
+ }
+
+ View
+ copy(I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ {
+ return new AscendingView(this, fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ View
+ descendingView()
+ {
+ return new DescendingView(this, _toKey, _toInclusive, _fromKey, _fromInclusive);
+ }
+
+ //
+ // IteratorModel methods
+ //
+
+ public EntryI<K, V>
+ firstEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException
+ {
+ return _index.firstEntry(cursor, _fromKey, _fromInclusive, _toKey, _toInclusive);
+ }
+
+ public EntryI<K, V>
+ nextEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException
+ {
+ return _index.nextEntry(cursor, _toKey, _toInclusive);
+ }
+ }
+
+ private class DescendingView extends View
+ {
+ DescendingView(I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ {
+ super(java.util.Collections.reverseOrder(_index.comparator()), fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ DescendingView(View v, I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ {
+ super(v, java.util.Collections.reverseOrder(_index.comparator()), fromKey, fromInclusive, toKey,
+ toInclusive);
+ }
+
+ //
+ // View methods
+ //
+
+ Search.Type
+ mapSearchType(Search.Type type)
+ {
+ return type.descending();
+ }
+
+ View
+ copy(I fromKey, boolean fromInclusive, I toKey, boolean toInclusive)
+ {
+ return new DescendingView(this, fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ View
+ descendingView()
+ {
+ return new AscendingView(this, _toKey, _toInclusive, _fromKey, _fromInclusive);
+ }
+
+ //
+ // IteratorModel methods
+ //
+
+ public EntryI<K, V>
+ firstEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException
+ {
+ return _index.lastEntry(cursor, _fromKey, _fromInclusive, _toKey, _toInclusive);
+ }
+
+ public EntryI<K, V>
+ nextEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException
+ {
+ return _index.previousEntry(cursor, _toKey, _toInclusive);
+ }
+ }
+
+ private final MapI<K, V> _map;
+ private final Index<K, V, I> _index;
+ private final View _view;
+ private java.util.Set<java.util.Map.Entry<I, java.util.Set<java.util.Map.Entry<K, V>>>> _entrySet;
+ private NavigableMap<I, java.util.Set<java.util.Map.Entry<K, V>>> _descendingMap;
+}
diff --git a/java/src/Freeze/MapInternal/IteratorI.java b/java/src/Freeze/MapInternal/IteratorI.java
new file mode 100644
index 00000000000..4af39cf7498
--- /dev/null
+++ b/java/src/Freeze/MapInternal/IteratorI.java
@@ -0,0 +1,422 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Freeze.MapInternal;
+
+import Freeze.Connection;
+import Freeze.ConnectionI;
+import Freeze.DatabaseException;
+import Freeze.DeadlockException;
+import Freeze.NotFoundException;
+import Freeze.Map;
+
+class IteratorI<K, V> implements Freeze.Map.EntryIterator<java.util.Map.Entry<K, V>>
+{
+ IteratorI(MapI<K, V> map, IteratorModel<K, V> model)
+ {
+ _map = map;
+ _model = model;
+ _trace = model.traceLevels();
+ _dbName = model.dbName();
+
+ try
+ {
+ _txn = _map.connection().dbTxn();
+ _cursor = _model.openCursor();
+ }
+ catch(com.sleepycat.db.DeadlockException dx)
+ {
+ dead();
+ DeadlockException ex = new DeadlockException(
+ _trace.errorPrefix + "EntryIterator constructor: " + dx.getMessage(),
+ _map.connection().currentTransaction());
+ ex.initCause(dx);
+ throw ex;
+ }
+ catch(com.sleepycat.db.DatabaseException dx)
+ {
+ dead();
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(dx);
+ ex.message = _trace.errorPrefix + "EntryIterator constructor: " + dx.getMessage();
+ throw ex;
+ }
+
+ _iteratorListToken = _map.addIterator(this);
+ }
+
+ public boolean
+ hasNext()
+ {
+ if(_current == null || _current == _lastReturned)
+ {
+ try
+ {
+ if(_current == null)
+ {
+ _current = _model.firstEntry(_cursor);
+ }
+ else
+ {
+ _current = _model.nextEntry(_cursor);
+ }
+ }
+ catch(com.sleepycat.db.DeadlockException dx)
+ {
+ dead();
+ DeadlockException ex = new DeadlockException(
+ _trace.errorPrefix + "Dbc.get: " + dx.getMessage(), _map.connection().currentTransaction());
+ ex.initCause(dx);
+ throw ex;
+ }
+ catch(com.sleepycat.db.DatabaseException dx)
+ {
+ dead();
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(dx);
+ ex.message = _trace.errorPrefix + "Dbc.get: " + dx.getMessage();
+ throw ex;
+ }
+
+ //
+ // For a read-only iterator, we can close the cursor automatically when there
+ // are no more entries.
+ //
+ if(_current == null && _txn == null)
+ {
+ close();
+ }
+
+ if(_current != null)
+ {
+ _current.iterator(this);
+ }
+
+ return _current != null;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ public java.util.Map.Entry<K, V>
+ next()
+ {
+ if(hasNext())
+ {
+ _lastReturned = _current;
+ return _lastReturned;
+ }
+ else
+ {
+ throw new java.util.NoSuchElementException();
+ }
+ }
+
+ public void
+ remove()
+ {
+ if(_txn == null)
+ {
+ throw new UnsupportedOperationException(
+ _trace.errorPrefix + "Cannot remove using an iterator without a transaction");
+ }
+
+ //
+ // Remove the last object returned by next()
+ //
+ if(_lastReturned == null)
+ {
+ throw new IllegalStateException();
+ }
+
+ if(_lastReturned == _current)
+ {
+ try
+ {
+ if(_cursor.delete() == com.sleepycat.db.OperationStatus.KEYEMPTY)
+ {
+ throw new IllegalStateException();
+ }
+ }
+ catch(com.sleepycat.db.DeadlockException e)
+ {
+ dead();
+ DeadlockException ex = new DeadlockException(_trace.errorPrefix + "Dbc.del: " + e.getMessage(),
+ _map.connection().currentTransaction());
+ ex.initCause(e);
+ throw ex;
+ }
+ catch(com.sleepycat.db.DatabaseException e)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(e);
+ ex.message = _trace.errorPrefix + "Dbc.del: " + e.getMessage();
+ throw ex;
+ }
+ }
+ else
+ {
+ //
+ // Duplicate the cursor and move the _lastReturned element to delete it (using the duplicate).
+ //
+
+ //
+ // This works only for non-index iterators.
+ //
+ if(_cursor instanceof com.sleepycat.db.SecondaryCursor)
+ {
+ throw new UnsupportedOperationException(
+ _trace.errorPrefix + "Cannot remove using an iterator retrieved through an index");
+ }
+
+ com.sleepycat.db.Cursor clone = null;
+
+ try
+ {
+ clone = _cursor.dup(true);
+
+ //
+ // Not interested in data.
+ //
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+ dbValue.setPartial(true);
+
+ com.sleepycat.db.OperationStatus rc = clone.getSearchKey(_lastReturned.getDbKey(), dbValue, null);
+
+ if(rc == com.sleepycat.db.OperationStatus.NOTFOUND)
+ {
+ throw new IllegalStateException();
+ }
+ if(clone.delete() == com.sleepycat.db.OperationStatus.KEYEMPTY)
+ {
+ throw new IllegalStateException();
+ }
+ }
+ catch(com.sleepycat.db.DeadlockException e)
+ {
+ dead();
+ DeadlockException ex = new DeadlockException(
+ _trace.errorPrefix + "EntryIterator.remove: " + e.getMessage(),
+ _map.connection().currentTransaction());
+ ex.initCause(e);
+ throw ex;
+ }
+ catch(com.sleepycat.db.DatabaseException e)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(e);
+ ex.message = _trace.errorPrefix + "EntryIterator.remove: " + e.getMessage();
+ throw ex;
+ }
+ finally
+ {
+ if(clone != null)
+ {
+ closeCursor(clone);
+ }
+ }
+ }
+ }
+
+ //
+ // Extra operations.
+ //
+ public void
+ close()
+ {
+ if(_iteratorListToken != null)
+ {
+ _map.removeIterator(_iteratorListToken);
+ _iteratorListToken = null;
+ }
+
+ if(_cursor != null)
+ {
+ com.sleepycat.db.Cursor cursor = _cursor;
+ _cursor = null;
+ closeCursor(cursor);
+ }
+ }
+
+ //
+ // An alias for close()
+ //
+ public void
+ destroy()
+ {
+ close();
+ }
+
+ protected void
+ finalize()
+ throws Throwable
+ {
+ if(_cursor != null)
+ {
+ _trace.logger.warning(
+ "iterator leaked for Map \"" + _dbName + "\"; the application " +
+ "should have closed it earlier by calling Map.EntryIterator.close(), " +
+ "Map.closeAllIterators(), Map.close(), Connection.close(), or (if also " +
+ "leaking a transaction) Transaction.commit() or Transaction.rollback()");
+ }
+ super.finalize();
+ }
+
+ void
+ setValue(EntryI<K, V> entry, V value)
+ {
+ if(_cursor instanceof com.sleepycat.db.SecondaryCursor)
+ {
+ throw new UnsupportedOperationException(
+ _trace.errorPrefix + "Cannot set an iterator retrieved through an index");
+ }
+
+ if(_txn == null)
+ {
+ throw new UnsupportedOperationException(
+ _trace.errorPrefix + "Cannot set a value without a transaction");
+ }
+
+ //
+ // Are we trying to update the current value?
+ //
+ if(_current == entry)
+ {
+ //
+ // Yes, update it directly
+ //
+ byte[] v = _map.encodeValue(value, _map.connection().getCommunicator());
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(v);
+
+ try
+ {
+ _cursor.putCurrent(dbValue);
+ }
+ catch(com.sleepycat.db.DeadlockException e)
+ {
+ dead();
+ DeadlockException ex = new DeadlockException(_trace.errorPrefix + "Dbc.put: " + e.getMessage(),
+ _map.connection().currentTransaction());
+ ex.initCause(e);
+ throw ex;
+ }
+ catch(com.sleepycat.db.DatabaseException e)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(e);
+ ex.message = _trace.errorPrefix + "Dbc.put: " + e.getMessage();
+ throw ex;
+ }
+ }
+ else
+ {
+ //
+ // Duplicate the cursor and move the entry
+ // element to update it (using the duplicate cursor)
+ //
+
+ com.sleepycat.db.Cursor clone = null;
+
+ try
+ {
+ clone = _cursor.dup(true);
+
+ //
+ // Not interested in data
+ //
+ com.sleepycat.db.DatabaseEntry dummy = new com.sleepycat.db.DatabaseEntry();
+ dummy.setPartial(true);
+
+ com.sleepycat.db.OperationStatus rc = clone.getSearchKey(entry.getDbKey(), dummy, null);
+
+ if(rc == com.sleepycat.db.OperationStatus.NOTFOUND)
+ {
+ NotFoundException ex = new NotFoundException();
+ ex.message = _trace.errorPrefix + "Dbc.get: DB_NOTFOUND";
+ throw ex;
+ }
+
+ byte[] v = _map.encodeValue(value, _map.connection().getCommunicator());
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(v);
+ clone.putCurrent(dbValue);
+ }
+ catch(com.sleepycat.db.DeadlockException e)
+ {
+ dead();
+ DeadlockException ex = new DeadlockException(
+ _trace.errorPrefix + "EntryIterator.setValue: " + e.getMessage(),
+ _map.connection().currentTransaction());
+ ex.initCause(e);
+ throw ex;
+ }
+ catch(com.sleepycat.db.DatabaseException e)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(e);
+ ex.message = _trace.errorPrefix + "EntryIterator.setValue: " + e.getMessage();
+ throw ex;
+ }
+ finally
+ {
+ if(clone != null)
+ {
+ closeCursor(clone);
+ }
+ }
+ }
+ }
+
+ private void
+ closeCursor(com.sleepycat.db.Cursor cursor)
+ {
+ try
+ {
+ cursor.close();
+ }
+ catch(com.sleepycat.db.DeadlockException e)
+ {
+ dead();
+ DeadlockException ex = new DeadlockException(
+ _trace.errorPrefix + "Dbc.close: " + e.getMessage(), _map.connection().currentTransaction());
+ ex.initCause(e);
+ throw ex;
+ }
+ catch(com.sleepycat.db.DatabaseException e)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(e);
+ ex.message = _trace.errorPrefix + "Dbc.close: " + e.getMessage();
+ throw ex;
+ }
+ }
+
+ private void
+ dead()
+ {
+ if(_cursor != null)
+ {
+ com.sleepycat.db.Cursor cursor = _cursor;
+ _cursor = null;
+ closeCursor(cursor);
+ }
+ }
+
+ private final MapI<K, V> _map;
+ private final IteratorModel<K, V> _model;
+
+ private final TraceLevels _trace;
+ private final String _dbName; // For use in finalizer.
+ private final com.sleepycat.db.Transaction _txn;
+ private com.sleepycat.db.Cursor _cursor;
+ private EntryI<K, V> _current;
+ private EntryI<K, V> _lastReturned;
+ private Object _iteratorListToken;
+}
diff --git a/java/src/Freeze/MapInternal/IteratorModel.java b/java/src/Freeze/MapInternal/IteratorModel.java
new file mode 100644
index 00000000000..8adeea782ac
--- /dev/null
+++ b/java/src/Freeze/MapInternal/IteratorModel.java
@@ -0,0 +1,25 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Freeze.MapInternal;
+
+interface IteratorModel<K, V>
+{
+ String dbName();
+ TraceLevels traceLevels();
+
+ com.sleepycat.db.Cursor openCursor()
+ throws com.sleepycat.db.DatabaseException;
+
+ EntryI<K, V> firstEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException;
+
+ EntryI<K, V> nextEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException;
+}
diff --git a/java/src/Freeze/KeyCodec.java b/java/src/Freeze/MapInternal/KeyCodec.java
index 3f4697c658f..3239d203797 100644
--- a/java/src/Freeze/KeyCodec.java
+++ b/java/src/Freeze/MapInternal/KeyCodec.java
@@ -7,10 +7,10 @@
//
// **********************************************************************
-package Freeze;
+package Freeze.MapInternal;
-public interface KeyCodec
+interface KeyCodec<K>
{
- public abstract byte[] encodeKey(Object o, Ice.Communicator communicator);
- public abstract Object decodeKey(byte[] b, Ice.Communicator communicator);
+ public abstract byte[] encodeKey(K k, Ice.Communicator communicator);
+ public abstract K decodeKey(byte[] b, Ice.Communicator communicator);
}
diff --git a/java/src/Freeze/MapInternal/MapI.java b/java/src/Freeze/MapInternal/MapI.java
new file mode 100644
index 00000000000..3d523f617ad
--- /dev/null
+++ b/java/src/Freeze/MapInternal/MapI.java
@@ -0,0 +1,1571 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Freeze.MapInternal;
+
+import Freeze.Catalog;
+import Freeze.CatalogIndexList;
+import Freeze.Connection;
+import Freeze.ConnectionI;
+import Freeze.DatabaseException;
+import Freeze.DeadlockException;
+import Freeze.IndexNotFoundException;
+import Freeze.LinkedList;
+import Freeze.Map;
+import Freeze.MapDb;
+import Freeze.MapIndex;
+import Freeze.NavigableMap;
+import Freeze.Transaction;
+import Freeze.Util;
+
+public abstract class MapI<K, V> extends java.util.AbstractMap<K, V>
+ implements Map<K, V>, KeyCodec<K>, IteratorModel<K, V>
+{
+ public abstract byte[] encodeValue(V o, Ice.Communicator communicator);
+ public abstract V decodeValue(byte[] b, Ice.Communicator communicator);
+
+ protected
+ MapI(Connection connection, String dbName, String key, String value, boolean createDb,
+ java.util.Comparator<K> comparator)
+ {
+ _connection = (ConnectionI)connection;
+ _dbName = dbName;
+ _comparator = (comparator == null) ? null : new Comparator(comparator);
+
+ _trace = new TraceLevels(_connection, dbName);
+
+ init(null, dbName, key, value, createDb);
+ }
+
+ protected
+ MapI(Connection connection, String dbName, java.util.Comparator<K> comparator)
+ {
+ _connection = (ConnectionI)connection;
+ _dbName = dbName;
+ _comparator = (comparator == null) ? null : new Comparator(comparator);
+
+ _trace = new TraceLevels(_connection, dbName);
+ }
+
+ protected static <K, V> void
+ recreate(MapI<K, V> map, String dbName, String key, String value, MapIndex[] indices)
+ {
+ ConnectionI connection = map._connection;
+ TraceLevels trace = map._trace;
+
+ if(dbName.equals(Util.catalogName()) || dbName.equals(Util.catalogIndexListName()))
+ {
+ throw new DatabaseException(trace.errorPrefix + "You cannot recreate the \"" + dbName + "\" database");
+ }
+
+ if(trace.level >= 1)
+ {
+ trace.logger.trace("Freeze.Map", "Recreating \"" + dbName + "\"");
+ }
+
+ Transaction tx = connection.currentTransaction();
+ boolean ownTx = (tx == null);
+
+ com.sleepycat.db.DatabaseEntry keyEntry = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry valueEntry = new com.sleepycat.db.DatabaseEntry();
+
+ com.sleepycat.db.Database oldDb = null;
+ MapDb newDb = null;
+
+ for(;;)
+ {
+ try
+ {
+ if(ownTx)
+ {
+ tx = null;
+ tx = connection.beginTransaction();
+ }
+
+ com.sleepycat.db.Transaction txn = connection.dbTxn();
+
+ if(trace.level >= 2)
+ {
+ trace.logger.trace("Freeze.Map", "Removing all existing indices for \"" + dbName + "\"");
+ }
+
+ CatalogIndexList catalogIndexList = new CatalogIndexList(connection, Util.catalogIndexListName(), true);
+ String[] oldIndices = catalogIndexList.remove(dbName);
+
+ if(oldIndices != null)
+ {
+ for(String oldIndex : oldIndices)
+ {
+ try
+ {
+ connection.removeMapIndex(dbName, oldIndex);
+ }
+ catch(IndexNotFoundException e)
+ {
+ //
+ // Ignored
+ //
+ }
+ }
+ }
+
+ //
+ // Rename existing database
+ //
+ String oldDbName = dbName + ".old-" + java.util.UUID.randomUUID().toString();
+
+ if(trace.level >= 2)
+ {
+ trace.logger.trace("Freeze.Map", "Renaming \"" + dbName + "\" to \"" + oldDbName + "\"");
+ }
+
+ connection.dbEnv().getEnv().renameDatabase(txn, dbName, null, oldDbName);
+
+ com.sleepycat.db.DatabaseConfig oldDbConfig = new com.sleepycat.db.DatabaseConfig();
+ oldDbConfig.setType(com.sleepycat.db.DatabaseType.BTREE);
+
+ oldDb = connection.dbEnv().getEnv().openDatabase(txn, oldDbName, null, oldDbConfig);
+
+ newDb = new MapDb(connection, dbName, key, value, map._comparator, indices, true);
+ map.init(newDb, indices);
+
+ if(trace.level >= 2)
+ {
+ trace.logger.trace("Freeze.Map", "Writing contents of \"" + oldDbName + "\" to fresh \"" +
+ dbName + "\"");
+ }
+
+ //
+ // Now simply write all of oldDb into newDb
+ //
+ com.sleepycat.db.Cursor dbc = null;
+ try
+ {
+ dbc = oldDb.openCursor(txn, null);
+
+ while(dbc.getNext(keyEntry, valueEntry, null) == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ newDb.db().put(txn, keyEntry, valueEntry);
+ }
+ }
+ finally
+ {
+ if(dbc != null)
+ {
+ dbc.close();
+ }
+ }
+
+ if(trace.level >= 2)
+ {
+ trace.logger.trace("Freeze.Map", "Transfer complete; removing \"" + oldDbName + "\"");
+ }
+ connection.dbEnv().getEnv().removeDatabase(txn, oldDbName, null);
+
+ if(ownTx)
+ {
+ try
+ {
+ tx.commit();
+ }
+ finally
+ {
+ tx = null;
+ }
+ }
+
+ break; // for (;;)
+ }
+ catch(com.sleepycat.db.DeadlockException dx)
+ {
+ if(ownTx)
+ {
+ if(trace.deadlockWarning)
+ {
+ trace.logger.warning("Deadlock in Freeze.Map.recreate on Db \"" + dbName + "\"; retrying ...");
+ }
+
+ //
+ // Ignored, try again
+ //
+ }
+ else
+ {
+ DeadlockException ex = new DeadlockException(
+ trace.errorPrefix + "Map.recreate: " + dx.getMessage(), tx);
+ ex.initCause(dx);
+ throw ex;
+ }
+ }
+ catch(com.sleepycat.db.DatabaseException dx)
+ {
+ DatabaseException ex = new DatabaseException(trace.errorPrefix + "Map.recreate: " + dx.getMessage());
+ ex.initCause(dx);
+ throw ex;
+ }
+ catch(java.io.FileNotFoundException fne)
+ {
+ DatabaseException ex = new DatabaseException(trace.errorPrefix + "Map.recreate: " + fne.getMessage());
+ ex.initCause(fne);
+ throw ex;
+ }
+ finally
+ {
+ if(ownTx && tx != null)
+ {
+ try
+ {
+ tx.rollback();
+ }
+ catch(DatabaseException de)
+ {
+ }
+ }
+
+ try
+ {
+ if(newDb != null)
+ {
+ newDb.close();
+ }
+
+ if(oldDb != null)
+ {
+ try
+ {
+ oldDb.close();
+ }
+ catch(com.sleepycat.db.DatabaseException dx)
+ {
+ DatabaseException ex = new DatabaseException(
+ trace.errorPrefix + "Map.recreate: " + dx.getMessage());
+ ex.initCause(dx);
+ throw ex;
+ }
+ }
+ }
+ finally
+ {
+ newDb = null;
+ oldDb = null;
+ }
+ }
+ }
+ }
+
+ protected void
+ init(MapIndex[] indices, String dbName, String key, String value, boolean createDb)
+ {
+ init(_connection.dbEnv().getSharedMapDb(dbName, key, value, _comparator, indices, createDb), indices);
+ }
+
+ protected void
+ init(MapDb db, MapIndex[] indices)
+ {
+ _db = db;
+ _token = _connection.registerMap(this);
+
+ if(indices != null)
+ {
+ for(MapIndex index : indices)
+ {
+ _indexMap.put(index.name(), index);
+ }
+ }
+ }
+
+ //
+ // Freeze.Map methods
+ //
+
+ public void
+ fastPut(K key, V value)
+ {
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
+ putImpl(dbKey, value);
+ }
+
+ public boolean
+ fastRemove(K key)
+ {
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
+ return removeImpl(dbKey);
+ }
+
+ public void
+ close()
+ {
+ if(_db != null)
+ {
+ try
+ {
+ closeAllIterators();
+ }
+ finally
+ {
+ _db = null;
+ _connection.unregisterMap(_token);
+ _token = null;
+ }
+ }
+ }
+
+ public int
+ closeAllIterators()
+ {
+ return closeAllIteratorsExcept(null);
+ }
+
+ //
+ // Close this map and destroy the underlying Berkeley DB database
+ //
+ public void
+ destroy()
+ {
+ if(_db == null)
+ {
+ throw new DatabaseException(_trace.errorPrefix + "This map is closed");
+ }
+
+ if(_dbName.equals(Util.catalogName()) || _dbName.equals(Util.catalogIndexListName()))
+ {
+ throw new DatabaseException(_trace.errorPrefix + "You cannot destroy the \"" + _dbName + "\" database");
+ }
+
+ if(_connection.currentTransaction() != null)
+ {
+ throw new DatabaseException(
+ _trace.errorPrefix + "You cannot destroy a database within an active transaction");
+ }
+
+ if(_trace.level >= 1)
+ {
+ _trace.logger.trace("Freeze.Map", "destroying \"" + _dbName + "\"");
+ }
+
+ closeDb();
+
+ for(;;)
+ {
+ Transaction tx = null;
+ try
+ {
+ tx = _connection.beginTransaction();
+ com.sleepycat.db.Transaction txn = _connection.dbTxn();
+
+ Catalog catalog = new Catalog(_connection, Util.catalogName(), true);
+ catalog.remove(_dbName);
+
+ CatalogIndexList catalogIndexList =
+ new CatalogIndexList(_connection, Util.catalogIndexListName(), true);
+ catalogIndexList.remove(_dbName);
+
+ _connection.dbEnv().getEnv().removeDatabase(txn, _dbName, null);
+
+ //
+ // Remove all indices
+ //
+ for(String index : _indexMap.keySet())
+ {
+ _connection.removeMapIndex(_dbName, index);
+ }
+
+ tx.commit();
+
+ break; // for(;;)
+ }
+ catch(java.io.FileNotFoundException dx)
+ {
+ try
+ {
+ tx.rollback();
+ }
+ catch(DatabaseException e)
+ {
+ }
+
+ DatabaseException e = new DatabaseException(_trace.errorPrefix + "file not found");
+ e.initCause(dx);
+ throw e;
+ }
+ catch(com.sleepycat.db.DeadlockException dx)
+ {
+ if(_trace.deadlockWarning)
+ {
+ _trace.logger.warning("Deadlock in Freeze.Map.destroy on Db \"" + _dbName + "\"; retrying...");
+ }
+
+ //
+ // Ignored, try again
+ //
+ }
+ catch(com.sleepycat.db.DatabaseException dx)
+ {
+ try
+ {
+ tx.rollback();
+ }
+ catch(DatabaseException e)
+ {
+ }
+
+ DatabaseException e = new DatabaseException(_trace.errorPrefix + dx.getMessage());
+ e.initCause(dx);
+ throw e;
+ }
+ catch(RuntimeException rx)
+ {
+ try
+ {
+ tx.rollback();
+ }
+ catch(DatabaseException e)
+ {
+ }
+
+ throw rx;
+ }
+ }
+ }
+
+ public Connection
+ getConnection()
+ {
+ return _connection;
+ }
+
+ public void
+ closeDb()
+ {
+ close();
+ _connection.dbEnv().removeSharedMapDb(_dbName);
+ }
+
+ //
+ // NavigableMap methods
+ //
+
+ public java.util.Map.Entry<K, V>
+ firstEntry()
+ {
+ return entrySearch(Search.Type.FIRST, null, true);
+ }
+
+ public java.util.Map.Entry<K, V>
+ lastEntry()
+ {
+ return entrySearch(Search.Type.LAST, null, true);
+ }
+
+ public java.util.Map.Entry<K, V>
+ ceilingEntry(K key)
+ {
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+ return entrySearch(Search.Type.CEILING, k, true);
+ }
+
+ public java.util.Map.Entry<K, V>
+ floorEntry(K key)
+ {
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+ return entrySearch(Search.Type.FLOOR, k, true);
+ }
+
+ public java.util.Map.Entry<K, V>
+ higherEntry(K key)
+ {
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+ return entrySearch(Search.Type.HIGHER, k, true);
+ }
+
+ public java.util.Map.Entry<K, V>
+ lowerEntry(K key)
+ {
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+ return entrySearch(Search.Type.LOWER, k, true);
+ }
+
+ public K
+ ceilingKey(K key)
+ {
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+ java.util.Map.Entry<K, V> e = entrySearch(Search.Type.CEILING, k, false);
+ return e != null ? e.getKey() : null;
+ }
+
+ public K
+ floorKey(K key)
+ {
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+ java.util.Map.Entry<K, V> e = entrySearch(Search.Type.FLOOR, k, false);
+ return e != null ? e.getKey() : null;
+ }
+
+ public K
+ higherKey(K key)
+ {
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+ java.util.Map.Entry<K, V> e = entrySearch(Search.Type.HIGHER, k, false);
+ return e != null ? e.getKey() : null;
+ }
+
+ public K
+ lowerKey(K key)
+ {
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+ java.util.Map.Entry<K, V> e = entrySearch(Search.Type.LOWER, k, false);
+ return e != null ? e.getKey() : null;
+ }
+
+ public java.util.Set<K>
+ descendingKeySet()
+ {
+ return descendingMap().keySet();
+ }
+
+ public NavigableMap<K, V>
+ descendingMap()
+ {
+ if(_comparator == null)
+ {
+ throw new UnsupportedOperationException("A comparator is required");
+ }
+
+ if(_descendingMap == null)
+ {
+ _descendingMap = new SubMap<K, V>(this, null, false, null, false, false);
+ }
+
+ return _descendingMap;
+ }
+
+ public NavigableMap<K, V>
+ headMap(K toKey, boolean inclusive)
+ {
+ if(toKey == null)
+ {
+ throw new NullPointerException();
+ }
+
+ if(_comparator == null)
+ {
+ throw new UnsupportedOperationException("A comparator is required");
+ }
+
+ return new SubMap<K, V>(this, null, false, toKey, inclusive, true);
+ }
+
+ public NavigableMap<K, V>
+ subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
+ {
+ if(fromKey == null || toKey == null)
+ {
+ throw new NullPointerException();
+ }
+
+ if(_comparator == null)
+ {
+ throw new UnsupportedOperationException("A comparator is required");
+ }
+
+ return new SubMap<K, V>(this, fromKey, fromInclusive, toKey, toInclusive, true);
+ }
+
+ public NavigableMap<K, V>
+ tailMap(K fromKey, boolean inclusive)
+ {
+ if(fromKey == null)
+ {
+ throw new NullPointerException();
+ }
+
+ if(_comparator == null)
+ {
+ throw new UnsupportedOperationException("A comparator is required");
+ }
+
+ return new SubMap<K, V>(this, fromKey, inclusive, null, false, true);
+ }
+
+ public java.util.Map.Entry<K, V>
+ pollFirstEntry()
+ {
+ EntryI<K, V> e = entrySearch(Search.Type.FIRST, null, true);
+ if(e != null)
+ {
+ removeImpl(e.getDbKey());
+ }
+ return e;
+ }
+
+ public java.util.Map.Entry<K, V>
+ pollLastEntry()
+ {
+ EntryI<K, V> e = entrySearch(Search.Type.LAST, null, true);
+ if(e != null)
+ {
+ removeImpl(e.getDbKey());
+ }
+ return e;
+ }
+
+ //
+ // SortedMap methods
+ //
+
+ public java.util.Comparator<? super K>
+ comparator()
+ {
+ if(_comparator == null)
+ {
+ return null;
+ }
+ else
+ {
+ //
+ // Return's the user's comparator, not the DB comparator.
+ //
+ return _comparator.comparator();
+ }
+ }
+
+ public K
+ firstKey()
+ {
+ EntryI<K, V> e = entrySearch(Search.Type.FIRST, null, false);
+ if(e == null)
+ {
+ throw new java.util.NoSuchElementException();
+ }
+ return e.getKey();
+ }
+
+ public K
+ lastKey()
+ {
+ EntryI<K, V> e = entrySearch(Search.Type.LAST, null, false);
+ if(e == null)
+ {
+ throw new java.util.NoSuchElementException();
+ }
+ return e.getKey();
+ }
+
+ public java.util.SortedMap<K, V>
+ headMap(K toKey)
+ {
+ return headMap(toKey, false);
+ }
+
+ public java.util.SortedMap<K, V>
+ tailMap(K fromKey)
+ {
+ return tailMap(fromKey, true);
+ }
+
+ public java.util.SortedMap<K, V>
+ subMap(K fromKey, K toKey)
+ {
+ return subMap(fromKey, true, toKey, false);
+ }
+
+ //
+ // Map methods
+ //
+
+ public int
+ size()
+ {
+ if(_db == null)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.message = _trace.errorPrefix + "\"" + _dbName + "\" has been closed";
+ throw ex;
+ }
+
+ //
+ // The number of records cannot be cached and then adjusted by
+ // the member functions since the map would no longer work in
+ // the presence of transactions - if a record is added (and
+ // the size adjusted) and the transaction aborted then the
+ // cached map size() would be incorrect.
+ //
+
+ //
+ // TODO: DB_FAST_STAT doesn't seem to do what the
+ // documentation says...
+ //
+ try
+ {
+ com.sleepycat.db.StatsConfig config = new com.sleepycat.db.StatsConfig();
+ //
+ // TODO: DB_FAST_STAT doesn't seem to do what the
+ // documentation says...
+ //
+ //config.setFast(true);
+ com.sleepycat.db.BtreeStats s = (com.sleepycat.db.BtreeStats)_db.db().getStats(null, config);
+ return s.getNumData();
+ }
+ catch(com.sleepycat.db.DatabaseException e)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(e);
+ ex.message = _trace.errorPrefix + "Db.stat: " + e.getMessage();
+ throw ex;
+ }
+ }
+
+ public boolean
+ containsValue(Object value)
+ {
+ for(;;)
+ {
+ Map.EntryIterator<java.util.Map.Entry<K, V>> p = null;
+ try
+ {
+ p = (Map.EntryIterator<java.util.Map.Entry<K, V>>)entrySet().iterator();
+
+ if(value == null)
+ {
+ while(p.hasNext())
+ {
+ Entry e = (Entry)p.next();
+ if(e.getValue() == null)
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ while(p.hasNext())
+ {
+ Entry e = (Entry)p.next();
+ if(value.equals(e.getValue()))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ catch(DeadlockException e)
+ {
+ if(_connection.dbTxn() != null)
+ {
+ throw e;
+ }
+ else
+ {
+ if(_trace.deadlockWarning)
+ {
+ _trace.logger.warning("Deadlock in Freeze.Map.containsValue while " + "iterating over Db \"" +
+ _dbName + "\"; retrying...");
+ }
+
+ //
+ // Try again
+ //
+ }
+ }
+ finally
+ {
+ if(p != null)
+ {
+ p.close();
+ }
+ }
+ }
+ }
+
+ public boolean
+ containsKey(Object o)
+ {
+ @SuppressWarnings("unchecked")
+ K key = (K)o;
+
+ if(_db == null)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.message = _trace.errorPrefix + "\"" + _dbName + "\" has been closed";
+ throw ex;
+ }
+
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+ dbValue.setPartial(true);
+
+ if(_trace.level >= 2)
+ {
+ _trace.logger.trace("Freeze.Map", "checking key in Db \"" + _dbName + "\"");
+ }
+
+ for(;;)
+ {
+ try
+ {
+ return _db.db().get(_connection.dbTxn(), dbKey, dbValue, null) ==
+ com.sleepycat.db.OperationStatus.SUCCESS;
+ }
+ catch(com.sleepycat.db.DeadlockException e)
+ {
+ if(_connection.dbTxn() != null)
+ {
+ DeadlockException ex = new DeadlockException(
+ _trace.errorPrefix + "Db.get: " + e.getMessage(), _connection.currentTransaction());
+ ex.initCause(e);
+ throw ex;
+ }
+ else
+ {
+ if(_trace.deadlockWarning)
+ {
+ _trace.logger.warning("Deadlock in Freeze.Map.containsKey while " + "reading Db \"" + _dbName +
+ "\"; retrying...");
+ }
+ //
+ // Try again
+ //
+ }
+ }
+ catch(com.sleepycat.db.DatabaseException e)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(e);
+ ex.message = _trace.errorPrefix + "Db.get: " + e.getMessage();
+ throw ex;
+ }
+ }
+ }
+
+ public V
+ get(Object o)
+ {
+ @SuppressWarnings("unchecked")
+ K key = (K)o;
+
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
+ byte[] v = getImpl(dbKey);
+ if(v == null)
+ {
+ return null;
+ }
+ else
+ {
+ return decodeValue(v, _connection.getCommunicator());
+ }
+ }
+
+ public V
+ put(K key, V value)
+ {
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
+ byte[] v = getImpl(dbKey);
+ V old = null;
+ if(v != null)
+ {
+ old = decodeValue(v, _connection.getCommunicator());
+ }
+ putImpl(dbKey, value);
+ return old;
+ }
+
+ public V
+ remove(Object o)
+ {
+ @SuppressWarnings("unchecked")
+ K key = (K)o;
+
+ byte[] k = encodeKey(key, _connection.getCommunicator());
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(k);
+ byte[] v = getImpl(dbKey);
+
+ if(v != null && removeImpl(dbKey))
+ {
+ return decodeValue(v, _connection.getCommunicator());
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public void
+ clear()
+ {
+ if(_db == null)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.message = _trace.errorPrefix + "\"" + _dbName + "\" has been closed";
+ throw ex;
+ }
+
+ com.sleepycat.db.Transaction txn = _connection.dbTxn();
+
+ for(;;)
+ {
+ try
+ {
+ _db.db().truncate(txn, false);
+ break;
+ }
+ catch(com.sleepycat.db.DeadlockException e)
+ {
+ if(txn != null)
+ {
+ DeadlockException ex = new DeadlockException(
+ _trace.errorPrefix + "Db.truncate: " + e.getMessage(), _connection.currentTransaction());
+ ex.initCause(e);
+ throw ex;
+ }
+ else
+ {
+ if(_trace.deadlockWarning)
+ {
+ _trace.logger.warning("Deadlock in Freeze.Map.clear on Db \"" + _dbName + "\"; retrying...");
+ }
+
+ //
+ // Try again
+ //
+ }
+ }
+ catch(com.sleepycat.db.DatabaseException e)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(e);
+ ex.message = _trace.errorPrefix + "Db.truncate: " + e.getMessage();
+ throw ex;
+ }
+ }
+ }
+
+ public java.util.Set<java.util.Map.Entry<K, V>>
+ entrySet()
+ {
+ if(_entrySet == null)
+ {
+ _entrySet = new java.util.AbstractSet<java.util.Map.Entry<K, V>>()
+ {
+ public java.util.Iterator<java.util.Map.Entry<K, V>>
+ iterator()
+ {
+ return new IteratorI<K, V>(MapI.this, MapI.this);
+ }
+
+ public boolean
+ contains(Object o)
+ {
+ if(!(o instanceof Entry))
+ {
+ return false;
+ }
+ @SuppressWarnings("unchecked")
+ EntryI<K, V> entry = (EntryI<K, V>)o;
+ V value = entry.getValue();
+
+ byte[] v = getImpl(entry.getDbKey());
+ return v != null && valEquals(decodeValue(v, _connection.getCommunicator()), value);
+ }
+
+ public boolean
+ remove(Object o)
+ {
+ if(!(o instanceof Entry))
+ {
+ return false;
+ }
+ @SuppressWarnings("unchecked")
+ EntryI<K, V> entry = (EntryI<K, V>)o;
+ V value = entry.getValue();
+
+ byte[] v = getImpl(entry.getDbKey());
+ if(v != null && valEquals(decodeValue(v, _connection.getCommunicator()), value))
+ {
+ return removeImpl(entry.getDbKey());
+ }
+ return false;
+ }
+
+ public int
+ size()
+ {
+ return MapI.this.size();
+ }
+
+ public void
+ clear()
+ {
+ MapI.this.clear();
+ }
+ };
+ }
+
+ return _entrySet;
+ }
+
+ //
+ // IteratorModel methods
+ //
+
+ public String
+ dbName()
+ {
+ return _dbName;
+ }
+
+ public TraceLevels
+ traceLevels()
+ {
+ return _trace;
+ }
+
+ public com.sleepycat.db.Cursor
+ openCursor()
+ throws com.sleepycat.db.DatabaseException
+ {
+ return _db.db().openCursor(_connection.dbTxn(), null);
+ }
+
+ public EntryI<K, V>
+ firstEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException
+ {
+ return firstEntry(cursor, null, false, null, false);
+ }
+
+ public EntryI<K, V>
+ nextEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException
+ {
+ return nextEntry(cursor, null, false);
+ }
+
+ com.sleepycat.db.Database
+ db()
+ {
+ return _db.db();
+ }
+
+ ConnectionI
+ connection()
+ {
+ return _connection;
+ }
+
+ int
+ closeAllIteratorsExcept(Map.EntryIterator<java.util.Map.Entry<K, V>> except)
+ {
+ int count = 0;
+
+ synchronized(_iteratorList)
+ {
+ java.util.Iterator<IteratorI> p = _iteratorList.iterator();
+
+ while(p.hasNext())
+ {
+ IteratorI i = p.next();
+ if(i != except)
+ {
+ i.close();
+ ++count;
+ }
+ }
+ }
+
+ return count;
+ }
+
+ Object
+ addIterator(IteratorI i)
+ {
+ synchronized(_iteratorList)
+ {
+ _iteratorList.addFirst(i);
+ java.util.Iterator<IteratorI> p = _iteratorList.iterator();
+ p.next();
+ return p;
+ }
+ }
+
+ void
+ removeIterator(Object token)
+ {
+ @SuppressWarnings("unchecked")
+ java.util.Iterator<IteratorI> i = (java.util.Iterator<IteratorI>)token;
+
+ synchronized(_iteratorList)
+ {
+ i.remove();
+ }
+ }
+
+ //
+ // Convenience method for use in this class.
+ //
+ private EntryI<K, V>
+ entrySearch(Search.Type type, byte[] key, boolean includeValue)
+ {
+ return entrySearch(type, key, includeValue, null);
+ }
+
+ //
+ // Also used by SubMap.
+ //
+ EntryI<K, V>
+ entrySearch(Search.Type type, byte[] key, boolean includeValue, Search.KeyValidator validator)
+ {
+ if(type != Search.Type.FIRST && type != Search.Type.LAST && key == null)
+ {
+ throw new NullPointerException();
+ }
+
+ if(_db.db() == null)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.message = _trace.errorPrefix + "\"" + dbName() + "\" has been closed";
+ throw ex;
+ }
+
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(key);
+ com.sleepycat.db.DatabaseEntry dbValue = includeValue ? new com.sleepycat.db.DatabaseEntry() : null;
+
+ if(Search.search(type, _connection, _dbName, _db.db(), dbKey, dbValue, _comparator, validator, _trace))
+ {
+ return new EntryI<K, V>(this, null, dbKey, dbValue != null ? dbValue.getData() : null, null);
+ }
+
+ return null;
+ }
+
+ //
+ // For ascending maps.
+ //
+ EntryI<K, V>
+ firstEntry(com.sleepycat.db.Cursor cursor, K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
+ throws com.sleepycat.db.DatabaseException
+ {
+ if(fromKey != null)
+ {
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+
+ byte[] k = encodeKey(fromKey, _connection.getCommunicator());
+ dbKey.setData(k);
+ dbKey.setReuseBuffer(false);
+
+ com.sleepycat.db.OperationStatus status = cursor.getSearchKeyRange(dbKey, dbValue, null);
+
+ if(status == com.sleepycat.db.OperationStatus.SUCCESS && !fromInclusive)
+ {
+ int cmp = _comparator.compare(dbKey.getData(), k);
+ assert(cmp >= 0);
+ if(cmp == 0)
+ {
+ status = cursor.getNextNoDup(dbKey, dbValue, null);
+ }
+ }
+
+ if(status == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ return newEntry(dbKey, dbValue, fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ return null;
+ }
+ else
+ {
+ return nextEntry(cursor, toKey, toInclusive);
+ }
+ }
+
+ //
+ // For ascending maps.
+ //
+ EntryI<K, V>
+ nextEntry(com.sleepycat.db.Cursor cursor, K toKey, boolean toInclusive)
+ throws com.sleepycat.db.DatabaseException
+ {
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+
+ if(cursor.getNext(dbKey, dbValue, null) == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ return newEntry(dbKey, dbValue, null, false, toKey, toInclusive);
+ }
+
+ return null;
+ }
+
+ //
+ // For descending maps.
+ //
+ EntryI<K, V>
+ lastEntry(com.sleepycat.db.Cursor cursor, K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
+ throws com.sleepycat.db.DatabaseException
+ {
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.OperationStatus status = null;
+
+ if(fromKey != null)
+ {
+ byte[] k = encodeKey(fromKey, _connection.getCommunicator());
+ dbKey.setData(k);
+ dbKey.setReuseBuffer(false);
+
+ status = cursor.getSearchKeyRange(dbKey, dbValue, null);
+
+ if(status == com.sleepycat.db.OperationStatus.SUCCESS && !fromInclusive)
+ {
+ int cmp = _comparator.compare(dbKey.getData(), k);
+ assert(cmp >= 0);
+ if(cmp == 0)
+ {
+ status = cursor.getPrevNoDup(dbKey, dbValue, null);
+ }
+ }
+ }
+ else
+ {
+ status = cursor.getLast(dbKey, dbValue, null);
+ }
+
+ if(status == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ return newEntry(dbKey, dbValue, toKey, toInclusive, fromKey, fromInclusive);
+ }
+
+ return null;
+ }
+
+ //
+ // For descending maps.
+ //
+ EntryI<K, V>
+ previousEntry(com.sleepycat.db.Cursor cursor, K toKey, boolean toInclusive)
+ throws com.sleepycat.db.DatabaseException
+ {
+ com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry();
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+
+ if(cursor.getPrev(dbKey, dbValue, null) == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ return newEntry(dbKey, dbValue, toKey, toInclusive, null, false);
+ }
+
+ return null;
+ }
+
+ void
+ putImpl(com.sleepycat.db.DatabaseEntry dbKey, V value)
+ {
+ if(_db == null)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.message = _trace.errorPrefix + "\"" + _dbName + "\" has been closed";
+ throw ex;
+ }
+
+ byte[] v = encodeValue(value, _connection.getCommunicator());
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(v);
+
+ if(_trace.level >= 2)
+ {
+ _trace.logger.trace("Freeze.Map", "writing value in Db \"" + _dbName + "\"");
+ }
+
+ com.sleepycat.db.Transaction txn = _connection.dbTxn();
+ if(txn == null)
+ {
+ closeAllIterators();
+ }
+
+ for(;;)
+ {
+ try
+ {
+ _db.db().put(txn, dbKey, dbValue);
+ break;
+ }
+ catch(com.sleepycat.db.DeadlockException e)
+ {
+ if(txn != null)
+ {
+ DeadlockException ex = new DeadlockException(
+ _trace.errorPrefix + "Db.put: " + e.getMessage(), _connection.currentTransaction());
+ ex.initCause(e);
+ throw ex;
+ }
+ else
+ {
+ if(_trace.deadlockWarning)
+ {
+ _trace.logger.warning("Deadlock in Freeze.Map.putImpl while " + "writing into Db \"" +
+ _dbName + "\"; retrying...");
+ }
+
+ //
+ // Try again
+ //
+ }
+ }
+ catch(com.sleepycat.db.DatabaseException e)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(e);
+ ex.message = _trace.errorPrefix + "Db.put: " + e.getMessage();
+ throw ex;
+ }
+ }
+ }
+
+ boolean
+ removeImpl(com.sleepycat.db.DatabaseEntry dbKey)
+ {
+ if(_db == null)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.message = _trace.errorPrefix + "\"" + _dbName + "\" has been closed";
+ throw ex;
+ }
+
+ if(_trace.level >= 2)
+ {
+ _trace.logger.trace("Freeze.Map", "deleting value from Db \"" + _dbName + "\"");
+ }
+
+ com.sleepycat.db.Transaction txn = _connection.dbTxn();
+ if(txn == null)
+ {
+ closeAllIterators();
+ }
+
+ for(;;)
+ {
+ try
+ {
+ com.sleepycat.db.OperationStatus rc = _db.db().delete(txn, dbKey);
+ return (rc == com.sleepycat.db.OperationStatus.SUCCESS);
+ }
+ catch(com.sleepycat.db.DeadlockException e)
+ {
+ if(txn != null)
+ {
+ DeadlockException ex = new DeadlockException(
+ _trace.errorPrefix + "Db.del: " + e.getMessage(), _connection.currentTransaction());
+ ex.initCause(e);
+ throw ex;
+ }
+ else
+ {
+ if(_trace.deadlockWarning)
+ {
+ _trace.logger.warning("Deadlock in Freeze.Map.removeImpl while " + "writing into Db \"" +
+ _dbName + "\"; retrying...");
+ }
+
+ //
+ // Try again
+ //
+ }
+ }
+ catch(com.sleepycat.db.DatabaseException e)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(e);
+ ex.message = _trace.errorPrefix + "Db.del: " + e.getMessage();
+ throw ex;
+ }
+ }
+ }
+
+ private byte[]
+ getImpl(com.sleepycat.db.DatabaseEntry dbKey)
+ {
+ if(_db == null)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.message = _trace.errorPrefix + "\"" + _dbName + "\" has been closed";
+ throw ex;
+ }
+
+ com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
+
+ if(_trace.level >= 2)
+ {
+ _trace.logger.trace("Freeze.Map", "reading value from Db \"" + _dbName + "\"");
+ }
+
+ for(;;)
+ {
+ try
+ {
+ com.sleepycat.db.OperationStatus rc = _db.db().get(_connection.dbTxn(), dbKey, dbValue, null);
+ if(rc == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ return dbValue.getData();
+ }
+ else
+ {
+ return null;
+ }
+ }
+ catch(com.sleepycat.db.DeadlockException e)
+ {
+ if(_connection.dbTxn() != null)
+ {
+ DeadlockException ex = new DeadlockException(
+ _trace.errorPrefix + "Db.get: " + e.getMessage(), _connection.currentTransaction());
+ ex.initCause(e);
+ throw ex;
+ }
+ else
+ {
+ if(_trace.deadlockWarning)
+ {
+ _trace.logger.warning("Deadlock in Freeze.Map.getImpl while " + "reading Db \"" + _dbName +
+ "\"; retrying...");
+ }
+
+ //
+ // Try again
+ //
+ }
+ }
+ catch(com.sleepycat.db.DatabaseException e)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(e);
+ ex.message = _trace.errorPrefix + "Db.get: " + e.getMessage();
+ throw ex;
+ }
+ }
+ }
+
+ private EntryI<K, V>
+ newEntry(com.sleepycat.db.DatabaseEntry dbKey, com.sleepycat.db.DatabaseEntry dbValue, K fromKey,
+ boolean fromInclusive, K toKey, boolean toInclusive)
+ {
+ K key = null;
+ if(fromKey != null || toKey != null)
+ {
+ key = decodeKey(dbKey.getData(), _connection.getCommunicator());
+ if(!checkRange(key, fromKey, fromInclusive, toKey, toInclusive))
+ {
+ return null;
+ }
+ }
+
+ return new EntryI<K, V>(this, key, dbKey, dbValue.getData(), null);
+ }
+
+ private boolean
+ checkRange(K key, K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
+ {
+ if(fromKey != null)
+ {
+ int cmp = _comparator.comparator().compare(key, fromKey);
+ if((fromInclusive && cmp < 0) || (!fromInclusive && cmp <= 0))
+ {
+ return false;
+ }
+ }
+ if(toKey != null)
+ {
+ int cmp = _comparator.comparator().compare(key, toKey);
+ if((toInclusive && cmp > 0) || (!toInclusive && cmp >= 0))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean
+ valEquals(Object v1, Object v2)
+ {
+ return (v1 == null ? v2 == null : v1.equals(v2));
+ }
+
+ private class Comparator implements java.util.Comparator<byte[]>
+ {
+ Comparator(java.util.Comparator<K> comparator)
+ {
+ _comparator = comparator;
+ }
+
+ public java.util.Comparator<K>
+ comparator()
+ {
+ return _comparator;
+ }
+
+ public int
+ compare(byte[] d1, byte[] d2)
+ {
+ Ice.Communicator communicator = _connection.getCommunicator();
+ return _comparator.compare(decodeKey(d1, communicator), decodeKey(d2, communicator));
+ }
+
+ //
+ // The user-supplied comparator
+ //
+ private final java.util.Comparator<K> _comparator;
+ }
+
+ public static class Patcher implements IceInternal.Patcher
+ {
+ public
+ Patcher(String type)
+ {
+ this.type = type;
+ }
+
+ public void
+ patch(Ice.Object v)
+ {
+ value = v;
+ }
+
+ public String
+ type()
+ {
+ return this.type;
+ }
+
+ public Ice.Object
+ value()
+ {
+ return this.value;
+ }
+
+ public String type;
+ public Ice.Object value;
+ }
+
+ private final ConnectionI _connection;
+ private final Comparator _comparator;
+ private final String _dbName;
+
+ private final TraceLevels _trace;
+ private java.util.Iterator _token;
+ private MapDb _db;
+
+ private java.util.Set<java.util.Map.Entry<K, V>> _entrySet;
+ private NavigableMap<K, V> _descendingMap;
+ private LinkedList<IteratorI> _iteratorList = new LinkedList<IteratorI>();
+ private java.util.Map<String, MapIndex> _indexMap = new java.util.HashMap<String, MapIndex>();
+}
diff --git a/java/src/Freeze/MapInternal/Search.java b/java/src/Freeze/MapInternal/Search.java
new file mode 100644
index 00000000000..195430c631e
--- /dev/null
+++ b/java/src/Freeze/MapInternal/Search.java
@@ -0,0 +1,238 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Freeze.MapInternal;
+
+import Freeze.ConnectionI;
+import Freeze.DatabaseException;
+import Freeze.DeadlockException;
+
+class Search
+{
+ enum Type
+ {
+ FIRST // The first entry
+ {
+ Type descending() { return LAST; };
+ },
+ LAST // The last entry
+ {
+ Type descending() { return FIRST; };
+ },
+ CEILING // The entry with the smallest key greater than or equal to the target key
+ {
+ Type descending() { return FLOOR; };
+ },
+ FLOOR // The entry with the greatest key less than or equal to the target key
+ {
+ Type descending() { return CEILING; };
+ },
+ HIGHER // The entry with the smallest key greater than the target key
+ {
+ Type descending() { return LOWER; };
+ },
+ LOWER // The entry with the greatest key less than the target key
+ {
+ Type descending() { return HIGHER; };
+ };
+
+ abstract Type descending(); // Returns the descending (opposite) value.
+ }
+
+ interface KeyValidator
+ {
+ boolean keyInRange(byte[] key);
+ }
+
+ static boolean
+ search(Type type, ConnectionI connection, String dbName, com.sleepycat.db.Database db,
+ com.sleepycat.db.DatabaseEntry key, com.sleepycat.db.DatabaseEntry value,
+ java.util.Comparator<byte[]> comparator, KeyValidator validator, TraceLevels trace)
+ {
+ if(type != Type.FIRST && type != Type.LAST && comparator == null)
+ {
+ throw new UnsupportedOperationException("A comparator is required");
+ }
+
+ if(trace.level >= 2)
+ {
+ trace.logger.trace("Freeze.Map", "searching Db \"" + dbName + "\"");
+ }
+
+ if(value == null)
+ {
+ value = new com.sleepycat.db.DatabaseEntry();
+ value.setPartial(true); // Not interested in the value.
+ }
+
+ try
+ {
+ for(;;)
+ {
+ com.sleepycat.db.Cursor dbc = null;
+ try
+ {
+ com.sleepycat.db.DatabaseEntry dbcKey =
+ new com.sleepycat.db.DatabaseEntry(key != null ? key.getData() : null);
+ dbcKey.setReuseBuffer(false);
+
+ dbc = db.openCursor(connection.dbTxn(), null);
+
+ com.sleepycat.db.OperationStatus status = null;
+
+ switch(type)
+ {
+ case FIRST:
+ {
+ status = dbc.getFirst(dbcKey, value, null);
+ break;
+ }
+ case LAST:
+ {
+ status = dbc.getLast(dbcKey, value, null);
+ break;
+ }
+ case CEILING:
+ {
+ //
+ // The semantics of getSearchKeyRange match CEILING.
+ //
+ status = dbc.getSearchKeyRange(dbcKey, value, null);
+ break;
+ }
+ case FLOOR:
+ {
+ status = dbc.getSearchKeyRange(dbcKey, value, null);
+ if(status == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ //
+ // getSearchKeyRange returns the smallest key greater than or equal to
+ // the target key. If the matching key is greater than the target key
+ // then we need to get the previous entry.
+ //
+ int cmp = comparator.compare(dbcKey.getData(), key.getData());
+ assert(cmp >= 0);
+ if(cmp > 0)
+ {
+ status = dbc.getPrevNoDup(dbcKey, value, null);
+ }
+ }
+ else if(status == com.sleepycat.db.OperationStatus.NOTFOUND)
+ {
+ //
+ // All keys must be less than the target key so we pick the largest of
+ // all (the last one).
+ //
+ status = dbc.getLast(dbcKey, value, null);
+ }
+ break;
+ }
+ case HIGHER:
+ {
+ status = dbc.getSearchKeyRange(dbcKey, value, null);
+ if(status == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ //
+ // getSearchKeyRange returns the smallest key greater than or equal to
+ // the target key. If the matching key is equal to the target key
+ // then we need to get the next entry.
+ //
+ int cmp = comparator.compare(dbcKey.getData(), key.getData());
+ assert(cmp >= 0);
+ if(cmp == 0)
+ {
+ status = dbc.getNextNoDup(dbcKey, value, null);
+ }
+ }
+ break;
+ }
+ case LOWER:
+ {
+ status = dbc.getSearchKeyRange(dbcKey, value, null);
+ if(status == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ //
+ // getSearchKeyRange returns the smallest key greater than or equal to
+ // the target key. We move to the previous entry, whose key must be less
+ // than the target key.
+ //
+ status = dbc.getPrevNoDup(dbcKey, value, null);
+ }
+ else if(status == com.sleepycat.db.OperationStatus.NOTFOUND)
+ {
+ //
+ // All keys must be less than the target key so we pick the largest of
+ // all (the last one).
+ //
+ status = dbc.getLast(dbcKey, value, null);
+ }
+ break;
+ }
+ }
+
+ if(status == com.sleepycat.db.OperationStatus.SUCCESS)
+ {
+ if(validator == null || validator.keyInRange(dbcKey.getData()))
+ {
+ key.setData(dbcKey.getData());
+ return true;
+ }
+ }
+
+ return false;
+ }
+ catch(com.sleepycat.db.DeadlockException dx)
+ {
+ if(connection.dbTxn() != null)
+ {
+ DeadlockException ex = new DeadlockException(
+ trace.errorPrefix + dx.getMessage(), connection.currentTransaction());
+ ex.initCause(dx);
+ throw ex;
+ }
+ else
+ {
+ if(trace.deadlockWarning)
+ {
+ trace.logger.warning("Deadlock in Freeze.Map while searching \"" + dbName +
+ "\"; retrying...");
+ }
+
+ //
+ // Retry
+ //
+ }
+ }
+ finally
+ {
+ if(dbc != null)
+ {
+ try
+ {
+ dbc.close();
+ }
+ catch(com.sleepycat.db.DeadlockException dx)
+ {
+ //
+ // Ignored
+ //
+ }
+ }
+ }
+ }
+ }
+ catch(com.sleepycat.db.DatabaseException dx)
+ {
+ DatabaseException ex = new DatabaseException();
+ ex.initCause(dx);
+ ex.message = trace.errorPrefix + dx.getMessage();
+ throw ex;
+ }
+ }
+}
diff --git a/java/src/Freeze/MapInternal/SubMap.java b/java/src/Freeze/MapInternal/SubMap.java
new file mode 100644
index 00000000000..c503fae0abf
--- /dev/null
+++ b/java/src/Freeze/MapInternal/SubMap.java
@@ -0,0 +1,695 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Freeze.MapInternal;
+
+import Freeze.ConnectionI;
+import Freeze.Map;
+import Freeze.NavigableMap;
+
+//
+// Submap of a Freeze Map or of another submap
+//
+
+class SubMap<K, V> extends java.util.AbstractMap<K, V> implements NavigableMap<K, V>
+{
+ SubMap(MapI<K, V> map, K fromKey, boolean fromInclusive, K toKey, boolean toInclusive, boolean ascending)
+ {
+ _map = map;
+ if(ascending)
+ {
+ _view = new AscendingView(fromKey, fromInclusive, toKey, toInclusive);
+ }
+ else
+ {
+ _view = new DescendingView(fromKey, fromInclusive, toKey, toInclusive);
+ }
+ }
+
+ private
+ SubMap(MapI<K, V> map, View v)
+ {
+ _map = map;
+ _view = v;
+ }
+
+ //
+ // NavigableMap methods
+ //
+
+ public boolean
+ fastRemove(K key)
+ {
+ if(!_view.inRange(key, true))
+ {
+ return false;
+ }
+
+ return _map.fastRemove(key);
+ }
+
+ public java.util.Map.Entry<K, V>
+ firstEntry()
+ {
+ return _view.first();
+ }
+
+ public java.util.Map.Entry<K, V>
+ lastEntry()
+ {
+ return _view.last();
+ }
+
+ public java.util.Map.Entry<K, V>
+ ceilingEntry(K key)
+ {
+ return _view.ceiling(key);
+ }
+
+ public java.util.Map.Entry<K, V>
+ floorEntry(K key)
+ {
+ return _view.floor(key);
+ }
+
+ public java.util.Map.Entry<K, V>
+ higherEntry(K key)
+ {
+ return _view.higher(key);
+ }
+
+ public java.util.Map.Entry<K, V>
+ lowerEntry(K key)
+ {
+ return _view.lower(key);
+ }
+
+ public K
+ ceilingKey(K key)
+ {
+ EntryI<K, V> e = _view.ceiling(key);
+ return e != null ? e.getKey() : null;
+ }
+
+ public K
+ floorKey(K key)
+ {
+ EntryI<K, V> e = _view.floor(key);
+ return e != null ? e.getKey() : null;
+ }
+
+ public K
+ higherKey(K key)
+ {
+ EntryI<K, V> e = _view.higher(key);
+ return e != null ? e.getKey() : null;
+ }
+
+ public K
+ lowerKey(K key)
+ {
+ EntryI<K, V> e = _view.lower(key);
+ return e != null ? e.getKey() : null;
+ }
+
+ public java.util.Set<K>
+ descendingKeySet()
+ {
+ return descendingMap().keySet();
+ }
+
+ public NavigableMap<K, V>
+ descendingMap()
+ {
+ if(_descendingMap == null)
+ {
+ View v = _view.descendingView();
+ _descendingMap = new SubMap<K, V>(_map, v);
+ }
+ return _descendingMap;
+ }
+
+ public NavigableMap<K, V>
+ headMap(K toKey, boolean inclusive)
+ {
+ if(toKey == null)
+ {
+ throw new NullPointerException();
+ }
+ View v = _view.subView(null, false, toKey, inclusive);
+ return new SubMap<K, V>(_map, v);
+ }
+
+ public NavigableMap<K, V>
+ subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
+ {
+ if(fromKey == null || toKey == null)
+ {
+ throw new NullPointerException();
+ }
+ View v = _view.subView(fromKey, fromInclusive, toKey, toInclusive);
+ return new SubMap<K, V>(_map, v);
+ }
+
+ public NavigableMap<K, V>
+ tailMap(K fromKey, boolean inclusive)
+ {
+ if(fromKey == null)
+ {
+ throw new NullPointerException();
+ }
+ View v = _view.subView(fromKey, inclusive, null, false);
+ return new SubMap<K, V>(_map, v);
+ }
+
+ public java.util.Map.Entry<K, V>
+ pollFirstEntry()
+ {
+ EntryI<K, V> e = _view.first();
+ if(e != null)
+ {
+ _map.removeImpl(e.getDbKey());
+ }
+ return e;
+ }
+
+ public java.util.Map.Entry<K, V>
+ pollLastEntry()
+ {
+ EntryI<K, V> e = _view.last();
+ if(e != null)
+ {
+ _map.removeImpl(e.getDbKey());
+ }
+ return e;
+ }
+
+ //
+ // SortedMap methods
+ //
+
+ public java.util.Comparator<? super K>
+ comparator()
+ {
+ return _view.comparator();
+ }
+
+ public K
+ firstKey()
+ {
+ EntryI<K, V> e = _view.first();
+ if(e == null)
+ {
+ throw new java.util.NoSuchElementException();
+ }
+ return e.getKey();
+ }
+
+ public K
+ lastKey()
+ {
+ EntryI<K, V> e = _view.last();
+ if(e == null)
+ {
+ throw new java.util.NoSuchElementException();
+ }
+ return e.getKey();
+ }
+
+ public java.util.SortedMap<K, V>
+ headMap(K toKey)
+ {
+ return headMap(toKey, false);
+ }
+
+ public java.util.SortedMap<K, V>
+ tailMap(K fromKey)
+ {
+ return tailMap(fromKey, true);
+ }
+
+ public java.util.SortedMap<K, V>
+ subMap(K fromKey, K toKey)
+ {
+ return subMap(fromKey, true, toKey, false);
+ }
+
+ //
+ // Map methods
+ //
+
+ public java.util.Set<java.util.Map.Entry<K, V>>
+ entrySet()
+ {
+ if(_entrySet == null)
+ {
+ _entrySet = new java.util.AbstractSet<java.util.Map.Entry<K, V>>()
+ {
+ public java.util.Iterator<java.util.Map.Entry<K, V>>
+ iterator()
+ {
+ return new IteratorI<K, V>(_map, _view);
+ }
+
+ public boolean
+ contains(Object o)
+ {
+ //
+ // If the main map contains this object, verify it's within the range of this submap.
+ //
+ if(_map.entrySet().contains(o))
+ {
+ @SuppressWarnings("unchecked")
+ EntryI<K, V> entry = (EntryI<K, V>)o;
+ return _view.inRange(entry.getKey(), true);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public boolean
+ remove(Object o)
+ {
+ if(o instanceof EntryI)
+ {
+ @SuppressWarnings("unchecked")
+ EntryI<K, V> entry = (EntryI<K, V>)o;
+ return _view.inRange(entry.getKey(), true) && _map.entrySet().remove(o);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public int
+ size()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean
+ isEmpty()
+ {
+ try
+ {
+ firstKey();
+ return false;
+ }
+ catch(java.util.NoSuchElementException e)
+ {
+ return true;
+ }
+ }
+ };
+ }
+ return _entrySet;
+ }
+
+ //
+ // Put is not implemented (you have to put in the main map view)
+ //
+
+ public boolean
+ constainsKey(Object key)
+ {
+ @SuppressWarnings("unchecked")
+ K k = (K)key;
+ if(!_view.inRange(k, true))
+ {
+ return false;
+ }
+
+ return _map.containsKey(k);
+ }
+
+ public V
+ get(Object key)
+ {
+ @SuppressWarnings("unchecked")
+ K k = (K)key;
+ if(!_view.inRange(k, true))
+ {
+ return null;
+ }
+
+ return _map.get(k);
+ }
+
+ public V
+ remove(Object key)
+ {
+ @SuppressWarnings("unchecked")
+ K k = (K)key;
+ if(!_view.inRange(k, true))
+ {
+ return null;
+ }
+
+ return _map.remove(k);
+ }
+
+ private abstract class View implements IteratorModel<K, V>, Search.KeyValidator
+ {
+ protected
+ View(java.util.Comparator<? super K> comparator, K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
+ {
+ _comparator = comparator;
+ _fromKey = fromKey;
+ _fromInclusive = fromInclusive;
+ _toKey = toKey;
+ _toInclusive = toInclusive;
+
+ //
+ // Validate the key range.
+ //
+ if(_fromKey != null && _toKey != null)
+ {
+ int cmp = comparator.compare(_fromKey, _toKey);
+ if(cmp > 0 || (cmp == 0 && !(_fromInclusive && _toInclusive)))
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+
+ protected
+ View(View v, java.util.Comparator<? super K> comparator, K fromKey, boolean fromInclusive, K toKey,
+ boolean toInclusive)
+ {
+ this(comparator, fromKey, fromInclusive, toKey, toInclusive);
+
+ //
+ // Verify that the key range is correct with respect to the original view.
+ //
+ if(!v.inRange(_fromKey, _fromInclusive) || !v.inRange(_toKey, _toInclusive))
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ abstract Search.Type mapSearchType(Search.Type type);
+ abstract View copy(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive);
+ abstract View descendingView();
+
+ final EntryI<K, V>
+ first()
+ {
+ Search.Type type;
+ byte[] key = null;
+ if(_fromKey != null)
+ {
+ type = _fromInclusive ? mapSearchType(Search.Type.CEILING) : mapSearchType(Search.Type.HIGHER);
+ key = fromKeyBytes();
+ }
+ else
+ {
+ type = mapSearchType(Search.Type.FIRST);
+ }
+ return _map.entrySearch(type, key, true, this);
+ }
+
+ final EntryI<K, V>
+ last()
+ {
+ Search.Type type;
+ byte[] key = null;
+ if(_toKey != null)
+ {
+ type = _toInclusive ? mapSearchType(Search.Type.FLOOR) : mapSearchType(Search.Type.LOWER);
+ key = toKeyBytes();
+ }
+ else
+ {
+ type = mapSearchType(Search.Type.LAST);
+ }
+ return _map.entrySearch(type, key, true, this);
+ }
+
+ final EntryI<K, V>
+ ceiling(K key)
+ {
+ byte[] k = _map.encodeKey(key, _map.connection().getCommunicator());
+ return _map.entrySearch(mapSearchType(Search.Type.CEILING), k, true, this);
+ }
+
+ final EntryI<K, V>
+ floor(K key)
+ {
+ byte[] k = _map.encodeKey(key, _map.connection().getCommunicator());
+ return _map.entrySearch(mapSearchType(Search.Type.FLOOR), k, true, this);
+ }
+
+ final EntryI<K, V>
+ higher(K key)
+ {
+ byte[] k = _map.encodeKey(key, _map.connection().getCommunicator());
+ return _map.entrySearch(mapSearchType(Search.Type.HIGHER), k, true, this);
+ }
+
+ final EntryI<K, V>
+ lower(K key)
+ {
+ byte[] k = _map.encodeKey(key, _map.connection().getCommunicator());
+ return _map.entrySearch(mapSearchType(Search.Type.LOWER), k, true, this);
+ }
+
+ final View
+ subView(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
+ {
+ if(fromKey == null)
+ {
+ fromKey = _fromKey;
+ fromInclusive = _fromInclusive;
+ }
+ if(toKey == null)
+ {
+ toKey = _toKey;
+ toInclusive = _toInclusive;
+ }
+ return copy(fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ //
+ // IteratorModel methods (partial)
+ //
+
+ final public String
+ dbName()
+ {
+ return _map.dbName();
+ }
+
+ final public TraceLevels
+ traceLevels()
+ {
+ return _map.traceLevels();
+ }
+
+ final public com.sleepycat.db.Cursor
+ openCursor()
+ throws com.sleepycat.db.DatabaseException
+ {
+ return _map.openCursor();
+ }
+
+ //
+ // Search.KeyValidator methods
+ //
+
+ final public boolean
+ keyInRange(byte[] key)
+ {
+ K k = _map.decodeKey(key, _map.connection().getCommunicator());
+ return inRange(k, true);
+ }
+
+ final boolean
+ inRange(K key, boolean inclusive)
+ {
+ return !tooLow(key, inclusive, _fromKey, _fromInclusive) &&
+ !tooHigh(key, inclusive, _toKey, _toInclusive);
+ }
+
+ final java.util.Comparator<? super K>
+ comparator()
+ {
+ return _comparator;
+ }
+
+ final protected byte[]
+ fromKeyBytes()
+ {
+ if(_fromKey != null && _fromKeyBytes == null)
+ {
+ _fromKeyBytes = _map.encodeKey(_fromKey, _map.connection().getCommunicator());
+ }
+ return _fromKeyBytes;
+ }
+
+ final protected byte[]
+ toKeyBytes()
+ {
+ if(_toKey != null && _toKeyBytes == null)
+ {
+ _toKeyBytes = _map.encodeKey(_toKey, _map.connection().getCommunicator());
+ }
+ return _toKeyBytes;
+ }
+
+ final protected boolean
+ tooLow(K key, boolean inclusive, K targetKey, boolean targetInclusive)
+ {
+ if(key != null && targetKey != null)
+ {
+ int cmp = comparator().compare(key, targetKey);
+ if(cmp < 0 || (cmp == 0 && inclusive && !targetInclusive))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ final protected boolean
+ tooHigh(K key, boolean inclusive, K targetKey, boolean targetInclusive)
+ {
+ if(key != null && targetKey != null)
+ {
+ int cmp = comparator().compare(key, targetKey);
+ if(cmp > 0 || (cmp == 0 && inclusive && !targetInclusive))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ final java.util.Comparator<? super K> _comparator;
+ final K _fromKey;
+ final boolean _fromInclusive;
+ final K _toKey;
+ final boolean _toInclusive;
+ private byte[] _fromKeyBytes;
+ private byte[] _toKeyBytes;
+ }
+
+ private class AscendingView extends View
+ {
+ AscendingView(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
+ {
+ super(_map.comparator(), fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ AscendingView(View v, K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
+ {
+ super(v, _map.comparator(), fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ //
+ // View methods
+ //
+
+ Search.Type
+ mapSearchType(Search.Type type)
+ {
+ return type;
+ }
+
+ View
+ copy(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
+ {
+ return new AscendingView(this, fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ View
+ descendingView()
+ {
+ return new DescendingView(this, _toKey, _toInclusive, _fromKey, _fromInclusive);
+ }
+
+ //
+ // IteratorModel methods
+ //
+
+ public EntryI<K, V>
+ firstEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException
+ {
+ return _map.firstEntry(cursor, _fromKey, _fromInclusive, _toKey, _toInclusive);
+ }
+
+ public EntryI<K, V>
+ nextEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException
+ {
+ return _map.nextEntry(cursor, _toKey, _toInclusive);
+ }
+ }
+
+ private class DescendingView extends View
+ {
+ DescendingView(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
+ {
+ super(java.util.Collections.reverseOrder(_map.comparator()), fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ DescendingView(View v, K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
+ {
+ super(v, java.util.Collections.reverseOrder(_map.comparator()), fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ //
+ // View methods
+ //
+
+ Search.Type
+ mapSearchType(Search.Type type)
+ {
+ return type.descending();
+ }
+
+ View
+ copy(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
+ {
+ return new DescendingView(this, fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ View
+ descendingView()
+ {
+ return new AscendingView(this, _toKey, _toInclusive, _fromKey, _fromInclusive);
+ }
+
+ //
+ // IteratorModel methods
+ //
+
+ public EntryI<K, V>
+ firstEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException
+ {
+ return _map.lastEntry(cursor, _fromKey, _fromInclusive, _toKey, _toInclusive);
+ }
+
+ public EntryI<K, V>
+ nextEntry(com.sleepycat.db.Cursor cursor)
+ throws com.sleepycat.db.DatabaseException
+ {
+ return _map.previousEntry(cursor, _toKey, _toInclusive);
+ }
+ }
+
+ private final MapI<K, V> _map;
+ private final View _view;
+ private java.util.Set<java.util.Map.Entry<K, V>> _entrySet;
+ private NavigableMap<K, V> _descendingMap;
+}
diff --git a/java/src/Freeze/MapInternal/TraceLevels.java b/java/src/Freeze/MapInternal/TraceLevels.java
new file mode 100644
index 00000000000..a6058f14f39
--- /dev/null
+++ b/java/src/Freeze/MapInternal/TraceLevels.java
@@ -0,0 +1,28 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Freeze.MapInternal;
+
+import Freeze.ConnectionI;
+
+class TraceLevels
+{
+ TraceLevels(ConnectionI connection, String dbName)
+ {
+ errorPrefix = "Freeze DB DbEnv(\"" + connection.envName() + "\") Db(\"" + dbName + "\"): ";
+ level = connection.trace();
+ deadlockWarning = connection.deadlockWarning();
+ logger = connection.getCommunicator().getLogger();
+ }
+
+ final String errorPrefix;
+ final int level;
+ final boolean deadlockWarning;
+ final Ice.Logger logger;
+}
diff --git a/java/src/Freeze/NavigableMap.java b/java/src/Freeze/NavigableMap.java
new file mode 100644
index 00000000000..7d9e3ecfbc8
--- /dev/null
+++ b/java/src/Freeze/NavigableMap.java
@@ -0,0 +1,42 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package Freeze;
+
+public interface NavigableMap<K, V> extends java.util.SortedMap<K, V>
+{
+ //
+ // Faster alternative to the standard remove() method because it
+ // doesn't read and decode the old value.
+ //
+ boolean fastRemove(K key);
+
+ java.util.Map.Entry<K, V> firstEntry();
+ java.util.Map.Entry<K, V> lastEntry();
+
+ java.util.Map.Entry<K, V> ceilingEntry(K key);
+ java.util.Map.Entry<K, V> floorEntry(K key);
+ java.util.Map.Entry<K, V> higherEntry(K key);
+ java.util.Map.Entry<K, V> lowerEntry(K key);
+
+ K ceilingKey(K key);
+ K floorKey(K key);
+ K higherKey(K key);
+ K lowerKey(K key);
+
+ java.util.Set<K> descendingKeySet();
+ NavigableMap<K, V> descendingMap();
+
+ NavigableMap<K, V> headMap(K toKey, boolean inclusive);
+ NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive);
+ NavigableMap<K, V> tailMap(K fromKey, boolean inclusive);
+
+ java.util.Map.Entry<K, V> pollFirstEntry();
+ java.util.Map.Entry<K, V> pollLastEntry();
+}
diff --git a/java/src/Freeze/ObjectStore.java b/java/src/Freeze/ObjectStore.java
index 1bf9f3ee1db..6bbdfa5024a 100644
--- a/java/src/Freeze/ObjectStore.java
+++ b/java/src/Freeze/ObjectStore.java
@@ -11,17 +11,17 @@ package Freeze;
class ObjectStore implements IceUtil.Store
{
- ObjectStore(String facet, String facetType, boolean createDb, EvictorI evictor,
- java.util.List indices, boolean populateEmptyIndices)
+ ObjectStore(String facet, String facetType, boolean createDb, EvictorI evictor, java.util.List<Index> indices,
+ boolean populateEmptyIndices)
{
_cache = new IceUtil.Cache(this);
-
+
_facet = facet;
-
+
_evictor = evictor;
_indices = indices;
_communicator = evictor.communicator();
-
+
if(facet.equals(""))
{
_dbName = EvictorI.defaultDb;
@@ -39,30 +39,29 @@ class ObjectStore implements IceUtil.Store
Ice.ObjectFactory factory = _communicator.findObjectFactory(facetType);
if(factory == null)
{
- throw new DatabaseException(_evictor.errorPrefix() + "No object factory registered for type-id '"
- + facetType + "'");
+ throw new DatabaseException(_evictor.errorPrefix() + "No object factory registered for type-id '" +
+ facetType + "'");
}
-
+
_sampleServant = factory.create(facetType);
}
-
Connection connection = Util.createConnection(_communicator, evictor.dbEnv().getEnvName());
try
{
- Catalog catalog = new Catalog(connection, Util.catalogName(), true);
- CatalogData catalogData = (CatalogData)catalog.get(evictor.filename());
-
+ Catalog catalog = new Catalog(connection, Util.catalogName(), true);
+ CatalogData catalogData = catalog.get(evictor.filename());
+
if(catalogData != null && catalogData.evictor == false)
{
DatabaseException ex = new DatabaseException();
ex.message = _evictor.errorPrefix() + evictor.filename() + " is not an evictor database";
throw ex;
}
-
+
com.sleepycat.db.Environment dbEnv = evictor.dbEnv().getEnv();
-
+
//
// TODO: FREEZE_DB_MODE
//
@@ -72,18 +71,19 @@ class ObjectStore implements IceUtil.Store
Ice.Properties properties = _evictor.communicator().getProperties();
String propPrefix = "Freeze.Evictor." + _evictor.filename() + ".";
-
+
int btreeMinKey = properties.getPropertyAsInt(propPrefix + _dbName + ".BtreeMinKey");
if(btreeMinKey > 2)
{
if(_evictor.trace() >= 1)
{
_evictor.communicator().getLogger().trace(
- "Freeze.Evictor", "Setting \"" + _evictor.filename() + "." + _dbName + "\"'s btree minkey to " + btreeMinKey);
+ "Freeze.Evictor", "Setting \"" + _evictor.filename() + "." + _dbName +
+ "\"'s btree minkey to " + btreeMinKey);
}
config.setBtreeMinKey(btreeMinKey);
}
-
+
boolean checksum = properties.getPropertyAsInt(propPrefix + "Checksum") > 0;
if(checksum)
{
@@ -92,10 +92,10 @@ class ObjectStore implements IceUtil.Store
_evictor.communicator().getLogger().trace(
"Freeze.Evictor", "Turning checksum on for \"" + _evictor.filename() + "\"");
}
-
+
config.setChecksum(true);
}
-
+
int pageSize = properties.getPropertyAsInt(propPrefix + "PageSize");
if(pageSize > 0)
{
@@ -107,21 +107,18 @@ class ObjectStore implements IceUtil.Store
config.setPageSize(pageSize);
}
-
try
- {
+ {
Transaction tx = connection.beginTransaction();
com.sleepycat.db.Transaction txn = Util.getTxn(tx);
_db = dbEnv.openDatabase(txn, evictor.filename(), _dbName, config);
- java.util.Iterator p = _indices.iterator();
- while(p.hasNext())
+ for(Index index : _indices)
{
- Index index = (Index) p.next();
index.associate(this, txn, createDb, populateEmptyIndices);
}
-
+
if(catalogData == null)
{
catalogData = new CatalogData();
@@ -172,11 +169,9 @@ class ObjectStore implements IceUtil.Store
try
{
_db.close();
-
- java.util.Iterator p = _indices.iterator();
- while(p.hasNext())
+
+ for(Index index : _indices)
{
- Index index = (Index)p.next();
index.close();
}
_indices.clear();
@@ -190,7 +185,7 @@ class ObjectStore implements IceUtil.Store
}
_db = null;
}
-
+
boolean
dbHasObject(Ice.Identity ident, TransactionI transaction)
{
@@ -205,22 +200,21 @@ class ObjectStore implements IceUtil.Store
}
}
-
byte[] key = marshalKey(ident, _communicator);
com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(key);
-
+
//
// Keep 0 length since we're not interested in the data
//
com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
dbValue.setPartial(true);
-
+
for(;;)
{
try
- {
+ {
com.sleepycat.db.OperationStatus err = _db.get(tx, dbKey, dbValue, null);
-
+
if(err == com.sleepycat.db.OperationStatus.SUCCESS)
{
return true;
@@ -239,8 +233,7 @@ class ObjectStore implements IceUtil.Store
if(_evictor.deadlockWarning())
{
_communicator.getLogger().warning("Deadlock in Freeze.ObjectStore.dhHasObject while reading " +
- "Db \"" + _evictor.filename() + "/" + _dbName +
- "\"");
+ "Db \"" + _evictor.filename() + "/" + _dbName + "\"");
}
if(tx != null)
@@ -376,19 +369,19 @@ class ObjectStore implements IceUtil.Store
{
return _db;
}
-
+
final Ice.Communicator
communicator()
{
return _communicator;
}
-
+
final EvictorI
evictor()
{
return _evictor;
}
-
+
final String
facet()
{
@@ -424,9 +417,9 @@ class ObjectStore implements IceUtil.Store
for(;;)
{
try
- {
+ {
com.sleepycat.db.OperationStatus rs = _db.get(null, dbKey, dbValue, null);
-
+
if(rs == com.sleepycat.db.OperationStatus.NOTFOUND)
{
return null;
@@ -461,7 +454,7 @@ class ObjectStore implements IceUtil.Store
ObjectRecord rec = unmarshalValue(dbValue.getData(), _communicator);
_evictor.initialize(ident, _facet, rec.servant);
-
+
Object result = _evictor.createEvictorElement(ident, rec, this);
return result;
}
@@ -489,9 +482,9 @@ class ObjectStore implements IceUtil.Store
com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry();
try
- {
+ {
com.sleepycat.db.OperationStatus rs = _db.get(tx, dbKey, dbValue, null);
-
+
if(rs == com.sleepycat.db.OperationStatus.NOTFOUND)
{
return null;
@@ -509,9 +502,9 @@ class ObjectStore implements IceUtil.Store
_communicator.getLogger().warning("Deadlock in Freeze.ObjectStore.load while reading Db \"" +
_evictor.filename() + "/" + _dbName + "\"");
}
-
- DeadlockException ex = new DeadlockException(_evictor.errorPrefix() + "Db.get: " + dx.getMessage(),
- transaction);
+
+ DeadlockException ex = new DeadlockException(
+ _evictor.errorPrefix() + "Db.get: " + dx.getMessage(), transaction);
ex.initCause(dx);
throw ex;
}
@@ -528,7 +521,6 @@ class ObjectStore implements IceUtil.Store
return rec;
}
-
void
update(Ice.Identity ident, ObjectRecord objectRecord, TransactionI transaction)
{
@@ -546,12 +538,13 @@ class ObjectStore implements IceUtil.Store
{
String msg = _evictor.errorPrefix() + "Attempting to save a '" + objectRecord.servant.ice_id()
+ "' servant in a database of '" + _sampleServant.ice_id() + "' servants";
-
+
throw new DatabaseException(msg);
}
com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(marshalKey(ident, _communicator));
- com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(marshalValue(objectRecord, _communicator));
+ com.sleepycat.db.DatabaseEntry dbValue =
+ new com.sleepycat.db.DatabaseEntry(marshalValue(objectRecord, _communicator));
try
{
@@ -568,7 +561,7 @@ class ObjectStore implements IceUtil.Store
_communicator.getLogger().warning("Deadlock in Freeze.ObjectStore.update while updating Db \"" +
_evictor.filename() + "/" + _dbName + "\"");
}
-
+
DeadlockException ex = new DeadlockException(
_evictor.errorPrefix() + "Db.put: " + dx.getMessage(), transaction);
ex.initCause(dx);
@@ -598,13 +591,14 @@ class ObjectStore implements IceUtil.Store
}
com.sleepycat.db.DatabaseEntry dbKey = new com.sleepycat.db.DatabaseEntry(marshalKey(ident, _communicator));
- com.sleepycat.db.DatabaseEntry dbValue = new com.sleepycat.db.DatabaseEntry(marshalValue(objectRecord, _communicator));
+ com.sleepycat.db.DatabaseEntry dbValue =
+ new com.sleepycat.db.DatabaseEntry(marshalValue(objectRecord, _communicator));
if(_sampleServant != null && !objectRecord.servant.ice_id().equals(_sampleServant.ice_id()))
{
- String msg = _evictor.errorPrefix() + "Attempting to save a '" + objectRecord.servant.ice_id()
- + "' servant in a database of '" + _sampleServant.ice_id() + "' servants";
-
+ String msg = _evictor.errorPrefix() + "Attempting to save a '" + objectRecord.servant.ice_id() +
+ "' servant in a database of '" + _sampleServant.ice_id() + "' servants";
+
throw new DatabaseException(msg);
}
@@ -621,7 +615,7 @@ class ObjectStore implements IceUtil.Store
_communicator.getLogger().warning("Deadlock in Freeze.ObjectStore.update while updating Db \"" +
_evictor.filename() + "/" + _dbName + "\"");
}
-
+
if(tx != null)
{
DeadlockException ex = new DeadlockException(
@@ -645,7 +639,7 @@ class ObjectStore implements IceUtil.Store
boolean
remove(Ice.Identity ident, TransactionI transaction)
- {
+ {
com.sleepycat.db.Transaction tx = null;
if(transaction != null)
@@ -675,8 +669,8 @@ class ObjectStore implements IceUtil.Store
if(tx != null)
{
- DeadlockException ex = new DeadlockException(_evictor.errorPrefix() + "Db.delete: " + dx.getMessage(),
- transaction);
+ DeadlockException ex = new DeadlockException(
+ _evictor.errorPrefix() + "Db.delete: " + dx.getMessage(), transaction);
ex.initCause(dx);
throw ex;
}
@@ -700,7 +694,7 @@ class ObjectStore implements IceUtil.Store
private final String _facet;
private final String _dbName;
private final EvictorI _evictor;
- private final java.util.List _indices;
+ private final java.util.List<Index> _indices;
private final Ice.Communicator _communicator;
private com.sleepycat.db.Database _db;
diff --git a/java/src/Freeze/SharedDbEnv.java b/java/src/Freeze/SharedDbEnv.java
index 983740d0f06..b39088ec48f 100644
--- a/java/src/Freeze/SharedDbEnv.java
+++ b/java/src/Freeze/SharedDbEnv.java
@@ -9,7 +9,7 @@
package Freeze;
-class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
+public class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
{
public static SharedDbEnv
get(Ice.Communicator communicator, String envName, com.sleepycat.db.Environment dbEnv)
@@ -20,12 +20,12 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
synchronized(_map)
{
- result = (SharedDbEnv)_map.get(key);
+ result = _map.get(key);
if(result == null)
{
result = new SharedDbEnv(key, dbEnv);
- Object previousValue = _map.put(key, result);
+ SharedDbEnv previousValue = _map.put(key, result);
assert(previousValue == null);
}
else
@@ -40,9 +40,9 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
//
// Returns a shared map Db; the caller should NOT close this Db.
//
- MapDb getSharedMapDb(String dbName, String key, String value,
- java.util.Comparator comparator, Map.Index[] indices, java.util.Map indexComparators,
- boolean createDb)
+ public MapDb
+ getSharedMapDb(String dbName, String key, String value, java.util.Comparator comparator, MapIndex[] indices,
+ boolean createDb)
{
if(dbName.equals(_catalog.dbName()))
{
@@ -64,14 +64,14 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
try
{
- db = new MapDb(insertConnection, dbName, key, value, comparator, indices, indexComparators, createDb);
+ db = new MapDb(insertConnection, dbName, key, value, comparator, indices, createDb);
}
finally
{
insertConnection.close();
}
- Object previousValue = _sharedDbMap.put(dbName, db);
+ MapDb previousValue = _sharedDbMap.put(dbName, db);
assert(previousValue == null);
}
else
@@ -86,7 +86,8 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
//
// Tell SharedDbEnv to close and remove this Shared Db from the map
//
- void removeSharedMapDb(String dbName)
+ public void
+ removeSharedMapDb(String dbName)
{
synchronized(_sharedDbMap)
{
@@ -126,7 +127,7 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
//
// Remove from map
//
- Object value = _map.remove(_key);
+ SharedDbEnv value = _map.remove(_key);
assert(value == this);
//
@@ -188,11 +189,9 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
_key.communicator.getLogger().error("Freeze database error in DbEnv \"" + _key.envName + "\": " + message);
}
-
//
// EvictorContext factory/manager
//
-
//
// Create an evictor context associated with the calling thread
@@ -200,9 +199,9 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
synchronized TransactionalEvictorContext
createCurrent()
{
- Object k = Thread.currentThread();
+ Thread t = Thread.currentThread();
- TransactionalEvictorContext ctx = (TransactionalEvictorContext)_ctxMap.get(k);
+ TransactionalEvictorContext ctx = _ctxMap.get(t);
assert ctx == null;
ctx = new TransactionalEvictorContext(this);
@@ -210,7 +209,7 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
{
_refCount++; // owned by the underlying ConnectionI
}
- _ctxMap.put(k, ctx);
+ _ctxMap.put(t, ctx);
return ctx;
}
@@ -218,8 +217,8 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
synchronized TransactionalEvictorContext
getCurrent()
{
- Object k = Thread.currentThread();
- return (TransactionalEvictorContext)_ctxMap.get(k);
+ Thread t = Thread.currentThread();
+ return _ctxMap.get(t);
}
synchronized void
@@ -245,20 +244,20 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
}
}
- Object k = Thread.currentThread();
+ Thread t = Thread.currentThread();
if(txi != null)
{
- TransactionalEvictorContext ctx = (TransactionalEvictorContext)_ctxMap.get(k);
+ TransactionalEvictorContext ctx = _ctxMap.get(t);
if(ctx == null || !tx.equals(ctx.transaction()))
{
ctx = new TransactionalEvictorContext(txi, getCommunicator());
- _ctxMap.put(k, ctx);
+ _ctxMap.put(t, ctx);
}
}
else
{
- _ctxMap.put(k, null);
+ _ctxMap.put(t, null);
}
}
@@ -357,7 +356,8 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
}
}
- _catalog = new MapDb(_key.communicator, _key.envName, Util.catalogName(), "string", "::Freeze::CatalogData", _dbEnv);
+ _catalog = new MapDb(_key.communicator, _key.envName, Util.catalogName(), "string",
+ "::Freeze::CatalogData", _dbEnv);
_catalogIndexList = new MapDb(_key.communicator, _key.envName, Util.catalogIndexListName(),
"string", "::Ice::StringSeq", _dbEnv);
}
@@ -499,7 +499,8 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
}
}
- public int hashCode()
+ public int
+ hashCode()
{
return envName.hashCode() ^ communicator.hashCode();
}
@@ -517,12 +518,10 @@ class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
private int _kbyte = 0;
private Thread _thread;
- private java.util.Map _ctxMap = new java.util.HashMap();
+ private java.util.Map<Thread, TransactionalEvictorContext> _ctxMap =
+ new java.util.HashMap<Thread, TransactionalEvictorContext>();
private java.util.Map<String, MapDb> _sharedDbMap = new java.util.HashMap<String, MapDb>();
- //
- // Hash map of (MapKey, SharedDbEnv)
- //
- private static java.util.Map _map = new java.util.HashMap();
+ private static java.util.Map<MapKey, SharedDbEnv> _map = new java.util.HashMap<MapKey, SharedDbEnv>();
}
diff --git a/java/src/Freeze/SubMap.java b/java/src/Freeze/SubMap.java
deleted file mode 100644
index f7b9f94ea6c..00000000000
--- a/java/src/Freeze/SubMap.java
+++ /dev/null
@@ -1,476 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
-//
-// This copy of Ice is licensed to you under the terms described in the
-// ICE_LICENSE file included in this distribution.
-//
-// **********************************************************************
-
-package Freeze;
-
-//
-// Sub-map of a Freeze Map or of another submap
-//
-//
-// When it's based of an index, the key is the index key and the value
-// is a Set of Map.Entry.
-//
-
-class SubMap extends java.util.AbstractMap implements java.util.SortedMap
-{
- private class IndexValue extends java.util.AbstractSet
- {
- public java.util.Iterator
- iterator()
- {
- return _index.untypedFind(_myKey, true);
- }
-
- public int
- size()
- {
- return _index.untypedCount(_myKey);
- }
-
- public boolean equals(Object o)
- {
- if(o instanceof IndexValue)
- {
- IndexValue indexValue = (IndexValue)o;
- return indexValue._myKey.equals(_myKey);
- }
- else
- {
- return false;
- }
- }
-
- public int hashCode()
- {
- return _myKey.hashCode();
- }
-
- private IndexValue(Object key)
- {
- _myKey = key;
- }
-
- private Object
- getKey()
- {
- return _myKey;
- }
-
- private Object _myKey;
- }
-
- private class IndexEntry implements java.util.Map.Entry
- {
- public Object getKey()
- {
- return _value.getKey();
- }
-
- public Object getValue()
- {
- return _value;
- }
-
- public Object setValue(Object value)
- {
- throw new UnsupportedOperationException();
- }
-
- public boolean equals(Object o)
- {
- if(o instanceof IndexEntry)
- {
- IndexEntry indexEntry = (IndexEntry)o;
- return indexEntry._value.equals(_value);
- }
- else
- {
- return false;
- }
- }
-
- public int hashCode()
- {
- return _value.hashCode();
- }
-
- SubMap parent()
- {
- return SubMap.this;
- }
-
- private IndexEntry(Object key)
- {
- _value = new IndexValue(key);
- }
-
- private IndexValue _value;
- }
-
- private class IndexIterator implements Map.EntryIterator
- {
- public boolean hasNext()
- {
- return _iterator.hasNext();
- }
-
- public Object next()
- {
- Map.Entry entry = (Map.Entry)_iterator.next();
- return new IndexEntry(_index.decodeKey(entry.getIndexBytes(),
- _map.connection().communicator()));
- }
-
- public void remove()
- {
- _iterator.remove();
- }
-
- public void close()
- {
- _iterator.close();
- }
-
- public void destroy()
- {
- close();
- }
-
- private IndexIterator()
- {
- assert _index != null;
- _iterator = _map.createIterator(_index, _fromKey, _toKey);
- }
-
- Map.EntryIterator _iterator;
- }
-
- SubMap(Map map, Object fromKey, Object toKey)
- {
- _fromKey = fromKey;
- _toKey = toKey;
- _map = map;
- _index = null;
-
- if(fromKey != null && toKey != null)
- {
- if(map.comparator().compare(fromKey, toKey) >= 0)
- {
- throw new IllegalArgumentException();
- }
- }
- }
-
- SubMap(Map.Index index, Object fromKey, Object toKey)
- {
- _fromKey = fromKey;
- _toKey = toKey;
- _map = index.parent();
- _index = index;
-
- if(fromKey != null && toKey != null)
- {
- if(index.comparator().compare(fromKey, toKey) >= 0)
- {
- throw new IllegalArgumentException();
- }
- }
- }
-
- private SubMap(SubMap subMap, Object fromKey, Object toKey)
- {
- _fromKey = fromKey;
- _toKey = toKey;
- _map = subMap._map;
- _index = subMap._index;
-
- if(fromKey != null && toKey != null)
- {
- if(comparator().compare(fromKey, toKey) >= 0)
- {
- throw new IllegalArgumentException();
- }
- }
- }
-
- //
- // SortedMap methods
- //
- public java.util.Comparator comparator()
- {
- if(_index != null)
- {
- return _index.comparator();
- }
- else
- {
- return _map.comparator();
- }
- }
-
- public Object firstKey()
- {
- return _index != null ?
- _index.firstKey(_fromKey, _toKey) :
- _map.firstKey(_fromKey, _toKey);
- }
-
- public Object lastKey()
- {
- return _index != null ?
- _index.lastKey(_fromKey, _toKey) :
- _map.lastKey(_fromKey, _toKey);
- }
-
- public java.util.SortedMap headMap(Object toKey)
- {
- if(toKey == null)
- {
- throw new NullPointerException();
- }
- return new SubMap(this, _fromKey, toKey);
-
- }
-
- public java.util.SortedMap tailMap(Object fromKey)
- {
- if(fromKey == null)
- {
- throw new NullPointerException();
- }
- return new SubMap(this, fromKey, _toKey);
- }
-
- public java.util.SortedMap subMap(Object fromKey, Object toKey)
- {
- if(fromKey == null || toKey == null )
- {
- throw new NullPointerException();
- }
- return new SubMap(this, fromKey, toKey);
- }
-
- //
- // java.util.Map methods
- //
- public java.util.Set
- entrySet()
- {
- if(_entrySet == null)
- {
- _entrySet = new java.util.AbstractSet()
- {
- public java.util.Iterator
- iterator()
- {
- if(_index == null)
- {
- return _map.createIterator(_index, _fromKey, _toKey);
- }
- else
- {
- return new IndexIterator();
- }
- }
-
- public boolean
- contains(Object o)
- {
- if(_index == null)
- {
- //
- // If the main map contains this object, check it's within [fromKey, toKey[
- //
- if(_map.entrySet().contains(o))
- {
- Map.Entry entry = (Map.Entry)o;
- return inRange(entry.getKey());
- }
- else
- {
- return false;
- }
- }
- else
- {
- if(o instanceof IndexEntry)
- {
- IndexEntry indexEntry = (IndexEntry)o;
- return indexEntry.parent() == SubMap.this &&
- _index.containsKey(indexEntry.getKey());
- }
- else
- {
- return false;
- }
- }
- }
-
- public boolean
- remove(Object o)
- {
- if(_index == null)
- {
- if(o instanceof Map.Entry)
- {
- Map.Entry entry = (Map.Entry)o;
- return inRange(entry.getKey()) && _map.entrySet().remove(o);
- }
- else
- {
- return false;
- }
- }
- else
- {
- //
- // Not yet implemented, should remove all objects that
- // match this index-key
- //
- throw new UnsupportedOperationException();
- }
- }
-
- public int
- size()
- {
- throw new UnsupportedOperationException();
- }
-
- public boolean
- isEmpty()
- {
- try
- {
- firstKey();
- return false;
- }
- catch(NoSuchElementException e)
- {
- return true;
- }
- }
- };
- }
- return _entrySet;
- }
-
- //
- // Put is not implemented (you have to put in the main map view)
- //
-
-
- public boolean constainsKey(Object key)
- {
- if(!inRange(key))
- {
- return false;
- }
-
- //
- // Then check if it's in the map
- //
- if(_index == null)
- {
- return _map.containsKey(key);
- }
- else
- {
- return _index.containsKey(key);
- }
- }
-
-
- public Object
- get(Object key)
- {
- if(!inRange(key))
- {
- return null;
- }
-
- if(_index == null)
- {
- return _map.get(key);
- }
- else
- {
- if(_index.containsKey(key))
- {
- return new IndexValue(key);
- }
- else
- {
- return null;
- }
- }
- }
-
- public Object
- remove(Object key)
- {
- if(!inRange(key))
- {
- return null;
- }
-
- if(_index == null)
- {
- return _map.remove(key);
- }
- else
- {
- //
- // Not yet implemented
- //
- throw new UnsupportedOperationException();
- }
- }
-
- public boolean
- fastRemove(Object key)
- {
- if(!inRange(key))
- {
- return false;
- }
-
- if(_index == null)
- {
- return _map.fastRemove(key);
- }
- else
- {
- //
- // Not yet implemented
- //
- throw new UnsupportedOperationException();
- }
- }
-
-
- private boolean inRange(Object key)
- {
- if(_fromKey != null && comparator().compare(_fromKey, key) > 0)
- {
- return false;
- }
- if(_toKey != null && comparator().compare(key, _toKey) >= 0)
- {
- return false;
- }
- return true;
- }
-
- private final Object _fromKey;
- private final Object _toKey;
- private final Map _map;
- private final Map.Index _index;
- private java.util.Set _entrySet;
-}
diff --git a/java/src/Freeze/TransactionI.java b/java/src/Freeze/TransactionI.java
index 2644f9c0fee..7d311acb2b9 100644
--- a/java/src/Freeze/TransactionI.java
+++ b/java/src/Freeze/TransactionI.java
@@ -29,7 +29,7 @@ class TransactionI implements Transaction
if(_txTrace >= 1)
{
- txnId = Long.toHexString((_txn.getId() & 0x7FFFFFFF) + 0x80000000L);
+ txnId = Long.toHexString((_txn.getId() & 0x7FFFFFFF) + 0x80000000L);
}
_txn.commit();
@@ -37,8 +37,8 @@ class TransactionI implements Transaction
if(_txTrace >= 1)
{
- _connection.communicator().getLogger().trace("Freeze.Transaction", _errorPrefix + "committed transaction " +
- txnId);
+ _connection.communicator().getLogger().trace("Freeze.Transaction", _errorPrefix +
+ "committed transaction " + txnId);
}
}
catch(com.sleepycat.db.DeadlockException e)
@@ -97,18 +97,18 @@ class TransactionI implements Transaction
try
{
_connection.closeAllIterators();
-
+
if(_txTrace >= 1)
{
- txnId = Long.toHexString((_txn.getId() & 0x7FFFFFFF) + 0x80000000L);
+ txnId = Long.toHexString((_txn.getId() & 0x7FFFFFFF) + 0x80000000L);
}
_txn.abort();
if(_txTrace >= 1)
{
- _connection.communicator().getLogger().trace("Freeze.Transaction", _errorPrefix + "rolled back transaction " +
- txnId);
+ _connection.communicator().getLogger().trace("Freeze.Transaction", _errorPrefix +
+ "rolled back transaction " + txnId);
}
}
catch(com.sleepycat.db.DeadlockException e)
@@ -152,7 +152,7 @@ class TransactionI implements Transaction
postCompletion(false, deadlock);
}
}
-
+
public Connection
getConnection()
{
@@ -168,13 +168,13 @@ class TransactionI implements Transaction
try
{
_txn = _connection.dbEnv().getEnv().beginTransaction(null, null);
-
+
if(_txTrace >= 1)
{
- String txnId = Long.toHexString((_txn.getId() & 0x7FFFFFFF) + 0x80000000L);
+ String txnId = Long.toHexString((_txn.getId() & 0x7FFFFFFF) + 0x80000000L);
- _connection.communicator().getLogger().trace("Freeze.Transaction", _errorPrefix + "started transaction " +
- txnId);
+ _connection.communicator().getLogger().trace("Freeze.Transaction", _errorPrefix +
+ "started transaction " + txnId);
}
}
catch(com.sleepycat.db.DatabaseException e)
@@ -192,13 +192,13 @@ class TransactionI implements Transaction
}
}
- void
+ void
setPostCompletionCallback(PostCompletionCallback cb)
{
_postCompletionCallback = cb;
}
- void
+ void
adoptConnection()
{
_ownConnection = true;
@@ -209,14 +209,13 @@ class TransactionI implements Transaction
{
return _connection;
}
-
+
com.sleepycat.db.Transaction
dbTxn()
{
return _txn;
}
-
private void
postCompletion(boolean committed, boolean deadlock)
{
diff --git a/java/src/Freeze/TransactionalEvictorContext.java b/java/src/Freeze/TransactionalEvictorContext.java
index 094b310b590..d934eb56e29 100644
--- a/java/src/Freeze/TransactionalEvictorContext.java
+++ b/java/src/Freeze/TransactionalEvictorContext.java
@@ -16,9 +16,9 @@ package Freeze;
class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallback, PostCompletionCallback
{
- public void
+ public void
postCompletion(boolean committed, boolean deadlock)
- {
+ {
try
{
if(committed)
@@ -26,10 +26,8 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
//
// Remove updated & removed objects from cache
//
- java.util.Iterator p = _invalidateList.iterator();
- while(p.hasNext())
+ for(ToInvalidate ti : _invalidateList)
{
- ToInvalidate ti = (ToInvalidate)p.next();
ti.invalidate();
}
_invalidateList.clear();
@@ -106,14 +104,13 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
return true;
}
-
class ServantHolder
{
ServantHolder(Ice.Current current, ObjectStore store)
{
_current = current;
_store = store;
-
+
ServantHolder sh = findServantHolder(_current.id, _store);
if(sh != null)
{
@@ -124,9 +121,9 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
if(_trace >= 3)
{
- _communicator.getLogger().trace("Freeze.Evictor", "found \""
- + _communicator.identityToString(_current.id) +"\" with facet \"" + _store.facet()
- + "\" in current context");
+ _communicator.getLogger().trace("Freeze.Evictor", "found \"" +
+ _communicator.identityToString(_current.id) +
+ "\" with facet \"" + _store.facet() + "\" in current context");
}
}
}
@@ -140,9 +137,10 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
{
if(_trace >= 3)
{
- _communicator.getLogger().trace("Freeze.Evictor", "loaded \""
- + _communicator.identityToString(_current.id) +"\" with facet \"" + _store.facet()
- + "\" into current context");
+ _communicator.getLogger().trace("Freeze.Evictor", "loaded \"" +
+ _communicator.identityToString(_current.id) +
+ "\" with facet \"" + _store.facet() +
+ "\" into current context");
}
_stack.push(this);
@@ -151,7 +149,7 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
}
}
- void
+ void
markReadWrite()
{
if(_ownServant)
@@ -167,7 +165,7 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
}
}
- void
+ void
release()
{
if(_ownServant)
@@ -181,12 +179,13 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
if(_trace >= 3)
{
- _communicator.getLogger().trace("Freeze.Evictor", "updated \""
- + _communicator.identityToString(_current.id) +"\" with facet \"" + _store.facet()
- + "\" within transaction");
+ _communicator.getLogger().trace("Freeze.Evictor", "updated \"" +
+ _communicator.identityToString(_current.id) +
+ "\" with facet \"" + _store.facet() +
+ "\" within transaction");
}
}
-
+
if(!_readOnly || _removed)
{
_invalidateList.add(new ToInvalidate(_current.id, _store));
@@ -195,15 +194,15 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
_stack.pop();
}
}
-
+
boolean
matches(Ice.Identity ident, ObjectStore store)
{
return ident.equals(_current.id) && store == _store;
}
- Ice.Object
- servant()
+ Ice.Object
+ servant()
{
if(_rec == null)
{
@@ -215,12 +214,12 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
}
}
- void
+ void
removed()
{
_removed = true;
}
-
+
private boolean _ownServant = false;
private boolean _removed = false;
private boolean _readOnly = true;
@@ -228,8 +227,7 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
private final Ice.Current _current;
private final ObjectStore _store;
private ObjectRecord _rec;
- };
-
+ }
TransactionalEvictorContext(SharedDbEnv dbEnv)
{
@@ -277,7 +275,6 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
}
}
-
void
checkDeadlockException()
{
@@ -296,16 +293,15 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
clearUserException()
{
//
- // No need to synchronize; _userExceptionDetected is only read/written by the
+ // No need to synchronize; _userExceptionDetected is only read/written by the
// dispatch thread
//
boolean result = _userExceptionDetected;
_userExceptionDetected = false;
return result;
}
-
-
- TransactionI
+
+ TransactionI
transaction()
{
return _tx;
@@ -316,7 +312,7 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
{
return new ServantHolder(current, store);
}
-
+
void
deadlockException()
{
@@ -328,7 +324,7 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
rollback();
}
-
+
Ice.Object
servantRemoved(Ice.Identity ident, ObjectStore store)
{
@@ -351,25 +347,12 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
}
return null;
}
-
-
- protected void
- finalize()
- {
- if(_tx != null)
- {
- _tx.getConnectionI().communicator().getLogger().warning
- ("Finalizing incomplete TransactionalEvictorContext on DbEnv '" + _tx.getConnectionI().dbEnv().getEnvName() + "'");
- }
- }
private ServantHolder
findServantHolder(Ice.Identity ident, ObjectStore store)
{
- java.util.Iterator p = _stack.iterator();
- while(p.hasNext())
+ for(ServantHolder sh : _stack)
{
- ServantHolder sh = (ServantHolder)p.next();
if(sh.matches(ident, store))
{
return sh;
@@ -377,7 +360,7 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
}
return null;
}
-
+
private static class ToInvalidate
{
ToInvalidate(Ice.Identity ident, ObjectStore store)
@@ -386,7 +369,7 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
_store = store;
}
- void
+ void
invalidate()
{
((TransactionalEvictorI)_store.evictor()).evict(_ident, _store);
@@ -396,16 +379,12 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
private final ObjectStore _store;
}
+ private final java.util.Stack<ServantHolder> _stack = new java.util.Stack<ServantHolder>();
//
- // Stack of ServantHolder
- //
- private final java.util.Stack _stack = new java.util.Stack();
-
- //
// List of objects to invalidate from the caches upon commit
//
- private final java.util.List _invalidateList = new java.util.LinkedList();
+ private final java.util.List<ToInvalidate> _invalidateList = new java.util.LinkedList<ToInvalidate>();
private TransactionI _tx;
private final Thread _owner;
@@ -418,7 +397,6 @@ class TransactionalEvictorContext implements Ice.DispatchInterceptorAsyncCallbac
//
private boolean _deadlockExceptionDetected = false;
-
//
// Only updated by the dispatch thread
//
diff --git a/java/src/Freeze/TransactionalEvictorI.java b/java/src/Freeze/TransactionalEvictorI.java
index 3eb79a879c9..5851a184bb8 100644
--- a/java/src/Freeze/TransactionalEvictorI.java
+++ b/java/src/Freeze/TransactionalEvictorI.java
@@ -22,73 +22,72 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
public Transaction
getCurrentTransaction()
{
- _deactivateController.lock();
- try
- {
- TransactionalEvictorContext ctx = _dbEnv.getCurrent();
- return ctx == null ? null : ctx.transaction();
- }
- finally
- {
- _deactivateController.unlock();
- }
+ _deactivateController.lock();
+ try
+ {
+ TransactionalEvictorContext ctx = _dbEnv.getCurrent();
+ return ctx == null ? null : ctx.transaction();
+ }
+ finally
+ {
+ _deactivateController.unlock();
+ }
}
-
+
public void
setCurrentTransaction(Transaction tx)
{
- _deactivateController.lock();
- try
- {
- _dbEnv.setCurrentTransaction(tx);
- }
- finally
- {
- _deactivateController.unlock();
- }
+ _deactivateController.lock();
+ try
+ {
+ _dbEnv.setCurrentTransaction(tx);
+ }
+ finally
+ {
+ _deactivateController.unlock();
+ }
}
public Ice.ObjectPrx
addFacet(Ice.Object servant, Ice.Identity ident, String facet)
{
- checkIdentity(ident);
-
- if(facet == null)
- {
- facet = "";
- }
-
- _deactivateController.lock();
- try
- {
- long currentTime = IceInternal.Time.currentMonotonicTimeMillis();
-
- ObjectRecord rec = new ObjectRecord(servant, new Statistics(currentTime, 0, 0));
-
- ObjectStore store = findStore(facet, _createDb);
- if(store == null)
- {
- NotFoundException ex = new NotFoundException();
- ex.message = _errorPrefix + "addFacet: could not open database for facet '"
- + facet + "'";
- throw ex;
- }
-
- TransactionI tx = beforeQuery();
-
- updateStats(rec.stats, currentTime);
-
- if(!store.insert(ident, rec, tx))
- {
- Ice.AlreadyRegisteredException ex = new Ice.AlreadyRegisteredException();
- ex.kindOfObject = "servant";
- ex.id = _communicator.identityToString(ident);
- if(facet.length() > 0)
- {
- ex.id += " -f " + IceUtilInternal.StringUtil.escapeString(facet, "");
- }
- throw ex;
- }
+ checkIdentity(ident);
+
+ if(facet == null)
+ {
+ facet = "";
+ }
+
+ _deactivateController.lock();
+ try
+ {
+ long currentTime = IceInternal.Time.currentMonotonicTimeMillis();
+
+ ObjectRecord rec = new ObjectRecord(servant, new Statistics(currentTime, 0, 0));
+
+ ObjectStore store = findStore(facet, _createDb);
+ if(store == null)
+ {
+ NotFoundException ex = new NotFoundException();
+ ex.message = _errorPrefix + "addFacet: could not open database for facet '" + facet + "'";
+ throw ex;
+ }
+
+ TransactionI tx = beforeQuery();
+
+ updateStats(rec.stats, currentTime);
+
+ if(!store.insert(ident, rec, tx))
+ {
+ Ice.AlreadyRegisteredException ex = new Ice.AlreadyRegisteredException();
+ ex.kindOfObject = "servant";
+ ex.id = _communicator.identityToString(ident);
+ if(facet.length() > 0)
+ {
+ ex.id += " -f " + IceUtilInternal.StringUtil.escapeString(facet, "");
+ }
+ throw ex;
+ }
if(_trace >= 1)
{
@@ -97,161 +96,160 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
{
objString += " with facet \"" + facet + "\"";
}
-
+
_communicator.getLogger().trace("Freeze.Evictor", "added " + objString + " to Db \"" + _filename +
"\"");
}
- Ice.ObjectPrx obj = _adapter.createProxy(ident);
- if(facet.length() > 0)
- {
- obj = obj.ice_facet(facet);
- }
- return obj;
- }
- finally
- {
- _deactivateController.unlock();
- }
+ Ice.ObjectPrx obj = _adapter.createProxy(ident);
+ if(facet.length() > 0)
+ {
+ obj = obj.ice_facet(facet);
+ }
+ return obj;
+ }
+ finally
+ {
+ _deactivateController.unlock();
+ }
}
public Ice.Object
removeFacet(Ice.Identity ident, String facet)
{
- checkIdentity(ident);
- if(facet == null)
- {
- facet = "";
- }
-
- _deactivateController.lock();
- try
- {
- Ice.Object servant = null;
- boolean removed = false;
-
- ObjectStore store = findStore(facet, false);
- if(store != null)
- {
- TransactionalEvictorContext ctx = _dbEnv.getCurrent();
- TransactionI tx = null;
- if(ctx != null)
- {
- tx = ctx.transaction();
- if(tx == null)
- {
- throw new DatabaseException(_errorPrefix + "inactive transaction");
- }
- }
-
- removed = store.remove(ident, tx);
-
- if(removed)
- {
- if(ctx != null)
- {
- //
- // Remove from cache when transaction commits
- //
- servant = ctx.servantRemoved(ident, store);
- }
- else
- {
- //
- // Remove from cache immediately
- //
- servant = evict(ident, store);
- }
- }
- }
-
- if(!removed)
- {
- Ice.NotRegisteredException ex = new Ice.NotRegisteredException();
- ex.kindOfObject = "servant";
- ex.id = _communicator.identityToString(ident);
- if(facet.length() > 0)
- {
- ex.id += " -f " + IceUtilInternal.StringUtil.escapeString(facet, "");
- }
- throw ex;
- }
-
- if(_trace >= 1)
- {
- String objString = "object \"" + _communicator.identityToString(ident) + "\"";
- if(!facet.equals(""))
- {
- objString += " with facet \"" + facet + "\"";
- }
-
- _communicator.getLogger().trace("Freeze.Evictor", "removed " + objString + " from Db \"" + _filename +
- "\"");
- }
- return servant;
- }
- finally
- {
- _deactivateController.unlock();
- }
+ checkIdentity(ident);
+ if(facet == null)
+ {
+ facet = "";
+ }
+
+ _deactivateController.lock();
+ try
+ {
+ Ice.Object servant = null;
+ boolean removed = false;
+
+ ObjectStore store = findStore(facet, false);
+ if(store != null)
+ {
+ TransactionalEvictorContext ctx = _dbEnv.getCurrent();
+ TransactionI tx = null;
+ if(ctx != null)
+ {
+ tx = ctx.transaction();
+ if(tx == null)
+ {
+ throw new DatabaseException(_errorPrefix + "inactive transaction");
+ }
+ }
+
+ removed = store.remove(ident, tx);
+
+ if(removed)
+ {
+ if(ctx != null)
+ {
+ //
+ // Remove from cache when transaction commits
+ //
+ servant = ctx.servantRemoved(ident, store);
+ }
+ else
+ {
+ //
+ // Remove from cache immediately
+ //
+ servant = evict(ident, store);
+ }
+ }
+ }
+
+ if(!removed)
+ {
+ Ice.NotRegisteredException ex = new Ice.NotRegisteredException();
+ ex.kindOfObject = "servant";
+ ex.id = _communicator.identityToString(ident);
+ if(facet.length() > 0)
+ {
+ ex.id += " -f " + IceUtilInternal.StringUtil.escapeString(facet, "");
+ }
+ throw ex;
+ }
+
+ if(_trace >= 1)
+ {
+ String objString = "object \"" + _communicator.identityToString(ident) + "\"";
+ if(!facet.equals(""))
+ {
+ objString += " with facet \"" + facet + "\"";
+ }
+
+ _communicator.getLogger().trace("Freeze.Evictor", "removed " + objString + " from Db \"" + _filename +
+ "\"");
+ }
+ return servant;
+ }
+ finally
+ {
+ _deactivateController.unlock();
+ }
}
public boolean
hasFacet(Ice.Identity ident, String facet)
{
- checkIdentity(ident);
- if(facet == null)
- {
- facet = "";
- }
-
- _deactivateController.lock();
- try
- {
- ObjectStore store = findStore(facet, false);
-
- if(store == null)
- {
- return false;
- }
-
- TransactionI tx = beforeQuery();
-
- if(tx == null)
- {
- EvictorElement element = (EvictorElement)store.cache().getIfPinned(ident);
- if(element != null)
- {
- return true;
- }
-
- return store.dbHasObject(ident, null);
- }
- else
- {
- return store.dbHasObject(ident, tx);
- }
- }
- finally
- {
- _deactivateController.unlock();
- }
+ checkIdentity(ident);
+ if(facet == null)
+ {
+ facet = "";
+ }
+
+ _deactivateController.lock();
+ try
+ {
+ ObjectStore store = findStore(facet, false);
+
+ if(store == null)
+ {
+ return false;
+ }
+
+ TransactionI tx = beforeQuery();
+
+ if(tx == null)
+ {
+ EvictorElement element = (EvictorElement)store.cache().getIfPinned(ident);
+ if(element != null)
+ {
+ return true;
+ }
+
+ return store.dbHasObject(ident, null);
+ }
+ else
+ {
+ return store.dbHasObject(ident, tx);
+ }
+ }
+ finally
+ {
+ _deactivateController.unlock();
+ }
}
-
-
+
public void
finished(Ice.Current current, Ice.Object servant, java.lang.Object cookieObj)
- {
- //
- // Nothing to do
- //
+ {
+ //
+ // Nothing to do
+ //
}
public void
deactivate(String category)
{
- if(_deactivateController.deactivate())
- {
+ if(_deactivateController.deactivate())
+ {
synchronized(this)
{
//
@@ -262,54 +260,56 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
evict();
}
- try
- {
- closeDbEnv();
- }
- finally
- {
- _deactivateController.deactivationComplete();
- }
- }
+ try
+ {
+ closeDbEnv();
+ }
+ finally
+ {
+ _deactivateController.deactivationComplete();
+ }
+ }
}
- TransactionalEvictorI(Ice.ObjectAdapter adapter, String envName, com.sleepycat.db.Environment dbEnv, String filename,
- java.util.Map facetTypes, ServantInitializer initializer, Index[] indices, boolean createDb)
+ TransactionalEvictorI(Ice.ObjectAdapter adapter, String envName, com.sleepycat.db.Environment dbEnv,
+ String filename, java.util.Map<String, String> facetTypes, ServantInitializer initializer,
+ Index[] indices, boolean createDb)
{
- super(adapter, envName, dbEnv, filename, facetTypes, initializer, indices, createDb);
-
- String propertyPrefix = "Freeze.Evictor." + envName + '.' + filename;
- _rollbackOnUserException = _communicator.getProperties().
- getPropertyAsIntWithDefault(propertyPrefix + ".RollbackOnUserException", 0) != 0;
+ super(adapter, envName, dbEnv, filename, facetTypes, initializer, indices, createDb);
+
+ String propertyPrefix = "Freeze.Evictor." + envName + '.' + filename;
+ _rollbackOnUserException = _communicator.getProperties().
+ getPropertyAsIntWithDefault(propertyPrefix + ".RollbackOnUserException", 0) != 0;
}
- TransactionalEvictorI(Ice.ObjectAdapter adapter, String envName, String filename,
- java.util.Map facetTypes, ServantInitializer initializer, Index[] indices, boolean createDb)
+ TransactionalEvictorI(Ice.ObjectAdapter adapter, String envName, String filename,
+ java.util.Map<String, String> facetTypes, ServantInitializer initializer, Index[] indices,
+ boolean createDb)
{
- this(adapter, envName, null, filename, facetTypes, initializer, indices, createDb);
+ this(adapter, envName, null, filename, facetTypes, initializer, indices, createDb);
}
//
// The interceptor dispatch call
//
- Ice.DispatchStatus
+ Ice.DispatchStatus
dispatch(Ice.Request request)
{
- _deactivateController.lock();
- try
- {
- Ice.Current current = request.getCurrent();
-
- ObjectStore store = findStore(current.facet, false);
- if(store == null)
- {
- servantNotFound(current);
- }
-
- TransactionalEvictorContext ctx = _dbEnv.getCurrent();
-
- Ice.Object sample = store.sampleServant();
- Ice.Object cachedServant = null;
+ _deactivateController.lock();
+ try
+ {
+ Ice.Current current = request.getCurrent();
+
+ ObjectStore store = findStore(current.facet, false);
+ if(store == null)
+ {
+ servantNotFound(current);
+ }
+
+ TransactionalEvictorContext ctx = _dbEnv.getCurrent();
+
+ Ice.Object sample = store.sampleServant();
+ Ice.Object cachedServant = null;
TransactionalEvictorContext.ServantHolder servantHolder = null;
try
@@ -317,11 +317,11 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
if(sample == null)
{
if(ctx != null)
- {
+ {
try
{
servantHolder = ctx.createServantHolder(current, store);
- }
+ }
catch(DeadlockException dx)
{
assert dx.tx == ctx.transaction();
@@ -335,9 +335,9 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
//
// find / load read-only servant
//
-
+
cachedServant = loadCachedServant(current.id, store);
-
+
if(cachedServant == null)
{
servantNotFound(current);
@@ -345,17 +345,17 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
sample = cachedServant;
}
}
-
+
assert sample != null;
int operationAttributes = sample.ice_operationAttributes(current.operation);
-
+
boolean readOnly = (operationAttributes & 0x1) == 0;
-
+
int txMode = (operationAttributes & 0x6) >> 1;
-
+
boolean ownCtx = false;
-
+
//
// Establish the proper context
//
@@ -396,7 +396,7 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
assert false;
}
}
-
+
if(ctx == null && !ownCtx)
{
//
@@ -406,7 +406,7 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
if(cachedServant == null)
{
cachedServant = loadCachedServant(current.id, store);
-
+
if(cachedServant == null)
{
servantNotFound(current);
@@ -425,13 +425,13 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
{
ctx = _dbEnv.createCurrent();
}
-
+
tx = ctx.transaction();
try
{
try
- {
+ {
TransactionalEvictorContext.ServantHolder sh;
if(servantHolder != null)
{
@@ -446,7 +446,7 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
{
sh = ctx.createServantHolder(current, store);
}
-
+
if(sh.servant() == null)
{
servantNotFound(current);
@@ -456,11 +456,12 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
{
sh.markReadWrite();
}
-
+
try
{
Ice.DispatchStatus dispatchStatus = sh.servant().ice_dispatch(request, ctx);
- if(dispatchStatus == Ice.DispatchStatus.DispatchUserException && _rollbackOnUserException)
+ if(dispatchStatus == Ice.DispatchStatus.DispatchUserException &&
+ _rollbackOnUserException)
{
ctx.rollback();
}
@@ -550,7 +551,7 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
servantHolder.release();
}
}
-
+
//
// Javac does not detect this can't be reached
//
@@ -563,260 +564,256 @@ class TransactionalEvictorI extends EvictorI implements TransactionalEvictor
}
}
- synchronized Ice.Object
+ synchronized Ice.Object
evict(Ice.Identity ident, ObjectStore store)
{
- EvictorElement element = (EvictorElement)store.cache().unpin(ident);
-
- if(element != null)
- {
- element.evict(false);
- return element.servant;
- }
- return null;
+ EvictorElement element = (EvictorElement)store.cache().unpin(ident);
+
+ if(element != null)
+ {
+ element.evict(false);
+ return element.servant;
+ }
+ return null;
}
- protected Object
+ protected Object
createEvictorElement(Ice.Identity ident, ObjectRecord rec, ObjectStore store)
{
- return new EvictorElement(rec.servant, ident, store);
+ return new EvictorElement(rec.servant, ident, store);
}
protected Ice.Object
locateImpl(Ice.Current current, Ice.LocalObjectHolder cookie)
{
- return _interceptor;
+ return _interceptor;
}
protected boolean
hasAnotherFacet(Ice.Identity ident, String facet)
{
- _deactivateController.lock();
- try
- {
- java.util.Map storeMapCopy;
- synchronized(this)
- {
- storeMapCopy = new java.util.HashMap(_storeMap);
- }
-
- TransactionI tx = beforeQuery();
-
- java.util.Iterator p = storeMapCopy.entrySet().iterator();
- while(p.hasNext())
- {
- java.util.Map.Entry entry = (java.util.Map.Entry)p.next();
-
- //
- // Do not check this facet again
- //
- if(!facet.equals(entry.getKey()))
- {
- ObjectStore store = (ObjectStore)entry.getValue();
-
- if(tx == null && store.cache().getIfPinned(ident) != null)
- {
- return true;
- }
-
- if(store.dbHasObject(ident, tx))
- {
- return true;
- }
- }
- }
-
- return false;
- }
- finally
- {
- _deactivateController.unlock();
- }
+ _deactivateController.lock();
+ try
+ {
+ java.util.Map<String, ObjectStore> storeMapCopy;
+ synchronized(this)
+ {
+ storeMapCopy = new java.util.HashMap<String, ObjectStore>(_storeMap);
+ }
+
+ TransactionI tx = beforeQuery();
+
+ for(java.util.Map.Entry<String, ObjectStore> entry : storeMapCopy.entrySet())
+ {
+ //
+ // Do not check this facet again
+ //
+ if(!facet.equals(entry.getKey()))
+ {
+ ObjectStore store = (ObjectStore)entry.getValue();
+
+ if(tx == null && store.cache().getIfPinned(ident) != null)
+ {
+ return true;
+ }
+
+ if(store.dbHasObject(ident, tx))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+ finally
+ {
+ _deactivateController.unlock();
+ }
}
protected void
evict()
- {
- assert Thread.holdsLock(this);
-
- while(_currentEvictorSize > _evictorSize)
- {
- //
- // Evict, no matter what!
- //
- EvictorElement element = (EvictorElement)_evictorList.getLast();
- element.evict(true);
- }
- }
+ {
+ assert Thread.holdsLock(this);
+
+ while(_currentEvictorSize > _evictorSize)
+ {
+ //
+ // Evict, no matter what!
+ //
+ EvictorElement element = _evictorList.getLast();
+ element.evict(true);
+ }
+ }
protected TransactionI
beforeQuery()
{
- TransactionalEvictorContext ctx = _dbEnv.getCurrent();
- TransactionI tx = null;
- if(ctx != null)
- {
- tx = ctx.transaction();
- if(tx == null)
- {
- throw new DatabaseException(_errorPrefix + "inactive transaction");
- }
- }
-
- return tx;
+ TransactionalEvictorContext ctx = _dbEnv.getCurrent();
+ TransactionI tx = null;
+ if(ctx != null)
+ {
+ tx = ctx.transaction();
+ if(tx == null)
+ {
+ throw new DatabaseException(_errorPrefix + "inactive transaction");
+ }
+ }
+
+ return tx;
}
- private void
+ private void
servantNotFound(Ice.Current current)
- {
- if(_trace >= 2)
- {
- _communicator.getLogger().trace("Freeze.Evictor", "could not find \""
- + _communicator.identityToString(current.id) +"\" with facet \"" + current.facet + "\"");
- }
-
- if(hasAnotherFacet(current.id, current.facet))
- {
- throw new Ice.FacetNotExistException(current.id, current.facet, current.operation);
- }
- else
- {
- throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation);
- }
+ {
+ if(_trace >= 2)
+ {
+ _communicator.getLogger().trace("Freeze.Evictor", "could not find \"" +
+ _communicator.identityToString(current.id) + "\" with facet \"" +
+ current.facet + "\"");
+ }
+
+ if(hasAnotherFacet(current.id, current.facet))
+ {
+ throw new Ice.FacetNotExistException(current.id, current.facet, current.operation);
+ }
+ else
+ {
+ throw new Ice.ObjectNotExistException(current.id, current.facet, current.operation);
+ }
}
private Ice.Object
loadCachedServant(Ice.Identity ident, ObjectStore store)
{
- for(;;)
- {
- EvictorElement element = (EvictorElement)store.cache().pin(ident);
-
- if(element == null)
- {
- return null;
- }
-
- synchronized(this)
- {
- if(element.stale)
- {
- //
- // try again
- //
- continue;
- }
-
- element.fixEvictPosition();
-
- //
- // if _evictorSize is 0, I may evict myself ... no big deal
- //
- evict();
+ for(;;)
+ {
+ EvictorElement element = (EvictorElement)store.cache().pin(ident);
+
+ if(element == null)
+ {
+ return null;
+ }
+
+ synchronized(this)
+ {
+ if(element.stale)
+ {
+ //
+ // try again
+ //
+ continue;
+ }
+
+ element.fixEvictPosition();
+
+ //
+ // if _evictorSize is 0, I may evict myself ... no big deal
+ //
+ evict();
if(_trace >= 3)
{
- _communicator.getLogger().trace("Freeze.Evictor", "loaded \""
- + _communicator.identityToString(ident) +"\" with facet \"" + store.facet()
- + "\" into the cache");
+ _communicator.getLogger().trace("Freeze.Evictor", "loaded \""
+ + _communicator.identityToString(ident) + "\" with facet \"" +
+ store.facet() + "\" into the cache");
}
- return element.servant;
- }
- }
+ return element.servant;
+ }
+ }
}
-
+
private class EvictorElement
{
- EvictorElement(Ice.Object servant, Ice.Identity identity, ObjectStore store)
- {
- this.servant = servant;
- _identity = identity;
- _store = store;
- }
-
- void
- evict(boolean unpin)
- {
- assert Thread.holdsLock(TransactionalEvictorI.this);
- assert stale == false;
- stale = true;
-
- if(unpin)
- {
- _store.cache().unpin(_identity);
- }
-
- if(_evictPosition != null)
- {
- _evictPosition.remove();
- _evictPosition = null;
- _currentEvictorSize--;
- }
- else
- {
- assert(!unpin);
- }
- }
-
- void
- fixEvictPosition()
- {
- assert Thread.holdsLock(TransactionalEvictorI.this);
- assert stale == false;
-
- if(_evictPosition == null)
- {
- //
- // New element
- //
- _currentEvictorSize++;
- }
- else
- {
- _evictPosition.remove();
- }
- _evictorList.addFirst(this);
- _evictPosition = _evictorList.iterator();
- //
- // Position the iterator "on" the element.
- //
- _evictPosition.next();
- }
-
-
- final Ice.Object servant;
-
- //
- // Protected by the TransactionEvictorI mutex
- //
- boolean stale = false; // stale = true means no longer in the cache
- private java.util.Iterator _evictPosition;
-
- //
- // These two fields are only needed for eviction
- //
- final private ObjectStore _store;
- final private Ice.Identity _identity;
- }
+ EvictorElement(Ice.Object servant, Ice.Identity identity, ObjectStore store)
+ {
+ this.servant = servant;
+ _identity = identity;
+ _store = store;
+ }
+ void
+ evict(boolean unpin)
+ {
+ assert Thread.holdsLock(TransactionalEvictorI.this);
+ assert stale == false;
+ stale = true;
+
+ if(unpin)
+ {
+ _store.cache().unpin(_identity);
+ }
+
+ if(_evictPosition != null)
+ {
+ _evictPosition.remove();
+ _evictPosition = null;
+ _currentEvictorSize--;
+ }
+ else
+ {
+ assert(!unpin);
+ }
+ }
+
+ void
+ fixEvictPosition()
+ {
+ assert Thread.holdsLock(TransactionalEvictorI.this);
+ assert stale == false;
+
+ if(_evictPosition == null)
+ {
+ //
+ // New element
+ //
+ _currentEvictorSize++;
+ }
+ else
+ {
+ _evictPosition.remove();
+ }
+ _evictorList.addFirst(this);
+ _evictPosition = _evictorList.iterator();
+ //
+ // Position the iterator "on" the element.
+ //
+ _evictPosition.next();
+ }
+
+ final Ice.Object servant;
+
+ //
+ // Protected by the TransactionEvictorI mutex
+ //
+ boolean stale = false; // stale = true means no longer in the cache
+ private java.util.Iterator<EvictorElement> _evictPosition;
+
+ //
+ // These two fields are only needed for eviction
+ //
+ final private ObjectStore _store;
+ final private Ice.Identity _identity;
+ }
//
// List of EvictorElement with stable iterators
//
- private final Freeze.LinkedList _evictorList = new Freeze.LinkedList();
+ private final Freeze.LinkedList<EvictorElement> _evictorList = new Freeze.LinkedList<EvictorElement>();
private int _currentEvictorSize = 0;
//
// A simple adapter
//
private Ice.DispatchInterceptor _interceptor = new Ice.DispatchInterceptor()
- {
- public Ice.DispatchStatus
- dispatch(Ice.Request request)
- {
- return TransactionalEvictorI.this.dispatch(request);
- }
- };
+ {
+ public Ice.DispatchStatus
+ dispatch(Ice.Request request)
+ {
+ return TransactionalEvictorI.this.dispatch(request);
+ }
+ };
private boolean _rollbackOnUserException;
}
diff --git a/java/src/Freeze/Util.java b/java/src/Freeze/Util.java
index 10497faf7a4..c045e9b0797 100644
--- a/java/src/Freeze/Util.java
+++ b/java/src/Freeze/Util.java
@@ -12,40 +12,40 @@ package Freeze;
public class Util
{
public static BackgroundSaveEvictor
- createBackgroundSaveEvictor(Ice.ObjectAdapter adapter, String envName, String filename, ServantInitializer initializer,
- Index[] indices, boolean createDb)
+ createBackgroundSaveEvictor(Ice.ObjectAdapter adapter, String envName, String filename,
+ ServantInitializer initializer, Index[] indices, boolean createDb)
{
return new BackgroundSaveEvictorI(adapter, envName, filename, initializer, indices, createDb);
- }
+ }
public static BackgroundSaveEvictor
- createBackgroundSaveEvictor(Ice.ObjectAdapter adapter, String envName, com.sleepycat.db.Environment dbEnv, String filename,
- ServantInitializer initializer, Index[] indices, boolean createDb)
+ createBackgroundSaveEvictor(Ice.ObjectAdapter adapter, String envName, com.sleepycat.db.Environment dbEnv,
+ String filename, ServantInitializer initializer, Index[] indices, boolean createDb)
{
return new BackgroundSaveEvictorI(adapter, envName, dbEnv, filename, initializer, indices, createDb);
- }
-
+ }
public static TransactionalEvictor
- createTransactionalEvictor(Ice.ObjectAdapter adapter, String envName, String filename, java.util.Map facetTypes,
- ServantInitializer initializer, Index[] indices, boolean createDb)
+ createTransactionalEvictor(Ice.ObjectAdapter adapter, String envName, String filename,
+ java.util.Map<String, String> facetTypes, ServantInitializer initializer,
+ Index[] indices, boolean createDb)
{
return new TransactionalEvictorI(adapter, envName, filename, facetTypes, initializer, indices, createDb);
- }
+ }
public static TransactionalEvictor
- createTransactionalEvictor(Ice.ObjectAdapter adapter, String envName, com.sleepycat.db.Environment dbEnv, String filename,
- java.util.Map facetTypes, ServantInitializer initializer, Index[] indices, boolean createDb)
+ createTransactionalEvictor(Ice.ObjectAdapter adapter, String envName, com.sleepycat.db.Environment dbEnv,
+ String filename, java.util.Map<String, String> facetTypes,
+ ServantInitializer initializer, Index[] indices, boolean createDb)
{
return new TransactionalEvictorI(adapter, envName, dbEnv, filename, facetTypes, initializer, indices, createDb);
}
-
public static Connection
createConnection(Ice.Communicator communicator, String envName)
{
return new ConnectionI(communicator, envName, null);
- }
+ }
public static Connection
createConnection(Ice.Communicator communicator, String envName, com.sleepycat.db.Environment dbEnv)
@@ -53,17 +53,18 @@ public class Util
return new ConnectionI(communicator, envName, dbEnv);
}
- public static String catalogName()
+ public static String
+ catalogName()
{
return _catalogName;
}
-
- public static String catalogIndexListName()
+
+ public static String
+ catalogIndexListName()
{
return _catalogIndexListName;
}
-
public static com.sleepycat.db.Transaction
getTxn(Transaction tx)
{
@@ -84,8 +85,9 @@ public class Util
_fatalErrorCallback = cb;
return result;
}
-
- static synchronized void handleFatalError(BackgroundSaveEvictor evictor, Ice.Communicator communicator, RuntimeException ex)
+
+ static synchronized void
+ handleFatalError(BackgroundSaveEvictor evictor, Ice.Communicator communicator, RuntimeException ex)
{
if(_fatalErrorCallback != null)
{
diff --git a/java/src/IceGridGUI/BareBonesBrowserLaunch.java b/java/src/IceGridGUI/BareBonesBrowserLaunch.java
index 6cfe3732c72..6900313af0c 100644
--- a/java/src/IceGridGUI/BareBonesBrowserLaunch.java
+++ b/java/src/IceGridGUI/BareBonesBrowserLaunch.java
@@ -26,10 +26,9 @@ public class BareBonesBrowserLaunch {
String osName = System.getProperty("os.name");
try {
if (osName.startsWith("Mac OS")) {
- Class macUtils = Class.forName("com.apple.mrj.MRJFileUtils");
- Method openURL = macUtils.getDeclaredMethod("openURL",
- new Class[] {String.class});
- openURL.invoke(null, new Object[] {url});
+ Class<?> macUtils = Class.forName("com.apple.mrj.MRJFileUtils");
+ Method openURL = macUtils.getDeclaredMethod("openURL", String.class);
+ openURL.invoke(null, url);
}
else if (osName.startsWith("Windows"))
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
diff --git a/java/src/IceInternal/PropertyNames.java b/java/src/IceInternal/PropertyNames.java
index 8812b8a54db..ab58a9d6731 100644
--- a/java/src/IceInternal/PropertyNames.java
+++ b/java/src/IceInternal/PropertyNames.java
@@ -8,7 +8,7 @@
// **********************************************************************
//
-// Generated by makeprops.py from file ../config/PropertyNames.xml, Fri May 15 13:11:40 2009
+// Generated by makeprops.py from file ../config/PropertyNames.xml, Mon May 18 11:29:29 2009
// IMPORTANT: Do not edit this file -- any edits made here will be lost!
@@ -556,7 +556,6 @@ public final class PropertyNames
new Property("Freeze\\.Trace\\.Evictor", false, null),
new Property("Freeze\\.Trace\\.Map", false, null),
new Property("Freeze\\.Trace\\.Transaction", false, null),
- new Property("Freeze\\.Warn\\.CloseInFinalize", false, null),
new Property("Freeze\\.Warn\\.Deadlocks", false, null),
new Property("Freeze\\.Warn\\.Rollback", false, null),
null
diff --git a/java/test/Freeze/complex/Client.java b/java/test/Freeze/complex/Client.java
index e3065200b46..4f6cd92f983 100644
--- a/java/test/Freeze/complex/Client.java
+++ b/java/test/Freeze/complex/Client.java
@@ -34,20 +34,20 @@ public class Client
try
{
Parser parser = new Parser();
-
+
System.out.print("testing database expressions... ");
- java.util.Iterator p = m.entrySet().iterator();
+ java.util.Iterator<java.util.Map.Entry<Key, Node>> p = m.entrySet().iterator();
while(p.hasNext())
{
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
+ java.util.Map.Entry<Key, Node> e = p.next();
- Key key = (Key)e.getKey();
+ Key key = e.getKey();
//
// Verify the stored record is correct.
//
- test(key.result == ((Node)e.getValue()).calc());
-
+ test(key.result == e.getValue().calc());
+
//
// Verify that the expression & result again.
//
@@ -61,17 +61,17 @@ public class Client
e.printStackTrace();
test(false);
}
-
+
m.close();
return 0;
}
-
+
private int
populate(String dbName)
throws DatabaseException
{
- String[] expressions =
+ String[] expressions =
{
"2",
"10",
@@ -79,13 +79,13 @@ public class Client
"5*(2+3)",
"10+(10+(20+(8*(2*(3*2+4+5+6)))))"
};
-
+
ComplexDict m = new ComplexDict(_connection, dbName, true);
try
{
Parser parser = new Parser();
-
+
System.out.print("populating the database... ");
for(String expr : expressions)
{
@@ -103,11 +103,11 @@ public class Client
e.printStackTrace();
test(false);
}
-
+
m.close();
return 0;
}
-
+
static void
usage(String name)
{
@@ -127,7 +127,7 @@ public class Client
_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(dbName);
@@ -137,17 +137,16 @@ public class Client
return validate(dbName);
}
usage(progName);
-
+
return 0;
}
-
+
private void
close()
{
_connection.close();
}
-
private
Client(Ice.Communicator communicator, String envName)
{
@@ -155,7 +154,6 @@ public class Client
_connection = Freeze.Util.createConnection(communicator, envName);
}
-
static public void
main(String[] args)
{
@@ -178,7 +176,7 @@ public class Client
usage(progName);
System.exit(1);
}
-
+
envName = args[i+1];
envName += "/";
envName += "db";
@@ -240,5 +238,4 @@ public class Client
private Ice.Communicator _communicator;
private Freeze.Connection _connection;
-
}
diff --git a/java/test/Freeze/complex/Parser.java b/java/test/Freeze/complex/Parser.java
index d2aa4b1c93f..61f7d8be4c5 100644
--- a/java/test/Freeze/complex/Parser.java
+++ b/java/test/Freeze/complex/Parser.java
@@ -71,10 +71,10 @@ public class Parser
{
throw new ParseError("Expected number");
}
-
+
NumberNode number = new NumberNodeI(Integer.parseInt(_token));
Node result = number;
-
+
//
// expr?
//
@@ -90,7 +90,7 @@ public class Parser
Node right = expr();
result = new AddNodeI(number, right);
}
-
+
//
// expr '*' expr
//
@@ -132,12 +132,12 @@ public class Parser
}
StringBuilder buf = new StringBuilder(128);
-
+
//
// Get the next character
//
char c = _buf.charAt(_pos);
-
+
//
// '(', ')', '+' and '*' are tokens.
//
@@ -156,7 +156,7 @@ public class Parser
buf.append(_buf.charAt(_pos++));
}
}
-
+
_token = buf.toString();
}
diff --git a/java/test/Freeze/dbmap/Client.java b/java/test/Freeze/dbmap/Client.java
index ba99c46a2d2..84f264f18a4 100644
--- a/java/test/Freeze/dbmap/Client.java
+++ b/java/test/Freeze/dbmap/Client.java
@@ -17,26 +17,25 @@ public class Client
{
public void
run()
- {
+ {
try
{
for(int i = 0; i < 10; ++i)
{
for(;;)
{
- java.util.Iterator p = null;
+ Transaction tx = _connection.beginTransaction();
try
{
- java.util.Set entrySet = _map.entrySet();
- p = entrySet.iterator();
-
+ java.util.Iterator<java.util.Map.Entry<Byte, Integer>> p = _map.entrySet().iterator();
while(p.hasNext())
{
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
- byte v = ((Byte)e.getKey()).byteValue();
+ java.util.Map.Entry<Byte, Integer> e = p.next();
+ byte v = e.getKey().byteValue();
test(e.getValue().equals(new Integer(v - (byte)'a')));
}
+
break;
}
catch(DeadlockException ex)
@@ -48,10 +47,7 @@ public class Client
}
finally
{
- if(p != null)
- {
- ((Freeze.Map.EntryIterator)p).close();
- }
+ tx.rollback();
}
}
}
@@ -63,11 +59,11 @@ public class Client
}
finally
{
- ((Freeze.Map) _map).close();
+ ((Freeze.Map)_map).close();
_connection.close();
}
}
-
+
ReadThread(Ice.Communicator communicator, String envName, String dbName)
{
_connection = Freeze.Util.createConnection(communicator, envName);
@@ -75,10 +71,9 @@ public class Client
}
private Freeze.Connection _connection;
- private java.util.Map _map;
+ private java.util.Map<Byte, Integer> _map;
}
-
static class WriteThread extends Thread
{
public void
@@ -90,21 +85,22 @@ public class Client
{
for(;;)
{
- java.util.Iterator p = null;
+ Transaction tx = _connection.beginTransaction();
try
{
- java.util.Set entrySet = _map.entrySet();
- p = entrySet.iterator();
-
+ java.util.Iterator<java.util.Map.Entry<Byte, Integer>> p = _map.entrySet().iterator();
while(p.hasNext())
{
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
- int v = ((Integer)e.getValue()).intValue() + 1;
- e.setValue(new Integer(v));
+ java.util.Map.Entry<Byte, Integer> e = p.next();
+ int v = e.getValue().intValue() + 1;
+ e.setValue(v);
p.remove();
}
-
+
+ tx.commit();
+ tx = null;
+
break;
}
catch(DeadlockException ex)
@@ -116,9 +112,9 @@ public class Client
}
finally
{
- if(p != null)
+ if(tx != null)
{
- ((Freeze.Map.EntryIterator)p).close();
+ tx.rollback();
}
}
}
@@ -136,7 +132,7 @@ public class Client
_connection.close();
}
}
-
+
WriteThread(Ice.Communicator communicator, String envName, String dbName)
{
_connection = Freeze.Util.createConnection(communicator, envName);
@@ -144,10 +140,9 @@ public class Client
}
private Freeze.Connection _connection;
- private java.util.Map _map;
+ private java.util.Map<Byte, Integer> _map;
}
-
static String alphabet = "abcdefghijklmnopqrstuvwxyz";
private static void
@@ -160,20 +155,20 @@ public class Client
}
private static void
- populateDB(Freeze.Connection connection, java.util.Map m)
+ populateDB(Freeze.Connection connection, java.util.Map<Byte, Integer> m)
throws DatabaseException
{
int length = alphabet.length();
for(;;)
{
-
+
try
{
Transaction tx = connection.beginTransaction();
for(int j = 0; j < length; ++j)
{
- m.put(new Byte((byte)alphabet.charAt(j)), new Integer(j));
+ m.put((byte)alphabet.charAt(j), j);
}
tx.commit();
break; // for(;;)
@@ -208,13 +203,13 @@ public class Client
{
Transaction tx = connection.beginTransaction();
ByteIntMap m = new ByteIntMap(connection, dbName, true);
-
- m.put(new Byte((byte)'a'), new Integer(1));
+
+ m.put((byte)'a', 1);
m.close();
tx.rollback();
}
- java.util.Map m = new ByteIntMap(connection, dbName, true);
+ java.util.Map<Byte, Integer> m = new ByteIntMap(connection, dbName, true);
//
// Populate the database with the alphabet.
@@ -227,39 +222,41 @@ public class Client
System.out.flush();
for(j = 0; j < alphabet.length(); ++j)
{
- Object value = m.get(new Byte((byte)alphabet.charAt(j)));
+ Integer value = m.get((byte)alphabet.charAt(j));
test(value != null);
}
- test(m.get(new Byte((byte)'0')) == null);
+ test(m.get((byte)'0') == null);
for(j = 0; j < alphabet.length(); ++j)
{
- test(m.containsKey(new Byte((byte)alphabet.charAt(j))));
+ test(m.containsKey((byte)alphabet.charAt(j)));
}
- test(!m.containsKey(new Byte((byte)'0')));
+ test(!m.containsKey((byte)'0'));
for(j = 0; j < alphabet.length(); ++j)
{
- test(m.containsValue(new Integer(j)));
+ test(m.containsValue(j));
}
- test(!m.containsValue(new Integer(-1)));
+ test(!m.containsValue(-1));
test(m.size() == alphabet.length());
test(!m.isEmpty());
System.out.println("ok");
System.out.print("testing erase... ");
System.out.flush();
- m.remove(new Byte((byte)'a'));
- m.remove(new Byte((byte)'b'));
- m.remove(new Byte((byte)'c'));
+ m.remove((byte)'a');
+ m.remove((byte)'b');
+ m.remove((byte)'c');
for(j = 3; j < alphabet.length(); ++j)
{
- Object value = m.get(new Byte((byte)alphabet.charAt(j)));
+ Integer value = m.get((byte)alphabet.charAt(j));
test(value != null);
}
- test(m.get(new Byte((byte)'a')) == null);
- test(m.get(new Byte((byte)'b')) == null);
- test(m.get(new Byte((byte)'c')) == null);
+ test(m.get((byte)'a') == null);
+ test(m.get((byte)'b') == null);
+ test(m.get((byte)'c') == null);
+ test(((ByteIntMap)m).fastRemove((byte)'d') == true);
+ test(((ByteIntMap)m).fastRemove((byte)'d') == false);
System.out.println("ok");
-
+
//
// Re-populate.
//
@@ -268,55 +265,338 @@ public class Client
{
System.out.print("testing keySet... ");
System.out.flush();
- java.util.Set keys = m.keySet();
+ java.util.Set<Byte> keys = m.keySet();
test(keys.size() == alphabet.length());
test(!keys.isEmpty());
- java.util.Iterator p = keys.iterator();
+ java.util.Iterator<Byte> p = keys.iterator();
while(p.hasNext())
{
- Object o = p.next();
- test(keys.contains(o));
-
- Byte b = (Byte)o;
+ Byte b = p.next();
+ test(keys.contains(b));
test(m.containsKey(b));
}
+
+ //
+ // The iterator should have already been closed when we reached the last entry.
+ //
+ int count = ((Freeze.Map)m).closeAllIterators();
+ test(count == 0);
+
+ try
+ {
+ keys.remove((byte)'a');
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - no transaction.
+ }
+
+ count = ((Freeze.Map)m).closeAllIterators();
+ test(count == 1); // Opened by keys.remove()
+
+ Transaction tx = connection.beginTransaction();
+ test(keys.remove((byte)'a') == true);
+ test(keys.remove((byte)'a') == false);
+ tx.commit();
+ test(m.containsKey((byte)'a') == false);
+
System.out.println("ok");
}
+ //
+ // Re-populate.
+ //
+ populateDB(connection, m);
+
{
System.out.print("testing values... ");
System.out.flush();
- java.util.Collection values = m.values();
+ java.util.Collection<Integer> values = m.values();
test(values.size() == alphabet.length());
test(!values.isEmpty());
- java.util.Iterator p = values.iterator();
+ java.util.Iterator<Integer> p = values.iterator();
while(p.hasNext())
{
- Object o = p.next();
- test(values.contains(o));
-
- Integer i = (Integer)o;
+ Integer i = p.next();
+ test(values.contains(i));
test(m.containsValue(i));
}
+
+ //
+ // The iterator should have already been closed when we reached the last entry.
+ //
+ int count = ((Freeze.Map)m).closeAllIterators();
+ test(count == 0);
+
+ try
+ {
+ values.remove(0);
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - no transaction.
+ }
+
+ count = ((Freeze.Map)m).closeAllIterators();
+ test(count == 1); // Opened by keys.remove()
+
+ Transaction tx = connection.beginTransaction();
+ test(values.remove(0) == true);
+ test(values.remove(0) == false);
+ tx.commit();
+ test(m.containsKey((byte)'a') == false);
+
System.out.println("ok");
}
+ //
+ // Re-populate.
+ //
+ populateDB(connection, m);
+
{
System.out.print("testing entrySet... ");
System.out.flush();
- java.util.Set entrySet = m.entrySet();
+ java.util.Set<java.util.Map.Entry<Byte, Integer>> entrySet = m.entrySet();
test(entrySet.size() == alphabet.length());
test(!entrySet.isEmpty());
- java.util.Iterator p = entrySet.iterator();
+ java.util.Iterator<java.util.Map.Entry<Byte, Integer>> p = entrySet.iterator();
while(p.hasNext())
{
- Object o = p.next();
- test(entrySet.contains(o));
+ java.util.Map.Entry<Byte, Integer> e = p.next();
+ test(entrySet.contains(e));
+ test(m.containsKey(e.getKey()));
+ test(m.containsValue(e.getValue()));
+ }
+
+ //
+ // The iterator should have already been closed when we reached the last entry.
+ //
+ int count = ((Freeze.Map)m).closeAllIterators();
+ test(count == 0);
+ System.out.println("ok");
+ }
+
+ {
+ System.out.print("testing unsorted map... ");
+ System.out.flush();
+
+ NavigableMap<Byte, Integer> nm = (NavigableMap<Byte, Integer>)m;
+ final byte firstByte = (byte)alphabet.charAt(0);
+ final byte lastByte = (byte)alphabet.charAt(alphabet.length() - 1);
+ final int length = alphabet.length();
+
+ //
+ // Keys
+ //
+
+ Byte key;
+
+ key = nm.firstKey();
+ test(key != null);
+ test(key.byteValue() == firstByte);
+
+ key = nm.lastKey();
+ test(key != null);
+ test(key.byteValue() == lastByte);
+
+ try
+ {
+ nm.ceilingKey((byte)0);
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - a comparator is required.
+ }
+
+ try
+ {
+ nm.floorKey((byte)0);
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - a comparator is required.
+ }
+
+ try
+ {
+ nm.higherKey((byte)0);
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - a comparator is required.
+ }
+
+ try
+ {
+ nm.lowerKey((byte)0);
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - a comparator is required.
+ }
+
+ m.clear();
+ try
+ {
+ nm.firstKey();
+ test(false);
+ }
+ catch(java.util.NoSuchElementException ex)
+ {
+ // Expected.
+ }
+ try
+ {
+ nm.lastKey();
+ test(false);
+ }
+ catch(java.util.NoSuchElementException ex)
+ {
+ // Expected.
+ }
+
+ populateDB(connection, m);
+
+ //
+ // Entries
+ //
+
+ java.util.Map.Entry<Byte, Integer> e;
+
+ e = nm.firstEntry();
+ test(e != null);
+ test(e.getKey().byteValue() == (byte)firstByte);
+ test(e.getValue().intValue() == 0);
+
+ e = nm.lastEntry();
+ test(e != null);
+ test(e.getKey().byteValue() == (byte)lastByte);
+ test(e.getValue().intValue() == length - 1);
+
+ try
+ {
+ nm.ceilingEntry((byte)0);
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - a comparator is required.
+ }
+
+ try
+ {
+ nm.floorEntry((byte)0);
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - a comparator is required.
+ }
+
+ try
+ {
+ nm.higherEntry((byte)0);
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - a comparator is required.
+ }
+
+ try
+ {
+ nm.lowerEntry((byte)0);
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - a comparator is required.
+ }
+
+ e = nm.pollFirstEntry();
+ test(e != null);
+ test(e.getKey().byteValue() == (byte)firstByte);
+ test(e.getValue().intValue() == 0);
+ test(!nm.containsKey(firstByte));
+
+ e = nm.pollLastEntry();
+ test(e != null);
+ test(e.getKey().byteValue() == (byte)lastByte);
+ test(e.getValue().intValue() == length - 1);
+ test(!nm.containsKey(lastByte));
+
+ ByteIntMap typedM = (ByteIntMap)m;
+
+ try
+ {
+ typedM.headMapForValue(0);
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - a comparator is required.
+ }
+
+ try
+ {
+ typedM.tailMapForValue(0);
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - a comparator is required.
+ }
+
+ try
+ {
+ typedM.subMapForValue(0, 0);
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - a comparator is required.
+ }
+
+ try
+ {
+ typedM.mapForValue();
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected - a comparator is required.
+ }
+
+ m.clear();
+ test(nm.firstEntry() == null);
+ test(nm.lastEntry() == null);
+ populateDB(connection, m);
- java.util.Map.Entry e = (java.util.Map.Entry)o;
+ System.out.println("ok");
+ }
+
+ {
+ System.out.print("testing for loop... ");
+ System.out.flush();
+ for(java.util.Map.Entry<Byte, Integer> e : m.entrySet())
+ {
test(m.containsKey(e.getKey()));
test(m.containsValue(e.getValue()));
}
+
+ //
+ // The iterator should have already been closed when we reached the last entry.
+ //
+ int count = ((Freeze.Map)m).closeAllIterators();
+ test(count == 0);
+
System.out.println("ok");
}
@@ -324,20 +604,40 @@ public class Client
System.out.print("testing iterator.remove... ");
System.out.flush();
+ Freeze.Map<Byte, Integer> fm = (Freeze.Map<Byte, Integer>)m;
+ java.util.Iterator<java.util.Map.Entry<Byte, Integer>> p;
+ Transaction tx;
+ int count;
+
test(m.size() == 26);
- test(m.get(new Byte((byte)'b')) != null);
- test(m.get(new Byte((byte)'n')) != null);
- test(m.get(new Byte((byte)'z')) != null);
+ test(m.get((byte)'b') != null);
+ test(m.get((byte)'n') != null);
+ test(m.get((byte)'z') != null);
+
+ //
+ // Verify that remove fails without a transaction.
+ //
+ p = m.entrySet().iterator();
+ test(p.hasNext());
+ p.next();
+ try
+ {
+ p.remove();
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected.
+ }
- ((Freeze.Map) m).closeAllIterators();
+ count = fm.closeAllIterators();
+ test(count == 1);
- java.util.Set entrySet = m.entrySet();
- java.util.Iterator p = entrySet.iterator();
-
+ tx = connection.beginTransaction();
+ p = m.entrySet().iterator();
while(p.hasNext())
{
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
- Byte b = (Byte)e.getKey();
+ java.util.Map.Entry<Byte, Integer> e = p.next();
+ Byte b = e.getKey();
byte v = b.byteValue();
if(v == (byte)'b' || v == (byte)'n' || v == (byte)'z')
{
@@ -352,37 +652,41 @@ public class Client
}
}
}
- ((Freeze.Map) m).closeAllIterators();
+ tx.commit();
+ count = fm.closeAllIterators(); // Committing the transaction should close the iterator.
+ test(count == 0);
test(m.size() == 23);
- test(m.get(new Byte((byte)'b')) == null);
- test(m.get(new Byte((byte)'n')) == null);
- test(m.get(new Byte((byte)'z')) == null);
+ test(m.get((byte)'b') == null);
+ test(m.get((byte)'n') == null);
+ test(m.get((byte)'z') == null);
//
// Re-populate.
//
populateDB(connection, m);
-
+
test(m.size() == 26);
- entrySet = m.entrySet();
- p = entrySet.iterator();
+ tx = connection.beginTransaction();
+ p = m.entrySet().iterator();
while(p.hasNext())
{
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
- byte v = ((Byte)e.getKey()).byteValue();
+ java.util.Map.Entry<Byte, Integer> e = p.next();
+ byte v = e.getKey().byteValue();
if(v == (byte)'a' || v == (byte)'b' || v == (byte)'c')
{
p.remove();
}
}
- ((Freeze.Map) m).closeAllIterators();
+ tx.commit();
+ count = fm.closeAllIterators(); // Committing the transaction should close the iterator.
+ test(count == 0);
test(m.size() == 23);
- test(m.get(new Byte((byte)'a')) == null);
- test(m.get(new Byte((byte)'b')) == null);
- test(m.get(new Byte((byte)'c')) == null);
+ test(m.get((byte)'a') == null);
+ test(m.get((byte)'b') == null);
+ test(m.get((byte)'c') == null);
System.out.println("ok");
}
@@ -395,28 +699,48 @@ public class Client
//
populateDB(connection, m);
- java.util.Set entrySet = m.entrySet();
- java.util.Iterator p = entrySet.iterator();
+ Freeze.Map<Byte, Integer> fm = (Freeze.Map<Byte, Integer>)m;
+ java.util.Iterator<java.util.Map.Entry<Byte, Integer>> p;
+ Transaction tx;
+ java.util.Map.Entry<Byte, Integer> e;
+
+ //
+ // Verify that setValue on an iterator fails without a transaction.
+ //
+ p = m.entrySet().iterator();
+ test(p.hasNext());
+ try
+ {
+ e = p.next();
+ e.setValue(0);
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected.
+ }
+
+ tx = connection.beginTransaction();
+ p = m.entrySet().iterator();
while(p.hasNext())
{
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
- byte v = ((Byte)e.getKey()).byteValue();
+ e = p.next();
+ byte v = e.getKey().byteValue();
if(v == (byte)'b' || v == (byte)'n' || v == (byte)'z')
{
- e.setValue(new Integer(v + 100));
+ e.setValue(v + 100);
}
}
- ((Freeze.Map) m).closeAllIterators();
+ tx.commit();
test(m.size() == 26);
- test(m.get(new Byte((byte)'b')) != null);
- test(m.get(new Byte((byte)'n')) != null);
- test(m.get(new Byte((byte)'z')) != null);
+ test(m.get((byte)'b') != null);
+ test(m.get((byte)'n') != null);
+ test(m.get((byte)'z') != null);
- p = entrySet.iterator();
+ p = m.entrySet().iterator();
while(p.hasNext())
{
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
- byte v = ((Byte)e.getKey()).byteValue();
+ e = p.next();
+ byte v = e.getKey().byteValue();
if(v == (byte)'b' || v == (byte)'n' || v == (byte)'z')
{
test(e.getValue().equals(new Integer(v + 100)));
@@ -426,6 +750,18 @@ public class Client
test(e.getValue().equals(new Integer(v - (byte)'a')));
}
}
+
+ //
+ // No transaction is necessary for entries obtained without an iterator.
+ //
+ e = fm.firstEntry();
+ test(e != null);
+ e.setValue(-1);
+ test(e.getValue().intValue() == -1);
+ e = fm.firstEntry();
+ test(e != null);
+ test(e.getValue().intValue() == -1);
+
System.out.println("ok");
}
@@ -440,8 +776,9 @@ public class Client
ByteIntMap typedM = (ByteIntMap)m;
- java.util.Map.Entry e;
- java.util.Iterator p;
+ java.util.Map.Entry<Byte, Integer> e;
+ java.util.Iterator<java.util.Map.Entry<Byte, Integer>> p;
+ Transaction tx;
int length = alphabet.length();
@@ -449,76 +786,95 @@ public class Client
{
p = typedM.findByValue(k);
test(p.hasNext());
- e = (java.util.Map.Entry)p.next();
- test(((Byte)e.getKey()).byteValue() == (byte)alphabet.charAt(k));
+ e = p.next();
+ test(e.getKey().byteValue() == (byte)alphabet.charAt(k));
test(!p.hasNext());
}
//
- // 2 items at 17
- //
- m.put(new Byte((byte)alphabet.charAt(21)), new Integer(17));
+ // Change the value associated with key 21 to 17.
+ //
+ m.put((byte)alphabet.charAt(21), 17);
//
- // Non-existent index value
+ // Verify that the index no longer has an entry for value 21.
//
p = typedM.findByValue(21);
test(!p.hasNext());
-
+ //
+ // Verify that the iterator returns two entries for value 17.
+ //
p = typedM.findByValue(17);
-
test(p.hasNext());
- e = (java.util.Map.Entry)p.next();
- byte v = ((Byte)e.getKey()).byteValue();
+ e = p.next();
+ byte v = e.getKey().byteValue();
test(v == (byte)alphabet.charAt(17) || v == (byte)alphabet.charAt(21));
-
+
test(p.hasNext());
- e = (java.util.Map.Entry)p.next();
- v = ((Byte)e.getKey()).byteValue();
+ e = p.next();
+ v = e.getKey().byteValue();
test(v == (byte)alphabet.charAt(17) || v == (byte)alphabet.charAt(21));
-
- test(!p.hasNext());
+
+ test(!p.hasNext()); // Iterator defaults to returning only exact matches.
test(typedM.valueCount(17) == 2);
+ //
+ // Cannot remove without a transaction.
+ //
+ p = typedM.findByValue(17);
+ test(p.hasNext());
+ p.next();
+ try
+ {
+ p.remove();
+ }
+ catch(UnsupportedOperationException ex)
+ {
+ // Expected.
+ }
+
+ tx = connection.beginTransaction();
p = typedM.findByValue(17);
test(p.hasNext());
p.next();
p.remove();
test(p.hasNext());
- e = (java.util.Map.Entry)p.next();
- v = ((Byte)e.getKey()).byteValue();
+ e = p.next();
+ v = e.getKey().byteValue();
test(v == (byte)alphabet.charAt(17) || v == (byte)alphabet.charAt(21));
test(!p.hasNext());
+ tx.commit();
- //
- // We need to close this write iterator before further reads
- //
- typedM.closeAllIterators();
+ int count = typedM.closeAllIterators();
+ test(count == 0); // Committing the transaction also closes the iterators.
test(typedM.valueCount(17) == 1);
p = typedM.findByValue(17);
test(p.hasNext());
- e = (java.util.Map.Entry)p.next();
+ e = p.next();
+ //
+ // Cannot set a value on an index iterator.
+ //
try
{
- e.setValue(new Integer(18));
+ e.setValue(18);
test(false);
}
catch(UnsupportedOperationException ex)
{
- // Expected
+ // Expected.
}
- v = ((Byte)e.getKey()).byteValue();
+ v = e.getKey().byteValue();
test(v == (byte)alphabet.charAt(17) || v == (byte)alphabet.charAt(21));
test(typedM.valueCount(17) == 1);
- m.put(new Byte((byte)alphabet.charAt(21)), new Integer(17));
-
- //
+ m.put((byte)alphabet.charAt(21), 17);
+
+ //
// Non-exact match
//
p = typedM.findByValue(21);
@@ -531,35 +887,33 @@ public class Client
p = typedM.findByValue(22, false);
int previous = 21;
- int count = 0;
+ count = 0;
while(p.hasNext())
{
- e = (java.util.Map.Entry)p.next();
+ e = p.next();
+
+ int val = e.getValue().intValue();
- int val = ((Integer)e.getValue()).intValue();
-
test(val > previous);
previous = val;
count++;
}
test(count == 4);
-
+
System.out.println("ok");
}
-
- ((Freeze.Map) m).closeAllIterators();
+ ((Freeze.Map)m).closeAllIterators();
{
System.out.print("testing concurrent access... ");
System.out.flush();
-
+
m.clear();
populateDB(connection, m);
-
- java.util.List l = new java.util.ArrayList();
-
+ java.util.List<Thread> l = new java.util.ArrayList<Thread>();
+
//
// Create each thread.
//
@@ -572,25 +926,21 @@ public class Client
//
// Start each thread.
//
- java.util.Iterator p = l.iterator();
- while(p.hasNext())
+ for(Thread t : l)
{
- Thread thr = (Thread)p.next();
- thr.start();
+ t.start();
}
-
+
//
// Wait for each thread to terminate.
//
- p = l.iterator();
- while(p.hasNext())
+ for(Thread t : l)
{
- Thread thr = (Thread)p.next();
- while(thr.isAlive())
+ while(t.isAlive())
{
try
{
- thr.join();
+ t.join();
}
catch(InterruptedException e)
{
@@ -610,42 +960,42 @@ public class Client
Ice.Identity odd = new Ice.Identity();
odd.name = "foo";
odd.category = "odd";
-
+
Ice.Identity even = new Ice.Identity();
even.name = "bar";
even.category = "even";
-
+
Transaction tx = connection.beginTransaction();
for(int i = 0; i < 1000; i++)
{
if(i % 2 == 0)
{
- iim.fastPut(new Integer(i), even);
+ iim.fastPut(i, even);
}
else
{
- iim.fastPut(new Integer(i), odd);
+ iim.fastPut(i, odd);
}
}
tx.commit();
iim.closeDb();
}
-
+
{
//
// Need true to create the index
//
IntIdentityMapWithIndex iim = new IntIdentityMapWithIndex(connection, "intIdentity", true);
-
+
test(iim.categoryCount("even") == 500);
test(iim.categoryCount("odd") == 500);
-
+
int count = 0;
- java.util.Iterator p = iim.findByCategory("even");
+ java.util.Iterator<java.util.Map.Entry<Integer, Ice.Identity>> p = iim.findByCategory("even");
while(p.hasNext())
{
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
- int k = ((Integer)e.getKey()).intValue();
+ java.util.Map.Entry<Integer, Ice.Identity> e = p.next();
+ int k = e.getKey().intValue();
test(k % 2 == 0);
++count;
}
@@ -655,52 +1005,61 @@ public class Client
p = iim.findByCategory("odd");
while(p.hasNext())
{
- java.util.Map.Entry e = (java.util.Map.Entry)p.next();
- int k = ((Integer)e.getKey()).intValue();
+ java.util.Map.Entry<Integer, Ice.Identity> e = p.next();
+ int k = e.getKey().intValue();
test(k % 2 == 1);
++count;
}
test(count == 500);
-
+
iim.destroy();
}
System.out.println("ok");
-
- System.out.print("testing sorting... ");
- System.out.flush();
+ //
+ // Sorting
+ //
- final java.util.Comparator less =
- new java.util.Comparator()
+ final java.util.Comparator<Integer> less = new java.util.Comparator<Integer>()
+ {
+ public int compare(Integer i1, Integer i2)
{
- public int compare(Object o1, Object o2)
+ if(i1 == i2)
{
- if(o1 == o2)
- {
- return 0;
- }
- else if(o1 == null)
- {
- return -((Comparable)o2).compareTo(o1);
- }
- else
- {
- return ((Comparable)o1).compareTo(o2);
- }
+ return 0;
+ }
+ else if(i1 == null)
+ {
+ return -i2.compareTo(i1);
}
- };
-
- java.util.Comparator greater =
- new java.util.Comparator()
+ else
+ {
+ return i1.compareTo(i2);
+ }
+ }
+ };
+
+ java.util.Comparator<String> greater = new java.util.Comparator<String>()
+ {
+ public int compare(String s1, String s2)
{
- public int compare(Object o1, Object o2)
+ if(s1 == s2)
{
- return -less.compare(o1, o2);
+ return 0;
}
- };
-
- java.util.Map indexComparators = new java.util.HashMap();
- indexComparators.put("category", greater);
+ else if(s1 == null)
+ {
+ return s2.compareTo(s1);
+ }
+ else
+ {
+ return -s1.compareTo(s2);
+ }
+ }
+ };
+
+ SortedMap.IndexComparators indexComparators = new SortedMap.IndexComparators();
+ indexComparators.categoryComparator = greater;
java.util.Random rand = new java.util.Random();
{
@@ -709,13 +1068,9 @@ public class Client
Transaction tx = connection.beginTransaction();
for(int i = 0; i < 500; i++)
{
- int k = rand.nextInt(1000);
-
- Ice.Identity id = new Ice.Identity("foo",
- String.valueOf(alphabet.charAt(k % 26)));
-
-
- sm.fastPut(new Integer(k), id);
+ int k = rand.nextInt(1000);
+ Ice.Identity id = new Ice.Identity("foo", String.valueOf(alphabet.charAt(k % 26)));
+ sm.fastPut(k, id);
}
tx.commit();
sm.close();
@@ -723,137 +1078,1032 @@ public class Client
{
SortedMap sm = new SortedMap(connection, "sortedMap", true, less, indexComparators);
-
+ NavigableMap<Integer, Ice.Identity> sub = null;
+
+ System.out.print("testing sorting with primary key... ");
+ System.out.flush();
+
+ testSortedMap(sm, true);
+
+ {
+ final Integer first = sm.firstKey();
+ final Integer last = sm.lastKey();
+
+ //
+ // fastRemove
+ //
+ sub = sm.headMap(first, true);
+ Ice.Identity id = sub.get(first);
+ test(sub.fastRemove(first) == true);
+ test(sub.fastRemove(first) == false);
+ test(sm.containsKey(first) == false);
+ sm.put(first, id);
+ test(sm.containsKey(first) == true);
+ }
+
+ System.out.println("ok");
+
//
- // Primary key
+ // Category index
//
- for(int i = 0; i < 100; i++)
+
{
- int k = rand.nextInt(1000);
+ System.out.print("testing sorting with secondary key... ");
+ System.out.flush();
+
+ NavigableMap<String, java.util.Set<java.util.Map.Entry<Integer, Ice.Identity>>> isub = null;
- java.util.SortedMap subMap = sm.tailMap(new Integer(k));
+ isub = sm.mapForCategory();
+ final String first = isub.firstKey();
+ final String last = isub.lastKey();
+
+ //
+ // Head map
+ //
+ isub = sm.headMapForCategory(last);
+ test(greater.compare(isub.lastKey(), last) < 0);
+ isub = sm.headMapForCategory(last, true);
+ test(greater.compare(isub.lastKey(), last) == 0);
+ isub = sm.headMapForCategory(first);
+ test(isub.firstEntry() == null); // map is empty
+ isub = sm.headMapForCategory(first, true);
+ test(greater.compare(isub.firstKey(), first) == 0);
+ test(greater.compare(isub.lastKey(), first) == 0);
+
+ sm.headMapForCategory(first, true).headMap(first, true);
+ sm.headMapForCategory(first, true).headMap(first);
+ sm.headMapForCategory(first).headMap(first);
try
{
- Integer fk = (Integer)subMap.firstKey();
- test(fk.intValue() >= k);
+ sm.headMapForCategory(first).headMap(first, true);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
}
- catch(NoSuchElementException e)
+
{
- // Expected from time to time
+ String category = null;
+ while(true)
+ {
+ int k = rand.nextInt(1000);
+ category = String.valueOf(alphabet.charAt(k % 26));
+ isub = sm.headMapForCategory(category);
+ if(isub.firstEntry() != null) // Make sure submap isn't empty.
+ {
+ break;
+ }
+ }
+
+ testSecondaryKey(isub, null, false, category, false);
+
+ try
+ {
+ isub.tailMap(category);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
}
-
- subMap = sm.headMap(new Integer(k));
+
+ {
+ String category = null;
+ while(true)
+ {
+ int k = rand.nextInt(1000);
+ category = String.valueOf(alphabet.charAt(k % 26));
+ isub = sm.headMapForCategory(category, true);
+ if(isub.firstEntry() != null) // Make sure submap isn't empty.
+ {
+ break;
+ }
+ }
+
+ testSecondaryKey(isub, null, false, category, true);
+
+ try
+ {
+ String invalid = String.valueOf(category.charAt(0) + 1);
+ isub.tailMap(invalid);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+ }
+
+ //
+ // Tail map
+ //
+ isub = sm.tailMapForCategory(first);
+ test(greater.compare(isub.firstKey(), first) == 0);
+ isub = sm.tailMapForCategory(first, false);
+ test(greater.compare(isub.firstKey(), first) > 0);
+ isub = sm.tailMapForCategory(last);
+ test(greater.compare(isub.firstKey(), last) == 0);
+ test(greater.compare(isub.lastKey(), last) == 0);
+ isub = sm.tailMapForCategory(last, false);
+ test(isub.firstEntry() == null); // map is empty
+
+ sm.tailMapForCategory(last).tailMap(last);
+ sm.tailMapForCategory(last).tailMap(last, false);
try
{
- Integer lk = (Integer)subMap.lastKey();
- test(lk.intValue() < k);
+ sm.tailMapForCategory(last, false).tailMap(last);
+ test(false);
}
- catch(NoSuchElementException e)
+ catch(IllegalArgumentException ex)
{
- // Expected from time to time
+ // Expected.
}
-
+
+ {
+ String category = null;
+ while(true)
+ {
+ int k = rand.nextInt(1000);
+ category = String.valueOf(alphabet.charAt(k % 26));
+ isub = sm.tailMapForCategory(category);
+ if(isub.firstEntry() != null) // Make sure submap isn't empty.
+ {
+ break;
+ }
+ }
+
+ testSecondaryKey(isub, category, true, null, false);
+
+ try
+ {
+ String invalid = String.valueOf((char)(category.charAt(0) + 1));
+ isub.headMap(invalid);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+ }
+
+ {
+ String category = null;
+ while(true)
+ {
+ int k = rand.nextInt(1000);
+ category = String.valueOf(alphabet.charAt(k % 26));
+ isub = sm.tailMapForCategory(category, false);
+ if(isub.firstEntry() != null) // Make sure submap isn't empty.
+ {
+ break;
+ }
+ }
+
+ testSecondaryKey(isub, category, false, null, false);
+
+ try
+ {
+ isub.headMap(category);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+ }
+
//
- // Now with an iterator
+ // Sub map
//
- java.util.Iterator p = subMap.keySet().iterator();
- while(p.hasNext())
+ isub = sm.subMapForCategory(first, last);
+ test(greater.compare(isub.firstKey(), first) == 0);
+ test(greater.compare(isub.lastKey(), last) < 0);
+ isub = sm.subMapForCategory(first, false, last, false);
+ test(greater.compare(isub.firstKey(), first) > 0);
+ isub = sm.subMapForCategory(first, true, last, true);
+ test(greater.compare(isub.firstKey(), first) == 0);
+ test(greater.compare(isub.lastKey(), last) == 0);
+
+ try
{
- Integer ck = (Integer)p.next();
- test(ck.intValue() < k);
+ sm.subMapForCategory(first, false, first, false);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
}
- sm.closeAllIterators();
- }
- //
- // Category index
- //
- for(int i = 0; i < 100; i++)
- {
- int k = rand.nextInt(1000);
- String category = String.valueOf(alphabet.charAt(k % 26));
-
- java.util.SortedMap subMap = sm.tailMapForIndex("category", category);
+ NavigableMap<String, java.util.Set<java.util.Map.Entry<Integer, Ice.Identity>>> isubsub = null;
+
+ isubsub = isub.subMap(first, true, last, true);
+ test(greater.compare(isubsub.firstKey(), first) == 0);
+ test(greater.compare(isubsub.lastKey(), last) == 0);
+
+ isubsub = isub.subMap(first, false, last, false);
+ test(greater.compare(isubsub.firstKey(), first) > 0);
+ test(greater.compare(isubsub.lastKey(), last) < 0);
+
try
{
- String fk = (String)subMap.firstKey();
- test(greater.compare(fk, category) >= 0);
+ isubsub.subMap(first, true, last, false);
+ test(false);
}
- catch(NoSuchElementException e)
+ catch(IllegalArgumentException ex)
{
- // Expected from time to time
+ // Expected.
}
-
- subMap = sm.headMapForIndex("category", category);
+
try
{
- String lk = (String)subMap.lastKey();
- test(greater.compare(lk, category) < 0);
+ isubsub.subMap(first, false, last, true);
+ test(false);
}
- catch(NoSuchElementException e)
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+
{
- // Expected from time to time
+ final boolean fromInclusive[] = { false, false, true, true };
+ final boolean toInclusive[] = { false, true, false, true };
+ for(int i = 0; i < 4; ++i)
+ {
+ String from = null, to = null;
+ while(true)
+ {
+ int f = rand.nextInt(1000) % 26;
+ int t = rand.nextInt(1000) % 26;
+ int f1 = Math.max(f, t);
+ int t1 = Math.min(f, t);
+ if(f1 - t1 < 10)
+ {
+ continue;
+ }
+ from = String.valueOf(alphabet.charAt(f1 % 26));
+ to = String.valueOf(alphabet.charAt(t1 % 26));
+ isub = sm.subMapForCategory(from, fromInclusive[i], to, toInclusive[i]);
+ if(isub.firstEntry() != null) // Make sure submap isn't empty.
+ {
+ break;
+ }
+ }
+
+ testSecondaryKey(isub, from, fromInclusive[i], to, toInclusive[i]);
+ }
}
//
- // Now with an iterator
+ // fastRemove
//
- java.util.Iterator p = subMap.keySet().iterator();
- while(p.hasNext())
+ isub = sm.headMapForCategory(first, true);
+ try
+ {
+ isub.fastRemove(first);
+ test(false);
+ }
+ catch(UnsupportedOperationException ex)
{
- String ck = (String)p.next();
- test(greater.compare(ck, category) < 0);
+ // Expected.
}
- sm.closeAllIterators();
+
+ System.out.println("ok");
}
-
- java.util.SortedMap subMap = sm.mapForIndex("category");
- java.util.Iterator p = subMap.entrySet().iterator();
- String category = null;
- while(p.hasNext())
+ sm.close();
+ }
+
+ {
+ SortedMap sm = new SortedMap(connection, "sortedMap", true, less, indexComparators);
+
+ System.out.print("testing descending map... ");
+ System.out.flush();
+
+ {
+ NavigableMap<Integer, Ice.Identity> dmap = sm.descendingMap();
+ testSortedMap(dmap, false);
+ testSortedMap(dmap.descendingMap(), true); // Ascending submap.
+ }
+
+ int finc, tinc; // Inclusive flags
+
+ for(tinc = 0; tinc < 2; ++tinc)
{
- java.util.Map.Entry entry = (java.util.Map.Entry)p.next();
-
- if(category != null)
+ while(true)
{
- test(greater.compare(category, entry.getKey()) < 0);
+ NavigableMap<Integer, Ice.Identity> sub = sm.headMap(rand.nextInt(1000), tinc == 0);
+ if(sub.firstEntry() == null)
+ {
+ continue;
+ }
+ NavigableMap<Integer, Ice.Identity> dmap = sub.descendingMap();
+ test(dmap.firstKey().equals(sub.lastKey()));
+ test(dmap.lastKey().equals(sub.firstKey()));
+ break;
}
- category = (String)entry.getKey();
- // System.out.println("*******Category == " + category);
+ }
-
- java.util.Iterator q = ((java.util.Set)entry.getValue()).iterator();
- while(q.hasNext())
+ for(finc = 0; finc < 2; ++finc)
+ {
+ while(true)
{
- //
- // All my map entries
- //
- entry = (java.util.Map.Entry)q.next();
- Ice.Identity id = (Ice.Identity)entry.getValue();
- test(category.equals(id.category));
-
- // System.out.println("Key == " + entry.getKey().toString());
+ NavigableMap<Integer, Ice.Identity> sub = sm.tailMap(rand.nextInt(1000), finc == 0);
+ if(sub.firstEntry() == null)
+ {
+ continue;
+ }
+ NavigableMap<Integer, Ice.Identity> dmap = sub.descendingMap();
+ test(dmap.firstKey().equals(sub.lastKey()));
+ test(dmap.lastKey().equals(sub.firstKey()));
+ break;
+ }
+ }
+ for(finc = 0; finc < 2; ++finc)
+ {
+ for(tinc = 0; tinc < 2; ++tinc)
+ {
+ while(true)
+ {
+ int f = rand.nextInt(1000);
+ int t = rand.nextInt(1000);
+ int from = Math.min(f, t);
+ int to = Math.max(f, t);
+ if(to - from < 100)
+ {
+ continue;
+ }
+ NavigableMap<Integer, Ice.Identity> sub = sm.subMap(from, finc == 0, to, tinc == 0);
+ if(sub.firstEntry() == null)
+ {
+ continue;
+ }
+ NavigableMap<Integer, Ice.Identity> dmap = sub.descendingMap();
+ test(dmap.firstKey().equals(sub.lastKey()));
+ test(dmap.lastKey().equals(sub.firstKey()));
+ break;
+ }
}
}
- sm.closeAllIterators();
+
+ {
+ NavigableMap<String, java.util.Set<java.util.Map.Entry<Integer, Ice.Identity>>> isub, dmap;
+ java.util.Comparator<? super String> c;
+
+ isub = sm.mapForCategory(); // An iterator for this map visits keys in descending order.
+ dmap = isub.descendingMap(); // An iterator for this map visits keys in ascending order.
+ test(dmap.firstKey().equals(isub.lastKey()));
+ test(dmap.lastKey().equals(isub.firstKey()));
+ c = dmap.comparator();
+ String prev = null;
+ for(java.util.Map.Entry<String, java.util.Set<java.util.Map.Entry<Integer, Ice.Identity>>> e :
+ dmap.entrySet())
+ {
+ if(prev != null)
+ {
+ test(c.compare(e.getKey(), prev) > 0);
+ }
+ prev = e.getKey();
+ }
+
+ dmap = dmap.descendingMap();
+ test(dmap.firstKey().equals(isub.firstKey()));
+ test(dmap.lastKey().equals(isub.lastKey()));
+ }
+
+ for(tinc = 0; tinc < 2; ++tinc)
+ {
+ while(true)
+ {
+ String category = String.valueOf(alphabet.charAt(rand.nextInt(1000) % 26));
+ NavigableMap<String, java.util.Set<java.util.Map.Entry<Integer, Ice.Identity>>> isub =
+ sm.headMapForCategory(category, tinc == 0);
+ if(isub.firstEntry() == null)
+ {
+ continue;
+ }
+ NavigableMap<String, java.util.Set<java.util.Map.Entry<Integer, Ice.Identity>>> dmap =
+ isub.descendingMap();
+ test(dmap.firstKey().equals(isub.lastKey()));
+ test(dmap.lastKey().equals(isub.firstKey()));
+ break;
+ }
+ }
+
+ for(finc = 0; finc < 2; ++finc)
+ {
+ while(true)
+ {
+ String category = String.valueOf(alphabet.charAt(rand.nextInt(1000) % 26));
+ NavigableMap<String, java.util.Set<java.util.Map.Entry<Integer, Ice.Identity>>> isub =
+ sm.tailMapForCategory(category, finc == 0);
+ if(isub.firstEntry() == null)
+ {
+ continue;
+ }
+ NavigableMap<String, java.util.Set<java.util.Map.Entry<Integer, Ice.Identity>>> dmap =
+ isub.descendingMap();
+ test(dmap.firstKey().equals(isub.lastKey()));
+ test(dmap.lastKey().equals(isub.firstKey()));
+ break;
+ }
+ }
+
+ for(finc = 0; finc < 2; ++finc)
+ {
+ for(tinc = 0; tinc < 2; ++tinc)
+ {
+ while(true)
+ {
+ int f = rand.nextInt(1000) % 26;
+ int t = rand.nextInt(1000) % 26;
+ int f1 = Math.max(f, t);
+ int t1 = Math.min(f, t);
+ if(f1 - t1 < 10)
+ {
+ continue;
+ }
+ String from = String.valueOf(alphabet.charAt(f1 % 26));
+ String to = String.valueOf(alphabet.charAt(t1 % 26));
+ NavigableMap<String, java.util.Set<java.util.Map.Entry<Integer, Ice.Identity>>> isub =
+ sm.subMapForCategory(from, finc == 0, to, tinc == 0);
+ if(isub.firstEntry() == null)
+ {
+ continue;
+ }
+ NavigableMap<String, java.util.Set<java.util.Map.Entry<Integer, Ice.Identity>>> dmap =
+ isub.descendingMap();
+ test(dmap.firstKey().equals(isub.lastKey()));
+ test(dmap.lastKey().equals(isub.firstKey()));
+ break;
+ }
+ }
+ }
+
+ {
+ java.util.Set<Integer> keys = sm.descendingKeySet();
+ Integer prev = null;
+ for(Integer i : keys)
+ {
+ if(prev != null)
+ {
+ test(i.compareTo(prev) < 0);
+ }
+ prev = i;
+ }
+ }
+
+ {
+ java.util.Set<String> keys = sm.mapForCategory().descendingKeySet();
+ String prev = null;
+ for(String category : keys)
+ {
+ if(prev != null)
+ {
+ test(category.compareTo(prev) > 0);
+ }
+ prev = category;
+ }
+ }
+
+ sm.close();
+
+ System.out.println("ok");
+ }
+
+ {
+ SortedMap sm = new SortedMap(connection, "sortedMap", true, less, indexComparators);
+
+ System.out.print("testing empty map... ");
+ System.out.flush();
+
sm.clear();
+
+ testEmptyMap(sm);
+ testEmptyMap(sm.headMap(0, false));
+ testEmptyMap(sm.headMap(0, false).headMap(0, false));
+ testEmptyMap(sm.tailMap(0, false));
+ testEmptyMap(sm.tailMap(0, false).tailMap(0, false));
+ testEmptyMap(sm.subMap(0, false, 1000, false));
+ testEmptyMap(sm.subMap(0, false, 1000, false).subMap(0, false, 1000, false));
+
sm.close();
+
+ System.out.println("ok");
}
- System.out.println("ok");
+
connection.close();
-
+
return 0;
}
+ static void
+ testSortedMap(NavigableMap<Integer, Ice.Identity> sm, boolean ascending)
+ {
+ java.util.Comparator<? super Integer> c = sm.comparator();
+ java.util.Random rand = new java.util.Random();
+ NavigableMap<Integer, Ice.Identity> sub = null;
+
+ final int first = sm.firstKey().intValue();
+ final int last = sm.lastKey().intValue();
+
+ testPrimaryKey(sm, null, false, null, false);
+
+ //
+ // Head map
+ //
+ sub = (NavigableMap<Integer, Ice.Identity>)sm.headMap(last);
+ test(c.compare(sub.lastKey(), last) < 0);
+ sub = sm.headMap(last, true);
+ test(c.compare(sub.lastKey(), last) == 0);
+ sub = (NavigableMap<Integer, Ice.Identity>)sm.headMap(first);
+ test(sub.firstEntry() == null); // map is empty
+ sub = sm.headMap(first, true);
+ test(c.compare(sub.firstKey(), first) == 0);
+ test(c.compare(sub.lastKey(), first) == 0);
+
+ sm.headMap(first, true).headMap(first, true);
+ sm.headMap(first, true).headMap(first);
+ sm.headMap(first).headMap(first);
+ try
+ {
+ ((NavigableMap<Integer, Ice.Identity>)sm.headMap(first)).headMap(first, true);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+
+ {
+ int k = 0;
+ while(true)
+ {
+ k = rand.nextInt(1000);
+ sub = (NavigableMap<Integer, Ice.Identity>)sm.headMap(k);
+ if(sub.firstEntry() != null) // Make sure submap isn't empty.
+ {
+ break;
+ }
+ }
+
+ testPrimaryKey(sub, null, false, k, false);
+
+ try
+ {
+ sub.tailMap(k);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+ }
+
+ {
+ int k = 0;
+ while(true)
+ {
+ k = rand.nextInt(1000);
+ sub = sm.headMap(k, true);
+ if(sub.firstEntry() != null) // Make sure submap isn't empty.
+ {
+ break;
+ }
+ }
+
+ testPrimaryKey(sub, null, false, k, true);
+
+ try
+ {
+ sub.tailMap(k, false);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+ }
+
+ //
+ // Tail map
+ //
+ sub = (NavigableMap<Integer, Ice.Identity>)sm.tailMap(first);
+ test(c.compare(sub.firstKey(), first) == 0);
+ sub = sm.tailMap(first, false);
+ test(c.compare(sub.firstKey(), first) > 0);
+ sub = (NavigableMap<Integer, Ice.Identity>)sm.tailMap(last);
+ test(c.compare(sub.firstKey(), last) == 0);
+ test(c.compare(sub.lastKey(), last) == 0);
+ sub = sm.tailMap(last, false);
+ test(sub.firstEntry() == null); // map is empty
+
+ sm.tailMap(last).tailMap(last);
+ ((NavigableMap<Integer, Ice.Identity>)sm.tailMap(last)).tailMap(last, false);
+ try
+ {
+ sm.tailMap(last, false).tailMap(last);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+
+ {
+ int k = 0;
+ while(true)
+ {
+ k = rand.nextInt(1000);
+ sub = (NavigableMap<Integer, Ice.Identity>)sm.tailMap(k);
+ if(sub.firstEntry() != null) // Make sure submap isn't empty.
+ {
+ break;
+ }
+ }
+
+ testPrimaryKey(sub, k, true, null, false);
+
+ try
+ {
+ sub.headMap(k);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+ }
+
+ {
+ int k = 0;
+ while(true)
+ {
+ k = rand.nextInt(1000);
+ sub = sm.tailMap(k, false);
+ if(sub.firstEntry() != null) // Make sure submap isn't empty.
+ {
+ break;
+ }
+ }
+
+ testPrimaryKey(sub, k, false, null, false);
+
+ try
+ {
+ sub.headMap(k);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+ }
+
+ //
+ // Sub map
+ //
+ sub = (NavigableMap<Integer, Ice.Identity>)sm.subMap(first, last);
+ test(c.compare(sub.firstKey(), first) == 0);
+ test(c.compare(sub.lastKey(), last) < 0);
+ sub = sm.subMap(first, false, last, false);
+ test(c.compare(sub.firstKey(), first) > 0);
+ sub = sm.subMap(first, true, last, true);
+ test(c.compare(sub.firstKey(), first) == 0);
+ test(c.compare(sub.lastKey(), last) == 0);
+
+ try
+ {
+ sm.subMap(first, false, first, false);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+
+ NavigableMap<Integer, Ice.Identity> subsub = null;
+
+ subsub = sub.subMap(first, true, last, true);
+ test(c.compare(subsub.firstKey(), first) == 0);
+ test(c.compare(subsub.lastKey(), last) == 0);
+
+ subsub = sub.subMap(first, false, last, false);
+ test(c.compare(subsub.firstKey(), first) > 0);
+ test(c.compare(subsub.lastKey(), last) < 0);
+
+ try
+ {
+ subsub.subMap(first, true, last, false);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+
+ try
+ {
+ subsub.subMap(first, false, last, true);
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+
+ {
+ final boolean fromInclusive[] = { false, false, true, true };
+ final boolean toInclusive[] = { false, true, false, true };
+ for(int i = 0; i < 4; ++i)
+ {
+ int from = 0, to = 0;
+ while(true)
+ {
+ int f = rand.nextInt(1000);
+ int t = rand.nextInt(1000);
+ if(ascending)
+ {
+ from = Math.min(f, t);
+ to = Math.max(f, t);
+ }
+ else
+ {
+ from = Math.max(f, t);
+ to = Math.min(f, t);
+ }
+ if(Math.abs(to - from) < 100)
+ {
+ continue;
+ }
+ sub = sm.subMap(from, fromInclusive[i], to, toInclusive[i]);
+ if(sub.firstEntry() != null) // Make sure submap isn't empty.
+ {
+ break;
+ }
+ }
+
+ testPrimaryKey(sub, from, fromInclusive[i], to, toInclusive[i]);
+ }
+ }
+ }
+
+ static void
+ testPrimaryKey(NavigableMap<Integer, Ice.Identity> m, Integer from, boolean fromInclusive, Integer to,
+ boolean toInclusive)
+ {
+ java.util.Comparator<? super Integer> c = m.comparator();
+
+ Integer first = m.firstKey();
+ Integer last = m.lastKey();
+
+ test(inRange(c, first, from, fromInclusive, to, toInclusive));
+ test(inRange(c, last, from, fromInclusive, to, toInclusive));
+
+ java.util.Random rand = new java.util.Random();
+ int i = 0;
+ while(i < 100)
+ {
+ int k = rand.nextInt(1000);
+ if(!inRange(c, k, from, fromInclusive, to, toInclusive))
+ {
+ continue;
+ }
+
+ java.util.Map.Entry<Integer, Ice.Identity> e;
+ Integer key;
+
+ key = m.ceilingKey(k);
+ if(key == null)
+ {
+ test(c.compare(k, last) > 0);
+ }
+ else
+ {
+ test(c.compare(key, k) >= 0);
+ }
+ e = m.ceilingEntry(k);
+ test((key == null && e == null) || key.equals(e.getKey()));
+
+ key = m.floorKey(k);
+ if(key == null)
+ {
+ test(c.compare(k, first) < 0);
+ }
+ else
+ {
+ test(c.compare(key, k) <= 0);
+ }
+ e = m.floorEntry(k);
+ test((key == null && e == null) || key.equals(e.getKey()));
+
+ key = m.higherKey(k);
+ if(key == null)
+ {
+ test(c.compare(k, last) >= 0);
+ }
+ else
+ {
+ test(c.compare(key, k) > 0);
+ }
+ e = m.higherEntry(k);
+ test((key == null && e == null) || key.equals(e.getKey()));
+
+ key = m.lowerKey(k);
+ if(key == null)
+ {
+ test(c.compare(k, first) <= 0);
+ }
+ else
+ {
+ test(c.compare(key, k) < 0);
+ }
+ e = m.lowerEntry(k);
+ test((key == null && e == null) || key.equals(e.getKey()));
+
+ ++i;
+ }
+
+ for(java.util.Map.Entry<Integer, Ice.Identity> p : m.entrySet())
+ {
+ test(inRange(c, p.getKey(), from, fromInclusive, to, toInclusive));
+ }
+ }
+
+ static boolean
+ inRange(java.util.Comparator<? super Integer> c, Integer val, Integer from, boolean fromInclusive, Integer to,
+ boolean toInclusive)
+ {
+ if(from != null)
+ {
+ int cmp = c.compare(val, from);
+ if((fromInclusive && cmp < 0) || (!fromInclusive && cmp <= 0))
+ {
+ return false;
+ }
+ }
+ if(to != null)
+ {
+ int cmp = c.compare(val, to);
+ if((toInclusive && cmp > 0) || (!toInclusive && cmp >= 0))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ static void
+ testSecondaryKey(NavigableMap<String, java.util.Set<java.util.Map.Entry<Integer, Ice.Identity>>> m, String from,
+ boolean fromInclusive, String to, boolean toInclusive)
+ {
+ java.util.Comparator<? super String> c = m.comparator();
+
+ String first = m.firstKey();
+ String last = m.lastKey();
+
+ test(inRange(c, first, from, fromInclusive, to, toInclusive));
+ test(inRange(c, last, from, fromInclusive, to, toInclusive));
+
+ java.util.Random rand = new java.util.Random();
+ int i = 0;
+ while(i < 100)
+ {
+ String category = String.valueOf(alphabet.charAt(rand.nextInt(1000) % 26));
+ if(!inRange(c, category, from, fromInclusive, to, toInclusive))
+ {
+ continue;
+ }
+
+ java.util.Map.Entry<String, java.util.Set<java.util.Map.Entry<Integer, Ice.Identity>>> e;
+ String key;
+
+ key = m.ceilingKey(category);
+ if(key == null)
+ {
+ test(c.compare(category, last) > 0);
+ }
+ else
+ {
+ test(c.compare(key, category) >= 0);
+ }
+ e = m.ceilingEntry(category);
+ test((key == null && e == null) || key.equals(e.getKey()));
+
+ key = m.floorKey(category);
+ if(key == null)
+ {
+ test(c.compare(category, first) < 0);
+ }
+ else
+ {
+ test(c.compare(key, category) <= 0);
+ }
+ e = m.floorEntry(category);
+ test((key == null && e == null) || key.equals(e.getKey()));
+
+ key = m.higherKey(category);
+ if(key == null)
+ {
+ test(c.compare(category, last) >= 0);
+ }
+ else
+ {
+ test(c.compare(key, category) > 0);
+ }
+ e = m.higherEntry(category);
+ test((key == null && e == null) || key.equals(e.getKey()));
+
+ key = m.lowerKey(category);
+ if(key == null)
+ {
+ test(c.compare(category, first) <= 0);
+ }
+ else
+ {
+ test(c.compare(key, category) < 0);
+ }
+ e = m.lowerEntry(category);
+ test((key == null && e == null) || key.equals(e.getKey()));
+
+ for(java.util.Map.Entry<String, java.util.Set<java.util.Map.Entry<Integer, Ice.Identity>>> p : m.entrySet())
+ {
+ test(inRange(c, p.getKey(), from, fromInclusive, to, toInclusive));
+ }
+
+ ++i;
+ }
+ }
+
+ static boolean
+ inRange(java.util.Comparator<? super String> c, String val, String from, boolean fromInclusive, String to,
+ boolean toInclusive)
+ {
+ if(from != null)
+ {
+ int cmp = c.compare(val, from);
+ if((fromInclusive && cmp < 0) || (!fromInclusive && cmp <= 0))
+ {
+ return false;
+ }
+ }
+ if(to != null)
+ {
+ int cmp = c.compare(val, to);
+ if((toInclusive && cmp > 0) || (!toInclusive && cmp >= 0))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ static private void
+ testEmptyMap(NavigableMap<Integer, Ice.Identity> m)
+ {
+ test(m.firstEntry() == null);
+ test(m.lastEntry() == null);
+ test(m.ceilingEntry(0) == null);
+ test(m.floorEntry(0) == null);
+ test(m.higherEntry(0) == null);
+ test(m.lowerEntry(0) == null);
+ test(m.pollFirstEntry() == null);
+ test(m.pollLastEntry() == null);
+
+ try
+ {
+ m.firstKey();
+ test(false);
+ }
+ catch(java.util.NoSuchElementException ex)
+ {
+ // Expected.
+ }
+ try
+ {
+ m.lastKey();
+ test(false);
+ }
+ catch(java.util.NoSuchElementException ex)
+ {
+ // Expected.
+ }
+
+ test(m.ceilingKey(0) == null);
+ test(m.floorKey(0) == null);
+ test(m.higherKey(0) == null);
+ test(m.lowerKey(0) == null);
+ }
+
static public void
main(String[] args)
{
int status;
Ice.Communicator communicator = null;
String envName = "db";
-
+
try
{
Ice.StringSeqHolder holder = new Ice.StringSeqHolder();
@@ -866,7 +2116,7 @@ public class Client
envName += "/";
envName += "db";
}
-
+
status = run(args, communicator, envName, "binary");
}
catch(Exception ex)
diff --git a/java/test/Freeze/evictor/AccountI.java b/java/test/Freeze/evictor/AccountI.java
index b2d7823555a..66493858476 100644
--- a/java/test/Freeze/evictor/AccountI.java
+++ b/java/test/Freeze/evictor/AccountI.java
@@ -19,7 +19,8 @@ public class AccountI extends Account
}
public void
- deposit(int amount, Ice.Current current) throws InsufficientFundsException
+ deposit(int amount, Ice.Current current)
+ throws InsufficientFundsException
{
//
// No need to synchronize since everything occurs within its own transaction
@@ -72,19 +73,22 @@ public class AccountI extends Account
class ResponseThread extends Thread
{
- synchronized void response()
+ synchronized void
+ response()
{
_response = true;
notify();
}
- synchronized void exception(Ice.UserException e)
+ synchronized void
+ exception(Ice.UserException e)
{
_exception = e;
notify();
}
- public synchronized void run()
+ public synchronized void
+ run()
{
if(_response == false && _exception == null)
{
@@ -131,7 +135,7 @@ public class AccountI extends Account
ResponseThread thread = new ResponseThread();
thread.setDaemon(true);
-
+
test(_evictor.getCurrentTransaction() != null);
try
@@ -159,17 +163,20 @@ public class AccountI extends Account
thread.response();
}
- public AccountI(int initialBalance, Freeze.TransactionalEvictor evictor)
+ public
+ AccountI(int initialBalance, Freeze.TransactionalEvictor evictor)
{
super(initialBalance);
_evictor = evictor;
}
- public AccountI()
+ public
+ AccountI()
{
}
- public void init(Freeze.TransactionalEvictor evictor)
+ public void
+ init(Freeze.TransactionalEvictor evictor)
{
assert _evictor == null;
_evictor = evictor;
diff --git a/java/test/Freeze/evictor/Client.java b/java/test/Freeze/evictor/Client.java
index 84af28ce6c4..1616bd706fa 100644
--- a/java/test/Freeze/evictor/Client.java
+++ b/java/test/Freeze/evictor/Client.java
@@ -39,10 +39,11 @@ public class Client extends test.Util.Application
{
ReadThread(ServantPrx[] servants)
{
- _servants = servants;
- }
+ _servants = servants;
+ }
- public void run()
+ public void
+ run()
{
int loops = 10;
while(loops-- > 0)
@@ -60,14 +61,14 @@ public class Client extends test.Util.Application
{
test(false);
}
-
+
for(int i = 1; i < _servants.length; ++i)
{
test(_servants[i].getValue() == i);
}
}
}
-
+
private ServantPrx[] _servants;
}
@@ -81,7 +82,7 @@ public class Client extends test.Util.Application
{
_servants = servants;
}
-
+
public void
run()
{
@@ -131,13 +132,13 @@ public class Client extends test.Util.Application
{
return _state;
}
-
+
synchronized boolean
validEx()
{
return _state == StateDeactivating || _state == StateDeactivated;
}
-
+
synchronized void
setEvictorState(int s)
{
@@ -148,9 +149,8 @@ public class Client extends test.Util.Application
private int _state = StateRunning;
}
-
static class AddForeverThread extends Thread
- {
+ {
AddForeverThread(RemoteEvictorPrx evictor, int prefix)
{
_evictor = evictor;
@@ -161,7 +161,7 @@ public class Client extends test.Util.Application
run()
{
int index = 0;
-
+
for(;;)
{
try
@@ -221,13 +221,13 @@ public class Client extends test.Util.Application
{
return _state;
}
-
+
synchronized boolean
validEx()
{
return _state == StateDeactivating || _state == StateDeactivated;
}
-
+
synchronized void
setEvictorState(int s)
{
@@ -239,16 +239,15 @@ public class Client extends test.Util.Application
private int _state = StateRunning;
}
-
static class CreateDestroyThread extends Thread
{
- CreateDestroyThread(RemoteEvictorPrx evictor, int id, int size)
+ CreateDestroyThread(RemoteEvictorPrx evictor, int id, int size)
{
_evictor = evictor;
_id = "" + id;
_size = size;
}
-
+
public void
run()
{
@@ -265,12 +264,12 @@ public class Client extends test.Util.Application
//
// Create when odd, destroy when even.
//
-
+
if(loops % 2 == 0)
{
ServantPrx servant = _evictor.getServant(id);
servant.destroy();
-
+
//
// Twice
//
@@ -287,7 +286,7 @@ public class Client extends test.Util.Application
else
{
ServantPrx servant = _evictor.createServant(id, i);
-
+
//
// Twice
//
@@ -352,17 +351,17 @@ public class Client extends test.Util.Application
for(int i = 0; i < 1000; i++)
{
//
- // Transfer 100 at random between two distinct accounts
+ // Transfer 100 at random between two distinct accounts
//
AccountPrx from = _accounts[Math.abs(_random.nextInt() % _accounts.length)];
-
+
AccountPrx to = null;
do
{
to = _accounts[Math.abs(_random.nextInt() % _accounts.length)];
}
while(from == to);
-
+
try
{
//
@@ -370,25 +369,25 @@ public class Client extends test.Util.Application
//
switch(transferOp)
{
- case 0:
- {
- from.transfer(100, to);
- break;
- }
- case 1:
- {
- from.transfer2(100, to);
- break;
- }
- case 2:
- {
- from.transfer3(100, to);
- break;
- }
- default:
- {
- test(false);
- }
+ case 0:
+ {
+ from.transfer(100, to);
+ break;
+ }
+ case 1:
+ {
+ from.transfer2(100, to);
+ break;
+ }
+ case 2:
+ {
+ from.transfer3(100, to);
+ break;
+ }
+ default:
+ {
+ test(false);
+ }
}
transferOp++;
transferOp = transferOp % 3;
@@ -406,7 +405,7 @@ public class Client extends test.Util.Application
//
test(false);
}
-
+
/*
if(i % 100 == 0)
{
@@ -420,7 +419,7 @@ public class Client extends test.Util.Application
private final AccountPrx[] _accounts;
private final java.util.Random _random;
}
-
+
private int
run(String[] args, PrintWriter out, boolean transactional, boolean shutdown)
throws AlreadyRegisteredException, NotRegisteredException, EvictorDeactivatedException
@@ -442,12 +441,12 @@ public class Client extends test.Util.Application
out.flush();
final int size = 5;
-
+
RemoteEvictorPrx evictor = factory.createEvictor("Test", transactional);
evictor.setSize(size);
//
- // Create some servants
+ // Create some servants
//
ServantPrx[] servants = new ServantPrx[size];
for(int i = 0; i < size; i++)
@@ -455,7 +454,7 @@ public class Client extends test.Util.Application
String id = "" + i;
servants[i] = evictor.createServant(id, i);
servants[i].ice_ping();
-
+
FacetPrx facet1 = FacetPrxHelper.uncheckedCast(servants[i], "facet1");
try
{
@@ -496,7 +495,7 @@ public class Client extends test.Util.Application
test(facet2 != null);
test(facet2.getData().equals("moreData"));
}
-
+
//
// Mutate servants.
//
@@ -510,7 +509,7 @@ public class Client extends test.Util.Application
test(facet2 != null);
facet2.setValue(100 * i + 100);
}
-
+
for(int i = 0; i < size; i++)
{
test(servants[i].getValue() == i + 100);
@@ -521,7 +520,7 @@ public class Client extends test.Util.Application
test(facet2 != null);
test(facet2.getValue() == 100 * i + 100);
}
-
+
//
// Evict and verify values.
//
@@ -540,10 +539,10 @@ public class Client extends test.Util.Application
if(!transactional)
{
- //
+ //
// Test saving while busy
//
-
+
AMI_Servant_setValueAsyncI setCB = new AMI_Servant_setValueAsyncI();
for(int i = 0; i < size; i++)
{
@@ -551,7 +550,7 @@ public class Client extends test.Util.Application
// Start a mutating operation so that the object is not idle.
//
servants[i].setValueAsync_async(setCB, i + 300);
-
+
test(servants[i].getValue() == i + 100);
//
// This operation modifies the object state but is not saved
@@ -559,7 +558,7 @@ public class Client extends test.Util.Application
//
servants[i].setValue(i + 200);
test(servants[i].getValue() == i + 200);
-
+
//
// Force the response to setValueAsync
//
@@ -570,7 +569,7 @@ public class Client extends test.Util.Application
//
// Add duplicate facet and catch corresponding exception
- //
+ //
for(int i = 0; i < size; i++)
{
try
@@ -582,10 +581,10 @@ public class Client extends test.Util.Application
{
}
}
-
+
//
// Remove a facet that does not exist
- //
+ //
try
{
servants[0].removeFacet("facet3");
@@ -606,7 +605,7 @@ public class Client extends test.Util.Application
evictor.setSize(0);
evictor.setSize(size);
-
+
//
// Destroy servants and verify ObjectNotExistException.
//
@@ -632,7 +631,6 @@ public class Client extends test.Util.Application
{
// Expected
}
-
}
//
@@ -642,7 +640,7 @@ public class Client extends test.Util.Application
//
// Recreate servants, set transient value
- //
+ //
for(int i = 0; i < size; i++)
{
String id = "" + i;
@@ -665,7 +663,6 @@ public class Client extends test.Util.Application
test(servants[i].getTransientValue() == -1);
}
-
if(!transactional)
{
//
@@ -680,7 +677,7 @@ public class Client extends test.Util.Application
evictor.saveNow();
evictor.setSize(0);
evictor.setSize(size);
-
+
//
// Check the transient value
//
@@ -688,7 +685,7 @@ public class Client extends test.Util.Application
{
test(servants[i].getTransientValue() == i);
}
-
+
//
// Again, after one release
//
@@ -703,7 +700,7 @@ public class Client extends test.Util.Application
{
test(servants[i].getTransientValue() == i);
}
-
+
//
// Again, after a second release
//
@@ -714,12 +711,12 @@ public class Client extends test.Util.Application
evictor.saveNow();
evictor.setSize(0);
evictor.setSize(size);
-
+
for(int i = 0; i < size; i++)
{
test(servants[i].getTransientValue() == -1);
}
-
+
//
// Release one more time
//
@@ -756,7 +753,7 @@ public class Client extends test.Util.Application
threads[i] = new TransferThread(accounts, i);
threads[i].start();
}
-
+
for(int i = 0; i < threadCount; i++)
{
try
@@ -768,13 +765,13 @@ public class Client extends test.Util.Application
break; // for
}
}
-
+
//
// Check that the total balance did not change!
//
test(totalBalance == servants[0].getTotalBalance());
}
-
+
//
// Deactivate and recreate evictor, to ensure that servants
// are restored properly after database close and reopen.
@@ -788,7 +785,6 @@ public class Client extends test.Util.Application
servants[i] = evictor.getServant(id);
test(servants[i].getValue() == i);
}
-
//
// Test concurrent lookups with a smaller evictor
@@ -796,17 +792,17 @@ public class Client extends test.Util.Application
//
evictor.setSize(size / 2);
servants[0].destroy();
-
+
{
int threadCount = size * 2;
-
+
Thread[] threads = new Thread[threadCount];
for(int i = 0; i < threadCount; i++)
{
threads[i] = new ReadThread(servants);
threads[i].start();
}
-
+
for(int i = 0; i < threadCount; i++)
{
for(;;)
@@ -822,27 +818,27 @@ public class Client extends test.Util.Application
}
}
}
-
+
//
// Clean up.
//
evictor.destroyAllServants("");
evictor.destroyAllServants("facet1");
evictor.destroyAllServants("facet2");
-
+
//
// CreateDestroy threads
//
{
int threadCount = size;
-
+
Thread[] threads = new Thread[threadCount];
for(int i = 0; i < threadCount; i++)
{
threads[i] = new CreateDestroyThread(evictor, i, size);
threads[i].start();
}
-
+
for(int i = 0; i < threadCount; i++)
{
for(;;)
@@ -857,11 +853,11 @@ public class Client extends test.Util.Application
}
}
}
-
+
//
// Verify all destroyed
- //
- for(int i = 0; i < size; i++)
+ //
+ for(int i = 0; i < size; i++)
{
try
{
@@ -874,31 +870,31 @@ public class Client extends test.Util.Application
}
}
}
-
+
//
// Recreate servants.
- //
+ //
servants = new ServantPrx[size];
for(int i = 0; i < size; i++)
{
String id = "" + i;
servants[i] = evictor.createServant(id, i);
}
-
+
//
// Deactivate in the middle of remote AMD operations
// (really testing Ice here)
//
{
int threadCount = size;
-
+
Thread[] threads = new Thread[threadCount];
for(int i = 0; i < threadCount; i++)
{
threads[i] = new ReadForeverThread(servants);
threads[i].start();
}
-
+
try
{
Thread.currentThread().sleep(500);
@@ -918,7 +914,7 @@ public class Client extends test.Util.Application
ReadForeverThread t = (ReadForeverThread)threads[i];
t.setEvictorState(StateDeactivated);
}
-
+
for(int i = 0; i < threadCount; i++)
{
for(;;)
@@ -934,26 +930,26 @@ public class Client extends test.Util.Application
}
}
}
-
+
//
// Resurrect
//
evictor = factory.createEvictor("Test", transactional);
evictor.destroyAllServants("");
-
+
//
// Deactivate in the middle of adds
//
{
int threadCount = size;
-
+
Thread[] threads = new Thread[threadCount];
for(int i = 0; i < threadCount; i++)
{
threads[i] = new AddForeverThread(evictor, i);
threads[i].start();
}
-
+
try
{
Thread.currentThread().sleep(500);
@@ -989,8 +985,7 @@ public class Client extends test.Util.Application
}
}
}
-
-
+
//
// Clean up.
//
@@ -999,7 +994,7 @@ public class Client extends test.Util.Application
evictor.deactivate();
out.println("ok");
-
+
if(shutdown)
{
factory.shutdown();
@@ -1039,7 +1034,8 @@ public class Client extends test.Util.Application
return status;
}
- protected Ice.InitializationData getInitData(Ice.StringSeqHolder argsH)
+ protected Ice.InitializationData
+ getInitData(Ice.StringSeqHolder argsH)
{
Ice.InitializationData initData = new Ice.InitializationData();
initData.properties = Ice.Util.createProperties(argsH);
@@ -1047,7 +1043,8 @@ public class Client extends test.Util.Application
return initData;
}
- public static void main(String[] args)
+ public static void
+ main(String[] args)
{
Client c = new Client();
int status = c.main("Client", args);
diff --git a/java/test/Freeze/evictor/FacetI.java b/java/test/Freeze/evictor/FacetI.java
index 0f7cb7a245a..14fa8723ae1 100644
--- a/java/test/Freeze/evictor/FacetI.java
+++ b/java/test/Freeze/evictor/FacetI.java
@@ -22,7 +22,7 @@ public class FacetI extends ServantI implements _FacetOperations
super(tie, remoteEvictor, evictor, value);
((Facet)_tie).data = data;
}
-
+
public String
getData(Ice.Current current)
{
diff --git a/java/test/Freeze/evictor/RemoteEvictorFactoryI.java b/java/test/Freeze/evictor/RemoteEvictorFactoryI.java
index 7691acdcdfb..a32c099d0ec 100644
--- a/java/test/Freeze/evictor/RemoteEvictorFactoryI.java
+++ b/java/test/Freeze/evictor/RemoteEvictorFactoryI.java
@@ -17,11 +17,10 @@ public final class RemoteEvictorFactoryI extends _RemoteEvictorFactoryDisp
_envName = envName;
}
-
public RemoteEvictorPrx
createEvictor(String name, boolean transactional, Ice.Current current)
{
- RemoteEvictorI remoteEvictor =
+ RemoteEvictorI remoteEvictor =
new RemoteEvictorI(current.adapter.getCommunicator(), _envName, name, transactional);
return RemoteEvictorPrxHelper.
uncheckedCast(current.adapter.add(remoteEvictor, current.adapter.getCommunicator().stringToIdentity(name)));
diff --git a/java/test/Freeze/evictor/RemoteEvictorI.java b/java/test/Freeze/evictor/RemoteEvictorI.java
index 4e026509ff1..d42ae449fd0 100644
--- a/java/test/Freeze/evictor/RemoteEvictorI.java
+++ b/java/test/Freeze/evictor/RemoteEvictorI.java
@@ -44,7 +44,6 @@ public final class RemoteEvictorI extends _RemoteEvictorDisp
private Freeze.Evictor _evictor;
}
-
RemoteEvictorI(Ice.Communicator communicator, String envName, String category, boolean transactional)
{
_envName = envName;
@@ -71,7 +70,7 @@ public final class RemoteEvictorI extends _RemoteEvictorDisp
}
initializer.init(this, _evictor);
-
+
_evictorAdapter.addServantLocator(_evictor, category);
_evictorAdapter.activate();
}
@@ -141,12 +140,12 @@ public final class RemoteEvictorI extends _RemoteEvictorDisp
_evictorAdapter.destroy();
current.adapter.remove(current.adapter.getCommunicator().stringToIdentity(_category));
}
-
+
public void
destroyAllServants(String facet, Ice.Current current)
{
//
- // Only for test purpose: don't use such a small value in
+ // Only for test purpose: don't use such a small value in
// a real application!
//
int batchSize = 2;
@@ -158,11 +157,11 @@ public final class RemoteEvictorI extends _RemoteEvictorDisp
}
}
- final public String
+ final public String
envName()
{
return _envName;
- }
+ }
private final String _envName;
private String _category;
diff --git a/java/test/Freeze/evictor/ServantI.java b/java/test/Freeze/evictor/ServantI.java
index faab9eb13f9..d8f6b3c0a67 100644
--- a/java/test/Freeze/evictor/ServantI.java
+++ b/java/test/Freeze/evictor/ServantI.java
@@ -21,7 +21,6 @@ public class ServantI implements _ServantOperations
}
}
-
static class DelayedResponse extends Thread
{
DelayedResponse(AMD_Servant_slowGetValue cb, int val)
@@ -48,7 +47,6 @@ public class ServantI implements _ServantOperations
private int _val;
}
-
ServantI(Servant tie)
{
_tie = tie;
diff --git a/java/test/Freeze/evictor/Server.java b/java/test/Freeze/evictor/Server.java
index c67f17354f8..e8123b0877c 100644
--- a/java/test/Freeze/evictor/Server.java
+++ b/java/test/Freeze/evictor/Server.java
@@ -11,7 +11,7 @@ package test.Freeze.evictor;
import test.Freeze.evictor.Test.*;
public class Server extends test.Util.Application
-{
+{
static class AccountFactory implements Ice.ObjectFactory
{
public Ice.Object
@@ -74,7 +74,7 @@ public class Server extends test.Util.Application
RemoteEvictorFactoryI factory = new RemoteEvictorFactoryI("db");
adapter.add(factory, communicator.stringToIdentity("factory"));
-
+
adapter.activate();
communicator.waitForShutdown();
@@ -82,7 +82,8 @@ public class Server extends test.Util.Application
return 0;
}
- protected Ice.InitializationData getInitData(Ice.StringSeqHolder argsH)
+ protected Ice.InitializationData
+ getInitData(Ice.StringSeqHolder argsH)
{
Ice.InitializationData initData = new Ice.InitializationData();
initData.properties = Ice.Util.createProperties(argsH);
@@ -91,7 +92,8 @@ public class Server extends test.Util.Application
return initData;
}
- public static void main(String[] args)
+ public static void
+ main(String[] args)
{
Server c = new Server();
int status = c.main("Server", args);