1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
package Evictor;
public abstract class EvictorBase implements Ice.ServantLocator
{
public
EvictorBase()
{
_size = 1000;
}
public
EvictorBase(int size)
{
_size = size < 0 ? 1000 : size;
}
public abstract Ice.Object
add(Ice.Current c, Ice.LocalObjectHolder cookie);
public abstract void
evict(Ice.Object servant, java.lang.Object cookie);
synchronized public final Ice.Object
locate(Ice.Current c, Ice.LocalObjectHolder cookie)
{
//
// Check if we have a servant in the map already.
//
EvictorEntry entry = _map.get(c.id);
if(entry != null)
{
//
// Got an entry already, dequeue the entry from its current position.
//
entry.queuePos.remove();
}
else
{
//
// We do not have entry. Ask the derived class to
// instantiate a servant and add a new entry to the map.
//
entry = new EvictorEntry();
Ice.LocalObjectHolder cookieHolder = new Ice.LocalObjectHolder();
entry.servant = add(c, cookieHolder); // Down-call
if(entry.servant == null)
{
return null;
}
entry.userCookie = cookieHolder.value;
entry.useCount = 0;
_map.put(c.id, entry);
}
//
// Increment the use count of the servant and enqueue
// the entry at the front, so we get LRU order.
//
++(entry.useCount);
_queue.addFirst(c.id);
entry.queuePos = _queue.iterator();
entry.queuePos.next(); // Position the iterator on the element.
cookie.value = entry;
return entry.servant;
}
synchronized public final void
finished(Ice.Current c, Ice.Object o, java.lang.Object cookie)
{
EvictorEntry entry = (EvictorEntry)cookie;
//
// Decrement use count and check if
// there is something to evict.
//
--(entry.useCount);
evictServants();
}
synchronized public final void
deactivate(String category)
{
_size = 0;
evictServants();
}
private class EvictorEntry
{
Ice.Object servant;
java.lang.Object userCookie;
java.util.Iterator<Ice.Identity> queuePos;
int useCount;
}
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.
//
java.util.Iterator<Ice.Identity> p = _queue.riterator();
int excessEntries = _map.size() - _size;
for(int i = 0; i < excessEntries; ++i)
{
Ice.Identity id = p.next();
EvictorEntry e = _map.get(id);
if(e.useCount == 0)
{
evict(e.servant, e.userCookie); // Down-call
e.queuePos.remove();
_map.remove(id);
}
}
}
private java.util.Map<Ice.Identity, EvictorEntry> _map =
new java.util.HashMap<Ice.Identity, EvictorEntry>();
private Evictor.LinkedList<Ice.Identity> _queue =
new Evictor.LinkedList<Ice.Identity>();
private int _size;
}
|