CacheContainer.java
4.99 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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package it.softecspa.fileproxy.cache;
import it.softecspa.fileproxy.DatabaseBalancer.Balancer;
import it.softecspa.fileproxy.services.ServerCacheFactory.CacheKey;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.SortedMap;
import org.apache.log4j.Logger;
public class CacheContainer {
// Singleton instance
private static CacheContainer instance;
private Logger log = Logger.getLogger(getClass());
// Mappe degli elementi
private HashMap<String, CacheElement<?,?>>[] cache = null;
private HashMap<String, List<CacheElement<?,?>>>[] cachedTables = null;
private CacheContainer() {
super();
synchronized (CacheContainer.class) {
if (instance == null) {
instance = this;
log.info(CacheContainer.class.getSimpleName()+" instance is starting!");
instance.flushAll();
}
}
}
public static CacheContainer getInstance() {
synchronized (CacheContainer.class) {
if (instance == null) new CacheContainer();
}
return instance;
}
protected synchronized void flushAll() {
flush(Balancer.MASTER);
flush(Balancer.STAGE);
}
@SuppressWarnings("unchecked")
protected synchronized void flush(Balancer balancer) {
// CACHE
if (cache==null) cache = new HashMap[2];
if (cache[balancer.index()]==null) cache[balancer.index()] = new HashMap<String, CacheElement<?,?>>();
// Elenco tabelle coinvolte per singola cache
if (cachedTables==null) cachedTables = new HashMap[2];
if (cachedTables[balancer.index()]==null) cachedTables[balancer.index()] = new HashMap<String, List<CacheElement<?,?>>>();
// ....pulizia
Collection<CacheElement<?,?>> collection = cache[balancer.index()].values();
for (Iterator<CacheElement<?,?>> i = collection.iterator(); i.hasNext(); ) {
CacheElement<?,?> element = i.next();
if (element!=null) element.flush();
}
}
public void createContainer(CacheElement<?,?> element) throws CacheException {
createContainer(element.getUniqueName(), element, true);
}
public void createContainer(CacheKey uniqueNane, CacheElement<?,?> element, boolean autoflush) throws CacheException {
if (element==null) return;
if (uniqueNane==null) throw new CacheException("CacheElement with null name");
String name = uniqueNane.toString();
if (log.isDebugEnabled()) log.debug("Create empty container with name '"+name+"'");
int index = element.getBalancer().index();
CacheElement<?, ?> found = cache[index].get(name);
if (found!=null) {
if (found.getClass()!=element.getClass()) {
throw new CacheException("CacheElement ClassCastException: element named '"+name+"' class is "+found.getClass().getSimpleName()+"!");
}
if (autoflush) {
// Se esiste già un container con quel nome lo pulisco;
cache[index].get(name).flush();
return;
} else {
throw new CacheException("CacheElement with name '"+name+"' just exist!");
}
} else {
addTables(name, element, index);
}
// Aggiungo l'elemento alla cache
cache[element.getBalancer().index()].put(name, element);
}
private void addTables(String name, CacheElement<?,?> element, int index) {
for (String table : element.getTables()) {
List<CacheElement<?,?>> lista = cachedTables[index].get(table);
if (lista==null) {
lista = new ArrayList<CacheElement<?,?>>();
cachedTables[index].put(table, lista);
}
if (!lista.contains(name)) {
lista.add(element);
}
}
}
@SuppressWarnings("unchecked")
public <K,V> CacheElement<K,V> getCacheElement(CacheKey uniqueName, Balancer balancer) throws CacheException {
int index = balancer.index();
String name = uniqueName.toString();
// Estraggo il container
CacheElement<K,V> container = null;
try {
container = (CacheElement<K,V>) cache[index].get(name);
// FIXME aggiungere log dell'errore su DB e invio email
return container;
} catch (ClassCastException e) {
throw new CacheException("ClassCastException estracting element with name '"+name+"'", e);
} catch (Exception e) {
throw new CacheException("Unhandled exception estracting element with name '"+name+"'");
}
}
/**
* Restituisce il container dati legato alla chiave
* @param uniqueName
* @param balancer
* @return
* @throws CacheException
*/
public <K,V> SortedMap<K,V> getContainer(CacheKey uniqueName, Balancer balancer) throws CacheException {
// Estraggo il container
CacheElement<K,V> cacheElement = getCacheElement(uniqueName, balancer);
// Controllo se i dati sono validi, altrimenti faccio un load
if (cacheElement.isExpired()) {
cacheElement.load();
}
return cacheElement.getContainer();
}
/**
* Restituisce la lista completa delle tabelle in cache
* @return
*/
public HashMap<String, List<CacheElement<?, ?>>>[] getCachedTables() {
return cachedTables;
}
}