Coverage Report - org.jscsi.target.storage.FileStorageModule
 
Classes in this File Line Coverage Branch Coverage Complexity
FileStorageModule
0%
0/60
0%
0/26
3.667
 
 1  
 package org.jscsi.target.storage;
 2  
 
 3  
 
 4  
 import java.io.File;
 5  
 import java.io.IOException;
 6  
 import java.nio.file.Files;
 7  
 
 8  
 import com.google.common.cache.Cache;
 9  
 import com.google.common.cache.CacheBuilder;
 10  
 
 11  
 
 12  
 /**
 13  
  * This file storage is used for faster access within the treetank iscsi module.
 14  
  * 
 15  
  * @author Andreas Rain
 16  
  * 
 17  
  */
 18  
 @Deprecated
 19  
 public class FileStorageModule implements IStorageModule {
 20  
 
 21  
     /** The base directory for the storage. */
 22  
     private final String mBaseDir;
 23  
 
 24  
     /** Size of the storage in bytes */
 25  
     private final long mStorageSize;
 26  
 
 27  
     /** Filesize for each file (can be used to reflect nodes) */
 28  
     private final int mFileSize;
 29  
 
 30  
     /** File cache */
 31  
     private Cache<Integer , byte[]> mCache;
 32  
 
 33  
     /** How many file contents have to be cached. */
 34  
     private final int CACHE_SIZE;
 35  
 
 36  
     /**
 37  
      * @param pBaseDir - The root directory for the filestorage (will be created if not exists)
 38  
      * @param pStorageSize - The size of the storage
 39  
      * @param pFileSize - The size of each file
 40  
      * @throws IOException
 41  
      */
 42  
     public FileStorageModule (String pBaseDir, long pStorageSize, int pFileSize) throws IOException {
 43  0
         super();
 44  0
         mBaseDir = pBaseDir;
 45  0
         mFileSize = pFileSize;
 46  0
         mStorageSize = pStorageSize;
 47  
 
 48  
         // 256MB cache since 256MB / pFileSize byte is the amount of files cached.
 49  0
         CACHE_SIZE = 1024 * 1024 * 256 / pFileSize;
 50  
 
 51  0
         File file = new File(pBaseDir);
 52  0
         if (!file.exists()) {
 53  0
             file.mkdirs();
 54  0
         } else if (!file.isDirectory()) { throw new IOException("The parameter pBaseDir does not seem to be a directory."); }
 55  
 
 56  0
         mCache = CacheBuilder.newBuilder().maximumSize(CACHE_SIZE).build();
 57  0
     }
 58  
 
 59  
     /**
 60  
      * Reading bytes from file
 61  
      * 
 62  
      * @param bytes
 63  
      * @param storageIndex
 64  
      * @throws IOException
 65  
      */
 66  
     public void read (byte[] bytes, long storageIndex) throws IOException {
 67  
 
 68  0
         long filePos = storageIndex / mFileSize;
 69  0
         int storageOffset = (int) (storageIndex % mFileSize);
 70  0
         byte[] cachedBytes = mCache.getIfPresent(filePos);
 71  
 
 72  0
         File fileAtPos = new File(mBaseDir + File.separator + filePos);
 73  0
         if (!fileAtPos.exists()) {
 74  0
             fileAtPos.createNewFile();
 75  0
             cachedBytes = new byte[mFileSize];
 76  0
             Files.write(fileAtPos.toPath(), cachedBytes);
 77  0
         } else if (cachedBytes == null) {
 78  0
             cachedBytes = Files.readAllBytes(fileAtPos.toPath());
 79  0
             mCache.put((int) filePos, cachedBytes);
 80  
         }
 81  
 
 82  0
         if ((storageOffset + bytes.length) > mFileSize) {
 83  0
             System.arraycopy(cachedBytes, storageOffset, bytes, 0, mFileSize - storageOffset);
 84  0
             byte[] nextStep = new byte[bytes.length - (mFileSize - storageOffset)];
 85  0
             read(nextStep, storageIndex + (mFileSize - storageOffset));
 86  0
             System.arraycopy(nextStep, 0, bytes, mFileSize - storageOffset, nextStep.length);
 87  0
         } else {
 88  0
             System.arraycopy(cachedBytes, storageOffset, bytes, 0, bytes.length);
 89  
         }
 90  
 
 91  0
     }
 92  
 
 93  
     /**
 94  
      * Writing into a file.
 95  
      * 
 96  
      * @param bytes
 97  
      * @param storageIndex
 98  
      * @throws IOException
 99  
      */
 100  
     public void write (byte[] bytes, long storageIndex) throws IOException {
 101  
 
 102  0
         long filePos = storageIndex / mFileSize;
 103  0
         boolean cached = true;
 104  0
         int storageOffset = (int) (storageIndex % mFileSize);
 105  0
         byte[] cachedBytes = mCache.getIfPresent(filePos);
 106  
 
 107  0
         File fileAtPos = new File(mBaseDir + File.separator + filePos);
 108  0
         if (!fileAtPos.exists()) {
 109  0
             fileAtPos.createNewFile();
 110  0
             cachedBytes = new byte[mFileSize];
 111  0
         } else if (cachedBytes == null) {
 112  0
             cachedBytes = Files.readAllBytes(fileAtPos.toPath());
 113  0
             cached = false;
 114  
         }
 115  
 
 116  0
         if ((storageOffset + bytes.length) > mFileSize) {
 117  0
             System.arraycopy(bytes, 0, cachedBytes, storageOffset, mFileSize - storageOffset);
 118  
 
 119  0
             Files.write(new File(mBaseDir + File.separator + filePos).toPath(), cachedBytes);
 120  
 
 121  0
             byte[] nextStep = new byte[bytes.length - (mFileSize - storageOffset)];
 122  0
             System.arraycopy(bytes, (mFileSize - storageOffset), nextStep, 0, bytes.length - (mFileSize - storageOffset));
 123  0
             write(nextStep, storageIndex + (mFileSize - storageOffset));
 124  0
         } else {
 125  0
             System.arraycopy(bytes, 0, cachedBytes, storageOffset, bytes.length);
 126  0
             Files.write(fileAtPos.toPath(), cachedBytes);
 127  
         }
 128  
 
 129  0
         if (!cached) {
 130  0
             mCache.put((int) filePos, cachedBytes);
 131  
         }
 132  
 
 133  0
     }
 134  
 
 135  
     /**
 136  
      * {@inheritDoc}
 137  
      */
 138  
     @Override
 139  
     public int checkBounds (long logicalBlockAddress, int transferLengthInBlocks) {
 140  
         // Checking if the logical block address is out of bounds
 141  0
         if (logicalBlockAddress < 0 || logicalBlockAddress >= getSizeInBlocks()) {
 142  0
             return 1;
 143  
         } else
 144  
         // if the logical block address is in bounds but the transferlength
 145  
         // either exceeds
 146  
         // the device size or is faulty return 2
 147  0
         if (transferLengthInBlocks < 0 || logicalBlockAddress + transferLengthInBlocks > getSizeInBlocks()) {
 148  0
             return 2;
 149  
         } else {
 150  0
             return 0;
 151  
         }
 152  
     }
 153  
 
 154  
     /**
 155  
      * {@inheritDoc}
 156  
      */
 157  
     @Override
 158  
     public long getSizeInBlocks () {
 159  0
         return mStorageSize / VIRTUAL_BLOCK_SIZE;
 160  
     }
 161  
 
 162  
     /**
 163  
      * {@inheritDoc}
 164  
      */
 165  
     @Override
 166  
     public void close () throws IOException {
 167  
         // Nothing to close, each bucket is opened individually.
 168  0
     }
 169  
 
 170  
 }