1 package com.jofti.store; 2 3 import java.io.File ; 4 import java.io.FileNotFoundException ; 5 import java.io.IOException ; 6 import java.util.Properties ; 7 8 import org.apache.commons.logging.Log; 9 import org.apache.commons.logging.LogConfigurationException; 10 import org.apache.commons.logging.LogFactory; 11 12 13 import com.jofti.exception.InsufficientSpaceException; 14 import com.jofti.exception.JoftiException; 15 16 import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue; 17 18 29 class FileManager { 30 31 private static Log log = LogFactory.getLog(FileManager.class); 32 33 private Object recordLock = new Object (); 35 36 37 42 FileStore[] fileSet = null; 43 44 49 long[] unallocatedBlocks = null; 50 51 55 long[] filePositions = null; 56 57 61 FileStore currentStore = null; 62 63 protected LinkedBlockingQueue removedBlockQueue = new LinkedBlockingQueue(); 66 private int maxFiles = 10; 68 69 private long maxSize = 0; 71 72 76 protected String OVERFLOW_DIRECTORY = "overflow-directory"; 77 78 protected String fileName = "jofti"; 79 80 protected String extension = "str"; 81 82 protected String logFileDirectory = "../tmp"; 83 84 private Properties props = null; 85 86 int blockSize = 0; 88 89 int payloadSize = 0; 91 92 93 FileManager() { 94 95 } 96 97 void init(int blockSize, String directory, String fileName, long size, 98 int maxFiles) throws JoftiException 99 { 100 101 103 this.blockSize = blockSize; 104 this.logFileDirectory = directory; 105 this.fileName = fileName; 106 this.maxSize = size; 107 this.maxFiles = maxFiles; 108 109 try { 111 open(); 112 } catch (Exception e) { 113 throw new JoftiException(e); 114 } 115 116 unallocatedBlocks = new long[fileSet.length]; 118 filePositions = new long[fileSet.length]; 119 120 long initialBlocks = maxSize / blockSize; 121 122 for (int i = 0; i < fileSet.length; i++) { 124 unallocatedBlocks[i] = initialBlocks; 125 } 126 127 payloadSize = blockSize 129 - (BlockBuffer.bufferHeaderSize + BlockBuffer.bufferFooterSize); 130 131 } 132 133 134 public synchronized void reset(){ 135 unallocatedBlocks = new long[fileSet.length]; 137 filePositions = new long[fileSet.length]; 138 139 long initialBlocks = maxSize / blockSize; 140 141 for (int i = 0; i < fileSet.length; i++) { 143 unallocatedBlocks[i] = initialBlocks; 144 } 145 removedBlockQueue.clear(); 146 } 147 156 public FilePositionHolder[] allocateBlocks(FilePositionHolder[] blocks, 157 int size) throws JoftiException 158 { 159 160 FilePositionHolder[] returnBlocks = null; 161 162 if (size == 0) { 164 return blocks; 165 } 166 167 int keysNeeded = size / payloadSize; 169 int remainder = size % payloadSize; 170 171 if (remainder != 0) { 173 keysNeeded++; 174 } 175 176 if (log.isDebugEnabled()) { 177 log.debug("payloadSize " + payloadSize + " number keys needed " 178 + keysNeeded + " for data size:" + size); 179 } 180 181 183 try { 184 returnBlocks = allocateRecords(blocks, keysNeeded); 185 } catch (Exception e) { 186 throw new JoftiException(e); 187 } 188 189 return returnBlocks; 190 191 } 192 193 private FilePositionHolder[] allocateRecords(FilePositionHolder[] blocks, 194 int number) throws InsufficientSpaceException, Exception 195 { 196 197 int originalRecordNumber = 0; 198 FilePositionHolder[] temp = null; 199 200 if (blocks != null) { 201 originalRecordNumber += blocks.length; 202 } 203 204 if (number == originalRecordNumber) { 205 temp = blocks; 207 } else if (number < originalRecordNumber) { 208 210 temp = new FilePositionHolder[number]; 211 212 for (int i = 0; i < blocks.length; i++) { 214 if (i < number) { 215 temp[i] = blocks[i]; 216 } else { 217 removedBlockQueue.put(blocks[i]); 218 } 219 220 } 221 return temp; 222 } 223 224 else if (number > originalRecordNumber) { 226 227 temp = new FilePositionHolder[number]; 229 231 System.arraycopy(blocks, 0, temp, 0, blocks.length); 232 233 for (int i = blocks.length; i < temp.length; i++) { 234 236 temp[i] = getNextPosition(); 237 } 238 239 } 240 return temp; 241 242 } 243 244 public void removePosition(FilePositionHolder holder) throws JoftiException { 245 removedBlockQueue.offer(holder); 246 } 247 248 public FilePositionHolder getNextPosition() throws JoftiException { 249 FileStore file = null; 250 251 FilePositionHolder fileHolder = null; 253 254 255 fileHolder = (FilePositionHolder) removedBlockQueue.poll(); 256 257 258 if (fileHolder != null) { 259 return fileHolder; 260 } 261 262 263 file = currentStore; 264 265 int marker = file.fileId; 267 long position = 0; 268 269 do { 270 synchronized (recordLock) { 271 if (unallocatedBlocks[file.fileId] > 0) { 272 position = filePositions[file.fileId]; 273 fileHolder = new FilePositionHolder(file.fileId, position); 274 filePositions[file.fileId] = position + blockSize; 275 unallocatedBlocks[file.fileId]--; 276 277 if (file.fileId == unallocatedBlocks.length - 1) { 279 currentStore = getFileStore(0); 280 } else { 281 currentStore = getFileStore(file.fileId + 1); 282 } 283 return fileHolder; 284 } else { 285 286 file = getFileStore(file.fileId + 1); 288 289 if (file != null) { 290 currentStore = file; 291 if (log.isInfoEnabled()) { 292 log.info("Storing in:" + file.fileId 293 + " moving to next store"); 294 } 295 } 296 } 297 } 298 } while (file != null && file.fileId != marker); 300 302 throw new JoftiException("No space available in any file"); 303 } 304 305 306 FileStore getFileStore(int id) { 307 FileStore lf = null; 308 int fsl = fileSet.length; 309 310 if (id >= fsl) { 311 return null; 312 } else { 313 return fileSet[id]; 314 } 315 316 } 317 318 319 327 void open() throws JoftiException, IOException , FileNotFoundException , 328 JoftiException 329 { 330 331 String logDir = logFileDirectory; 333 String logFileName = fileName; 334 String logFileExt = extension; 335 336 File dir = new File (logDir); 338 dir.mkdirs(); 339 340 int existingFiles = 0; 341 342 fileSet = new FileStore[maxFiles]; 344 for (int i = 0; i < maxFiles; ++i) { 345 File name = new File (logDir + "/" + logFileName + "_" + (i + 1) 346 + "." + logFileExt); 347 if (name.exists()) { 348 name.delete(); 349 name.createNewFile(); 350 } 351 352 try { 353 fileSet[i] = new FileStore(name, i).open("rw"); 354 355 } catch (FileNotFoundException e) { 356 while (--i >= 0) { 357 fileSet[i].close(); 358 fileSet[i] = null; 359 } 360 361 throw e; 362 } 363 364 } 365 currentStore = fileSet[0]; 366 367 } 368 369 376 void close() throws IOException , InterruptedException { 377 378 if (fileSet == null) 379 return; 380 381 for (int i = 0; i < fileSet.length; ++i) { 383 if (fileSet[i] != null) 384 fileSet[i].close(); 385 } 386 387 } 388 389 } | Popular Tags |