\Drupal\strata\Cas FrameIndexInterface

Tracks which frames the store already holds.

Deduplication is the whole reason this exists: before a frame is compressed, sealed and uploaded, the index is asked whether its content address is already present. A hit costs one local lookup and skips the entire pipeline plus a network round trip.

It also holds the reference counts a prune depends on. A frame is collectable only when nothing points at it, and the three things that can point at one - a segment, a tree and a file map - are counted the same way.

The index is derived state. Everything in it can be rebuilt from the objects in the bucket by strata:reindex, which is what makes it safe for a module uninstall to drop the tables.

Summary

Methods
Constants
has()
get()
record()
relocate()
reference()
dereference()
orphans()
page()
forget()
dependents()
deepestChains()
dictionaries()
clear()
statistics()
No public constants found

Methods

has()

has(string  $hash) : bool

Whether the store already holds a frame.

Parameters

string $hash

Content address of the decoded frame.

Returns

bool —

TRUE when the frame is present and the pipeline can be skipped.

get()

get(string  $hash) : \Drupal\strata\Cas\FrameRecord|null

The record for a frame.

Parameters

string $hash

Content address of the decoded frame.

Returns

\Drupal\strata\Cas\FrameRecord|null —

The record, or NULL when the frame is unknown.

record()

record(\Drupal\strata\Cas\FrameRecord  $record) : \Drupal\strata\Cas\FrameRecord

Records a newly stored frame, or increments an existing one.

Recording a frame the index already holds adds a reference rather than replacing the record, because the stored bytes are identical by construction and the location is already correct.

Parameters

\Drupal\strata\Cas\FrameRecord $record

The record.

Returns

\Drupal\strata\Cas\FrameRecord —

The stored record, with its resulting reference count.

relocate()

relocate(\Drupal\strata\Cas\FrameRecord  $record) : \Drupal\strata\Cas\FrameRecord

Replaces where a frame lives and how it is encoded, keeping its reference count.

What compaction needs. Recompressing a frame changes its object, its offset, its codec and its stored size, and changes nothing about its content address or who points at it - the address is the digest of the decoded bytes, so it survives a change of encoding by construction.

Distinct from FrameIndexInterface::record(), which treats a frame it already holds as a second reference to the same bytes in the same place and must not move it.

Parameters

\Drupal\strata\Cas\FrameRecord $record

The record's new location and encoding. Its reference count is ignored in favour of the one already stored.

Returns

\Drupal\strata\Cas\FrameRecord —

The stored record, with the reference count it kept.

reference()

reference(string  $hash, int  $count = 1) : int

Adds references to a frame.

Parameters

string $hash

Content address of the decoded frame.

int $count

How many references to add.

Returns

int —

The resulting reference count, or 0 when the frame is unknown.

dereference()

dereference(string  $hash, int  $count = 1) : int

Removes references from a frame.

The record is kept at zero references rather than deleted, so a prune can find it, report what it is about to remove, and be told not to.

Parameters

string $hash

Content address of the decoded frame.

int $count

How many references to remove.

Returns

int —

The resulting reference count, never below zero.

orphans()

orphans(int  $limit = 1000) : list<\Drupal\strata\Cas\FrameRecord>

Frames nothing points at any more.

Parameters

int $limit

Most records to return.

Returns

list<\Drupal\strata\Cas\FrameRecord> —

Collectable records.

page()

page(int  $limit = 1000, int  $offset = 0) : list<\Drupal\strata\Cas\FrameRecord>

One page of every frame the index holds, referenced or not, oldest first.

A pass that has to touch the whole store rather than a reachable part of it needs this: orphans() answers what is collectable and a tree walk answers what is reachable, and a key rotation is neither. Ordered by creation and then by address, so paging is stable while frames are being added.

Parameters

int $limit

Most records to return.

int $offset

Records to skip.

Returns

list<\Drupal\strata\Cas\FrameRecord> —

The page, empty once the offset is past the end.

forget()

forget(list  $hashes) : int

Removes records for frames that have been deleted from the store.

Parameters

list $hashes

Content addresses to forget.

Returns

int —

How many records were removed.

dependents()

dependents(string  $hash, int  $limit = 100) : list<\Drupal\strata\Cas\FrameRecord>

Frames that decode against a given frame.

The upward half of delta-chain reachability: a frame nothing references directly is still not collectable while something that IS referenced decodes against it.

Parameters

string $hash

Content address of the candidate parent.

int $limit

Most records to return, so the query stays bounded on a frame with many children.

Returns

list<\Drupal\strata\Cas\FrameRecord> —

Records naming this frame as their delta parent.

deepestChains()

deepestChains(int  $minimum, int  $limit = 100) : list<\Drupal\strata\Cas\FrameRecord>

Frames whose delta chains are at least a given depth, deepest first.

What a re-anchoring pass works from. Ordered deepest first because re-anchoring the deepest link shortens every chain hanging off it, so one rewrite can bring several chains back inside the cap.

Parameters

int $minimum

Fewest links a chain must have to be returned. Zero returns every delta frame.

int $limit

Most records to return, so a pass over a store with many long chains stays bounded.

Returns

list<\Drupal\strata\Cas\FrameRecord> —

The records, deepest chain first.

dictionaries()

dictionaries() : array<string,int>

Dictionaries the store cannot decode without.

Returns

array

Dictionary id keyed to how many referenced frames need it. A dictionary absent from this map is not needed by anything that is still reachable.

clear()

clear() : int

Drops every record.

Used by strata:reindex, which rebuilds the whole index from the bucket and must not inherit a stale row for an object that is no longer there.

Returns

int —

How many records were removed.

statistics()

statistics() : array{frames: int, rawBytes: int, storedBytes: int, orphans: int, ratio: float}

What the store holds, for the settings form and the storage explorer.

Returns

array{frames: int, rawBytes: int, storedBytes: int, orphans: int, ratio: float} —

Frame count, decoded and stored byte totals, how many frames are collectable, and the overall compression ratio.