public Editor Edit(string key, long expectedSequenceNumber = AnySequenceNumber) { CheckNotClosed(); ValidateKey(key); lruEntries.TryGetValue(key, out var entry); if (expectedSequenceNumber != AnySequenceNumber && (null == entry || entry.UnsafeSequenceNumber != expectedSequenceNumber)) { return(null); // Snapshot is stale. } if (null == entry) { entry = new UnsafeEntry(key, Directory, ValueCount); lruEntries[key] = entry; } else if (null != entry.UnsafeCurrentEditor) { return(null); // Another edit is in progress. } var editor = new Editor(entry, this); entry.UnsafeCurrentEditor = editor; // Flush the journal before creating files to prevent file leaks. journalWriter.WriteLine($"{DirtyFlag} {key}"); journalWriter.Flush(); return(editor); }
public Editor(UnsafeEntry entry, DiskLruCache parent) { this.parent = parent; Entry = entry; written = entry.UnsafeReadable ? null : new bool[parent.ValueCount]; }
private void ReadJournalLine(string line) { if (null == line) { throw new EndOfStreamException(); } var firstSpace = line.IndexOf(' '); if (firstSpace == -1) { throw new IOException($"unexpected journal line: {line}"); } var keyBegin = firstSpace + 1; var secondSpace = line.IndexOf(' ', keyBegin); string key; if (secondSpace == -1) { key = line.Substring(keyBegin); if (firstSpace == RemoveFlag.Length && line.StartsWith(RemoveFlag)) { lruEntries.Remove(key); return; } } else { var length = secondSpace - keyBegin; key = line.Substring(keyBegin, length); } lruEntries.TryGetValue(key, out var entry); if (null == entry) { entry = new UnsafeEntry(key, Directory, ValueCount); lruEntries[key] = entry; } if (secondSpace != -1 && firstSpace == CleanFlag.Length && line.StartsWith(CleanFlag)) { var parts = line.Substring(secondSpace + 1).Split(' '); entry.UnsafeReadable = true; entry.UnsafeCurrentEditor = null; entry.SetLengths(parts); } else if (secondSpace == -1 && firstSpace == DirtyFlag.Length && line.StartsWith(DirtyFlag)) { entry.UnsafeCurrentEditor = new Editor(entry, this); } else if (secondSpace == -1 && firstSpace == ReadFlag.Length && line.StartsWith(ReadFlag)) { // This work was already done by calling lruEntries.get(). } else { throw new IOException($"unexpected journal line: {line}"); } }