Function: put in read-repair/read_repair.py

Date: 2026-05-29

Time: 14:05

Replica.put — Versioned Write with Staleness Guard

Purpose

put is the write primitive for a single replica node in a leaderless replication system. It stores a key-value pair only if the incoming version is not older than what the replica already holds. This prevents read-repair and anti-entropy processes from accidentally overwriting newer data with stale values — a critical safety property in eventually consistent systems.

Contract

Parameters

| Parameter | Type | Meaning |

|-----------|------|---------|

| key | str | The logical key to store. No validation — empty strings are accepted. |

| value | any | The payload. Untyped; the store treats it as opaque. |

| version | int | A logical timestamp. Compared against the current version to decide whether to accept the write. |

Edge cases: If version == current_version, the write is accepted and the value is overwritten. This means two writes at the same version are last-writer-wins with no conflict detection.

Return Value

Returns bool:

The caller can use this to detect stale writes but in practice the return value is ignored by all callers in this module (ReadRepairStore.put, read repair in get, and antientropyrepair all call r.put() without checking the result).

Algorithm

1. Check if key already exists in _store.

2. If it does, extract the current version and compare: if version < current_version, reject with False.

3. Otherwise (key is new, or version >= currentversion), overwrite store[key] with (value, version) and return True.

The comparison is strictly less than — equal versions are accepted. This is a deliberate choice: during read repair, the winning version is pushed to stale replicas, and some replicas may already hold that exact version. Accepting >= makes repair idempotent for same-version writes.

Side Effects

Mutates self._store on success. No I/O, no logging, no callbacks. This is a pure in-memory operation.

Error Handling

None. No exceptions are raised. Invalid types for version (e.g., passing a string) would produce a TypeError at the < comparison, but this is not guarded.

Usage Patterns

put is called in three contexts within ReadRepairStore:

1. Normal writes (ReadRepairStore.put, line ~68): The store computes maxversion + 1 across all replicas, then calls r.put(key, value, newversion) on the first W available replicas. Since the version is freshly computed, the guard never triggers here.

2. Read repair (ReadRepairStore.get, line ~105): After a quorum read discovers stale replicas, it pushes the winning (value, version) to them. The guard protects against the (unlikely in this implementation) case where a concurrent write advanced the version between the read and the repair.

3. Anti-entropy repair (antientropyrepair, line ~124): Same pattern — find the max version, push it to all replicas with older data.

Dependencies

None beyond Python builtins. The method operates entirely on self._store, a plain dict.

Assumptions Not Enforced by Types