示例#1
0
 /**
  * Remove all stored blocks for the given id.
  *
  * @param id the id
  */
 public void remove(byte[] id) {
   ByteBuffer idBuffer = ByteBuffer.wrap(id);
   while (idBuffer.hasRemaining()) {
     switch (idBuffer.get()) {
       case 0:
         // in-place: 0, len (int), data
         int len = DataUtils.readVarInt(idBuffer);
         idBuffer.position(idBuffer.position() + len);
         break;
       case 1:
         // block: 1, len (int), blockId (long)
         DataUtils.readVarInt(idBuffer);
         long k = DataUtils.readVarLong(idBuffer);
         map.remove(k);
         break;
       case 2:
         // indirect: 2, total len (long), blockId (long)
         DataUtils.readVarLong(idBuffer);
         long k2 = DataUtils.readVarLong(idBuffer);
         // recurse
         remove(map.get(k2));
         map.remove(k2);
         break;
       default:
         throw DataUtils.newIllegalArgumentException("Unsupported id {0}", Arrays.toString(id));
     }
   }
 }
示例#2
0
 /**
  * Calculate the number of data bytes for the given id. As the length is encoded in the id, this
  * operation does not cause any reads in the map.
  *
  * @param id the id
  * @return the length
  */
 public long length(byte[] id) {
   ByteBuffer idBuffer = ByteBuffer.wrap(id);
   long length = 0;
   while (idBuffer.hasRemaining()) {
     switch (idBuffer.get()) {
       case 0:
         // in-place: 0, len (int), data
         int len = DataUtils.readVarInt(idBuffer);
         idBuffer.position(idBuffer.position() + len);
         length += len;
         break;
       case 1:
         // block: 1, len (int), blockId (long)
         length += DataUtils.readVarInt(idBuffer);
         DataUtils.readVarLong(idBuffer);
         break;
       case 2:
         // indirect: 2, total len (long), blockId (long)
         length += DataUtils.readVarLong(idBuffer);
         DataUtils.readVarLong(idBuffer);
         break;
       default:
         throw DataUtils.newIllegalArgumentException("Unsupported id {0}", Arrays.toString(id));
     }
   }
   return length;
 }
示例#3
0
 /**
  * Get the key of the biggest block, of -1 for inline data. This method is used to garbage collect
  * orphaned blocks.
  *
  * @param id the id
  * @return the key, or -1
  */
 public long getMaxBlockKey(byte[] id) {
   long maxKey = -1;
   ByteBuffer idBuffer = ByteBuffer.wrap(id);
   while (idBuffer.hasRemaining()) {
     switch (idBuffer.get()) {
       case 0:
         // in-place: 0, len (int), data
         int len = DataUtils.readVarInt(idBuffer);
         idBuffer.position(idBuffer.position() + len);
         break;
       case 1:
         // block: 1, len (int), blockId (long)
         DataUtils.readVarInt(idBuffer);
         long k = DataUtils.readVarLong(idBuffer);
         maxKey = Math.max(maxKey, k);
         break;
       case 2:
         // indirect: 2, total len (long), blockId (long)
         DataUtils.readVarLong(idBuffer);
         long k2 = DataUtils.readVarLong(idBuffer);
         // recurse
         byte[] r = map.get(k2);
         maxKey = Math.max(maxKey, getMaxBlockKey(r));
         break;
       default:
         throw DataUtils.newIllegalArgumentException("Unsupported id {0}", Arrays.toString(id));
     }
   }
   return maxKey;
 }
示例#4
0
 private ByteArrayInputStream nextBuffer() {
   while (idBuffer.hasRemaining()) {
     switch (idBuffer.get()) {
       case 0:
         {
           int len = DataUtils.readVarInt(idBuffer);
           if (skip >= len) {
             skip -= len;
             idBuffer.position(idBuffer.position() + len);
             continue;
           }
           int p = (int) (idBuffer.position() + skip);
           int l = (int) (len - skip);
           idBuffer.position(p + l);
           return new ByteArrayInputStream(idBuffer.array(), p, l);
         }
       case 1:
         {
           int len = DataUtils.readVarInt(idBuffer);
           long key = DataUtils.readVarLong(idBuffer);
           if (skip >= len) {
             skip -= len;
             continue;
           }
           byte[] data = store.getBlock(key);
           int s = (int) skip;
           skip = 0;
           return new ByteArrayInputStream(data, s, data.length - s);
         }
       case 2:
         {
           long len = DataUtils.readVarLong(idBuffer);
           long key = DataUtils.readVarLong(idBuffer);
           if (skip >= len) {
             skip -= len;
             continue;
           }
           byte[] k = store.getBlock(key);
           ByteBuffer newBuffer =
               ByteBuffer.allocate(k.length + idBuffer.limit() - idBuffer.position());
           newBuffer.put(k);
           newBuffer.put(idBuffer);
           newBuffer.flip();
           idBuffer = newBuffer;
           return nextBuffer();
         }
       default:
         throw DataUtils.newIllegalArgumentException(
             "Unsupported id {0}", Arrays.toString(idBuffer.array()));
     }
   }
   return null;
 }
示例#5
0
 /**
  * Try to open the file.
  *
  * @param fileName the file name
  * @param readOnly whether the file should only be opened in read-only mode, even if the file is
  *     writable
  * @param encryptionKey the encryption key, or null if encryption is not used
  */
 public void open(String fileName, boolean readOnly, char[] encryptionKey) {
   if (file != null) {
     return;
   }
   if (fileName != null) {
     FilePath p = FilePath.get(fileName);
     // if no explicit scheme was specified, NIO is used
     if (p instanceof FilePathDisk && !fileName.startsWith(p.getScheme() + ":")) {
       // ensure the NIO file system is registered
       FilePathNio.class.getName();
       fileName = "nio:" + fileName;
     }
   }
   this.fileName = fileName;
   FilePath f = FilePath.get(fileName);
   FilePath parent = f.getParent();
   if (parent != null && !parent.exists()) {
     throw DataUtils.newIllegalArgumentException("Directory does not exist: {0}", parent);
   }
   if (f.exists() && !f.canWrite()) {
     readOnly = true;
   }
   this.readOnly = readOnly;
   try {
     file = f.open(readOnly ? "r" : "rw");
     if (encryptionKey != null) {
       byte[] key = FilePathEncrypt.getPasswordBytes(encryptionKey);
       encryptedFile = file;
       file = new FilePathEncrypt.FileEncrypt(fileName, key, file);
     }
     file = FilePathCache.wrap(file);
     try {
       if (readOnly) {
         fileLock = file.tryLock(0, Long.MAX_VALUE, true);
       } else {
         fileLock = file.tryLock();
       }
     } catch (OverlappingFileLockException e) {
       throw DataUtils.newIllegalStateException(
           DataUtils.ERROR_FILE_LOCKED, "The file is locked: {0}", fileName, e);
     }
     if (fileLock == null) {
       throw DataUtils.newIllegalStateException(
           DataUtils.ERROR_FILE_LOCKED, "The file is locked: {0}", fileName);
     }
     fileSize = file.size();
   } catch (IOException e) {
     throw DataUtils.newIllegalStateException(
         DataUtils.ERROR_READING_FAILED, "Could not open file {0}", fileName, e);
   }
 }