Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

RelaxedCacheThread.java

00001 /**
00002  * C-JDBC: Clustered JDBC.
00003  * Copyright (C) 2002-2005 French National Institute For Research In Computer
00004  * Science And Control (INRIA).
00005  * Contact: c-jdbc@objectweb.org
00006  * 
00007  * This library is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU Lesser General Public License as published by the
00009  * Free Software Foundation; either version 2.1 of the License, or any later
00010  * version.
00011  * 
00012  * This library is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
00015  * for more details.
00016  * 
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this library; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00020  *
00021  * Initial developer(s): Nicolas Modrzyk.
00022  * Contributor(s): ______________________.
00023  */
00024 
00025 package org.objectweb.cjdbc.controller.cache.result.threads;
00026 
00027 import java.util.ArrayList;
00028 import java.util.Iterator;
00029 
00030 import org.objectweb.cjdbc.common.i18n.Translate;
00031 import org.objectweb.cjdbc.common.log.Trace;
00032 import org.objectweb.cjdbc.controller.cache.result.ResultCache;
00033 import org.objectweb.cjdbc.controller.cache.result.entries.ResultCacheEntryRelaxed;
00034 
00035 /**
00036  * This thread manages relaxed cache entries and remove them from the cache if
00037  * their deadline has expired or they are dirty.
00038  * 
00039  * @author <a href="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
00040  * @version 1.0
00041  */
00042 public final class RelaxedCacheThread extends Thread
00043 {
00044   private long              threadWakeUpTime = 0;
00045   private final ResultCache cache;
00046   int                       refreshCacheRate = 60;
00047   int                       refreshCacheTime = 60 / refreshCacheRate;
00048   private Trace             logger           = Trace
00049                                                  .getLogger(RelaxedCacheThread.class
00050                                                      .getName());
00051 
00052   private boolean           isKilled         = false;
00053 
00054   /**
00055    * Creates a new <code>RelaxedCacheThread</code> object
00056    * 
00057    * @param cache ResultCache creating this thread
00058    */
00059   public RelaxedCacheThread(ResultCache cache)
00060   {
00061     super("RelaxedCacheThread");
00062     this.cache = cache;
00063   }
00064 
00065   /**
00066    * Creates a new <code>RelaxedCacheThread</code> object
00067    * 
00068    * @param cache ResultCache creating this thread
00069    * @param refreshCacheRate cache refresh rate in seconds
00070    */
00071   public RelaxedCacheThread(ResultCache cache, int refreshCacheRate)
00072   {
00073     this(cache);
00074     this.refreshCacheRate = refreshCacheRate;
00075   }
00076 
00077   /**
00078    * @see java.lang.Runnable#run()
00079    */
00080   public void run()
00081   {
00082     ResultCacheEntryRelaxed entry;
00083     long now;
00084     long sleep;
00085     // Keep trace of relaxed cache entries to delete
00086     ArrayList toRemoveFromRelaxedCache = new ArrayList();
00087     while (!isKilled)
00088     {
00089       synchronized (this)
00090       {
00091         try
00092         {
00093           threadWakeUpTime = 0;
00094           if (cache.getRelaxedCache().isEmpty())
00095           { // Nothing in the cache, just sleep!
00096             if (logger.isDebugEnabled())
00097               logger.debug(Translate.get("cachethread.cache.empty.sleeping"));
00098             wait();
00099           }
00100           else
00101           { // Look for first deadline
00102             now = System.currentTimeMillis();
00103             for (Iterator iter = cache.getRelaxedCache().iterator(); iter
00104                 .hasNext();)
00105             {
00106               entry = (ResultCacheEntryRelaxed) iter.next();
00107               if (entry.getDeadline() < now)
00108               { // Deadline has expired
00109                 if (entry.isDirty() || !entry.getKeepIfNotDirty())
00110                 { // Remove this entry
00111                   toRemoveFromRelaxedCache.add(entry);
00112                   continue;
00113                 }
00114                 else
00115                   // Entry is still valid, reset deadline
00116                   entry.setDeadline(now + entry.getTimeout());
00117               }
00118 
00119               // Recompute next wakeup time if needed
00120               if (threadWakeUpTime == 0
00121                   || (entry.getDeadline() < threadWakeUpTime))
00122                 threadWakeUpTime = entry.getDeadline();
00123             }
00124 
00125             // Clean up all dirty entries from the relaxed cache
00126             int size = toRemoveFromRelaxedCache.size();
00127             for (int i = 0; i < size; i++)
00128             {
00129               entry = (ResultCacheEntryRelaxed) toRemoveFromRelaxedCache.get(i);
00130               if (logger.isDebugEnabled())
00131                 logger.debug(Translate.get(
00132                     "cachethread.remove.entry.from.cache", entry.getRequest()
00133                         .getSQL()));
00134               this.cache.removeFromCache(entry.getRequest());
00135               cache.getRelaxedCache().remove(entry);
00136             }
00137             toRemoveFromRelaxedCache.clear();
00138             if (threadWakeUpTime == 0)
00139             { // All entries were dirty and not kept in the cache, therefore
00140               // there is no next deadline. (and no cache entry to wait for)
00141               continue;
00142             }
00143             else
00144             { // Sleep until the next deadline
00145               sleep = (threadWakeUpTime - now) / 1000 + refreshCacheTime;
00146               if (logger.isDebugEnabled())
00147               {
00148                 logger.debug(Translate.get("cachethread.sleeping", sleep));
00149               }
00150               sleep = (sleep) * 1000;
00151               wait(sleep);
00152             }
00153           }
00154         }
00155         catch (Exception e)
00156         {
00157           logger.warn(e.getMessage(), e);
00158         }
00159       }
00160     }
00161   }
00162 
00163   /**
00164    * Returns the threadWakeUpTime value.
00165    * 
00166    * @return Returns the threadWakeUpTime.
00167    */
00168   public long getThreadWakeUpTime()
00169   {
00170     return threadWakeUpTime;
00171   }
00172 }

Generated on Mon Apr 11 22:01:34 2005 for C-JDBC by  doxygen 1.3.9.1