1 30 31 32 package org.hsqldb.persist; 33 34 import java.io.IOException ; 35 36 import org.hsqldb.Trace; 37 import org.hsqldb.lib.Iterator; 38 import org.hsqldb.lib.ObjectComparator; 39 import org.hsqldb.lib.Sort; 40 import org.hsqldb.lib.StopWatch; 41 import org.hsqldb.store.ObjectCacheHashMap; 42 43 54 public class Cache { 55 56 final DataFileCache dataFileCache; 57 private int capacity; private long bytesCapacity; private final CachedObjectComparator rowComparator; 60 61 private CachedObject[] rowTable; 63 64 private final ObjectCacheHashMap cacheMap; 66 long cacheBytesLength; 67 68 StopWatch saveAllTimer = new StopWatch(false); 70 StopWatch makeRowTimer = new StopWatch(false); 71 StopWatch sortTimer = new StopWatch(false); 72 int makeRowCount = 0; 73 int saveRowCount = 0; 74 75 Cache(DataFileCache dfc) { 76 77 dataFileCache = dfc; 78 capacity = dfc.capacity(); 79 bytesCapacity = dfc.bytesCapacity(); 80 rowComparator = new CachedObjectComparator(); 81 rowTable = new CachedObject[capacity]; 82 cacheMap = new ObjectCacheHashMap(capacity); 83 cacheBytesLength = 0; 84 } 85 86 90 void init(int capacity, long bytesCapacity) {} 91 92 int size() { 93 return cacheMap.size(); 94 } 95 96 long getTotalCachedBlockSize() { 97 return cacheBytesLength; 98 } 99 100 103 synchronized CachedObject get(int pos) { 104 return (CachedObject) cacheMap.get(pos); 105 } 106 107 110 synchronized void put(int key, 111 CachedObject row) throws IOException { 112 113 int storageSize = row.getStorageSize(); 114 115 if (cacheMap.size() >= capacity 116 || storageSize + cacheBytesLength > bytesCapacity) { 117 cleanUp(); 118 } 119 120 cacheMap.put(key, row); 121 122 cacheBytesLength += storageSize; 123 } 124 125 128 synchronized CachedObject release(int i) { 129 130 CachedObject r = (CachedObject) cacheMap.remove(i); 131 132 if (r == null) { 133 return null; 134 } 135 136 cacheBytesLength -= r.getStorageSize(); 137 138 return r; 139 } 140 141 151 private synchronized void cleanUp() throws IOException { 152 153 int removeCount = cacheMap.size() / 2; 154 int accessTarget = cacheMap.getAccessCountCeiling(removeCount, 155 removeCount / 8); 156 ObjectCacheHashMap.ObjectCacheIterator it = cacheMap.iterator(); 157 int savecount = 0; 158 159 for (; it.hasNext(); ) { 160 CachedObject r = (CachedObject) it.next(); 161 162 if (it.getAccessCount() <= accessTarget) { 163 if (!r.isKeepInMemory()) { 164 if (r.hasChanged()) { 165 rowTable[savecount++] = r; 166 } 167 168 it.remove(); 169 170 cacheBytesLength -= r.getStorageSize(); 171 } 172 } 173 } 174 175 cacheMap.setAccessCountFloor(accessTarget); 176 saveRows(savecount); 177 } 178 179 private synchronized void saveRows(int count) throws IOException { 180 181 if (count == 0) { 182 return; 183 } 184 185 rowComparator.setType(rowComparator.COMPARE_POSITION); 186 sortTimer.start(); 187 Sort.sort(rowTable, rowComparator, 0, count - 1); 188 sortTimer.stop(); 189 saveAllTimer.start(); 190 dataFileCache.saveRows(rowTable, 0, count); 191 192 saveRowCount += count; 193 194 200 saveAllTimer.stop(); 201 } 202 203 206 synchronized void saveAll() throws IOException { 207 208 Iterator it = cacheMap.iterator(); 209 int savecount = 0; 210 211 for (; it.hasNext(); ) { 212 CachedObject r = (CachedObject) it.next(); 213 214 if (r.hasChanged()) { 215 rowTable[savecount++] = r; 216 } 217 } 218 219 saveRows(savecount); 220 Trace.printSystemOut( 221 saveAllTimer.elapsedTimeToMessage( 222 "Cache.saveRow() total row save time")); 223 Trace.printSystemOut("Cache.saveRow() total row save count = " 224 + saveRowCount); 225 Trace.printSystemOut( 226 makeRowTimer.elapsedTimeToMessage( 227 "Cache.makeRow() total row load time")); 228 Trace.printSystemOut("Cache.makeRow() total row load count = " 229 + makeRowCount); 230 Trace.printSystemOut( 231 sortTimer.elapsedTimeToMessage("Cache.sort() total time")); 232 } 233 234 237 synchronized void clear() { 238 239 cacheMap.clear(); 240 241 cacheBytesLength = 0; 242 } 243 244 static class CachedObjectComparator implements ObjectComparator { 245 246 static final int COMPARE_LAST_ACCESS = 0; 247 static final int COMPARE_POSITION = 1; 248 static final int COMPARE_SIZE = 2; 249 private int compareType; 250 251 CachedObjectComparator() {} 252 253 void setType(int type) { 254 compareType = type; 255 } 256 257 public int compare(Object a, Object b) { 258 259 switch (compareType) { 260 261 case COMPARE_POSITION : 262 return ((CachedObject) a).getPos() 263 - ((CachedObject) b).getPos(); 264 265 case COMPARE_SIZE : 266 return ((CachedObject) a).getStorageSize() 267 - ((CachedObject) b).getStorageSize(); 268 269 default : 270 return 0; 271 } 272 } 273 } 274 } 275 | Popular Tags |