\Drupal\strata\File FileMap

One version of one file, as the ordered list of blocks that rebuild it.

This is what a file version costs to store: a few dozen bytes per block rather than the blocks themselves, since the blocks are content-addressed and shared with every other version that contains them. A 256 MiB file is 4,096 blocks, so its map is about 270 KiB of digests - and the second version of the same file with a 2 MiB edit stores a second map plus the 33 blocks that changed.

The order matters and is the whole point: the same blocks in a different order are a different file. So a map is a list, never a set, and its own address covers the order.

Summary

Methods
Properties
Constants
__construct
address
count
isEmpty
distinct
storedCeiling
positionOf
key
encode
decode
jsonSerialize
path
blocks
length
blockSize
capturedAt
VERSION
PREFIX
No protected methods found
No protected properties found
No protected constants found
No private methods found
No private properties found
No private constants found

Constant

VERSION

VERSION = 1

Format marker, so a future change is a new version rather than a silent misread.

PREFIX

PREFIX = 'filemaps'

Key prefix maps are stored under.

Properties

$path

$path : string

Type

string

$blocks

$blocks : array

Type

array<string|int, mixed>

$length

$length : int

Type

int

$blockSize

$blockSize : int

Type

int

$capturedAt

$capturedAt : int

Type

int

Methods

__construct()

__construct(string  $path, list  $blocks, int  $length, int  $blockSize = \Drupal\strata\File\BlockSplitter::DEFAULT_SIZE, int  $capturedAt = 0) : mixed

Constructs a map.

Parameters

string $path

The file's path, relative to whatever root the capture walked.

list $blocks

Block content addresses, in file order.

int $length

The file's length in bytes.

int $blockSize

The block size the map was split at, recorded because a map split at one size cannot be compared with one split at another and a reader has to be able to tell.

int $capturedAt

Unix seconds.

Throws

\InvalidArgumentException

When the path is empty, a block is not a digest, or the length disagrees with the block count.

Returns

mixed —

address()

address() : string

This map's content address.

Returns

string —

A 64-character lowercase hex digest.

count()

count() : int

How many blocks the file has.

Returns

int —

The count.

isEmpty()

isEmpty() : bool

Whether the file has no content.

Returns

bool —

TRUE for a zero-length file.

distinct()

distinct() : list<string>

The distinct blocks the file is made of.

A file with a long run of identical content - a sparse image, a padded archive - has far fewer distinct blocks than blocks, and only the distinct ones are stored.

Returns

list

Block addresses, deduplicated, in first-seen order.

storedCeiling()

storedCeiling() : int

Bytes the distinct blocks occupy, at most.

The last block of a file is usually short, so this is an upper bound rather than a measurement.

Returns

int —

Bytes.

positionOf()

positionOf(int  $index) : array{offset: int, length: int}|null

Where one block sits in the file.

Parameters

int $index

Block index, zero-based.

Returns

array{offset: int, length: int}|null —

The offset and length, or NULL when the index is past the end.

key()

key() : string

The object key this map is stored under.

Keyed by the file's identity and the map's own address, so every version of a file lists together and no two versions collide.

Returns

string —

The key.

encode()

encode() : string

The stored form.

Throws

\JsonException

When the path holds bytes that are not valid UTF-8, which a filename can. (string) false would otherwise write an empty map addressed as Hash::of('').

Returns

string —

JSON.

decode()

decode(string  $payload) : \Drupal\strata\File\FileMap

A map from its stored form.

Parameters

string $payload

The bytes.

Throws

\RuntimeException

When the payload is not a map this release can read.

Returns

\Drupal\strata\File\FileMap —

The map.

jsonSerialize()

jsonSerialize() : array<string,mixed>

{@inheritdoc}

Returns

array

The map as data.