Example #1
0
  private synchronized void completeEdit(Editor editor, boolean success) throws IOException {
    Entry entry = editor.entry;
    if (entry.currentEditor != editor) {
      throw new IllegalStateException();
    }

    // If this edit is creating the entry for the first time, every index must have a value.
    if (success && !entry.readable) {
      for (int i = 0; i < valueCount; i++) {
        if (!editor.written[i]) {
          editor.abort();
          throw new IllegalStateException("Newly created entry didn't create value for index " + i);
        }
        if (!entry.getDirtyFile(i).exists()) {
          editor.abort();
          return;
        }
      }
    }

    for (int i = 0; i < valueCount; i++) {
      File dirty = entry.getDirtyFile(i);
      if (success) {
        if (dirty.exists()) {
          File clean = entry.getCleanFile(i);
          dirty.renameTo(clean);
          long oldLength = entry.lengths[i];
          long newLength = clean.length();
          entry.lengths[i] = newLength;
          size = size - oldLength + newLength;
          fileCount++;
        }
      } else {
        deleteIfExists(dirty);
      }
    }

    redundantOpCount++;
    entry.currentEditor = null;
    if (entry.readable | success) {
      entry.readable = true;
      journalWriter.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n');
      if (success) {
        entry.sequenceNumber = nextSequenceNumber++;
      }
    } else {
      lruEntries.remove(entry.key);
      journalWriter.write(REMOVE + ' ' + entry.key + '\n');
    }
    journalWriter.flush();

    if (size > maxSize || fileCount > maxFileCount || journalRebuildRequired()) {
      executorService.submit(cleanupCallable);
    }
  }
Example #2
0
 /**
  * Returns a new unbuffered output stream to write the value at {@code index}. If the underlying
  * output stream encounters errors when writing to the filesystem, this edit will be aborted
  * when {@link #commit} is called. The returned output stream does not throw IOExceptions.
  */
 public OutputStream newOutputStream(int index) throws IOException {
   synchronized (DiskLruCache.this) {
     if (entry.currentEditor != this) {
       throw new IllegalStateException();
     }
     if (!entry.readable) {
       written[index] = true;
     }
     File dirtyFile = entry.getDirtyFile(index);
     FileOutputStream outputStream;
     try {
       outputStream = new FileOutputStream(dirtyFile);
     } catch (FileNotFoundException e) {
       // Attempt to recreate the cache directory.
       directory.mkdirs();
       try {
         outputStream = new FileOutputStream(dirtyFile);
       } catch (FileNotFoundException e2) {
         // We are unable to recover. Silently eat the writes.
         return NULL_OUTPUT_STREAM;
       }
     }
     return new FaultHidingOutputStream(outputStream);
   }
 }
Example #3
0
 /**
  * Returns a new unbuffered output stream to write the value at {@code index}. If the underlying
  * output stream encounters errors when writing to the filesystem, this edit will be aborted
  * when {@link #commit} is called. The returned output stream does not throw IOExceptions.
  */
 public OutputStream newOutputStream(int index) throws IOException {
   if (index < 0 || index >= valueCount) {
     throw new IllegalArgumentException(
         "Expected index "
             + index
             + " to "
             + "be greater than 0 and less than the maximum value count "
             + "of "
             + valueCount);
   }
   synchronized (DiskLruCache.this) {
     if (entry.currentEditor != this) {
       throw new IllegalStateException();
     }
     if (!entry.readable) {
       written[index] = true;
     }
     File dirtyFile = entry.getDirtyFile(index);
     FileOutputStream outputStream;
     try {
       outputStream = new FileOutputStream(dirtyFile);
     } catch (FileNotFoundException e) {
       // Attempt to recreate the cache directory.
       directory.mkdirs();
       try {
         outputStream = new FileOutputStream(dirtyFile);
       } catch (FileNotFoundException e2) {
         // We are unable to recover. Silently eat the writes.
         return NULL_OUTPUT_STREAM;
       }
     }
     return new FaultHidingOutputStream(outputStream);
   }
 }
Example #4
0
 /**
  * Returns a new unbuffered output stream to write the value at {@code index}. If the underlying
  * output stream encounters errors when writing to the filesystem, this edit will be aborted
  * when {@link #commit} is called. The returned output stream does not throw IOExceptions.
  */
 public OutputStream newOutputStream(int index) throws IOException {
   synchronized (DiskLruCache.this) {
     if (entry.currentEditor != this) {
       throw new IllegalStateException();
     }
     return new FaultHidingOutputStream(new FileOutputStream(entry.getDirtyFile(index)));
   }
 }
Example #5
0
 /**
  * Computes the initial size and collects garbage as a part of opening the cache. Dirty entries
  * are assumed to be inconsistent and will be deleted.
  */
 private void processJournal() throws IOException {
   deleteIfExists(journalFileTmp);
   for (Iterator<Entry> i = lruEntries.values().iterator(); i.hasNext(); ) {
     Entry entry = i.next();
     if (entry.currentEditor == null) {
       for (int t = 0; t < valueCount; t++) {
         size += entry.lengths[t];
       }
     } else {
       entry.currentEditor = null;
       for (int t = 0; t < valueCount; t++) {
         deleteIfExists(entry.getCleanFile(t));
         deleteIfExists(entry.getDirtyFile(t));
       }
       i.remove();
     }
   }
 }