private void initCache(ConfigTO configTO) { cache = new Cache(cacheDir); if (configTO.getCacheKeepBytes() != null && configTO.getCacheKeepBytes() >= 0) { cache.setKeepBytes(configTO.getCacheKeepBytes()); } }
/** * Deletes files in the the cache directory using a LRU-strategy until <tt>keepBytes</tt> * bytes are left. This method calls {@link #clear(long)} using the <tt>keepBytes</tt> * property. * * <p>This method should not be run while an operation is executed. */ public void clear() { clear(keepBytes); }
/** * Creates a temporary file, either using the config (if initialized) or * using the global temporary directory. */ protected File createTempFile(String name) throws IOException { if (config == null) { return File.createTempFile(String.format("temp-%s-", name), ".tmp"); } else { return config.getCache().createTempFile(name); } }
@Test public void testCacheSizeOkay() throws Exception { File testCacheFolder = TestFileUtil.createTempDirectoryInSystemTemp(); Cache cache = new Cache(testCacheFolder); cache.setKeepBytes(50*1024); TestFileUtil.createRandomFilesInDirectory(testCacheFolder, 10*1024, 4); assertEquals(4, testCacheFolder.listFiles().length); cache.clear(); assertEquals(4, testCacheFolder.listFiles().length); TestFileUtil.deleteDirectory(testCacheFolder); }
File localEncryptedMultiChunkFile = config.getCache().getEncryptedMultiChunkFile(multiChunkId); File localDecryptedMultiChunkFile = config.getCache().getDecryptedMultiChunkFile(multiChunkId); MultichunkRemoteFile remoteMultiChunkFile = new MultichunkRemoteFile(multiChunkId);
File reconstructedFileInCache = config.getCache().createTempFile("reconstructedFileVersion"); logger.log(Level.INFO, " - Creating file " + fileVersion.getPath() + " to " + reconstructedFileInCache + " ..."); File decryptedMultiChunkFile = config.getCache().getDecryptedMultiChunkFile(multiChunkIdForChunk);
/** * Returns a file path of a database remote file. */ public File getDatabaseFile(String name) { // TODO [low] This should be a database file or another key return getFileInCache(FILE_FORMAT_DATABASE_FILE_ENCRYPTED, name); }
/** * Downloads the previously identified new/unknown remote databases to the local cache * and returns a map with the local cache files mapped to the given remote database * files. The method additionally fires events for every database it downloads. */ private SortedMap<File, DatabaseRemoteFile> downloadUnknownRemoteDatabases(List<DatabaseRemoteFile> unknownRemoteDatabases) throws StorageException { logger.log(Level.INFO, "Downloading unknown databases."); SortedMap<File, DatabaseRemoteFile> unknownRemoteDatabasesInCache = new TreeMap<File, DatabaseRemoteFile>(); int downloadFileIndex = 0; for (DatabaseRemoteFile remoteFile : unknownRemoteDatabases) { File unknownRemoteDatabaseFileInCache = config.getCache().getDatabaseFile(remoteFile.getName()); DatabaseRemoteFile unknownDatabaseRemoteFile = new DatabaseRemoteFile(remoteFile.getName()); logger.log(Level.INFO, "- Downloading {0} to local cache at {1}", new Object[] { remoteFile.getName(), unknownRemoteDatabaseFileInCache }); eventBus.post(new DownDownloadFileSyncExternalEvent(config.getLocalDir().getAbsolutePath(), "database", ++downloadFileIndex, unknownRemoteDatabases.size())); transferManager.download(unknownDatabaseRemoteFile, unknownRemoteDatabaseFileInCache); unknownRemoteDatabasesInCache.put(unknownRemoteDatabaseFileInCache, unknownDatabaseRemoteFile); result.getDownloadedUnknownDatabases().add(remoteFile.getName()); } return unknownRemoteDatabasesInCache; }
@Override public File getMultiChunkFile(MultiChunkId multiChunkId) { return config.getCache().getEncryptedMultiChunkFile(multiChunkId); }
/** * Returns the file using the given format and parameters, and * updates the last modified date of the file (used for LRU strategy). */ private File getFileInCache(String format, Object... params) { File fileInCache = new File(cacheDir.getAbsoluteFile(), String.format(format, params)); if (fileInCache.exists()) { touchFile(fileInCache); } return fileInCache; }
List<File> cacheFiles = getSortedFileList();
@Test public void testCacheNeedsCleaning5Left() throws Exception { File testCacheFolder = TestFileUtil.createTempDirectoryInSystemTemp(); Cache cache = new Cache(testCacheFolder); cache.setKeepBytes(50*1024); TestFileUtil.createRandomFilesInDirectory(testCacheFolder, 10*1024, 10); assertEquals(10, testCacheFolder.listFiles().length); cache.clear(); assertEquals(5, testCacheFolder.listFiles().length); TestFileUtil.deleteDirectory(testCacheFolder); }
/** * Returns a file path of a decrypted multichunk file, * given the identifier of a multichunk. */ public File getDecryptedMultiChunkFile(MultiChunkId multiChunkId) { return getFileInCache(FILE_FORMAT_MULTICHUNK_DECRYPTED, multiChunkId.toString()); }
/** * This method writes the file with merged databases for a single client and adds it to a Map containing all merged * database files. This is done by querying the local database for all {@link DatabaseVersion}s by this client and * serializing them. * * @param clientName for which we want to write the merged dataabse file. * @param allMergedDatabaseFiles Map where we add the merged file once it is written. */ private void writeMergeFile(String clientName, Map<File, DatabaseRemoteFile> allMergedDatabaseFiles) throws StorageException, IOException { // Increment the version by 1, to signal cleanup has occurred long lastClientVersion = getNewestDatabaseFileVersion(clientName, localDatabase.getKnownDatabases()); DatabaseRemoteFile newRemoteMergeDatabaseFile = new DatabaseRemoteFile(clientName, lastClientVersion + 1); File newLocalMergeDatabaseFile = config.getCache().getDatabaseFile(newRemoteMergeDatabaseFile.getName()); logger.log(Level.INFO, " + Writing new merge file (all files up to {0}) to {1} ...", new Object[] { lastClientVersion, newLocalMergeDatabaseFile }); Iterator<DatabaseVersion> lastNDatabaseVersions = localDatabase.getDatabaseVersionsTo(clientName, lastClientVersion); DatabaseXmlSerializer databaseDAO = new DatabaseXmlSerializer(config.getTransformer()); databaseDAO.save(lastNDatabaseVersions, newLocalMergeDatabaseFile); allMergedDatabaseFiles.put(newLocalMergeDatabaseFile, newRemoteMergeDatabaseFile); }
/** * This methods adds the multichunks that are not yet present in the remote repo to the {@link RemoteTransaction} for * uploading. Multichunks are not uploaded if they are dirty. * * @param multiChunkEntries Collection of multiChunkEntries that are included in the new {@link DatabaseVersion} */ private void addMultiChunksToTransaction(RemoteTransaction remoteTransaction, Collection<MultiChunkEntry> multiChunksEntries) throws InterruptedException, StorageException { List<MultiChunkId> dirtyMultiChunkIds = localDatabase.getDirtyMultiChunkIds(); for (MultiChunkEntry multiChunkEntry : multiChunksEntries) { if (dirtyMultiChunkIds.contains(multiChunkEntry.getId())) { logger.log(Level.INFO, "- Ignoring multichunk (from dirty database, already uploaded), " + multiChunkEntry.getId() + " ..."); } else { File localMultiChunkFile = config.getCache().getEncryptedMultiChunkFile(multiChunkEntry.getId()); MultichunkRemoteFile remoteMultiChunkFile = new MultichunkRemoteFile(multiChunkEntry.getId()); logger.log(Level.INFO, "- Uploading multichunk {0} from {1} to {2} ...", new Object[] { multiChunkEntry.getId(), localMultiChunkFile, remoteMultiChunkFile }); remoteTransaction.upload(localMultiChunkFile, remoteMultiChunkFile); } } }
@Test public void testCacheNeedsCleaning2Left() throws Exception { File testCacheFolder = TestFileUtil.createTempDirectoryInSystemTemp(); Cache cache = new Cache(testCacheFolder); cache.setKeepBytes(50*1024); TestFileUtil.createRandomFile(new File(testCacheFolder, "40"), 40*1024); Thread.sleep(1001); // Linux/ext3 only has 1s accuracy TestFileUtil.createRandomFile(new File(testCacheFolder, "30"), 30*1024); Thread.sleep(1001); TestFileUtil.createRandomFile(new File(testCacheFolder, "20"), 20*1024); Thread.sleep(1001); TestFileUtil.createRandomFile(new File(testCacheFolder, "10"), 10*1024); assertEquals(4, testCacheFolder.listFiles().length); cache.clear(); assertEquals(2, testCacheFolder.listFiles().length); assertFalse(new File(testCacheFolder, "40").exists()); assertFalse(new File(testCacheFolder, "30").exists()); assertTrue(new File(testCacheFolder, "20").exists()); assertTrue(new File(testCacheFolder, "10").exists()); TestFileUtil.deleteDirectory(testCacheFolder); } }
private void clearCache() { config.getCache().clear(); } }
/** * Creates a temporary file, either using the config (if initialized) or * using the global temporary directory. */ protected File createTempFile(String name) throws IOException { // TODO [low] duplicate code with AbstractTransferManager if (config == null) { return File.createTempFile(String.format("temp-%s-", name), ".tmp"); } else { return config.getCache().createTempFile(name); } } }
/** * Returns a file path of a encrypted multichunk file, * given the identifier of a multichunk. */ public File getEncryptedMultiChunkFile(MultiChunkId multiChunkId) { return getFileInCache(FILE_FORMAT_MULTICHUNK_ENCRYPTED, multiChunkId.toString()); }
File localDeltaDatabaseFile = config.getCache().getDatabaseFile(remoteDeltaDatabaseFile.getName());