diff options
author | Michi Henning <michi@zeroc.com> | 2003-06-30 05:03:49 +0000 |
---|---|---|
committer | Michi Henning <michi@zeroc.com> | 2003-06-30 05:03:49 +0000 |
commit | b4dca8c1afc8c55b1790ea0ff6fd632e19cbaa57 (patch) | |
tree | 521242de3a418a1813070ccbb0d737b372e9a167 /java/src | |
parent | file EvictorBase.java was initially added on branch Evictor. (diff) | |
download | ice-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.java | 15 | ||||
-rw-r--r-- | java/src/Ice/EvictorBase.java | 277 | ||||
-rw-r--r-- | java/src/Ice/PropertiesI.java | 2 | ||||
-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; |