commit method

Future<void> commit()

Commit pending dirty pages to disk and finalise the transaction.

Protocol:

  1. fsync the journal (already done incrementally on each undo capture).
  2. Write every dirty page to the data file at its offset.
  3. fsync the data file.
  4. Delete the journal — this is the atomic commit point.

Implementation

Future<void> commit() async {
  _ensureOpen();
  if (_dirty.isEmpty && _journal == null) return;
  // Make sure the data file is large enough for any newly allocated
  // pages — if we appended in [allocatePage] but never wrote anything
  // beyond their cached buffer, the file may still be short.
  final needLen = _pageCount * pageSize;
  if (await _data!.length() < needLen) {
    await _data!.truncate(needLen);
  }
  // Flush dirty pages in sorted order for predictable I/O patterns.
  // A dirty page may have been evicted (its bytes were written
  // through under the journal) — in that case it's already on disk
  // and there's nothing to do at commit time.
  final sorted = _dirty.toList()..sort();
  for (final p in sorted) {
    final buf = _cache[p];
    if (buf == null) continue; // already flushed via eviction
    await _data!.setPosition(p * pageSize);
    await _data!.writeFrom(buf);
  }
  await _data!.flush();
  _dirty.clear();
  _journaled.clear();
  await _closeAndDeleteJournal();
}