\Drupal\strata\Estimate Measurement

The shape of a site and the policy applied to it, as an estimate's input.

Two kinds of thing, deliberately in one object because an estimate is meaningless without both. The shape - users, nodes, rows, files - decides how much churn there is. The policy - flush interval, base interval, retention, whether files are captured at all - decides what that churn costs. A site twice the size on half the interval is not twice the bill.

Per-realm daily operation counts can be supplied directly. Left empty they are derived from the shape using the recorded per-subject rates, which is what the estimate form does. A calibration pass instead counts what the site actually wrote in the last day and passes those, which turns a projection into a back-test.

Summary

Methods
Properties
Constants
__construct
subjects
activeUsers
flushesPerMonth
basesPerYear
with
fromArray
jsonSerialize
users
nodes
rows
files
fileBytes
activeShare
segmentInterval
baseInterval
retentionDays
deploysPerYear
accessChurn
captureFiles
opsPerDay
ACCESS_EVENT
ACCESS_DELTA
ACCESS_OFF
ACCESS_MODES
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

ACCESS_EVENT

ACCESS_EVENT = 'event'

Access churn recorded as a compact login event.

The default. 48 bytes per event, 24% cheaper than a full field delta, and it keeps the security trail a rollback should never erase.

ACCESS_DELTA

ACCESS_DELTA = 'delta'

Access churn recorded as a full field delta.

ACCESS_OFF

ACCESS_OFF = 'off'

Access churn not recorded at all.

Measured as costing MORE than the event mode rather than less, because the row is still dirty and the reconciler picks it up later at full price.

ACCESS_MODES

ACCESS_MODES = [self::ACCESS_EVENT, self::ACCESS_DELTA, self::ACCESS_OFF]

Every access churn mode.

Properties

$users

$users : int

Type

int

$nodes

$nodes : int

Type

int

$rows

$rows : int

Type

int

$files

$files : int

Type

int

$fileBytes

$fileBytes : int

Type

int

$activeShare

$activeShare : float

Type

float

$segmentInterval

$segmentInterval : int

Type

int

$baseInterval

$baseInterval : int

Type

int

$retentionDays

$retentionDays : int

Type

int

$deploysPerYear

$deploysPerYear : int

Type

int

$accessChurn

$accessChurn : string

Type

string

$captureFiles

$captureFiles : bool

Type

bool

$opsPerDay

$opsPerDay : array

Type

array<string|int, mixed>

Methods

__construct()

__construct(int  $users = 0, int  $nodes = 0, int  $rows = 0, int  $files = 0, int  $fileBytes = 0, float  $activeShare = 0.1, int  $segmentInterval = 15, int  $baseInterval = 14400, int  $retentionDays = 365, int  $deploysPerYear = 150, string  $accessChurn = \self::ACCESS_EVENT, bool  $captureFiles = false, array  $opsPerDay = []) : mixed

Constructs a measurement.

Parameters

int $users

Registered users.

int $nodes

Content items.

int $rows

Rows in tables the site's own modules write, which are subjects like any other.

int $files

Managed and unmanaged files.

int $fileBytes

Total bytes those files occupy.

float $activeShare

Share of users active on a given day, which is what generates access churn.

int $segmentInterval

Seconds between flushes, which is the durability window and the request-cost dial.

int $baseInterval

Seconds between base anchors.

int $retentionDays

How long the coarsest retention level keeps history.

int $deploysPerYear

Deploys, which is how often the code realm changes.

string $accessChurn

One of the access modes.

bool $captureFiles

Whether the file realm is captured, which is the single largest switch in the model.

array $opsPerDay

Realm value keyed to operations a day, overriding what the shape would imply. Empty to derive them.

Throws

\InvalidArgumentException

When a count is negative, an interval is not positive, or the access mode is unknown.

Returns

mixed —

subjects()

subjects() : int

How many distinct things the history describes.

The number the tree cost scales with, and the reason a user costs about ten times what a node costs: both are one subject, but a user is written to far more often.

Returns

int —

Subjects.

activeUsers()

activeUsers() : float

Users active on a given day.

Returns

float —

The count, fractional because it is a rate rather than a headcount.

flushesPerMonth()

flushesPerMonth() : int

Flushes a month, which is what the write-request bill is made of.

Independent of the site's size, which is the whole point of stating it separately: a thousand-user site and a million-user site perform the same number of flushes.

Returns

int —

Flushes.

basesPerYear()

basesPerYear() : int

Base anchors a year.

Returns

int —

Bases.

with()

with(array  $changes) : \Drupal\strata\Estimate\Measurement

The same measurement with one field replaced.

What a capacity search and a what-if column both need: an estimate is run many times over one shape with one dial moved, and a value object that cannot be varied would force the caller to repeat every other field.

Parameters

array $changes

Field name keyed to its new value.

Returns

\Drupal\strata\Estimate\Measurement —

The new measurement.

fromArray()

fromArray(array  $values) : \Drupal\strata\Estimate\Measurement

A measurement from its serialized form.

Parameters

array $values

The fields, any of which may be missing.

Returns

\Drupal\strata\Estimate\Measurement —

The measurement.

jsonSerialize()

jsonSerialize() : array<string,mixed>

{@inheritdoc}

Returns

array

The measurement as data.