00001
00025
package org.objectweb.cjdbc.controller.cache.result;
00026
00027
import java.util.ArrayList;
00028
import java.util.HashMap;
00029
import java.util.HashSet;
00030
import java.util.Iterator;
00031
00032
import org.objectweb.cjdbc.common.i18n.Translate;
00033
import org.objectweb.cjdbc.common.log.Trace;
00034
import org.objectweb.cjdbc.common.sql.AbstractWriteRequest;
00035
import org.objectweb.cjdbc.common.sql.CreateRequest;
00036
import org.objectweb.cjdbc.common.sql.ParsingGranularities;
00037
import org.objectweb.cjdbc.common.sql.RequestType;
00038
import org.objectweb.cjdbc.common.sql.SelectRequest;
00039
import org.objectweb.cjdbc.common.sql.UpdateRequest;
00040
import org.objectweb.cjdbc.common.sql.schema.DatabaseSchema;
00041
import org.objectweb.cjdbc.common.xml.DatabasesXmlTags;
00042
import org.objectweb.cjdbc.controller.cache.CacheException;
00043
import org.objectweb.cjdbc.controller.cache.CacheStatistics;
00044
import org.objectweb.cjdbc.controller.cache.result.entries.CacheEntry;
00045
import org.objectweb.cjdbc.controller.cache.result.entries.ResultCacheEntry;
00046
import org.objectweb.cjdbc.controller.cache.result.entries.ResultCacheEntryNoCache;
00047
import org.objectweb.cjdbc.controller.cache.result.entries.ResultCacheEntryRelaxed;
00048
import org.objectweb.cjdbc.controller.cache.result.schema.CacheDatabaseSchema;
00049
import org.objectweb.cjdbc.controller.cache.result.schema.CacheDatabaseTable;
00050
import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet;
00051
import org.objectweb.cjdbc.driver.Field;
00052
00077 public abstract class ResultCache extends AbstractResultCache
00078 {
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 private int maxEntries;
00092 private long pendingQueryTimeout = 0;
00093
00094 private HashMap
queries;
00095
00096 private HashSet
pendingQueries;
00097
00098 private HashSet
cachingRules;
00099 private ResultCacheRule defaultRule;
00100 private ArrayList
relaxedCache;
00101
00102
00103 private CacheEntry
lruHead;
00104
00105 private CacheEntry
lruTail;
00106
00107
00108 protected CacheDatabaseSchema
cdbs;
00109
00110 private CacheStatistics stats;
00111
00112 private long threadWakeUpTime;
00113 private RelaxedCacheThread relaxedThread;
00114 private static final boolean[]
TRUE_TRUE =
new boolean[]{
true,
true};
00115
00116
00117
00118
00119
00126 public ResultCache(
int maxEntries,
int pendingTimeout)
00127 {
00128
this.maxEntries = maxEntries;
00129
this.pendingQueryTimeout = pendingTimeout;
00130
cdbs = null;
00131
stats =
new CacheStatistics();
00132
queries =
new HashMap(1000, (
float) 0.75);
00133
pendingQueries =
new HashSet();
00134
cachingRules =
new HashSet();
00135
relaxedCache =
new ArrayList();
00136
lruHead = null;
00137
lruTail = null;
00138
defaultRule = null;
00139
threadWakeUpTime = 0;
00140
relaxedThread =
new RelaxedCacheThread();
00141
relaxedThread.setPriority(9);
00142
relaxedThread.start();
00143 }
00144
00151 public int getPendingQueryTimeout()
00152 {
00153
return (
int) (
pendingQueryTimeout / 1000);
00154 }
00155
00162 public void setPendingQueryTimeout(
int pendingQueryTimeout)
00163 {
00164
this.pendingQueryTimeout = pendingQueryTimeout * 1000L;
00165 }
00166
00172 public HashMap
getQueries()
00173 {
00174
return this.queries;
00175 }
00176
00183 public void setDatabaseSchema(
DatabaseSchema dbs)
00184 {
00185
if (
cdbs == null)
00186 {
00187 logger.
info(
Translate.get(
"resultcache.setting.database.schema"));
00188
cdbs =
new CacheDatabaseSchema(dbs);
00189 }
00190
else
00191 {
00192 CacheDatabaseSchema newSchema =
new CacheDatabaseSchema(dbs);
00193 ArrayList tables =
cdbs.getTables();
00194 ArrayList newTables = newSchema.getTables();
00195
if (newTables == null)
00196 {
00197 logger.
info(
Translate.get(
"resultcache.flusing.whole.cache"));
00198
flushCache();
00199
cdbs = null;
00200
return;
00201 }
00202
00203
00204
for (
int i = 0; i < tables.size(); i++)
00205 {
00206
CacheDatabaseTable t = (
CacheDatabaseTable) tables.get(i);
00207
if (!newSchema.hasTable(t.
getName()))
00208 {
00209 t.
invalidateAll();
00210
cdbs.removeTable(t);
00211
if (logger.
isInfoEnabled())
00212 logger.
info(
Translate
00213 .get(
"resultcache.removing.table", t.
getName()));
00214 }
00215 }
00216
00217
00218
int size = newTables.size();
00219
for (
int i = 0; i < size; i++)
00220 {
00221
CacheDatabaseTable t = (
CacheDatabaseTable) newTables.get(i);
00222
if (!
cdbs.hasTable(t.
getName()))
00223 {
00224
cdbs.addTable(t);
00225
if (logger.
isInfoEnabled())
00226 logger.
info(
Translate.get(
"resultcache.adding.table", t.
getName()));
00227 }
00228 }
00229 }
00230 }
00231
00238 public void mergeDatabaseSchema(
DatabaseSchema dbs)
00239 {
00240
try
00241 {
00242 logger.
info(
Translate.get(
"resultcache.merging.new.database.schema"));
00243
cdbs.mergeSchema(
new CacheDatabaseSchema(dbs));
00244 }
00245
catch (Exception e)
00246 {
00247 logger.
error(
Translate.get(
"resultcache.error.while.merging", e));
00248 }
00249 }
00250
00257 public void addCachingRule(
ResultCacheRule rule)
00258 {
00259
cachingRules.add(rule);
00260 }
00261
00265 public ResultCacheRule getDefaultRule()
00266 {
00267
return defaultRule;
00268 }
00269
00273 public void setDefaultRule(
ResultCacheRule defaultRule)
00274 {
00275
this.defaultRule = defaultRule;
00276 }
00277
00286 private CacheBehavior getCacheBehavior(
SelectRequest request)
00287 {
00288
CacheBehavior behavior = null;
00289
for (Iterator iter =
cachingRules.iterator(); iter.hasNext();)
00290 {
00291 behavior = ((
ResultCacheRule) iter.next()).matches(request);
00292
if (behavior != null)
00293 {
00294
break;
00295 }
00296 }
00297
if (behavior == null)
00298 behavior =
defaultRule.
getCacheBehavior();
00299
if (logger.
isDebugEnabled())
00300 logger.
debug(
Translate.get(
"resultcache.behavior.for.request",
00301
new String[]{request.
getSQL(), behavior.
getType()}));
00302
return behavior;
00303 }
00304
00305
00306
00307
00308
00319 public boolean[] needInvalidate(
ControllerResultSet result,
00320
UpdateRequest request)
00321 {
00322 HashMap updatedValues = request.
getUpdatedValues();
00323
boolean needInvalidate =
false;
00324
boolean needToSendQuery =
false;
00325 String value;
00326 String columnName;
00327
try
00328 {
00329
00330
if ((result == null) || (result.
getData() == null)
00331 || (result.
getData().size() != 1))
00332
return TRUE_TRUE;
00333 }
00334
catch (Exception e)
00335 {
00336
return TRUE_TRUE;
00337 }
00338
Field[] fields = result.
getFields();
00339 ArrayList data = result.
getData();
00340
int size = fields.length;
00341
for (Iterator iter = updatedValues.keySet().iterator(); iter.hasNext();)
00342 {
00343 columnName = (String) iter.next();
00344 value = (String) updatedValues.get(columnName);
00345
for (
int i = 0; i < size; i++)
00346 {
00347
00348
00349
00350
00351
if (columnName.equals(fields[i].getFieldName()))
00352 {
00353 Object o = ((Object[]) data.get(0))[i];
00354
if (!value.equals(o))
00355 {
00356
00357
00358
00359
return TRUE_TRUE;
00360 }
00361
else
00362
break;
00363 }
00364 }
00365
00366
00367 needToSendQuery =
true;
00368
00369
00370
00371 }
00372
return new boolean[]{needInvalidate, needToSendQuery};
00373 }
00374
00383 public void addToCache(
SelectRequest request,
ControllerResultSet result)
00384
throws CacheException
00385 {
00386 String sqlQuery = request.getSQL();
00387
00388
00389
if (request.getCacheAbility() ==
RequestType.UNCACHEABLE)
00390
throw new CacheException(
Translate.get(
"resultcache.uncacheable.request",
00391 sqlQuery));
00392
00393
if (result == null)
00394
throw new CacheException(
Translate.get(
"resultcache.null.result",
00395 sqlQuery));
00396
00397
synchronized (pendingQueries)
00398 {
00399
00400
00401
if (pendingQueries.remove(sqlQuery))
00402 {
00403
if (logger.isDebugEnabled())
00404 logger.debug(
Translate.get(
"resultcache.removing.pending.query",
00405 sqlQuery));
00406 pendingQueries.notifyAll();
00407 }
00408
else
00409 logger.warn(
Translate.get(
"resultcache.removing.pending.query.failed",
00410 sqlQuery));
00411
00412
00413
if (result.hasMoreData())
00414 {
00415 logger.info(
Translate.get(
"resultcache.streamed.resultset", request
00416 .getSQLShortForm(20)));
00417
return;
00418 }
00419
00420
if (logger.isDebugEnabled())
00421 logger.debug(
Translate.get(
"resultcache.adding.query", sqlQuery));
00422
00423 CacheEntry ce;
00424
synchronized (queries)
00425 {
00426
00427 ce = (
ResultCacheEntry) queries.get(sqlQuery);
00428
if (ce == null)
00429 {
00430
00431
00432
CacheBehavior behavior = getCacheBehavior(request);
00433 ce = behavior.
getCacheEntry(request, result,
this);
00434
if (ce instanceof
ResultCacheEntryNoCache)
00435
return;
00436
00437
00438
if (maxEntries > 0)
00439 {
00440
int size = queries.size();
00441
if (size >= maxEntries)
00442
00443 removeOldest();
00444 }
00445
00446 queries.put(sqlQuery, ce);
00447
if (ce instanceof
ResultCacheEntryRelaxed)
00448 {
00449
ResultCacheEntryRelaxed qcer = (
ResultCacheEntryRelaxed) ce;
00450
synchronized (relaxedThread)
00451 {
00452 relaxedCache.add(qcer);
00453
if (qcer.
getDeadline() < threadWakeUpTime
00454 || threadWakeUpTime == 0)
00455 {
00456 relaxedThread.notify();
00457 }
00458 }
00459 }
00460 }
00461
else
00462 {
00463
if (ce.isValid())
00464 logger.warn(
Translate.get(
00465
"resultcache.modifying.result.valid.entry", sqlQuery));
00466 ce.setResult(result);
00467 }
00468
00469
00470
if (lruHead != null)
00471 {
00472 lruHead.setPrev(ce);
00473 ce.setNext(lruHead);
00474 ce.setPrev(null);
00475 }
00476
if (lruTail == null)
00477 lruTail = ce;
00478 lruHead = ce;
00479 }
00480 processAddToCache(ce);
00481 }
00482 }
00483
00489
protected abstract void processAddToCache(
CacheEntry qe);
00490
00506 public CacheEntry getFromCache(
SelectRequest request,
00507
boolean addToPendingQueries)
00508 {
00509 stats.addSelect();
00510
00511
if (request.
getCacheAbility() ==
RequestType.UNCACHEABLE)
00512 {
00513 stats.addUncacheable();
00514
return null;
00515 }
00516
00517 String sqlQuery = request.
getSQL();
00518
00519
00520
synchronized (pendingQueries)
00521 {
00522
if (addToPendingQueries)
00523 {
00524
long timeout = pendingQueryTimeout;
00525
00526
00527
00528
while (pendingQueries.contains(sqlQuery))
00529 {
00530
try
00531 {
00532
if (logger.isDebugEnabled())
00533 logger.debug(
Translate.get(
"resultcache.waiting.pending.query",
00534 sqlQuery));
00535
00536
if (timeout > 0)
00537 {
00538
long start = System.currentTimeMillis();
00539 pendingQueries.wait(pendingQueryTimeout);
00540
long end = System.currentTimeMillis();
00541 timeout = timeout - (end - start);
00542
if (timeout <= 0)
00543 {
00544 logger.warn(
Translate.get(
"resultcache.pending.query.timeout"));
00545
break;
00546 }
00547 }
00548
else
00549 pendingQueries.wait();
00550 }
00551
catch (InterruptedException e)
00552 {
00553 logger.warn(
Translate.get(
"resultcache.pending.query.timeout"));
00554
break;
00555 }
00556 }
00557 }
00558
00559
00560
ResultCacheEntry ce;
00561
synchronized (queries)
00562 {
00563 ce = (
ResultCacheEntry) queries.get(sqlQuery);
00564
if (ce == null)
00565
00566 {
00567
if (addToPendingQueries)
00568 {
00569 pendingQueries.add(sqlQuery);
00570
00571
if (logger.isDebugEnabled())
00572 {
00573 logger.debug(
Translate.get(
"resultcache.cache.miss"));
00574 logger.debug(
Translate.get(
00575
"resultcache.adding.to.pending.queries", sqlQuery));
00576 }
00577 }
00578
return null;
00579 }
00580
else
00581 {
00582
00583 CacheEntry before = ce.
getPrev();
00584
if (before != null)
00585 {
00586 CacheEntry after = ce.
getNext();
00587 before.setNext(after);
00588
if (after != null)
00589 after.setPrev(before);
00590
else
00591
00592 lruTail = before;
00593 ce.
setNext(lruHead);
00594 ce.
setPrev(null);
00595
if (lruHead != ce)
00596 lruHead.setPrev(ce);
00597 lruHead = ce;
00598 }
00599
00600 }
00601 }
00602
00603
if (ce.
getResult() == null)
00604 {
00605
if (addToPendingQueries)
00606 {
00607 pendingQueries.add(sqlQuery);
00608
00609
if (logger.isDebugEnabled())
00610 {
00611 logger.debug(
Translate.get(
"resultcache.cache.miss"));
00612 logger.debug(
Translate.get(
"resultcache.adding.to.pending.queries",
00613 sqlQuery));
00614 }
00615 }
00616
if (ce.
isValid() && logger.isInfoEnabled())
00617 logger.info(
Translate.get(
"resultcache.valid.entry.without.result",
00618 ce.
getRequest().
getSQL()));
00619 }
00620
else
00621 {
00622
if (logger.isDebugEnabled())
00623 logger.debug(
Translate.get(
"resultcache.cache.hit", sqlQuery));
00624 stats.addHits();
00625 }
00626
00627
return ce;
00628 }
00629 }
00630
00638 public void removeFromCache(
SelectRequest request)
00639 {
00640 String sqlQuery = request.
getSQL();
00641
00642
if (logger.isDebugEnabled())
00643 logger.debug(
"Removing from cache: " + sqlQuery);
00644
00645
synchronized (queries)
00646 {
00647
00648
ResultCacheEntry ce = (
ResultCacheEntry) queries.remove(sqlQuery);
00649
if (ce == null)
00650
return;
00651
else
00652 {
00653
00654 ce.
setResult(null);
00655
00656 CacheEntry before = ce.
getPrev();
00657 CacheEntry after = ce.
getNext();
00658
if (before != null)
00659 {
00660 before.setNext(after);
00661
if (after != null)
00662 after.setPrev(before);
00663
else
00664
00665 lruTail = before;
00666 }
00667
else
00668 {
00669 lruHead = ce.
getNext();
00670
if (after != null)
00671 after.setPrev(null);
00672
else
00673
00674 lruTail = before;
00675 }
00676 }
00677 }
00678 }
00679
00685 public void removeFromPendingQueries(
SelectRequest request)
00686 {
00687 String sqlQuery = request.
getSQL();
00688
00689
synchronized (pendingQueries)
00690 {
00691
00692
00693
if (pendingQueries.remove(sqlQuery))
00694 pendingQueries.notifyAll();
00695 }
00696 }
00697
00701
public abstract boolean isUpdateNecessary(
UpdateRequest request)
00702
throws CacheException;
00703
00712 public void writeNotify(
AbstractWriteRequest request)
throws CacheException
00713 {
00714
00715
if (request.isInsert())
00716 stats.addInsert();
00717
else if (request.isUpdate())
00718 stats.addUpdate();
00719
else if (request.isDelete())
00720 stats.addDelete();
00721
else if (request.isCreate())
00722 {
00723 stats.addCreate();
00724
00725
if (parsingGranularity !=
ParsingGranularities.NO_PARSING)
00726 cdbs.addTable(
new CacheDatabaseTable(((
CreateRequest) request)
00727 .getDatabaseTable()));
00728
return;
00729 }
00730
else if (request.isDrop())
00731 {
00732 stats.addDrop();
00733
00734
if (parsingGranularity !=
ParsingGranularities.NO_PARSING)
00735 {
00736
00737
CacheDatabaseTable cdt = cdbs.getTable(request.getTableName());
00738
if (cdt != null)
00739 {
00740 cdt.
invalidateAll();
00741 cdbs.removeTable(cdt);
00742
return;
00743 }
00744
00745
00746 }
00747 }
00748
else
00749 {
00750 stats.addUnknown();
00751 }
00752
if (logger.isDebugEnabled())
00753 logger.debug(
"Notifying write " + request.getSQL());
00754
00755 processWriteNotify(request);
00756 }
00757
00763
protected abstract void processWriteNotify(
AbstractWriteRequest request);
00764
00768 public void flushCache()
00769 {
00770
synchronized (queries)
00771 {
00772
while (!queries.isEmpty())
00773 {
00774 Iterator iter = queries.values().iterator();
00775 ((
ResultCacheEntry) iter.next()).invalidate();
00776 }
00777 }
00778
00779
synchronized (pendingQueries)
00780 {
00781
00782 pendingQueries.clear();
00783 pendingQueries.notifyAll();
00784 }
00785
00786
if (logger.isDebugEnabled())
00787 logger.debug(
Translate.get(
"resultcache.cache.flushed"));
00788 }
00789
00795 public long getCacheSize()
00796 {
00797
00798
return queries.size();
00799 }
00800
00807 private void removeOldest()
00808 {
00809
if (lruTail == null)
00810
return;
00811
00812
ResultCacheEntry oldce = (
ResultCacheEntry) lruTail;
00813 lruTail = lruTail.getPrev();
00814
if (lruTail != null)
00815 lruTail.setNext(null);
00816
00817
if (logger.isDebugEnabled())
00818 logger.debug(
Translate.get(
"resultcache.removing.oldest.cache.entry",
00819 oldce.
getRequest().
getSQL()));
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829 queries.remove(oldce.
getRequest().
getSQL());
00830
00831
if (oldce.
isValid())
00832 {
00833 oldce.
setResult(null);
00834 oldce.
invalidate();
00835 }
00836
00837 stats.addRemove();
00838 }
00839
00845 public int getParsingGranularity()
00846 {
00847
return this.parsingGranularity;
00848 }
00849
00855
public abstract String getName();
00856
00857
00858
00859
00860
00867 public void commit(
long transactionId)
throws CacheException
00868 {
00869
00870 }
00871
00878 public void rollback(
long transactionId)
throws CacheException
00879 {
00880 logger.info(
Translate.get(
"resultcache.flushing.cache.cause.rollback",
00881 transactionId));
00882 flushCache();
00883 }
00884
00885
00886
00887
00888
00892 public String[][] getCacheData() throws
CacheException
00893 {
00894
try
00895 {
00896
synchronized (queries)
00897 {
00898 String[][] data =
new String[queries.size()][];
00899
int count = 0;
00900
for (Iterator iter = queries.values().iterator(); iter.hasNext(); count++)
00901 {
00902
ResultCacheEntry qe = (
ResultCacheEntry) iter.next();
00903
if (qe != null)
00904 {
00905 data[count] = qe.
toStringTable();
00906 }
00907 }
00908
return data;
00909 }
00910 }
00911
catch (Exception e)
00912 {
00913 logger.error(
Translate.get(
"resultcache.error.retrieving.cache.data", e));
00914
throw new CacheException(e.getMessage());
00915 }
00916 }
00917
00921 public String[][] getCacheStatsData() throws
CacheException
00922 {
00923 String[][] data =
new String[1][];
00924 String[] stat = stats.getCacheStatsData();
00925 data[0] =
new String[stat.length + 1];
00926
for (
int i = 0; i < stat.length; i++)
00927 data[0][i] = stat[i];
00928 data[0][data[0].length - 1] =
"" + queries.size();
00929
return data;
00930 }
00931
00935 public CacheStatistics getCacheStatistics()
00936 {
00937
return stats;
00938 }
00939
00945 protected String getXmlImpl()
00946 {
00947 StringBuffer info =
new StringBuffer();
00948 info.append(
"<" +
DatabasesXmlTags.ELT_ResultCache +
" "
00949 +
DatabasesXmlTags.ATT_pendingTimeout +
"=\"" + pendingQueryTimeout
00950 +
"\" " +
DatabasesXmlTags.ATT_maxNbOfEntries +
"=\"" + maxEntries
00951 +
"\" " +
DatabasesXmlTags.ATT_granularity +
"=\"" + getName() +
"\">");
00952 info.append(
"<" +
DatabasesXmlTags.ELT_DefaultResultCacheRule +
" "
00953 +
DatabasesXmlTags.ATT_timestampResolution +
"=\""
00954 + defaultRule.getTimestampResolution() / 1000 +
"\">");
00955 info.append(defaultRule.getCacheBehavior().getXml());
00956 info.append(
"</" +
DatabasesXmlTags.ELT_DefaultResultCacheRule +
">");
00957
for (Iterator iter = cachingRules.iterator(); iter.hasNext();)
00958 info.append(((
ResultCacheRule) iter.next()).getXml());
00959 info.append(
"</" +
DatabasesXmlTags.ELT_ResultCache +
">");
00960
return info.toString();
00961 }
00962
00966 private final class RelaxedCacheThread extends Thread
00967 {
00968 int refreshCacheRate = 60;
00969 int refreshCacheTime = 60 / refreshCacheRate;
00970 private Trace logger = Trace
00971 .getLogger(
"org.objectweb.cjdbc.controller.cache.cache.RelaxedThread");
00972
00973 private boolean isKilled =
false;
00974
00978 public RelaxedCacheThread()
00979 {
00980 super(
"RelaxedCacheThread");
00981 }
00982
00988 public RelaxedCacheThread(
int refreshCacheRate)
00989 {
00990
this();
00991
this.refreshCacheRate = refreshCacheRate;
00992 }
00993
00997 public void run()
00998 {
00999
ResultCacheEntryRelaxed entry;
01000
long now;
01001
long sleep;
01002
01003 ArrayList toRemoveFromRelaxedCache =
new ArrayList();
01004
while (!isKilled)
01005 {
01006
synchronized (
this)
01007 {
01008
try
01009 {
01010 threadWakeUpTime = 0;
01011
if (relaxedCache.isEmpty())
01012 {
01013
if (logger.isDebugEnabled())
01014 logger.debug(
Translate
01015 .get(
"relaxedcachethread.cache.empty.sleeping"));
01016 wait();
01017 }
01018
else
01019 {
01020 now = System.currentTimeMillis();
01021 clean :
for (Iterator iter = relaxedCache.iterator(); iter
01022 .hasNext();)
01023 {
01024 entry = (
ResultCacheEntryRelaxed) iter.next();
01025
if (entry.
getDeadline() < now)
01026 {
01027
if (entry.
isDirty() || !entry.
getKeepIfNotDirty())
01028 {
01029 {
01030 toRemoveFromRelaxedCache.add(entry);
01031 }
01032
continue clean;
01033 }
01034
else
01035 entry.
setDeadline(now + entry.
getTimeout());
01036 }
01037
if (threadWakeUpTime == 0
01038 || (entry.
getDeadline() < threadWakeUpTime))
01039 threadWakeUpTime = entry.
getDeadline();
01040 }
01041
01042
01043
for (
int i = 0; i < toRemoveFromRelaxedCache.size(); i++)
01044 {
01045 entry = (
ResultCacheEntryRelaxed) toRemoveFromRelaxedCache
01046 .get(i);
01047
if (logger.isDebugEnabled())
01048 logger.debug(
Translate.get(
01049
"relaxedcachethread.remove.entry.from.cache", entry
01050 .
getRequest().
getSQL()));
01051 removeFromCache(entry.
getRequest());
01052 relaxedCache.remove(toRemoveFromRelaxedCache.get(i));
01053 toRemoveFromRelaxedCache.remove(i);
01054 }
01055
if (threadWakeUpTime == 0)
01056 {
01057
01058
continue;
01059 }
01060
else
01061 {
01062 sleep = (threadWakeUpTime - now) / 1000 + refreshCacheTime;
01063
if (logger.isDebugEnabled())
01064 {
01065 logger.debug(
Translate.get(
"relaxedcachethread.sleeping",
01066 sleep));
01067 }
01068 sleep = (sleep) * 1000;
01069 wait(sleep);
01070 }
01071 }
01072 }
01073
catch (Exception e)
01074 {
01075 logger.warn(e.getMessage(), e);
01076 }
01077 }
01078 }
01079 }
01080 }
01081
01082 }