forked from maxifier/mxcache
/
AbstractBooleanByteCache.java
133 lines (126 loc) · 5.19 KB
/
AbstractBooleanByteCache.java
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
/*
* Copyright (c) 2008-2014 Maxifier Ltd. All Rights Reserved.
*/
package com.maxifier.mxcache.impl.caches.abs;
import com.maxifier.mxcache.CacheFactory;
import com.maxifier.mxcache.caches.*;
import com.maxifier.mxcache.exceptions.*;
import com.maxifier.mxcache.impl.MutableStatistics;
import com.maxifier.mxcache.impl.CacheId;
import com.maxifier.mxcache.impl.CalculatableHelper;
import com.maxifier.mxcache.impl.resource.*;
import com.maxifier.mxcache.provider.CacheDescriptor;
import com.maxifier.mxcache.storage.*;
/**
* THIS IS GENERATED CLASS! DON'T EDIT IT MANUALLY!
*
* GENERATED FROM P2PCache.template
*
* @author Andrey Yakoushin (andrey.yakoushin@maxifier.com)
* @author Alexander Kochurov (alexander.kochurov@maxifier.com)
*/
public abstract class AbstractBooleanByteCache extends AbstractCache implements BooleanByteCache, BooleanObjectStorage {
private final BooleanByteCalculatable calculatable;
public AbstractBooleanByteCache(Object owner, BooleanByteCalculatable calculatable, MutableStatistics statistics) {
super(owner, statistics);
this.calculatable = calculatable;
}
@Override
@SuppressWarnings({ "unchecked" })
public byte getOrCreate(boolean o) {
if (DependencyTracker.isBypassCaches()) {
return calculatable.calculate(owner, o);
} else {
preCheckDirty();
lock();
try {
Object v = load(o);
if (v != UNDEFINED) {
DependencyTracker.mark(getDependencyNode());
hit();
ExceptionHelper.throwIfExceptionRecordNotExpired(v);
return (Byte)v;
}
DependencyNode callerNode = DependencyTracker.track(getDependencyNode());
try {
while(true) {
try {
return create(o);
} catch (ResourceOccupied e) {
if (callerNode != null) {
throw e;
} else {
unlock();
try {
e.getResource().waitForEndOfModification();
} finally {
lock();
}
v = load(o);
if (v != UNDEFINED) {
hit();
ExceptionHelper.throwIfExceptionRecordNotExpired(v);
return (Byte)v;
}
}
}
}
} finally {
DependencyTracker.exit(callerNode);
}
} finally {
unlock();
postCheckDirty();
}
}
}
@SuppressWarnings({ "unchecked" })
protected byte create(boolean o) {
long start = System.nanoTime();
try {
int retry = 0;
// retry on exception loop
while (true) {
try {
byte t = calculatable.calculate(owner, o);
// successful invocation => just store the value and return
save(o, t);
return t;
} catch (Exception e) {
// We catch Exception here, but not Error and not Throwable.
// this is because in case of Error we are likely have no chance even to save
// an ExceptionRecord to a storage, so don't even try to do so.
// For example in case of OOM (out of memory) it may be impossible to create
// even a single new object.
CacheExceptionHandler exceptionHandler = getDescriptor().getExceptionHandler();
switch (exceptionHandler.getAction(retry, e)) {
case RETRY:
retry++;
continue;
case REMEMBER_AND_RETHROW:
save(o, new ExceptionRecord(e, exceptionHandler.getRememberExceptionExpirationTimestamp(e)));
// fall through
case RETHROW:
default:
// this method always throws an exception
ExceptionHelper.throwCheckedExceptionHack(e);
break;
}
}
}
} finally {
// record calculation time even if calculation fails
long end = System.nanoTime();
miss(end - start);
}
}
@Override
public CacheDescriptor getDescriptor() {
CacheId id = CalculatableHelper.getId(calculatable.getClass());
return CacheFactory.getProvider().getDescriptor(id);
}
@Override
public String toString() {
return getDescriptor() + ": " + owner;
}
}