001: /**
002: * Sequoia: Database clustering technology.
003: * Copyright (C) 2002-2004 French National Institute For Research In Computer
004: * Science And Control (INRIA).
005: * Copyright (C) 2005 AmicoSoft, Inc. dba Emic Networks
006: * Contact: sequoia@continuent.org
007: *
008: * Licensed under the Apache License, Version 2.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: * Initial developer(s): Emmanuel Cecchet.
021: * Contributor(s): Julie Marguerite, Sara Bouchenak.
022: */package org.continuent.sequoia.controller.cache.result.schema;
023:
024: import java.util.ArrayList;
025: import java.util.Hashtable;
026: import java.util.Iterator;
027:
028: import org.continuent.sequoia.controller.cache.result.entries.AbstractResultCacheEntry;
029: import org.continuent.sequoia.controller.requests.RequestType;
030: import org.continuent.sequoia.controller.requests.SelectRequest;
031:
032: /**
033: * A <code>CacheDatabaseColumn</code> represents a column of a database table.
034: * It is composed of a <code>DatabaseColumn</code> object and an
035: * <code>ArrayList</code> of cache entries.
036: *
037: * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
038: * @author <a href="mailto:Julie.Marguerite@inria.fr">Julie Marguerite </a>
039: * @author <a href="mailto:Sara.Bouchenak@epfl.ch">Sara Bouchenak </a>
040: * @version 1.0
041: */
042: public class CacheDatabaseColumn {
043: private String name;
044: private ArrayList cacheEntries;
045:
046: /**
047: * Creates a new <code>CacheDatabaseColumn</code> instance.
048: *
049: * @param name name of the column
050: */
051: public CacheDatabaseColumn(String name) {
052: this .name = name;
053: cacheEntries = new ArrayList();
054: }
055:
056: /**
057: * Gets the column name.
058: *
059: * @return the column name
060: */
061: public String getName() {
062: return name;
063: }
064:
065: /**
066: * Two <code>CacheDatabaseColumn</code> are equals if they have the same
067: * <code>DatabaseColumn</code>.
068: *
069: * @param other the object to compare with
070: * @return <code>true</code> if the objects are the same
071: */
072: public boolean equals(Object other) {
073: if (!(other instanceof CacheDatabaseColumn))
074: return false;
075:
076: return name.equals(((CacheDatabaseColumn) other).getName());
077: }
078:
079: /**
080: * Adds an <code>AbstractResultCacheEntry</code> object whose consistency
081: * depends on this column.
082: *
083: * @param ce a <code>AbstractResultCacheEntry</code> value
084: */
085: public synchronized void addCacheEntry(AbstractResultCacheEntry ce) {
086: cacheEntries.add(ce);
087: }
088:
089: /**
090: * Marks dirty all valid cache entries depending on this colum that are non
091: * unique.
092: */
093: public synchronized void markDirtyAllNonUnique() {
094: // Do not try to optimize by moving cacheEntries.size()
095: // out of the for statement
096: for (int i = 0; i < cacheEntries.size(); i++) {
097: AbstractResultCacheEntry ce = (AbstractResultCacheEntry) cacheEntries
098: .get(i);
099: if ((ce.getRequest().getCacheAbility() != RequestType.UNIQUE_CACHEABLE)
100: && ce.isValid())
101: ce.markDirty();
102: }
103: }
104:
105: /**
106: * Invalidates all cache entries depending on this column.
107: */
108: public synchronized void invalidateAll() {
109: for (Iterator i = cacheEntries.iterator(); i.hasNext();) {
110: AbstractResultCacheEntry entry = (AbstractResultCacheEntry) i
111: .next();
112: entry.invalidate();
113: }
114: cacheEntries.clear();
115: }
116:
117: /**
118: * Invalidates all cache entries depending on this column that are non
119: * <code>UNIQUE</code>.
120: */
121: public synchronized void invalidateAllNonUnique() {
122: // Do not try to optimize by moving cacheEntries.size()
123: // out of the for statement
124: for (int i = 0; i < cacheEntries.size();) {
125: AbstractResultCacheEntry ce = (AbstractResultCacheEntry) cacheEntries
126: .get(i);
127: if (ce.getRequest().getCacheAbility() != RequestType.UNIQUE_CACHEABLE) {
128: ce.invalidate();
129: cacheEntries.remove(i);
130: } else {
131: i++;
132: }
133: }
134: }
135:
136: /**
137: * Invalidates all cache entries depending on this column that are either non-
138: * unique or unique and associated with given values.
139: *
140: * @param val a <code>String</code> representing the value of the current
141: * column.
142: * @param columns an <code>ArrayList</code> of CacheDatabaseColumn objects
143: * @param values an <code>ArrayList</code> of String objects representing
144: * values.
145: */
146: public synchronized void invalidateAllUniqueWithValuesAndAllNonUnique(
147: String val, ArrayList columns, ArrayList values) {
148: // Do not try to optimize by moving cacheEntries.size()
149: // out of the for statement
150: for (int i = 0; i < cacheEntries.size();) {
151: AbstractResultCacheEntry ce = (AbstractResultCacheEntry) cacheEntries
152: .get(i);
153: if (ce.getRequest().getCacheAbility() == RequestType.UNIQUE_CACHEABLE) {
154: Hashtable queryValues;
155: String value, v;
156: SelectRequest query;
157: int size, j;
158:
159: query = ce.getRequest();
160: queryValues = query.getWhereValues();
161: // queryValues != null in a UNIQUE_CACHEABLE request
162: value = (String) queryValues.get(this .name);
163: if (value.compareToIgnoreCase(val) == 0) {
164: // The value associated with this column in the WHERE clause
165: // of the UNIQUE SELECT query equals val:
166: // Check if the values associated with the other columns are equal.
167: size = values.size();
168: j = 0;
169: for (Iterator it = columns.iterator(); it.hasNext()
170: && (j < size); j++) {
171: CacheDatabaseColumn cdc = (CacheDatabaseColumn) it
172: .next();
173: if (!this .equals(cdc)) {
174: v = (String) values.get(j);
175: value = (String) queryValues.get(cdc
176: .getName());
177: if (value.compareToIgnoreCase(v) != 0) {
178: // UNIQUE_CACHEABLE request with a different value
179: // Do not invalidate it
180: return;
181: }
182: }
183: }
184: // UNIQUE_CACHEABLE request with same values
185: // Invalidate it
186: ce.invalidate();
187: cacheEntries.remove(i);
188: } else {
189: // UNIQUE_CACHEABLE request with a different value
190: // Do not invalidate it
191: i++;
192: }
193: } else {
194: // NON UNIQUE_CACHEABLE request
195: // Invalidate it
196: ce.invalidate();
197: cacheEntries.remove(i);
198: }
199: }
200: }
201:
202: /**
203: * Invalidates all cache entries depending on this column that are non
204: * <code>UNIQUE</code> and mark dirty <code>UNIQUE</code> queries.
205: */
206: public synchronized void invalidateAllNonUniqueAndMarkDirtyUnique() {
207: // Do not try to optimize by moving cacheEntries.size()
208: // out of the for statement
209: for (int i = 0; i < cacheEntries.size(); i++) {
210: AbstractResultCacheEntry ce = (AbstractResultCacheEntry) cacheEntries
211: .get(i);
212: if ((ce.getRequest().getCacheAbility() != RequestType.UNIQUE_CACHEABLE)
213: && ce.isValid())
214: ce.markDirty();
215: else {
216: ce.invalidate();
217: cacheEntries.remove(i);
218: }
219: }
220: }
221:
222: /**
223: * Returns the column name.
224: *
225: * @return a <code>String</code> value
226: */
227: public String getInformation() {
228: return name;
229: }
230: }
|