\Drupal\strata\Verify Reindexer

Rebuilds the local index from the bucket.

The local tables are a cache over objects that already exist. Uninstalling the module drops them and leaves the bucket untouched, a restore into a fresh site starts with no tables at all, and a corrupt row is faster to rebuild than to repair. All three are the same operation.

It works because every object says what it is. A commit is a JSON document addressed by its own content. A standalone frame carries a plaintext header naming its codec, cipher, dictionary and decoded length. A pack carries a directory of the same fields for every frame inside it. Nothing here has to be guessed or inferred from a database row, which is the property that makes the bucket the record and the tables derived state.

Reference counts are recomputed rather than restored, by reading the segments every reachable commit names. A count derived from what actually points at a frame is correct by construction; a count carried over from a backup of the index would be exactly as stale as the index it came from.

Summary

Methods
Properties
Constants
__construct
reindex
No public properties found
No public constants found
No protected methods found
No protected properties found
No protected constants found
indexObjects
indexCommits
indexBranches
attributeReferences
attributeSegment
keys
provider
index
commitIndex
commits
refs
segments
logger
placement
branches
branchIndex
PAGE

Constant

PAGE

PAGE = 1000

How many keys to ask for per listing page.

Properties

$commitIndex

$commitIndex : \Drupal\strata\Tree\CommitIndex

Type

CommitIndex

$commits

$commits : \Drupal\strata\Tree\CommitLog

Type

CommitLog

$refs

$refs : \Drupal\strata\Tree\RefStore

Type

RefStore

$segments

$segments : \Drupal\strata\Segment\SegmentReader

Type

SegmentReader

$logger

$logger : \Psr\Log\LoggerInterface

Type

LoggerInterface

$branches

$branches : ?\Drupal\strata\Branch\BranchStore

Type

BranchStore|null

$branchIndex

$branchIndex : ?\Drupal\strata\Branch\BranchIndex

Type

BranchIndex|null

Methods

__construct()

__construct(\Drupal\strata\Storage\StorageProviderInterface  $provider, \Drupal\strata\Cas\FrameIndexInterface  $index, \Drupal\strata\Tree\CommitIndex  $commitIndex, \Drupal\strata\Tree\CommitLog  $commits, \Drupal\strata\Tree\RefStore  $refs, \Drupal\strata\Segment\SegmentReader  $segments, \Psr\Log\LoggerInterface  $logger, \Drupal\strata\Tier\TierPlacementRebuilder|null  $placement = null, \Drupal\strata\Branch\BranchStore|null  $branches = null, \Drupal\strata\Branch\BranchIndex|null  $branchIndex = null) : mixed

Constructs a reindexer.

Parameters

\Drupal\strata\Storage\StorageProviderInterface $provider

The bucket to walk.

\Drupal\strata\Cas\FrameIndexInterface $index

The frame index to rebuild.

\Drupal\strata\Tree\CommitIndex $commitIndex

The commit index to rebuild.

\Drupal\strata\Tree\CommitLog $commits

Reads commit objects.

\Drupal\strata\Tree\RefStore $refs

Lists the refs whose history is reachable.

\Drupal\strata\Segment\SegmentReader $segments

Reads segment manifests so payload frames can be counted.

\Psr\Log\LoggerInterface $logger

Records progress, since a full rebuild on a large bucket is not quick.

\Drupal\strata\Tier\TierPlacementRebuilder|null $placement

Rebuilds which bucket holds which object, or NULL on a store with one destination, where there is no such question to answer.

\Drupal\strata\Branch\BranchStore|null $branches

Reads the branches back out of the refs and the metadata beside them, or NULL to leave the branch index alone.

\Drupal\strata\Branch\BranchIndex|null $branchIndex

The branch index to rebuild.

Returns

mixed —

reindex()

reindex(bool  $fresh = true) : \Drupal\strata\Verify\ReindexReport

Rebuilds both indexes from what is in the bucket.

Parameters

bool $fresh

TRUE to drop both tables first. A rebuild that keeps existing rows cannot notice an object that has gone away, so this is the default for a repair and FALSE only when topping up an index that is known to be merely incomplete.

Returns

\Drupal\strata\Verify\ReindexReport —

What was rebuilt, and what could not be.

indexObjects()

indexObjects(list  $problems) : array{packs: int, frames: int}

Rebuilds the frame index from the pack and frame objects.

Every frame starts at zero references. Attribution is a separate pass over the segments, because a frame's object says nothing about who points at it.

Parameters

list $problems

Collects one line per unusable object.

Returns

array{packs: int, frames: int} —

How many packs were read and how many frame records were written.

indexCommits()

indexCommits(list  $problems) : int

Rebuilds the commit index from the commit objects.

Every commit object is indexed, not only the ones a ref reaches. A commit orphaned by a restore that rewound a ref is still a restore target and still the parent of a chain someone may want back, so dropping it here would quietly delete history the bucket still holds.

Parameters

list $problems

Collects one line per unusable object.

Returns

int —

How many commit rows were written.

indexBranches()

indexBranches(list  $problems) : int

Rebuilds the branch index from the refs and the metadata objects beside them.

A branch is a ref plus a small object naming where it was cut from, so both already exist in the bucket and neither is invented here. A ref whose metadata has gone is still indexed, with its own tip standing in as its fork point, because a branch that lost its provenance is still a branch and dropping it would hide history the store holds.

Parameters

list $problems

Collects one line per branch that could not be read.

Returns

int —

How many branch rows were written.

attributeReferences()

attributeReferences(list  $problems) : array{references: int, segments: int}

Counts what points at each frame, by reading every segment a ref can reach.

Segment payloads are the only thing counted, and matching what a flush counts is the whole point: a flush adds one reference per frame per operation payload as it writes, and nothing else. Base anchors name the same frames, but an anchor carries an entry for every subject that changed in its whole interval, so counting anchor entries would attribute a second reference to every frame the segments already counted. Whether a surviving anchor still needs a frame is a reachability question, answered by walking at prune time rather than by a counter.

Walking from the refs rather than from the commit table means a commit no ref reaches contributes no references. It stays indexed and restorable; it just does not hold frames alive against a prune.

Every parent is followed, not only the first. A merge commit's second parent is a line of history this ref reaches, and its segments were counted when they were flushed, so a rebuild that skipped them would come back with lower counts than the store was written with.

Parameters

list $problems

Collects one line per unusable object.

Returns

array{references: int, segments: int} —

How many references were attributed, and how many segments were read to find them.

attributeSegment()

attributeSegment(string  $key, list  $problems) : int

Adds one reference per payload frame a segment names.

Parameters

string $key

The segment's object key.

list $problems

Collects one line per unusable object.

Returns

int —

How many references were added.

keys()

keys(string  $prefix) : list<string>

Every key under a prefix, a page at a time.

Parameters

string $prefix

The prefix to list.

Returns

list

Object keys.