00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 package org.objectweb.cjdbc.controller.cache.metadata;
00026
00027 import java.util.Hashtable;
00028
00029 import org.objectweb.cjdbc.common.i18n.Translate;
00030 import org.objectweb.cjdbc.common.log.Trace;
00031 import org.objectweb.cjdbc.common.sql.AbstractRequest;
00032 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags;
00033 import org.objectweb.cjdbc.driver.Field;
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 public class MetadataCache
00045 {
00046 private static Trace logger = Trace.getLogger(MetadataCache.class.getName());
00047 private Hashtable metadataCache;
00048 private Hashtable fieldCache;
00049 private int maxNbOfMetadata;
00050 private int maxNbOfField;
00051
00052
00053
00054
00055
00056
00057
00058 public MetadataCache(int maxNbOfMetadata, int maxNbOfField)
00059 {
00060 metadataCache = new Hashtable(maxNbOfMetadata == 0
00061 ? 10000
00062 : maxNbOfMetadata);
00063 fieldCache = new Hashtable(maxNbOfField == 0 ? 100 : maxNbOfField);
00064 if (maxNbOfMetadata < 0)
00065 throw new RuntimeException(Translate.get("cache.metadata.invalid.size",
00066 maxNbOfMetadata));
00067 if (maxNbOfMetadata == 0)
00068 this.maxNbOfMetadata = Integer.MAX_VALUE;
00069 else
00070 this.maxNbOfMetadata = maxNbOfMetadata;
00071 if (maxNbOfField < 0)
00072 throw new RuntimeException(Translate.get("cache.metadata.invalid.size",
00073 maxNbOfField));
00074 if (maxNbOfField == 0)
00075 this.maxNbOfField = Integer.MAX_VALUE;
00076 else
00077 this.maxNbOfField = maxNbOfField;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 public Field[] getMetadata(AbstractRequest request)
00089 {
00090 String sqlSkeleton = request.getSqlSkeleton();
00091 if (sqlSkeleton != null)
00092 return (Field[]) metadataCache.get(sqlSkeleton);
00093 else
00094 return (Field[]) metadataCache.get(request.getSQL());
00095 }
00096
00097
00098
00099
00100
00101
00102
00103 public void addMetadata(AbstractRequest request, Field[] metadata)
00104 {
00105
00106
00107
00108
00109 while (metadataCache.size() > maxNbOfMetadata)
00110 {
00111
00112
00113 synchronized (metadataCache)
00114 {
00115 try
00116 {
00117 metadataCache.remove(metadataCache.keys().nextElement());
00118 }
00119 catch (Exception ignore)
00120 {
00121 break;
00122 }
00123 }
00124 }
00125
00126
00127 try
00128 {
00129 String sqlSkeleton = request.getSqlSkeleton();
00130 if (sqlSkeleton != null)
00131 metadataCache.put(sqlSkeleton, metadata);
00132 else
00133 metadataCache.put(request.getSQL(), metadata);
00134 }
00135 catch (OutOfMemoryError oome)
00136 {
00137 synchronized (metadataCache)
00138 {
00139 metadataCache.clear();
00140 }
00141 System.gc();
00142 logger.warn(Translate.get("cache.memory.error.cache.flushed", this
00143 .getClass()));
00144 }
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 public Field getField(String fullyQualifiedFieldName)
00156 {
00157 return (Field) fieldCache.get(fullyQualifiedFieldName);
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167 public void addField(String fullyQualifiedFieldName, Field field)
00168 {
00169
00170
00171
00172
00173 while (fieldCache.size() > maxNbOfField)
00174 {
00175
00176
00177 synchronized (fieldCache)
00178 {
00179 try
00180 {
00181 fieldCache.remove(fieldCache.keys().nextElement());
00182 }
00183 catch (Exception ignore)
00184 {
00185 break;
00186 }
00187 }
00188 }
00189
00190 try
00191 {
00192 fieldCache.put(fullyQualifiedFieldName, field);
00193 }
00194 catch (OutOfMemoryError oome)
00195 {
00196 synchronized (fieldCache)
00197 {
00198 fieldCache.clear();
00199 }
00200 System.gc();
00201 logger.warn(Translate.get("cache.memory.error.cache.flushed", this
00202 .getClass()));
00203 }
00204 }
00205
00206
00207
00208
00209
00210
00211 public String getXml()
00212 {
00213 return "<" + DatabasesXmlTags.ELT_MetadataCache + " "
00214 + DatabasesXmlTags.ATT_maxNbOfMetadata + "=\"" + maxNbOfMetadata
00215 + "\" " + DatabasesXmlTags.ATT_maxNbOfField + "=\""
00216 + (maxNbOfField == Integer.MAX_VALUE ? 0 : maxNbOfField) + "\"/>";
00217 }
00218
00219 }