analyzeForRecovery method

Future<({int lastCheckpointLsn, List<WalBinRecord> toRedo, Set<int> uncommittedTxns})> analyzeForRecovery()

Implementation

Future<({
  List<WalBinRecord> toRedo,
  Set<int> uncommittedTxns,
  int lastCheckpointLsn,
})> analyzeForRecovery() async {
  final all = await readAll();
  if (all.isEmpty) {
    return (toRedo: <WalBinRecord>[], uncommittedTxns: <int>{}, lastCheckpointLsn: 0);
  }

  final committed   = <int>{0};
  final rolledBack  = <int>{};
  final started     = <int>{};
  int lastCheckpointLsn = 0;

  for (final r in all) {
    switch (r.op) {
      case WalBinOp.begin:      started.add(r.txnId);
      case WalBinOp.commit:     committed.add(r.txnId); started.remove(r.txnId);
      case WalBinOp.rollback:   rolledBack.add(r.txnId); started.remove(r.txnId);
      case WalBinOp.checkpoint: lastCheckpointLsn = r.lsn;
      default: break;
    }
  }

  final uncommitted = started.where((id) =>
      !committed.contains(id) && !rolledBack.contains(id)).toSet();

  final toRedo = all.where((r) {
    if (!r.op.isDataOp) return false;
    if (rolledBack.contains(r.txnId)) return false;
    return committed.contains(r.txnId);
  }).toList()
    ..sort((a, b) => a.lsn.compareTo(b.lsn));

  return (
    toRedo: toRedo,
    uncommittedTxns: uncommitted,
    lastCheckpointLsn: lastCheckpointLsn,
  );
}