1 8 9 package com.sleepycat.je.log; 10 11 import java.io.IOException ; 12 import java.nio.ByteBuffer ; 13 import java.util.Iterator ; 14 import java.util.LinkedList ; 15 16 import com.sleepycat.je.DatabaseException; 17 import com.sleepycat.je.EnvironmentStats; 18 import com.sleepycat.je.StatsConfig; 19 import com.sleepycat.je.config.EnvironmentParams; 20 import com.sleepycat.je.dbi.DbConfigManager; 21 import com.sleepycat.je.dbi.EnvironmentImpl; 22 import com.sleepycat.je.latch.Latch; 23 import com.sleepycat.je.latch.LatchSupport; 24 25 28 class LogBufferPool { 29 private static final String DEBUG_NAME = LogBufferPool.class.getName(); 30 31 private EnvironmentImpl envImpl = null; 32 private int logBufferSize; private LinkedList bufferPool; 35 36 private LogBuffer currentWriteBuffer; 37 38 private FileManager fileManager; 39 40 41 private long nNotResident = 0; private long nCacheMiss = 0; private boolean runInMemory; 44 45 59 private Latch bufferPoolLatch; 60 61 LogBufferPool(FileManager fileManager, 62 EnvironmentImpl envImpl) 63 throws DatabaseException { 64 65 this.fileManager = fileManager; 66 this.envImpl = envImpl; 67 bufferPoolLatch = 68 LatchSupport.makeLatch(DEBUG_NAME + "_FullLatch", envImpl); 69 70 71 DbConfigManager configManager = envImpl.getConfigManager(); 72 runInMemory = envImpl.isMemOnly(); 73 reset(configManager); 74 75 76 currentWriteBuffer = (LogBuffer) bufferPool.getFirst(); 77 } 78 79 final int getLogBufferSize() { 80 return logBufferSize; 81 } 82 83 87 void reset(DbConfigManager configManager) 88 throws DatabaseException { 89 90 94 if (runInMemory && bufferPool != null) { 95 return; 96 } 97 98 102 int numBuffers = 103 configManager.getInt(EnvironmentParams.NUM_LOG_BUFFERS); 104 long logBufferBudget = envImpl.getMemoryBudget().getLogBufferBudget(); 105 106 107 int newBufferSize = (int) logBufferBudget / numBuffers; 108 109 110 LinkedList newPool = new LinkedList (); 111 112 116 if (runInMemory) { 117 numBuffers = 1; 118 } 119 120 for (int i = 0; i < numBuffers; i++) { 121 newPool.add(new LogBuffer(newBufferSize, envImpl)); 122 } 123 124 137 bufferPoolLatch.acquire(); 138 bufferPool = newPool; 139 logBufferSize = newBufferSize; 140 bufferPoolLatch.release(); 141 } 142 143 150 LogBuffer getWriteBuffer(int sizeNeeded, boolean flippedFile) 151 throws IOException , DatabaseException { 152 153 160 if ((!currentWriteBuffer.hasRoom(sizeNeeded)) || flippedFile) { 161 162 166 writeBufferToFile(sizeNeeded); 167 } 168 169 if (flippedFile) { 170 171 if (!runInMemory) { 172 fileManager.syncLogEndAndFinishFile(); 173 } 174 } 175 176 return currentWriteBuffer; 177 } 178 179 187 void writeBufferToFile(int sizeNeeded) 188 throws IOException , DatabaseException { 189 190 int bufferSize = 191 ((logBufferSize > sizeNeeded) ? logBufferSize : sizeNeeded); 192 193 194 currentWriteBuffer.latchForWrite(); 195 LogBuffer latchedBuffer = currentWriteBuffer; 196 try { 197 ByteBuffer currentByteBuffer = currentWriteBuffer.getDataBuffer(); 198 int savePosition = currentByteBuffer.position(); 199 int saveLimit = currentByteBuffer.limit(); 200 currentByteBuffer.flip(); 201 202 203 if (runInMemory) { 204 205 latchedBuffer.release(); 206 latchedBuffer = null; 207 208 bufferPoolLatch.acquire(); 209 currentWriteBuffer = new LogBuffer(bufferSize, envImpl); 210 bufferPool.add(currentWriteBuffer); 211 bufferPoolLatch.release(); 212 } else { 213 214 218 try { 219 fileManager.writeLogBuffer(currentWriteBuffer); 220 221 222 currentWriteBuffer.getDataBuffer().rewind(); 223 224 225 latchedBuffer.release(); 226 latchedBuffer = null; 227 228 232 LogBuffer nextToUse = null; 233 try { 234 bufferPoolLatch.acquire(); 235 Iterator iter = bufferPool.iterator(); 236 nextToUse = (LogBuffer) iter.next(); 237 238 boolean done = bufferPool.remove(nextToUse); 239 assert done; 240 nextToUse.reinit(); 241 242 243 bufferPool.add(nextToUse); 244 245 246 currentWriteBuffer = nextToUse; 247 } finally { 248 bufferPoolLatch.releaseIfOwner(); 249 } 250 } catch (DatabaseException DE) { 251 currentByteBuffer.position(savePosition); 252 currentByteBuffer.limit(saveLimit); 253 throw DE; 254 } 255 } 256 } finally { 257 if (latchedBuffer != null) { 258 latchedBuffer.release(); 259 } 260 } 261 } 262 263 270 void writeCompleted(long lsn, boolean flushRequired) 271 throws DatabaseException, IOException { 272 273 currentWriteBuffer.registerLsn(lsn); 274 if (flushRequired) { 275 writeBufferToFile(0); 276 } 277 } 278 279 284 LogBuffer getReadBuffer(long lsn) 285 throws DatabaseException { 286 287 LogBuffer foundBuffer = null; 288 289 bufferPoolLatch.acquire(); 290 try { 291 nNotResident++; 292 Iterator iter = bufferPool.iterator(); 293 while (iter.hasNext()) { 294 LogBuffer l = (LogBuffer) iter.next(); 295 if (l.containsLsn(lsn)) { 296 foundBuffer = l; 297 break; 298 } 299 } 300 301 305 if (foundBuffer == null && 306 currentWriteBuffer.containsLsn(lsn)) { 307 foundBuffer = currentWriteBuffer; 308 } 309 310 if (foundBuffer == null) { 311 nCacheMiss++; 312 } 313 314 } finally { 315 bufferPoolLatch.releaseIfOwner(); 316 } 317 318 if (foundBuffer == null) { 319 return null; 320 } else { 321 return foundBuffer; 322 } 323 } 324 325 void loadStats(StatsConfig config, EnvironmentStats stats) 326 throws DatabaseException { 327 328 stats.setNCacheMiss(nCacheMiss); 329 stats.setNNotResident(nNotResident); 330 if (config.getClear()) { 331 nCacheMiss = 0; 332 nNotResident = 0; 333 } 334 335 336 bufferPoolLatch.acquire(); 337 long bufferBytes = 0; 338 int nLogBuffers = 0; 339 try { 340 Iterator iter = bufferPool.iterator(); 341 while (iter.hasNext()) { 342 LogBuffer l = (LogBuffer) iter.next(); 343 nLogBuffers++; 344 bufferBytes += l.getCapacity(); 345 } 346 } finally { 347 bufferPoolLatch.release(); 348 } 349 stats.setNLogBuffers(nLogBuffers); 350 stats.setBufferBytes(bufferBytes); 351 } 352 } 353 | Popular Tags |