8281a.diff
new/src/com/goldencode/p2j/persist/CacheManager.java 2024-02-16 06:12:40 +0000 | ||
---|---|---|
2 | 2 |
** Module : CacheManager.java |
3 | 3 |
** Abstract : Manages caches in the persistent package based on the directory configuration. |
4 | 4 |
** |
5 |
** Copyright (c) 2023, Golden Code Development Corporation. |
|
5 |
** Copyright (c) 2023-2024, Golden Code Development Corporation.
|
|
6 | 6 |
** |
7 | 7 |
** -#- -I- --Date-- -----------------------------------Description----------------------------------- |
8 | 8 |
** 001 DDF 20230613 Created initial version. |
... | ... | |
10 | 10 |
** that caches are initialized even if binding fails. |
11 | 11 |
** DDF 20230706 Added an additional createLRUCache wrapper method which will use a null |
12 | 12 |
** discriminator by default. |
13 |
** 002 DDF 20240216 Initialize DynamicQueryHelper and DynamicValidationHelper caches through |
|
14 |
** CacheManager. |
|
13 | 15 |
*/ |
14 | 16 | |
15 | 17 |
/* |
... | ... | |
119 | 121 |
String className = Utils.getDirectoryNodeString(ds, nodePath + "/class-name", null, false); |
120 | 122 |
int cacheSize = Utils.getDirectoryNodeInt(ds, nodePath + "/size", -1, false); |
121 | 123 |
String discriminator = Utils.getDirectoryNodeString(ds, |
122 |
nodePath + "/discriminator", |
|
123 |
null, |
|
124 |
false); |
|
124 |
nodePath + "/discriminator",
|
|
125 |
null,
|
|
126 |
false);
|
|
125 | 127 |
|
126 | 128 |
if (className == null) |
127 | 129 |
{ |
... | ... | |
180 | 182 |
// There are also caches that are not static and are initialized in their specific class. |
181 | 183 |
|
182 | 184 |
FQLPreprocessor.initializeCache(); |
183 |
SortCriterion.initializeCache(); |
|
185 |
SortCriterion.initializeCache(); |
|
186 |
DynamicQueryHelper.initializeCache(); |
|
187 |
DynamicValidationHelper.initializeCache(); |
|
184 | 188 |
} |
185 | 189 |
} |
186 | 190 |
|
new/src/com/goldencode/p2j/persist/DynamicQueryHelper.java 2024-02-16 07:28:36 +0000 | ||
---|---|---|
2 | 2 |
** Module : DynamicQueryHelper.java |
3 | 3 |
** Abstract : Helper class for dynamic queries. |
4 | 4 |
** |
5 |
** Copyright (c) 2013-2023, Golden Code Development Corporation.
|
|
5 |
** Copyright (c) 2013-2024, Golden Code Development Corporation.
|
|
6 | 6 |
** |
7 | 7 |
** -#- -I- --Date-- ---------------------------------------Description---------------------------------------- |
8 | 8 |
** 001 CA 20130929 Created initial version. |
... | ... | |
87 | 87 |
** 044 AL2 20230411 Ensure delayed execute is run only once. The flag is reset on query close. |
88 | 88 |
** 045 GBB 20230512 Logging methods replaced by CentralLogger/ConversionStatus. |
89 | 89 |
** 046 EVL 20231124 Avoid duplicating string related methods for performance reason. |
90 |
** 047 DDF 20240216 lvl1Cache and lvl2Cache can only be created through CacheManager now and |
|
91 |
** have been made non-final. |
|
90 | 92 |
*/ |
91 | 93 | |
92 | 94 |
/* |
... | ... | |
155 | 157 |
import com.goldencode.cache.*; |
156 | 158 |
import com.goldencode.p2j.cfg.*; |
157 | 159 |
import com.goldencode.p2j.convert.*; |
158 |
import com.goldencode.p2j.directory.*; |
|
159 | 160 |
import com.goldencode.p2j.jmx.*; |
160 | 161 |
import com.goldencode.p2j.persist.P2JQuery.QueryEventListener; |
161 | 162 |
import com.goldencode.p2j.persist.lock.LockType; |
... | ... | |
200 | 201 |
/** The name of the generated java class. */ |
201 | 202 |
private static final String DYN_GEN_QUERY_CLASS = "DynGenQuery"; |
202 | 203 |
|
203 |
/** The name of the directory key for the size of level 1 cache holding converted queries. */ |
|
204 |
private static final String LVL1_CACHE_SIZE = "dynamic-query-cache-lvl1-size"; |
|
205 |
|
|
206 |
/** The name of the directory key for the size of level 2 cache holding converted queries. */ |
|
207 |
private static final String LVL2_CACHE_SIZE = "dynamic-query-cache-lvl2-size"; |
|
208 |
|
|
209 | 204 |
/** Logger. */ |
210 | 205 |
private static final CentralLogger LOG = CentralLogger.get(DynamicQueryHelper.class.getName()); |
211 | 206 |
|
... | ... | |
221 | 216 |
} |
222 | 217 |
}; |
223 | 218 |
|
224 |
/** |
|
225 |
* 1st level cache. Holds the queries and their default parameters. Its management uses |
|
226 |
* an aging and usage algorithm to chose entries to be dropped when the maximum capacity |
|
227 |
* is reached. |
|
228 |
*/ |
|
229 |
private static final ExpiryCache<QueryCacheKey, ParametrizedJast> lvl1Cache; |
|
230 |
|
|
231 |
/** |
|
232 |
* 2nd level cache. Queries from this level of cache do not require default parameters |
|
233 |
* because they are computed before the cache key. Its management uses an aging and usage |
|
234 |
* algorithm to chose entries to be dropped when the maximum capacity is reached. |
|
235 |
*/ |
|
236 |
private static final ExpiryCache<QueryCacheKey, JavaAst> lvl2Cache; |
|
237 |
|
|
238 |
static |
|
239 |
{ |
|
240 |
Directory dir = DirectoryManager.getInstance(); |
|
241 |
lvl1Cache = new LRUCache<>("DynamicQueryHelper.1", |
|
242 |
dir.getInt(Directory.ID_RELATIVE, LVL1_CACHE_SIZE, 65536)); |
|
243 |
lvl1Cache.addCacheExpiryListener(event -> { |
|
244 |
// debug only: to see when the cache is full |
|
245 |
if (LOG.isLoggable(Level.INFO)) |
|
246 |
{ |
|
247 |
LOG.log(Level.INFO, |
|
248 |
"DynamicQueryHelper cache level #1 is full. " + |
|
249 |
"Dumped " + event.getExpiredEntries().size() + " old entries."); |
|
250 |
} |
|
251 |
}); |
|
252 |
|
|
253 |
lvl2Cache = new LRUCache<>("DynamicQueryHelper.2", |
|
254 |
dir.getInt(Directory.ID_RELATIVE, LVL2_CACHE_SIZE, 16384)); |
|
255 |
lvl2Cache.addCacheExpiryListener(event -> { |
|
256 |
// debug only: to see when the cache is full |
|
257 |
if (LOG.isLoggable(Level.INFO)) |
|
258 |
{ |
|
259 |
LOG.log(Level.INFO, |
|
260 |
"DynamicQueryHelper cache level #2 is full. " + |
|
261 |
"Dumped " + event.getExpiredEntries().size() + " old entries."); |
|
262 |
} |
|
263 |
}); |
|
264 |
} |
|
265 |
|
|
266 | 219 |
/** Instrumentation for {@link #parseFindQuery}. */ |
267 | 220 |
private static final NanoTimer PARSE_FIND = NanoTimer.getInstance(FwdJMX.TimeStat.OrmDynParseFind); |
268 | 221 |
|
... | ... | |
281 | 234 |
public static final NanoTimer PROCESS_INTERN = NanoTimer.getInstance(FwdJMX.TimeStat.OrmDynQueryProcess_Intern); |
282 | 235 |
|
283 | 236 |
/** |
237 |
* 1st level cache. Holds the queries and their default parameters. Its management uses |
|
238 |
* an aging and usage algorithm to chose entries to be dropped when the maximum capacity |
|
239 |
* is reached. |
|
240 |
*/ |
|
241 |
private static ExpiryCache<QueryCacheKey, ParametrizedJast> lvl1Cache; |
|
242 |
|
|
243 |
/** |
|
244 |
* 2nd level cache. Queries from this level of cache do not require default parameters |
|
245 |
* because they are computed before the cache key. Its management uses an aging and usage |
|
246 |
* algorithm to chose entries to be dropped when the maximum capacity is reached. |
|
247 |
*/ |
|
248 |
private static ExpiryCache<QueryCacheKey, JavaAst> lvl2Cache; |
|
249 |
|
|
250 |
/** |
|
251 |
* Initialize caches using CacheManager. The default value of the cache |
|
252 |
* is used when there is no size available from the configuration. |
|
253 |
*/ |
|
254 |
public static void initializeCache() |
|
255 |
{ |
|
256 |
lvl1Cache = CacheManager.createLRUCache(DynamicQueryHelper.class, "lvl1", 65536); |
|
257 |
lvl1Cache.addCacheExpiryListener(event -> { |
|
258 |
// debug only: to see when the cache is full |
|
259 |
if (LOG.isLoggable(Level.INFO)) |
|
260 |
{ |
|
261 |
LOG.log(Level.INFO, |
|
262 |
"DynamicQueryHelper cache level #1 is full. " + |
|
263 |
"Dumped " + event.getExpiredEntries().size() + " old entries."); |
|
264 |
} |
|
265 |
}); |
|
266 |
lvl2Cache = CacheManager.createLRUCache(DynamicQueryHelper.class, "lvl2", 16384); |
|
267 |
lvl2Cache.addCacheExpiryListener(event -> { |
|
268 |
// debug only: to see when the cache is full |
|
269 |
if (LOG.isLoggable(Level.INFO)) |
|
270 |
{ |
|
271 |
LOG.log(Level.INFO, |
|
272 |
"DynamicQueryHelper cache level #2 is full. " + |
|
273 |
"Dumped " + event.getExpiredEntries().size() + " old entries."); |
|
274 |
} |
|
275 |
}); |
|
276 |
} |
|
277 |
|
|
278 |
/** |
|
284 | 279 |
* Private worker for parsing a given query string using the QueryProcessor and return a |
285 | 280 |
* {@link P2JQuery} instance. |
286 | 281 |
* This method is only called by the package-public methods {@link #parseQuery} and |
new/src/com/goldencode/p2j/persist/DynamicValidationHelper.java 2024-02-16 07:28:46 +0000 | ||
---|---|---|
2 | 2 |
** Module : DynamicValidationHelper.java |
3 | 3 |
** Abstract : Helper class for dynamic validation expressions. |
4 | 4 |
** |
5 |
** Copyright (c) 2017-2023, Golden Code Development Corporation.
|
|
5 |
** Copyright (c) 2017-2024, Golden Code Development Corporation.
|
|
6 | 6 |
** |
7 | 7 |
** -#- -I- --Date-- ---------------------------------------Description--------------------------------------- |
8 | 8 |
** 001 SVL 20171024 Created initial version. |
... | ... | |
18 | 18 |
** CA 20230116 Avoid using handle.unwrap, handle.getReference or other BDT usage from within FWD runtime. |
19 | 19 |
** 004 OM 20230215 Handled collision of buffers with same dynamic table name. |
20 | 20 |
** 005 GBB 20230512 Logging methods replaced by CentralLogger/ConversionStatus. |
21 |
** 006 DDF 20240216 cache can only be created through CacheManager now and has been made non-final. |
|
21 | 22 |
*/ |
22 | 23 | |
23 | 24 |
/* |
... | ... | |
79 | 80 |
import com.goldencode.ast.*; |
80 | 81 |
import com.goldencode.cache.*; |
81 | 82 |
import com.goldencode.p2j.convert.*; |
82 |
import com.goldencode.p2j.directory.*; |
|
83 | 83 |
import com.goldencode.p2j.schema.*; |
84 | 84 |
import com.goldencode.p2j.security.*; |
85 | 85 |
import com.goldencode.p2j.uast.*; |
... | ... | |
101 | 101 |
/** Counter for converted validation expressions. */ |
102 | 102 |
private static final AtomicLong valexpCounter = new AtomicLong(1); |
103 | 103 |
|
104 |
/** Name of the directory parameter which specifies cache size. */ |
|
105 |
private static final String CACHE_SIZE_PARAMETER = "dynamic-valexp-cache-size"; |
|
106 |
|
|
107 | 104 |
/** Name of the variable which replaces the validated field reference in the validation expression. */ |
108 | 105 |
public static final String VAL_EXPR_VAR_NAME = "valExprDynParam"; |
109 | 106 |
|
110 | 107 |
/** The name of the generated java class. */ |
111 | 108 |
private static final String DYN_GEN_VAL_EXPR_CLASS = "DynGenValExpr"; |
112 | 109 |
|
113 |
/** |
|
114 |
* Cache for JASTs generated from validation expressions. Cache management uses an aging and |
|
115 |
* usage algorithm to chose entries to be dropped when the maximum capacity is reached. |
|
116 |
*/ |
|
117 |
private static final ExpiryCache<ValExprCacheKey, JavaAst> cache; |
|
118 |
|
|
119 | 110 |
/** Logger. */ |
120 | 111 |
private static final CentralLogger LOG = CentralLogger.get(DynamicValidationHelper.class.getName()); |
121 | 112 |
|
... | ... | |
128 | 119 |
} |
129 | 120 |
}; |
130 | 121 |
|
131 |
static |
|
122 |
/** |
|
123 |
* Cache for JASTs generated from validation expressions. Cache management uses an aging and |
|
124 |
* usage algorithm to chose entries to be dropped when the maximum capacity is reached. |
|
125 |
*/ |
|
126 |
private static ExpiryCache<ValExprCacheKey, JavaAst> cache; |
|
127 |
|
|
128 |
/** |
|
129 |
* Initializes the cache using CacheManager. The default value of the cache |
|
130 |
* is used when there is no size available from the configuration. |
|
131 |
*/ |
|
132 |
public static void initializeCache() |
|
132 | 133 |
{ |
133 |
Directory dir = DirectoryManager.getInstance(); |
|
134 |
cache = new LRUCache<>("DynamicValidationHelper", |
|
135 |
dir.getInt(Directory.ID_RELATIVE, CACHE_SIZE_PARAMETER, 65536)); |
|
134 |
cache = CacheManager.createLRUCache(DynamicValidationHelper.class, 65536); |
|
136 | 135 |
cache.addCacheExpiryListener(event -> |
137 | 136 |
{ |
138 | 137 |
// debug only: to see when the cache is full |