summaryrefslogtreecommitdiff
path: root/java/src
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/src
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/src')
-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
30 files changed, 5816 insertions, 4099 deletions
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