public synchronized void remove(K key) { String digest = mKeyToDigest.remove(key); sLog.debug("Removing %s, digest=%s", key, digest); if (digest != null) { Set<K> keys = mDigestToKeys.get(digest); if (keys != null) { keys.remove(key); } if (keys == null || keys.isEmpty()) { File file = mDigestToFile.remove(digest); mDigestToKeys.remove(digest); sLog.debug("Deleting unreferenced file %s.", file); if (file != null) { try { FileUtil.delete(file); } catch (Exception e) { // IOException and SecurityException ZimbraLog.store.warn("Unable to remove a file from the uncompressed cache.", e); } } } else { sLog.debug("Not deleting %s. It is referenced by %s.", digest, keys); } } }
/** * Returns the uncompressed version of the given file. If the uncompressed file is not in the * cache, uncompresses it and adds it to the cache. * * @param key the key used to look up the uncompressed data * @param compressedFile the compressed file. This file is read, if necessary, to write the * uncompressed file. * @param sync <tt>true</tt> to use fsync */ public SharedFile get(K key, File compressedFile, boolean sync) throws IOException { File uncompressedFile = null; sLog.debug("Looking up SharedFile for key %s, path %s.", key, compressedFile.getPath()); synchronized (this) { String digest = mKeyToDigest.get(key); sLog.debug("Digest for %s is %s", key, digest); if (digest != null) { uncompressedFile = mDigestToFile.get(digest); if (uncompressedFile != null) { sLog.debug("Found existing uncompressed file. Returning new SharedFile."); return new SharedFile(uncompressedFile); } else { sLog.debug("No existing uncompressed file."); } } } // Uncompress the file outside of the synchronized block. UncompressedFile temp = uncompressToTempFile(compressedFile, sync); SharedFile shared = null; synchronized (this) { uncompressedFile = mDigestToFile.get(temp.digest); if (uncompressedFile != null) { // Another thread uncompressed the same file at the same time. sLog.debug("Found existing uncompressed file. Deleting %s.", temp.file); mapKeyToDigest(key, temp.digest); FileUtil.delete(temp.file); shared = new SharedFile(uncompressedFile); } else { uncompressedFile = new File(mCacheDir, temp.digest); sLog.debug("Renaming %s to %s.", temp.file, uncompressedFile); FileUtil.rename(temp.file, uncompressedFile); shared = new SharedFile(uncompressedFile); // Opens the file implicitly. put(key, temp.digest, uncompressedFile); } } return shared; }