Get serious about skin caching
This commit is contained in:
parent
c2605e72b6
commit
6a1aaaea58
2 changed files with 56 additions and 24 deletions
|
@ -15,12 +15,7 @@ import helma.util.*;
|
||||||
import FESI.Data.*;
|
import FESI.Data.*;
|
||||||
import FESI.Interpreter.*;
|
import FESI.Interpreter.*;
|
||||||
import com.sleepycat.db.DbException;
|
import com.sleepycat.db.DbException;
|
||||||
import java.util.Hashtable;
|
import java.util.*;
|
||||||
import java.util.Vector;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.Stack;
|
|
||||||
import java.util.EmptyStackException;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The central class of a HOP application. This class keeps a pool of so-called
|
* The central class of a HOP application. This class keeps a pool of so-called
|
||||||
|
@ -85,6 +80,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
|
|
||||||
private CryptFile pwfile;
|
private CryptFile pwfile;
|
||||||
|
|
||||||
|
CacheMap skincache = new CacheMap (100, 0.75f);
|
||||||
|
|
||||||
public Application () throws RemoteException {
|
public Application () throws RemoteException {
|
||||||
super ();
|
super ();
|
||||||
|
|
|
@ -3,17 +3,14 @@
|
||||||
|
|
||||||
package helma.framework.core;
|
package helma.framework.core;
|
||||||
|
|
||||||
import java.util.Vector;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
import java.io.*;
|
|
||||||
import helma.objectmodel.*;
|
import helma.objectmodel.*;
|
||||||
import helma.objectmodel.db.*;
|
import helma.objectmodel.db.*;
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
import helma.framework.extensions.*;
|
import helma.framework.extensions.*;
|
||||||
import helma.xmlrpc.fesi.*;
|
import helma.xmlrpc.fesi.*;
|
||||||
import helma.util.*;
|
import helma.util.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.*;
|
||||||
import Acme.LruHashtable;
|
import Acme.LruHashtable;
|
||||||
import FESI.Data.*;
|
import FESI.Data.*;
|
||||||
import FESI.Interpreter.*;
|
import FESI.Interpreter.*;
|
||||||
|
@ -49,6 +46,9 @@ public class RequestEvaluator implements Runnable {
|
||||||
protected ArrayPrototype reqPath;
|
protected ArrayPrototype reqPath;
|
||||||
private ESRequestData reqData;
|
private ESRequestData reqData;
|
||||||
|
|
||||||
|
// Used to cache skins within one request evaluation
|
||||||
|
HashMap skincache;
|
||||||
|
|
||||||
// vars for FESI EcmaScript support
|
// vars for FESI EcmaScript support
|
||||||
protected Evaluator evaluator;
|
protected Evaluator evaluator;
|
||||||
protected ObjectPrototype esNodePrototype;
|
protected ObjectPrototype esNodePrototype;
|
||||||
|
@ -87,8 +87,9 @@ public class RequestEvaluator implements Runnable {
|
||||||
*/
|
*/
|
||||||
public RequestEvaluator (Application app) {
|
public RequestEvaluator (Application app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.objectcache = new LruHashtable (100, .80f);
|
objectcache = new LruHashtable (100, .80f);
|
||||||
this.prototypes = new Hashtable ();
|
prototypes = new Hashtable ();
|
||||||
|
skincache = new HashMap ();
|
||||||
initEvaluator ();
|
initEvaluator ();
|
||||||
initialized = false;
|
initialized = false;
|
||||||
// startThread ();
|
// startThread ();
|
||||||
|
@ -144,6 +145,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
IPathElement root, currentElement;
|
IPathElement root, currentElement;
|
||||||
// reset skinManager
|
// reset skinManager
|
||||||
skinmanagers = null;
|
skinmanagers = null;
|
||||||
|
skincache.clear ();
|
||||||
|
|
||||||
switch (reqtype) {
|
switch (reqtype) {
|
||||||
case HTTP:
|
case HTTP:
|
||||||
|
@ -748,19 +750,30 @@ public class RequestEvaluator implements Runnable {
|
||||||
public Skin getSkin (Prototype proto, String skinname) {
|
public Skin getSkin (Prototype proto, String skinname) {
|
||||||
if (proto == null)
|
if (proto == null)
|
||||||
return null;
|
return null;
|
||||||
|
// First check if the skin has been already used within the execution of this request
|
||||||
|
CompositeKey key = new CompositeKey (proto.getName(), skinname);
|
||||||
|
Skin skin = (Skin) skincache.get (key);
|
||||||
|
if (skin != null) {
|
||||||
|
return skin;
|
||||||
|
}
|
||||||
|
// Skin skin = null;
|
||||||
if (skinmanagers == null)
|
if (skinmanagers == null)
|
||||||
getSkinManagers ();
|
getSkinManagers ();
|
||||||
do {
|
do {
|
||||||
for (int i=0; i<skinmanagers.length; i++) {
|
for (int i=0; i<skinmanagers.length; i++) {
|
||||||
Skin skin = getSkinFromNode (skinmanagers[i], proto.getName (), skinname);
|
skin = getSkinFromNode (skinmanagers[i], proto.getName (), skinname);
|
||||||
if (skin != null)
|
if (skin != null) {
|
||||||
|
skincache.put (key, skin);
|
||||||
return skin;
|
return skin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// not found in node managers for this prototype.
|
// not found in node managers for this prototype.
|
||||||
// the next step is to look if it is defined as skin file for this prototype
|
// the next step is to look if it is defined as skin file for this prototype
|
||||||
Skin skin = proto.getSkin (skinname);
|
skin = proto.getSkin (skinname);
|
||||||
if (skin != null)
|
if (skin != null) {
|
||||||
|
skincache.put (key, skin);
|
||||||
return skin;
|
return skin;
|
||||||
|
}
|
||||||
// still not found. See if there is a parent prototype which might define the skin
|
// still not found. See if there is a parent prototype which might define the skin
|
||||||
proto = proto.getPrototype ();
|
proto = proto.getPrototype ();
|
||||||
} while (proto != null);
|
} while (proto != null);
|
||||||
|
@ -777,18 +790,20 @@ public class RequestEvaluator implements Runnable {
|
||||||
n = n.getNode (skinname, false);
|
n = n.getNode (skinname, false);
|
||||||
if (n != null) {
|
if (n != null) {
|
||||||
String skin = n.getString ("skin", false);
|
String skin = n.getString ("skin", false);
|
||||||
if (skin != null)
|
if (skin != null) {
|
||||||
return new Skin (skin, app);
|
Skin s = (Skin) app.skincache.get (skin);
|
||||||
|
if (s == null) {
|
||||||
|
s = new Skin (skin, app);
|
||||||
|
app.skincache.put (skin, s);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if this is not for the global prototype, also check hopobject
|
|
||||||
|
|
||||||
// NOT! inheritance is taken care of in the above getSkin method.
|
// Inheritance is taken care of in the above getSkin method.
|
||||||
// the sequence is prototype.skin-from-db, prototype.skin-from-file, parent.from-db, parent.from-file etc.
|
// the sequence is prototype.skin-from-db, prototype.skin-from-file, parent.from-db, parent.from-file etc.
|
||||||
|
|
||||||
// if (!"global".equalsIgnoreCase (prototype) && !"hopobject".equalsIgnoreCase (prototype)) {
|
|
||||||
// return getSkinFromNode (node, "hopobject", skinname);
|
|
||||||
// }
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,6 +932,27 @@ public class RequestEvaluator implements Runnable {
|
||||||
prototypes.put (protoName, op);
|
prototypes.put (protoName, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class CompositeKey {
|
||||||
|
|
||||||
|
final String first, second;
|
||||||
|
|
||||||
|
public CompositeKey (String first, String second) {
|
||||||
|
this.first = first;
|
||||||
|
this.second = second;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals (Object other) {
|
||||||
|
try {
|
||||||
|
CompositeKey key = (CompositeKey) other;
|
||||||
|
return first.equals (key.first) && second.equals (key.second);
|
||||||
|
} catch (Exception x) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode () {
|
||||||
|
return first.hashCode () + second.hashCode ();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue