1 24 25 package org.objectweb.cjdbc.controller.cache.parsing; 26 27 import java.sql.SQLException ; 28 import java.util.Hashtable ; 29 30 import org.objectweb.cjdbc.common.i18n.Translate; 31 import org.objectweb.cjdbc.common.log.Trace; 32 import org.objectweb.cjdbc.common.sql.AbstractRequest; 33 import org.objectweb.cjdbc.common.sql.ParsingGranularities; 34 import org.objectweb.cjdbc.common.sql.RequestType; 35 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags; 36 import org.objectweb.cjdbc.controller.requestmanager.ParserThread; 37 import org.objectweb.cjdbc.controller.requestmanager.RequestManager; 38 39 45 public class ParsingCache 46 { 47 private static Trace logger = Trace.getLogger(ParsingCache.class.getName()); 48 private Hashtable cache; private Hashtable currentlyParsing; private RequestManager requestManager; 51 private int granularity; 52 private int maxNbOfEntries; 53 private boolean backgroundParsing; private boolean caseSensitiveParsing; 56 63 private class CurrentlyParsingEntry 64 { 65 private ParserThread parserThread; 66 private AbstractRequest request; 67 68 74 public CurrentlyParsingEntry(ParserThread parserThread, 75 AbstractRequest request) 76 { 77 this.parserThread = parserThread; 78 this.request = request; 79 } 80 81 86 public ParserThread getParserThread() 87 { 88 return parserThread; 89 } 90 91 96 public AbstractRequest getRequest() 97 { 98 return request; 99 } 100 101 } 102 103 110 public ParsingCache(int size, boolean backgroundParsing) 111 { 112 cache = new Hashtable (size == 0 ? 10000 : size); 113 currentlyParsing = new Hashtable (); 114 if (size < 0) 115 throw new RuntimeException (Translate.get("cache.parsing.invalid.size", 116 size)); 117 if (size == 0) 118 this.maxNbOfEntries = Integer.MAX_VALUE; 119 else 120 this.maxNbOfEntries = size; 121 this.backgroundParsing = backgroundParsing; 122 caseSensitiveParsing = false; 123 } 124 125 130 public int getGranularity() 131 { 132 return granularity; 133 } 134 135 140 public void setGranularity(int granularity) 141 { 142 this.granularity = granularity; 143 } 144 145 150 public RequestManager getRequestManager() 151 { 152 return requestManager; 153 } 154 155 160 public void setRequestManager(RequestManager requestManager) 161 { 162 this.requestManager = requestManager; 163 } 164 165 173 public void getParsingFromCache(AbstractRequest request) 174 { 175 if (request.isParsed()) 176 return; 177 178 String sql = request.getSqlSkeleton(); 179 if (sql == null) 180 sql = request.getSQL(); 181 AbstractRequest parsedRequest = (AbstractRequest) cache.get(sql); 182 183 if (parsedRequest != null) 184 { request.cloneParsing(parsedRequest); 186 return; 187 } 188 else if (backgroundParsing) 189 { synchronized (currentlyParsing) 191 { 192 if (!currentlyParsing.contains(sql)) 193 { ParserThread pt = new ParserThread(request, requestManager 195 .getDatabaseSchema(), granularity, caseSensitiveParsing); 196 currentlyParsing.put(sql, new CurrentlyParsingEntry(pt, request)); 197 } 198 } 199 } 200 } 201 202 208 public void getParsingFromCacheAndParseIfMissing(AbstractRequest request) 209 throws SQLException 210 { 211 if (request.isParsed()) 212 return; 213 214 String instanciatedSQL = request.getSQL(); 216 AbstractRequest parsedRequest = (AbstractRequest) cache 217 .get(instanciatedSQL); 218 219 220 try 221 { 222 223 if (parsedRequest == null) 224 { String sqlSkeleton = request.getSqlSkeleton(); 226 String sql; 227 if (sqlSkeleton != null) 228 { sql = sqlSkeleton; 230 parsedRequest = (AbstractRequest) cache.get(sql); 231 if (parsedRequest != null) 232 { request.cloneParsing(parsedRequest); 234 return; 235 } 236 } 237 else 238 sql = instanciatedSQL; 239 240 while (cache.size() > maxNbOfEntries) 245 { synchronized (cache) 249 { 250 try 251 { 252 cache.remove(cache.keys().nextElement()); 253 } 254 catch (Exception ignore) 255 { 256 break; 257 } 258 } 259 } 260 261 262 if (backgroundParsing) 264 { 265 CurrentlyParsingEntry cpe = (CurrentlyParsingEntry) currentlyParsing 268 .get(sql); 269 if (cpe != null) 270 { 271 ParserThread pt = cpe.getParserThread(); 272 try 273 { 274 if (pt != null) 275 { 276 pt.join(); 278 synchronized (currentlyParsing) 279 { 280 currentlyParsing.remove(sql); 281 } 282 283 if ((granularity != ParsingGranularities.COLUMN_UNIQUE) 285 || (sqlSkeleton == null)) 286 cache.put(instanciatedSQL, cpe.getRequest()); 288 else 289 { if (request.getCacheAbility() != RequestType.UNIQUE_CACHEABLE) 291 cache.put(sqlSkeleton, cpe.getRequest()); 293 else 294 cache.put(instanciatedSQL, cpe.getRequest()); 296 } 297 } 298 } 299 catch (InterruptedException failed) 300 { 301 throw new SQLException (Translate.get( 302 "cache.parsing.failed.join.parser.thread", new String []{ 303 "" + request.getId(), failed.getMessage()})); 304 } 305 } 306 } 307 request.parse(requestManager.getDatabaseSchema(), granularity, 310 caseSensitiveParsing); 311 312 if ((sqlSkeleton != null) 314 && (granularity == ParsingGranularities.COLUMN_UNIQUE) 315 && (request.getCacheAbility() == RequestType.UNIQUE_CACHEABLE)) 316 cache.put(instanciatedSQL, request); 319 else 320 cache.put(sql, request); 321 } 322 else 323 request.cloneParsing(parsedRequest); 325 326 } 327 catch (OutOfMemoryError oome) 328 { 329 synchronized (cache) 330 { 331 cache.clear(); 332 } 333 System.gc(); 334 logger.warn(Translate.get("cache.memory.error.cache.flushed", this 335 .getClass())); 336 } 337 } 338 339 344 public boolean isBackgroundParsing() 345 { 346 return backgroundParsing; 347 } 348 349 355 public void setBackgroundParsing(boolean backgroundParsing) 356 { 357 this.backgroundParsing = backgroundParsing; 358 } 359 360 365 public void setCaseSensitiveParsing(boolean isCaseSensitiveParsing) 366 { 367 this.caseSensitiveParsing = isCaseSensitiveParsing; 368 } 369 370 375 public boolean isCaseSensitiveParsing() 376 { 377 return caseSensitiveParsing; 378 } 379 380 385 public String getXml() 386 { 387 return "<" + DatabasesXmlTags.ELT_ParsingCache + " " 388 + DatabasesXmlTags.ATT_backgroundParsing + "=\"" + backgroundParsing 389 + "\" " + DatabasesXmlTags.ATT_maxNbOfEntries + "=\"" + maxNbOfEntries 390 + "\"/>"; 391 } 392 393 } | Popular Tags |