FacetCache.java
4.54 KB
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
125
126
127
128
129
130
131
132
133
134
/*
* Decompiled with CFR 0_118.
*
* Could not load the following classes:
* org.apache.commons.collections.map.AbstractLinkedMap
* org.apache.commons.collections.map.AbstractLinkedMap$LinkEntry
* org.apache.commons.collections.map.LRUMap
* org.slf4j.Logger
* org.slf4j.LoggerFactory
*/
package com.day.cq.search.impl.builder;
import com.day.cq.search.PredicateGroup;
import com.day.cq.search.facets.Facet;
import java.util.Map;
import org.apache.commons.collections.map.AbstractLinkedMap;
import org.apache.commons.collections.map.LRUMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class FacetCache {
private final Logger log;
private final Map<PredicateGroup, Entry> map;
private final int maxEntries;
private final long entryLifetimeMsec;
private int accesses;
private int misses;
public FacetCache(int maxEntries, long entryLifetimeMsec) {
this.log = LoggerFactory.getLogger(this.getClass());
this.map = new CustomLRUMap();
this.accesses = 0;
this.misses = 0;
this.maxEntries = Math.max(maxEntries, 0);
this.entryLifetimeMsec = entryLifetimeMsec;
this.log.info("{}", (Object)this.toString());
}
public String toString() {
return this.getClass().getSimpleName() + ", max entries=" + this.maxEntries + ", entry lifetime (msec)=" + this.entryLifetimeMsec + (this.maxEntries <= 0 ? ", OFF" : ", ON");
}
public synchronized void clear() {
this.log.info("clearing facet cache");
this.map.clear();
}
public synchronized Map<String, Facet> get(PredicateGroup key) {
boolean doInfoStats;
Map<String, Facet> result;
if (this.maxEntries == 0) {
this.log.trace("max entries is set to zero, caching disabled");
return null;
}
if ((long)this.accesses == Long.MAX_VALUE) {
this.accesses = 0;
this.misses = 0;
}
++this.accesses;
Entry e = this.map.get(key);
if (e == null) {
++this.misses;
result = null;
} else if (e.expired()) {
this.log.debug("expired facets entry, removing from cache:\n{}", (Object)key);
this.map.remove(key);
++this.misses;
result = null;
} else {
result = e.data;
}
boolean bl = doInfoStats = this.accesses % 10 == 0;
if (this.log.isInfoEnabled() && doInfoStats || this.log.isDebugEnabled()) {
long ratio = 100;
if (this.misses >= 0) {
ratio -= (long)this.misses * 100 / (long)this.accesses;
}
StringBuilder statistics = new StringBuilder();
statistics.append("size=").append(this.map.size());
statistics.append(", #accesses=").append(this.accesses);
statistics.append(", #hits=").append(this.accesses - this.misses);
statistics.append(", #misses=").append(this.misses);
statistics.append(", cacheRatio=").append(ratio).append("%");
if (doInfoStats) {
this.log.info(statistics.toString());
} else {
this.log.debug(statistics.toString());
}
}
return result;
}
public synchronized void put(PredicateGroup key, Map<String, Facet> value) {
if (this.maxEntries == 0) {
this.log.trace("max entries is set to zero, caching disabled");
return;
}
this.log.trace("caching facets:\n{}", (Object)key);
this.map.put(key, new Entry(value));
}
private class CustomLRUMap
extends LRUMap {
private static final long serialVersionUID = 1;
private CustomLRUMap() {
}
public boolean isFull() {
return this.size() >= FacetCache.this.maxEntries;
}
protected boolean removeLRU(AbstractLinkedMap.LinkEntry entry) {
FacetCache.this.log.debug("cache hit size limit at {} entries, removing least recently used one:\n{}", (Object)this.size(), entry.getKey());
return super.removeLRU(entry);
}
}
private class Entry {
final Map<String, Facet> data;
final long expirationTime;
Entry(Map<String, Facet> data) {
this.data = data;
this.expirationTime = FacetCache.this.entryLifetimeMsec > 0 ? System.currentTimeMillis() + FacetCache.this.entryLifetimeMsec : -1;
}
boolean expired() {
return this.expirationTime >= 0 && System.currentTimeMillis() > this.expirationTime;
}
}
}