summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2003-06-30 05:03:49 +0000
committerMichi Henning <michi@zeroc.com>2003-06-30 05:03:49 +0000
commitb4dca8c1afc8c55b1790ea0ff6fd632e19cbaa57 (patch)
tree521242de3a418a1813070ccbb0d737b372e9a167 /java/src
parentfile EvictorBase.java was initially added on branch Evictor. (diff)
downloadice-b4dca8c1afc8c55b1790ea0ff6fd632e19cbaa57.tar.bz2
ice-b4dca8c1afc8c55b1790ea0ff6fd632e19cbaa57.tar.xz
ice-b4dca8c1afc8c55b1790ea0ff6fd632e19cbaa57.zip
merging changes from Evictor branch
Diffstat (limited to 'java/src')
-rw-r--r--java/src/Freeze/EvictorI.java15
-rw-r--r--java/src/Ice/EvictorBase.java277
-rw-r--r--java/src/Ice/PropertiesI.java2
-rw-r--r--java/src/IceInternal/LinkedList.java (renamed from java/src/Freeze/LinkedList.java)18
4 files changed, 296 insertions, 16 deletions
diff --git a/java/src/Freeze/EvictorI.java b/java/src/Freeze/EvictorI.java
index d72af248452..bf11dff02e4 100644
--- a/java/src/Freeze/EvictorI.java
+++ b/java/src/Freeze/EvictorI.java
@@ -106,7 +106,8 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore
if(_trace >= 1)
{
- _db.getCommunicator().getLogger().trace("Evictor", "created \"" + Ice.Util.identityToString(ident) + "\"");
+ _db.getCommunicator().getLogger().trace("Freeze::Evictor",
+ "created \"" + Ice.Util.identityToString(ident) + "\"");
}
//
@@ -155,7 +156,7 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore
if(_trace >= 1)
{
- _db.getCommunicator().getLogger().trace("Evictor", "destroyed \"" +
+ _db.getCommunicator().getLogger().trace("Freeze::Evictor", "destroyed \"" +
Ice.Util.identityToString(ident) + "\"");
}
}
@@ -224,7 +225,7 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore
{
if(_trace >= 2)
{
- _db.getCommunicator().getLogger().trace("Evictor",
+ _db.getCommunicator().getLogger().trace("Freeze::Evictor",
"found \"" + Ice.Util.identityToString(ident) +
"\" in the queue");
}
@@ -247,7 +248,7 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore
if(_trace >= 2)
{
_db.getCommunicator().getLogger().trace(
- "Evictor",
+ "Freeze::Evictor",
"couldn't find \"" + Ice.Util.identityToString(ident) + "\" in the queue\n"
+ "loading \"" + Ice.Util.identityToString(ident) + "\" from the database");
}
@@ -347,7 +348,7 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore
if(_trace >= 1)
{
- _db.getCommunicator().getLogger().trace("Evictor",
+ _db.getCommunicator().getLogger().trace("Freeze::Evictor",
"deactivating, saving unsaved Ice objects to the database");
}
@@ -445,7 +446,7 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore
if(_trace >= 2)
{
_db.getCommunicator().getLogger().trace(
- "Evictor",
+ "Freeze::Evictor",
"evicted \"" + Ice.Util.identityToString(ident) +
"\" from the queue\n" + "number of elements in the queue: " +
_evictorMap.size());
@@ -529,7 +530,7 @@ class EvictorI extends Ice.LocalObjectImpl implements Evictor, ObjectStore
//
// This is a list of Ice.Identity.
//
- private LinkedList _evictorList = new LinkedList();
+ private IceInternal.LinkedList _evictorList = new IceInternal.LinkedList();
private int _evictorSize = 10;
private boolean _deactivated = false;
diff --git a/java/src/Ice/EvictorBase.java b/java/src/Ice/EvictorBase.java
new file mode 100644
index 00000000000..9a7f50317c0
--- /dev/null
+++ b/java/src/Ice/EvictorBase.java
@@ -0,0 +1,277 @@
+// **********************************************************************
+//
+// Copyright (c) 2003
+// ZeroC, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved.
+//
+// Ice is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation.
+//
+// **********************************************************************
+
+package Ice;
+
+public abstract class EvictorBase extends LocalObjectImpl implements Ice.Evictor
+{
+
+ public
+ EvictorBase()
+ {
+ _size = 0;
+ _initialized = false;
+ _hits = 0;
+ _misses = 0;
+ _evictions = 0;
+ _traceLevel = 0;
+ }
+
+ synchronized public final void
+ setSize(int size)
+ {
+ if(size < 1)
+ {
+ return; // Ignore stupid values.
+ }
+
+ _size = size;
+ evictServants();
+ }
+
+ synchronized public final int
+ getSize()
+ {
+ return _size;
+ }
+
+ public abstract Ice.Object instantiate(Current curr, Ice.LocalObjectHolder cookie);
+
+ public abstract void evict(Identity id, Ice.Object servant, Ice.LocalObject cookie);
+
+ synchronized public final Ice.Object
+ locate(Ice.Current c, Ice.LocalObjectHolder cookie)
+ {
+ if(!_initialized) // Lazy initialization of evictor size and tracing.
+ {
+ _initialized = true;
+ initialize(c);
+ }
+
+ //
+ // Make a copy of the ID. We need to do this because
+ // Ice.Current.id is the same reference on every call:
+ // it's contents change, but it is the same object every time.
+ // We need a separate object to insert into the queue and the map.
+ //
+ Ice.Identity idCopy = new Ice.Identity();
+ idCopy.name = c.id.name;
+ idCopy.category = c.id.category;
+
+ //
+ // Check if we have an entry for the servant already.
+ //
+ EvictorCookie ec = new EvictorCookie();
+ cookie.value = ec;
+ ec.entry = (EvictorEntry)_map.get(idCopy);
+ boolean newEntry = ec.entry == null;
+ if(!newEntry)
+ {
+ //
+ // Got an entry already, dequeue the entry from its current position.
+ //
+ ec.entry.pos.remove();
+
+ ++_hits; // Update statistics.
+ if(_traceLevel >= 3)
+ {
+ String msg = c.id.category.length() == 0 ? "default category" : ("category `" + c.id.category + "'");
+ msg += ": cache hit for name `" + c.id.name + "'";
+ _communicator.getLogger().trace("Ice::Evictor", msg);
+ }
+ }
+ else
+ {
+ //
+ // Don't have an entry yet. Ask the application to instantiate a servant
+ // and create a new entry in the map.
+ //
+ ec.entry = new EvictorEntry();
+ Ice.LocalObjectHolder cookieHolder = new Ice.LocalObjectHolder();
+ ec.entry.servant = instantiate(c, cookieHolder); // Down-call to application-supplied method
+ if(ec.entry.servant == null)
+ {
+ throw new Ice.ObjectNotExistException();
+ }
+ ec.entry.userCookie = cookieHolder.value;
+ ec.entry.useCount = 0;
+ _map.put(idCopy, ec.entry);
+
+ ++_misses; // Update statistics.
+ if(_traceLevel >= 2)
+ {
+ String msg = c.id.category.length() == 0 ? "default category" : ("category `" + c.id.category + "'");
+ msg += ": cache miss for name `" + c.id.name + "'";
+ _communicator.getLogger().trace("Ice::Evictor", msg);
+ }
+ }
+
+ //
+ // Increment the use count of the servant and enqueue the entry at the front,
+ // so we get LRU order.
+ //
+ ++(ec.entry.useCount);
+ _queue.addFirst(idCopy);
+ ec.entry.pos = _queue.iterator();
+ ec.entry.pos.next(); // Position the iterator on the element.
+
+ //
+ // If we added an entry, that might make another entry eligible for eviction.
+ //
+ if(newEntry)
+ {
+ evictServants();
+ }
+
+ return ec.entry.servant;
+ }
+
+ synchronized public final void
+ finished(Ice.Current c, Ice.Object o, Ice.LocalObject cookie)
+ {
+ EvictorCookie ec = (EvictorCookie)cookie;
+
+ //
+ // Decrement use count and check if there is something to evict.
+ //
+ --(ec.entry.useCount);
+ evictServants();
+ }
+
+ synchronized public final void
+ deactivate(String category)
+ {
+ if(_traceLevel >= 1)
+ {
+ String msg = "deactivating ";
+ msg += category.length() == 0 ? "default category" : ("category `" + category + "'");
+ msg += ", number of cached servants = " + _map.size();
+ _communicator.getLogger().trace("Ice::Evictor", msg);
+
+ msg = "#evictions = " + _evictions;
+ msg += ", #hits = " + _hits;
+ msg += ", #misses = " + _misses;
+ double total = (double)_hits + (double)_misses;
+ double ratio = total == 0 ? 100 : ((double)_hits * 100 / total);
+ java.text.DecimalFormat f = new java.text.DecimalFormat("###.00");
+ msg += ", %hits = " + f.format(ratio) + "%";
+ _communicator.getLogger().trace("Ice::Evictor", msg);
+ }
+ _size = 0;
+ evictServants();
+ }
+
+ synchronized private void
+ evictServants()
+ {
+ //
+ // If the evictor queue has grown larger than the limit,
+ // look at the excess elements to see whether any of them
+ // can be evicted.
+ //
+ for(int i = _map.size() - _size; i > 0; --i)
+ {
+ java.util.Iterator p = _queue.riterator();
+ Ice.Identity id = (Ice.Identity)p.next();
+ EvictorEntry e = (EvictorEntry)_map.get(id);
+ assert(e != null);
+ if(e.useCount == 0)
+ {
+ if(_traceLevel >= 2)
+ {
+ String msg = id.category.length() == 0 ? "default category" : ("category `" + id.category + "'");
+ msg += ": evicting `" + id.name + "'";
+ _communicator.getLogger().trace("Ice::Evictor", msg);
+ }
+
+ evict(id, e.servant, e.userCookie); // Down-call to application-supplied method.
+ p.remove();
+ _map.remove(id);
+ ++_evictions; // Update statistics.
+ }
+ }
+ }
+
+ private void
+ initialize(Ice.Current c)
+ {
+ _communicator = c.adapter.getCommunicator();
+
+ Ice.Properties p = _communicator.getProperties();
+ int num;
+
+ //
+ // Check evictor size properties.
+ //
+ if((num = p.getPropertyAsInt("Ice.Evictor.Size")) > 0)
+ {
+ _size = num;
+ }
+ if((num = p.getPropertyAsInt(c.adapter.getName() + ".Evictor.Size")) > 0)
+ {
+ _size = num;
+ }
+ if(c.id.category.length() != 0
+ && (num = p.getPropertyAsInt(c.adapter.getName() + "." + c.id.category + ".Evictor.Size")) > 0)
+ {
+ _size = num;
+ }
+ if(_size < 1)
+ {
+ _size = defaultSize;
+ }
+
+ //
+ // Check evictor trace properties.
+ //
+ if(p.getProperty("Ice.Evictor.Trace").length() != 0)
+ {
+ _traceLevel = p.getPropertyAsInt("Ice.Evictor.Trace");
+ }
+ if(p.getProperty(c.adapter.getName() + ".Evictor.Trace").length() != 0)
+ {
+ _traceLevel = p.getPropertyAsInt(c.adapter.getName() + ".Evictor.Trace");
+ }
+ if(c.id.category.length() != 0
+ && p.getProperty(c.adapter.getName() + "." + c.id.category + ".Evictor.Trace").length() != 0)
+ {
+ _traceLevel = p.getPropertyAsInt(c.adapter.getName() + "." + c.id.category + ".Evictor.Trace");
+ }
+ }
+
+ private final static int defaultSize = 1000;
+
+ private class EvictorEntry
+ {
+ int useCount;
+ java.util.Iterator pos;
+ Ice.Object servant;
+ Ice.LocalObject userCookie;
+ }
+
+ private class EvictorCookie extends Ice.LocalObjectImpl
+ {
+ public EvictorEntry entry;
+ }
+
+ private IceInternal.LinkedList _queue = new IceInternal.LinkedList();
+ private java.util.Map _map = new java.util.HashMap();
+ private int _size;
+ private boolean _initialized;
+ private int _hits;
+ private int _misses;
+ private int _evictions;
+ private int _traceLevel;
+ private Ice.Communicator _communicator;
+}
diff --git a/java/src/Ice/PropertiesI.java b/java/src/Ice/PropertiesI.java
index 2702f7835f4..98a82efc469 100644
--- a/java/src/Ice/PropertiesI.java
+++ b/java/src/Ice/PropertiesI.java
@@ -378,6 +378,8 @@ final class PropertiesI extends LocalObjectImpl implements Properties
"Default.Locator",
"Default.Protocol",
"Default.Router",
+ "Evictor.Size",
+ "Evictor.Trace",
"Logger.Timestamp",
"MonitorConnections",
"Nohup",
diff --git a/java/src/Freeze/LinkedList.java b/java/src/IceInternal/LinkedList.java
index cca341a6f24..7091238d7c5 100644
--- a/java/src/Freeze/LinkedList.java
+++ b/java/src/IceInternal/LinkedList.java
@@ -12,7 +12,7 @@
//
// **********************************************************************
-package Freeze;
+package IceInternal;
//
// Stripped down LinkedList implementation for use in the Evictor. The
@@ -25,7 +25,7 @@ package Freeze;
// retained over structural changes to the list itself (similar to an
// STL list).
//
-class LinkedList
+public class LinkedList
{
public
LinkedList()
@@ -33,7 +33,7 @@ class LinkedList
_header.next = _header.previous = _header;
}
- public Object
+ public java.lang.Object
getFirst()
{
if(_size == 0)
@@ -45,7 +45,7 @@ class LinkedList
}
public void
- addFirst(Object o)
+ addFirst(java.lang.Object o)
{
addBefore(o, _header.next);
}
@@ -82,7 +82,7 @@ class LinkedList
return _next != null;
}
- public Object
+ public java.lang.Object
next()
{
if(_next == null)
@@ -139,7 +139,7 @@ class LinkedList
return _next != null;
}
- public Object
+ public java.lang.Object
next()
{
if(_next == null)
@@ -190,11 +190,11 @@ class LinkedList
private static class Entry
{
- Object element;
+ java.lang.Object element;
Entry next;
Entry previous;
- Entry(Object element, Entry next, Entry previous)
+ Entry(java.lang.Object element, Entry next, Entry previous)
{
this.element = element;
this.next = next;
@@ -203,7 +203,7 @@ class LinkedList
}
private Entry
- addBefore(Object o, Entry e)
+ addBefore(java.lang.Object o, Entry e)
{
Entry newEntry = new Entry(o, e, e.previous);
newEntry.previous.next = newEntry;