KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > cache > result > ResultCacheColumnUnique


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2005 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Emmanuel Cecchet.
22  * Contributor(s): Nicolas Modrzyk.
23  */

24
25 package org.objectweb.cjdbc.controller.cache.result;
26
27 import java.util.ArrayList JavaDoc;
28 import java.util.Iterator JavaDoc;
29
30 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest;
31 import org.objectweb.cjdbc.common.sql.DeleteRequest;
32 import org.objectweb.cjdbc.common.sql.ParsingGranularities;
33 import org.objectweb.cjdbc.common.sql.RequestType;
34 import org.objectweb.cjdbc.common.sql.SelectRequest;
35 import org.objectweb.cjdbc.common.sql.UpdateRequest;
36 import org.objectweb.cjdbc.common.sql.schema.TableColumn;
37 import org.objectweb.cjdbc.controller.cache.result.entries.AbstractResultCacheEntry;
38 import org.objectweb.cjdbc.controller.cache.result.schema.CacheDatabaseColumn;
39 import org.objectweb.cjdbc.controller.cache.result.schema.CacheDatabaseTable;
40 import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet;
41
42 /**
43  * This is a query cache implementation with a column unique granularity:
44  * <ul>
45  * <li><code>COLUMN_UNIQUE</code>: same as <code>COLUMN</code> except that
46  * <code>UNIQUE</code> queries that selects a single row based on a key are
47  * invalidated only when needed.
48  * </ul>
49  *
50  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
51  * @author <a HREF="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
52  * @version 1.0
53  */

54 public class ResultCacheColumnUnique extends ResultCache
55 {
56
57   /**
58    * Builds a new ResultCache with a column unique granularity.
59    *
60    * @param maxEntries maximum number of entries
61    * @param pendingTimeout pending timeout for concurrent queries
62    */

63   public ResultCacheColumnUnique(int maxEntries, int pendingTimeout)
64   {
65     super(maxEntries, pendingTimeout);
66     parsingGranularity = ParsingGranularities.COLUMN_UNIQUE;
67   }
68
69   /**
70    * @see org.objectweb.cjdbc.controller.cache.result.ResultCache#processAddToCache(AbstractResultCacheEntry)
71    */

72   public void processAddToCache(AbstractResultCacheEntry qe)
73   {
74     SelectRequest request = qe.getRequest();
75     ArrayList JavaDoc selectedColumns = request.getSelect();
76     // Update the tables columns dependencies
77
if (selectedColumns == null || selectedColumns.isEmpty())
78     {
79       logger
80           .warn("No parsing of select clause found - Fallback to table granularity");
81       for (Iterator JavaDoc i = request.getFrom().iterator(); i.hasNext();)
82       {
83         CacheDatabaseTable table = cdbs.getTable((String JavaDoc) i.next());
84         table.addCacheEntry(qe);
85         // Add all columns, entries will be added below.
86
ArrayList JavaDoc columns = table.getColumns();
87         for (int j = 0; j < columns.size(); j++)
88         {
89           ((CacheDatabaseColumn) columns.get(j)).addCacheEntry(qe);
90         }
91         return;
92       }
93     }
94     for (Iterator JavaDoc i = request.getSelect().iterator(); i.hasNext();)
95     {
96       TableColumn tc = (TableColumn) i.next();
97       cdbs.getTable(tc.getTableName()).getColumn(tc.getColumnName())
98           .addCacheEntry(qe);
99     }
100     if (request.getWhere() != null)
101     { // Add all columns dependencies
102
for (Iterator JavaDoc i = request.getWhere().iterator(); i.hasNext();)
103       {
104         TableColumn tc = (TableColumn) i.next();
105         cdbs.getTable(tc.getTableName()).getColumn(tc.getColumnName())
106             .addCacheEntry(qe);
107       }
108       if (request.getCacheAbility() == RequestType.UNIQUE_CACHEABLE)
109       { // Add a specific entry for this pk
110
String JavaDoc tableName = (String JavaDoc) request.getFrom().get(0);
111         AbstractResultCacheEntry entry = cdbs.getTable(tableName)
112             .getPkResultCacheEntry(request.getPkValue());
113         if (entry != null)
114         {
115           if (entry.isValid())
116           { // Do not add an entry which has a lower selection than the current
117
// one
118
if (entry.getRequest().getSelect().size() >= request.getSelect()
119                 .size())
120               return;
121           }
122         }
123         cdbs.getTable(tableName).addPkCacheEntry(request.getPkValue(), qe);
124       }
125     }
126   }
127
128   /**
129    * @see org.objectweb.cjdbc.controller.cache.result.AbstractResultCache#isUpdateNecessary(org.objectweb.cjdbc.common.sql.UpdateRequest)
130    */

131   public boolean isUpdateNecessary(UpdateRequest request)
132   {
133     if (request.getCacheAbility() != RequestType.UNIQUE_CACHEABLE)
134       return true;
135     CacheDatabaseTable cacheTable = cdbs.getTable(request.getTableName());
136     if (request.getColumns() == null)
137       return true;
138     String JavaDoc pk = request.getPk();
139     AbstractResultCacheEntry qce = cacheTable.getPkResultCacheEntry(pk);
140     if (qce != null)
141     {
142       if (!qce.isValid())
143         return true;
144       ControllerResultSet rs = qce.getResult();
145       if (rs == null)
146         return true;
147       else
148         return needInvalidate(rs, request)[1];
149     }
150     else
151       return true;
152   }
153
154   /**
155    * @see org.objectweb.cjdbc.controller.cache.result.ResultCache#processWriteNotify(org.objectweb.cjdbc.common.sql.AbstractWriteRequest)
156    */

157   protected void processWriteNotify(AbstractWriteRequest request)
158   {
159     // Sanity check
160
CacheDatabaseTable cacheTable = cdbs.getTable(request.getTableName());
161     if (request.getColumns() == null)
162     {
163       logger.warn("No column parsing found - Fallback to table granularity ("
164           + request.getSQL() + ")");
165       cacheTable.invalidateAll();
166       return;
167     }
168     if (request.isInsert())
169     {
170       for (Iterator JavaDoc i = request.getColumns().iterator(); i.hasNext();)
171       {
172         TableColumn tc = (TableColumn) i.next();
173         cdbs.getTable(tc.getTableName()).getColumn(tc.getColumnName())
174             .invalidateAllNonUnique();
175       }
176     }
177     else
178     {
179       if (request.getCacheAbility() == RequestType.UNIQUE_CACHEABLE)
180       {
181         if (request.isUpdate())
182         {
183           String JavaDoc pk = ((UpdateRequest) request).getPk();
184           AbstractResultCacheEntry qce = cacheTable.getPkResultCacheEntry(pk);
185           if (qce != null)
186           {
187             boolean[] invalidate = needInvalidate(qce.getResult(),
188                 (UpdateRequest) request);
189             if (invalidate[0])
190             { // We must invalidate this entry
191
cacheTable.removePkResultCacheEntry(pk);
192               return;
193             }
194             else
195             {
196               if (logger.isDebugEnabled())
197                 logger.debug("No invalidate needed for request:"
198                     + request.getSQLShortForm(20));
199               return; // We don't need to invalidate
200
}
201           }
202         }
203         else if (request.isDelete())
204         { // Invalidate the corresponding cache entry
205
cacheTable
206               .removePkResultCacheEntry(((DeleteRequest) request).getPk());
207           return;
208         }
209       }
210       // At this point this is a non unique write query or a request
211
// we didn't handle properly (unknown request for example)
212
for (Iterator JavaDoc i = request.getColumns().iterator(); i.hasNext();)
213       {
214         TableColumn tc = (TableColumn) i.next();
215         CacheDatabaseTable table = cdbs.getTable(tc.getTableName());
216         table.invalidateAll(); // Pk are associated to tables
217
if (!request.isAlter())
218           table.getColumn(tc.getColumnName()).invalidateAll();
219       }
220     }
221   }
222
223   /**
224    * @see org.objectweb.cjdbc.controller.cache.result.ResultCache#getName()
225    */

226   public String JavaDoc getName()
227   {
228     return "columnUnique";
229   }
230
231 }
Popular Tags