edit method
Returns an editor for the entry named key
, or null if another
edit is in progress.
Implementation
Future<Editor?> edit(String key, [int? expectedSequenceNumber]) =>
_lock.synchronized(() async {
await _initialize();
_checkNotClosed();
_validateKey(key);
var entry = _lruEntries[key];
if (expectedSequenceNumber != null &&
(entry == null || entry.sequenceNumber != expectedSequenceNumber)) {
return null; // Snapshot is stale.
}
if (entry?.currentEditor != null) {
return null; // Another edit is in progress.
}
if (entry != null && entry.lockingSourceCount != 0) {
return null; // We can't write this file because a reader is still reading it.
}
if (_mostRecentTrimFailed || _mostRecentRebuildFailed) {
// The OS has become our enemy! If the trim job failed, it means we are storing more data than
// requested by the user. Do not allow edits so we do not go over that limit any further. If
// the journal rebuild failed, the journal writer will not be active, meaning we will not be
// able to record the edit, causing file leaks. In both cases, we want to retry the clean up
// so we can get out of this state!
_cleanup();
return null;
}
// Flush the journal before creating files to prevent file leaks.
await _journalWriter!.writeLine('$_kDirty $key');
await _journalWriter!.flush();
if (_hasJournalErrors) {
return null; // Don't edit; the journal can't be written.
}
entry = _lruEntries.putIfAbsent(key, () => Entry(key, this));
final editor = Editor._(this, entry);
entry.currentEditor = editor;
return editor;
});