@Override public synchronized void clear() { try { getDiskCache().delete(); } catch (IOException e) { if (Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "Unable to clear disk cache or disk cache cleared externally", e); } } finally { // Delete can close the cache but still throw. If we don't null out the disk cache here, every // subsequent request will try to act on a closed disk cache and fail. By nulling out the disk // cache we at least allow for attempts to open the cache in the future. See #2465. resetDiskCache(); } }
private synchronized DiskLruCache getDiskCache() throws IOException { if (diskLruCache == null) { diskLruCache = DiskLruCache.open(directory, APP_VERSION, VALUE_COUNT, maxSize); } return diskLruCache; }
/** Force buffered operations to the filesystem. */ public synchronized void flush() throws IOException { checkNotClosed(); trimToSize(); journalWriter.flush(); }
@Test public void editSinceEvicted() throws Exception { cache.close(); cache = DiskLruCache.open(cacheDir, appVersion, 2, 10); set("a", "aa", "aaa"); // size 5 DiskLruCache.Value value = cache.get("a"); set("b", "bb", "bbb"); // size 5 set("c", "cc", "ccc"); // size 5; will evict 'A' cache.flush(); assertThat(value.edit()).isNull(); }
backupFile.delete(); } else { renameTo(backupFile, journalFile, false); DiskLruCache cache = new DiskLruCache(directory, appVersion, valueCount, maxSize); if (cache.journalFile.exists()) { try { cache.readJournal(); cache.processJournal(); return cache; } catch (IOException journalIsCorrupt) { + journalIsCorrupt.getMessage() + ", removing"); cache.delete(); cache = new DiskLruCache(directory, appVersion, valueCount, maxSize); cache.rebuildJournal(); return cache;
@Test public void journalWithEditAndPublishAndRead() throws Exception { DiskLruCache.Editor k1Creator = cache.edit("k1"); k1Creator.set(0, "AB"); k1Creator.set(1, "C"); k1Creator.commit(); DiskLruCache.Editor k2Creator = cache.edit("k2"); k2Creator.set(0, "DEF"); k2Creator.set(1, "G"); k2Creator.commit(); DiskLruCache.Value k1Value = cache.get("k1"); cache.close(); assertJournalEquals("DIRTY k1", "CLEAN k1 2 1", "DIRTY k2", "CLEAN k2 3 1", "READ k1"); }
@Override public File get(Key key) { String safeKey = safeKeyGenerator.getSafeKey(key); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "Get: Obtained: " + safeKey + " for for Key: " + key); } File result = null; try { // It is possible that the there will be a put in between these two gets. If so that shouldn't // be a problem because we will always put the same value at the same key so our input streams // will still represent the same data. final DiskLruCache.Value value = getDiskCache().get(safeKey); if (value != null) { result = value.getFile(0); } } catch (IOException e) { if (Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "Unable to get from disk cache", e); } } return result; }
/** * Returns an editor for the entry named {@code key}, or null if another * edit is in progress. */ public Editor edit(String key) throws IOException { return edit(key, ANY_SEQUENCE_NUMBER); }
@Test public void evictOnUpdate() throws Exception { cache.close(); cache = DiskLruCache.open(cacheDir, appVersion, 2, 10); set("a", "a", "aa"); // size 3 set("b", "b", "bb"); // size 3 set("c", "c", "cc"); // size 3 assertThat(cache.size()).isEqualTo(9); // Causing the size to grow to 11 should evict 'A'. set("b", "b", "bbbb"); cache.flush(); assertThat(cache.size()).isEqualTo(8); assertAbsent("a"); assertValue("b", "b", "bbbb"); assertValue("c", "c", "cc"); }
@Test public void explicitRemoveAppliedToDiskImmediately() throws Exception { DiskLruCache.Editor editor = cache.edit("k1"); editor.set(0, "ABC"); editor.set(1, "B"); editor.commit(); File k1 = getCleanFile("k1", 0); assertThat(readFile(k1)).isEqualTo("ABC"); cache.remove("k1"); assertThat(k1.exists()).isFalse(); }
@Override public void delete(Key key) { String safeKey = safeKeyGenerator.getSafeKey(key); try { getDiskCache().remove(safeKey); } catch (IOException e) { if (Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "Unable to delete from disk cache", e); } } }
@Test public void shrinkMaxSizeEvicts() throws Exception { cache.close(); cache = DiskLruCache.open(cacheDir, appVersion, 2, 20); set("a", "a", "aaa"); // size 4 set("b", "bb", "bbbb"); // size 6 set("c", "c", "c"); // size 12 cache.setMaxSize(10); cache.executorService.shutdown(); cache.executorService.awaitTermination(500, TimeUnit.MILLISECONDS); assertThat(cache.size()).isEqualTo(8 /* 12 - 4 */); }
/** * Returns a snapshot of the entry named {@code key}, or null if it doesn't * exist is not currently readable. If a value is returned, it is moved to * the head of the LRU queue. */ public synchronized Value get(String key) throws IOException { checkNotClosed(); Entry entry = lruEntries.get(key); if (entry == null) { return null; } if (!entry.readable) { return null; } for (File file : entry.cleanFiles) { // A file must have been deleted manually! if (!file.exists()) { return null; } } redundantOpCount++; journalWriter.append(READ); journalWriter.append(' '); journalWriter.append(key); journalWriter.append('\n'); if (journalRebuildRequired()) { executorService.submit(cleanupCallable); } return new Value(key, entry.sequenceNumber, entry.cleanFiles, entry.lengths); }
deleteIfExists(dirty); if (size > maxSize || journalRebuildRequired()) { executorService.submit(cleanupCallable);