Function: _rotate in write-ahead-log/wal.py

Date: 2026-05-29

Time: 06:36

WriteAheadLog._rotate

Purpose

_rotate closes the current WAL segment file and opens a fresh one with a sequentially numbered filename. WAL implementations split their log across multiple files (segments) so that old, fully-checkpointed segments can be deleted without rewriting the active file. This method is the mechanism that creates the next segment in that chain.

Contract

Preconditions:

Postconditions:

Invariants:

Parameters

None — this is a private method operating entirely on instance state.

Return Value

None. All effects are via mutation of self.fd and self.current_file.

Algorithm

1. Close the old segment. If self._fd is not None, flush the userspace buffer, call os.fsync to force the kernel buffer to durable storage, then close the file descriptor. This ensures no data from the prior segment is lost.

2. Determine the next filename. List all existing .wal files (sorted lexicographically, which equals numerically due to zero-padding). If any exist, parse the highest-numbered filename by splitting on "." and taking the integer prefix, then add 1. If no files exist, start at 1.

3. Open the new segment. Construct the path as {next_num:06d}.wal (e.g., 000001.wal, 000002.wal) and open it in append-binary mode. Store both the path and the fd on the instance.

Side Effects

Error Handling

No exceptions are caught. If os.fsync or open fails (e.g., disk full, permission denied), the exception propagates to the caller. This is appropriate — a WAL that can't write is a fatal condition.

There's one subtle assumption: if self.fd is non-None but already closed (e.g., due to a bug elsewhere), calling self.fd.flush() will raise ValueError. The code trusts that _fd is either None or a valid open descriptor.

Usage Patterns

_rotate is called from two places:

1. openlatest — at startup, when no WAL files exist or the latest one is already at capacity. This is the "create the very first segment" path.

2. mayberotate — after each write operation, when self.fd.tell() >= self.maxfilesize. This enforces the segment size limit.

Callers never call _rotate directly from outside the class (it's private by convention).

Dependencies

Assumptions Not Enforced by Types