@cloudbitmaps/roaring 0.19.1 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PRIVACY.md +59 -34
- package/README.md +3 -1
- package/dist/bin/export-segments.js +91 -110
- package/dist/bin/export-segments.js.map +2 -2
- package/dist/index.d.ts +110 -73
- package/dist/index.js +89 -112
- package/dist/index.js.map +2 -2
- package/dist/open-charging-storage.d.ts +3 -2
- package/dist/testing/conformance.d.ts +15 -10
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -23,8 +23,6 @@ import {
|
|
|
23
23
|
excludingReservedRows,
|
|
24
24
|
dropSegment,
|
|
25
25
|
eraseIdFromSegment,
|
|
26
|
-
estimateCost,
|
|
27
|
-
groundedReport,
|
|
28
26
|
judgeLoad,
|
|
29
27
|
loadSegment,
|
|
30
28
|
loadSegmentChunks,
|
|
@@ -45,7 +43,7 @@ import {
|
|
|
45
43
|
splitId,
|
|
46
44
|
takeLease
|
|
47
45
|
} from "@cloudbitmaps/core";
|
|
48
|
-
import { validateSegmentRef } from "@cloudbitmaps/core/driver-kit";
|
|
46
|
+
import { pointerIdOf, validateSegmentRef } from "@cloudbitmaps/core/driver-kit";
|
|
49
47
|
|
|
50
48
|
// src/open-charging-storage.ts
|
|
51
49
|
var OpenChargingStorage = class {
|
|
@@ -78,8 +76,9 @@ var OpenChargingStorage = class {
|
|
|
78
76
|
if (!this.free.has(key.generation)) this.charge();
|
|
79
77
|
return this.inner.getTail(key, maxBytes);
|
|
80
78
|
}
|
|
81
|
-
delete
|
|
82
|
-
|
|
79
|
+
/** Handed through whole: the erasure's delete of a holder is conditioned on the object it searched. */
|
|
80
|
+
delete(key, options) {
|
|
81
|
+
return this.inner.delete(key, options);
|
|
83
82
|
}
|
|
84
83
|
list(ref) {
|
|
85
84
|
return this.inner.list(ref);
|
|
@@ -648,10 +647,7 @@ import {
|
|
|
648
647
|
BufferReader,
|
|
649
648
|
CountingMetricsSink,
|
|
650
649
|
RecordingAuditSink,
|
|
651
|
-
DEFAULT_RETRY_POLICY as DEFAULT_RETRY_POLICY2
|
|
652
|
-
AWS_US_EAST_1_ONDEMAND,
|
|
653
|
-
ELASTICACHE_REDIS_US_EAST_1_ONDEMAND,
|
|
654
|
-
ONE_REDIS_HA_CLUSTER
|
|
650
|
+
DEFAULT_RETRY_POLICY as DEFAULT_RETRY_POLICY2
|
|
655
651
|
} from "@cloudbitmaps/core";
|
|
656
652
|
var SystemRng = class {
|
|
657
653
|
/** A float in `[0, 1)`. Jitter only — never key material, never anything a caller can observe. */
|
|
@@ -773,23 +769,7 @@ var CALL_KEYS = {
|
|
|
773
769
|
"concurrency",
|
|
774
770
|
"summaries"
|
|
775
771
|
]),
|
|
776
|
-
exportSegments: keysOf()(["format", "codec", "namespace", "ndjsonBatchBytes"])
|
|
777
|
-
costReport: keysOf()(["pricing", "workload"]),
|
|
778
|
-
workload: keysOf()([
|
|
779
|
-
"readsPerSec",
|
|
780
|
-
"intersectsPerSec",
|
|
781
|
-
"cacheHitRate",
|
|
782
|
-
"chunksPerIntersect",
|
|
783
|
-
"operandsPerIntersect",
|
|
784
|
-
"loadsPerMonth",
|
|
785
|
-
"requestsPerLoad",
|
|
786
|
-
"hotSegments",
|
|
787
|
-
"readerProcesses",
|
|
788
|
-
"genTtlMs",
|
|
789
|
-
"retirementsPerMonth",
|
|
790
|
-
"purgesPerMonth",
|
|
791
|
-
"conditionalDelete"
|
|
792
|
-
])
|
|
772
|
+
exportSegments: keysOf()(["format", "codec", "namespace", "ndjsonBatchBytes"])
|
|
793
773
|
};
|
|
794
774
|
var kindOf = (v) => v === null ? "null" : Array.isArray(v) ? "an array" : `a ${typeof v}`;
|
|
795
775
|
function optionsError(options, op, known, booleans = []) {
|
|
@@ -1141,22 +1121,24 @@ var CloudRoaring = class _CloudRoaring {
|
|
|
1141
1121
|
}
|
|
1142
1122
|
/**
|
|
1143
1123
|
* Get a handle to a segment. Validates the name (non-empty, well-formed, within the encoded-length cap). The options
|
|
1144
|
-
* are `{ namespace }` and nothing else:
|
|
1145
|
-
* misspelt `namespace` would otherwise address the default namespace
|
|
1146
|
-
*
|
|
1147
|
-
* `undefined` is read as absent, so a
|
|
1124
|
+
* are a plain object holding `{ namespace }` and nothing else: any other own key, enumerable or not, is refused with
|
|
1125
|
+
* {@link ValidationError}, by name, since a misspelt `namespace` would otherwise address the default namespace, and a
|
|
1126
|
+
* deadline such as `expiresAt` would be left unread. A class instance, or an object built on another, is refused too,
|
|
1127
|
+
* since it can carry an option no scan of its own keys sees. A key whose value is `undefined` is read as absent, so a
|
|
1128
|
+
* spread of options keeps working.
|
|
1148
1129
|
*/
|
|
1149
1130
|
segment(name, options) {
|
|
1150
1131
|
if (options !== void 0 && options !== null) {
|
|
1151
1132
|
if (typeof options !== "object" || Array.isArray(options)) {
|
|
1152
1133
|
throw new ValidationError2("segment: options must be an object such as { namespace }");
|
|
1153
1134
|
}
|
|
1154
|
-
|
|
1135
|
+
const proto = Object.getPrototypeOf(options);
|
|
1136
|
+
if (proto !== null && Object.getPrototypeOf(proto) !== null) {
|
|
1155
1137
|
throw new ValidationError2(
|
|
1156
|
-
"segment:
|
|
1138
|
+
"segment: options must be a plain object such as { namespace }, not a class instance or an object built on another"
|
|
1157
1139
|
);
|
|
1158
1140
|
}
|
|
1159
|
-
const unknown = Object.
|
|
1141
|
+
const unknown = Object.getOwnPropertyNames(options).filter(
|
|
1160
1142
|
(k) => k !== "namespace" && options[k] !== void 0
|
|
1161
1143
|
);
|
|
1162
1144
|
if (unknown.length > 0) {
|
|
@@ -1190,13 +1172,20 @@ var CloudRoaring = class _CloudRoaring {
|
|
|
1190
1172
|
* of it. A materialisation is a load whose ids happen to come from a combine instead of from upstream, so
|
|
1191
1173
|
* everything `load()` learned the hard way applies unchanged: the generation is written UNPUBLISHED, the
|
|
1192
1174
|
* guard runs while the old generation is still authoritative, the publish is fenced as above, and a refused
|
|
1193
|
-
* object is reclaimed only when a re-read finds the row unchanged (the same token
|
|
1194
|
-
*
|
|
1195
|
-
*
|
|
1196
|
-
*
|
|
1197
|
-
*
|
|
1198
|
-
* the
|
|
1199
|
-
*
|
|
1175
|
+
* object is reclaimed only when a re-read finds the row unchanged (the same token, or one that differs only in
|
|
1176
|
+
* its leases), `destroyed`, or gone, or finds key material on it when the load wrote cleartext; under any other
|
|
1177
|
+
* row it is kept (hard invariant 1: deleting it after a purge-and-recreate would put a live row over a missing
|
|
1178
|
+
* generation).
|
|
1179
|
+
*
|
|
1180
|
+
* Where the row is gone, or keyed over a cleartext write, the object is proved the load's own by its footer, and
|
|
1181
|
+
* the delete passes the version that read reported, so on a storage driver that reports `conditionalDelete` an
|
|
1182
|
+
* object put under the number since is kept. Where the row is unchanged or `destroyed`, the check narrows the
|
|
1183
|
+
* window rather than closing it: the row read and the delete are two round trips, and the delete is by number,
|
|
1184
|
+
* since the write reports no version of the object it made. The other deletes a load leads to are by number too: its
|
|
1185
|
+
* collection deletes what a listing, or the row's list of kept generations, names below the pointer, and a drop's
|
|
1186
|
+
* sweep and a tombstoned segment's collection delete what a listing names under a `destroyed` row. The failure the
|
|
1187
|
+
* checks leave when they refuse is an orphan object, which costs storage until something collects it —
|
|
1188
|
+
* deliberately the cheaper side of the trade.
|
|
1200
1189
|
*
|
|
1201
1190
|
* Written and published in one step, with no guard, an empty combine — a typo'd operand, an `exclude` that
|
|
1202
1191
|
* swallowed everything, an operand that had not loaded yet — would silently replace `dest` with an empty
|
|
@@ -1561,7 +1550,7 @@ var CloudRoaring = class _CloudRoaring {
|
|
|
1561
1550
|
}
|
|
1562
1551
|
}
|
|
1563
1552
|
const row = await this.withRetries(() => registry.get(ref));
|
|
1564
|
-
return row === null ? null : { generation: row.currentGen, token: row
|
|
1553
|
+
return row === null ? null : { generation: row.currentGen, token: pointerIdOf(row) };
|
|
1565
1554
|
}
|
|
1566
1555
|
/** Throw what a read of, or a publish to, `handle` must throw now: its lease error, if it has one. */
|
|
1567
1556
|
assertLease(handle) {
|
|
@@ -1606,7 +1595,7 @@ var CloudRoaring = class _CloudRoaring {
|
|
|
1606
1595
|
const ref = { segment: rec.segment, namespace: rec.namespace };
|
|
1607
1596
|
if (this.crbmSource !== void 0) {
|
|
1608
1597
|
const held = await this.crbmSource.currentVersion(ref);
|
|
1609
|
-
const listed = rec.currentGen === null ? null : `${rec.currentGen}:${
|
|
1598
|
+
const listed = rec.currentGen === null ? null : `${rec.currentGen}:${pointerIdOf(rec)}`;
|
|
1610
1599
|
if (rowVersionOfLive(held) !== listed) this.engine.invalidate(ref);
|
|
1611
1600
|
}
|
|
1612
1601
|
return await this.engine.has(ref, id) ? { segment: rec.segment, namespace: rec.namespace } : null;
|
|
@@ -1626,10 +1615,14 @@ var CloudRoaring = class _CloudRoaring {
|
|
|
1626
1615
|
* can still hold it, and so can one above the pointer after a {@link CloudRoaring.rollback}, which the rollback
|
|
1627
1616
|
* could make current again. Each holder is deleted — below the pointer by a `keep: 0` collection, above it one
|
|
1628
1617
|
* by one, re-proved against the row first — and the generations above the pointer that never held the id stay
|
|
1629
|
-
* as rollback targets
|
|
1630
|
-
*
|
|
1631
|
-
*
|
|
1632
|
-
*
|
|
1618
|
+
* as rollback targets, but for any object no read of the segment can open, which goes whatever the id. An entry
|
|
1619
|
+
* says `erased: true` only once the call has listed the bucket and read what is left: **no generation of the
|
|
1620
|
+
* segment holds the id**. The returned per-segment record is your **erasure ledger** —
|
|
1621
|
+
* persist it / route it to your audit sink as the proof of deletion (when you pass `audit`, an audit event is also
|
|
1622
|
+
* emitted per segment erased: `segment.rewrite` for a rewrite, `segment.collect` where only other generations held
|
|
1623
|
+
* the id and nothing was rewritten). A segment where the erasure deleted only objects no read of it can open (a first
|
|
1624
|
+
* load's sealed under a key no row holds) found the id in none, so the ledger does not list it; the audit sink gets
|
|
1625
|
+
* `segment.collect` for it with no `fromGeneration`, which is the only record of that deletion.
|
|
1633
1626
|
*
|
|
1634
1627
|
* Uses the backend's **own** two halves, so the membership check and the rewrite provably run
|
|
1635
1628
|
* over the same generation. Requires the store built with a **backend** (throws
|
|
@@ -1651,13 +1644,21 @@ var CloudRoaring = class _CloudRoaring {
|
|
|
1651
1644
|
* an error, read off the row: a moved pointer is a `'superseded'` entry, which a re-run settles, and a segment
|
|
1652
1645
|
* that a concurrent `dropSegment` tombstoned or a retention sweep purged is left out of the ledger. A tombstoned
|
|
1653
1646
|
* segment is still searched: a cleartext object left under it that holds the id is deleted, with everything under
|
|
1654
|
-
* the tombstone, and the entry reads `erased: true`.
|
|
1647
|
+
* the tombstone, and the entry reads `erased: true`. So is a segment whose row names no generation yet (a retention
|
|
1648
|
+
* policy set before its first load): a first load's object that holds the id is deleted, once the row's `pointerId`
|
|
1649
|
+
* is renewed so that the load, if still running, is refused at its publish, and the entry reads `erased: true`. An
|
|
1650
|
+
* encrypted first load's object there cannot be searched, so it is deleted whatever the id: on an encrypted store,
|
|
1651
|
+
* an erasure of any id refuses an encrypted first load in flight that has written its object onto a segment made
|
|
1652
|
+
* ahead of its data. Each such delete, and each of a holder above the pointer, names the object the erasure read:
|
|
1653
|
+
* on a storage driver that reports `conditionalDelete`, another erasure of the id that deletes it first, followed by
|
|
1654
|
+
* a load that takes the number freed and publishes, does not lose that load's generation to this erasure's delete,
|
|
1655
|
+
* which is refused, and the entry says what the row says; on one that does not, it can.
|
|
1655
1656
|
*
|
|
1656
1657
|
* **Read `note` on any `erased: false` entry — the two reasons mean different things.** `'superseded'` means
|
|
1657
|
-
* another writer (a load, another erasure, or a rollback) moved the pointer
|
|
1658
|
-
* erase the id. Re-run: it erases the id if it is still there, and lists
|
|
1659
|
-
* erasure of the same id already removed it. Do not read `'superseded'` as
|
|
1660
|
-
* read it as "not done by this call, and the re-run settles it".
|
|
1658
|
+
* another writer (a load, another erasure, or a rollback) moved the pointer, or replaced an object the call meant to
|
|
1659
|
+
* delete, mid-call, so **this call** did not erase the id. Re-run: it erases the id if it is still there, and lists
|
|
1660
|
+
* nothing for the segment if a racing erasure of the same id already removed it. Do not read `'superseded'` as
|
|
1661
|
+
* "the id is still present" — read it as "not done by this call, and the re-run settles it".
|
|
1661
1662
|
* `` `error: …` `` is a per-segment fault (caught so one segment can't discard the whole ledger) and it can land
|
|
1662
1663
|
* on either side of the publish: if the rewrite had not published, the id is still there and a re-run erases
|
|
1663
1664
|
* it; if the publish succeeded and only the **collection** of the old generation failed, the id is already
|
|
@@ -1852,8 +1853,9 @@ var CloudRoaring = class _CloudRoaring {
|
|
|
1852
1853
|
* and are then *above* `currentGen`, where collection never looks. They remain until loads pass them (the first
|
|
1853
1854
|
* load whose number one of them holds numbers above them all, and collection then keeps the newest `keep` of what is
|
|
1854
1855
|
* below its pointer), {@link CloudRoaring.dropSegment}
|
|
1855
|
-
* deletes them, or {@link CloudRoaring.eraseSubject} does: all of those present when it rewrites, and
|
|
1856
|
-
*
|
|
1856
|
+
* deletes them, or {@link CloudRoaring.eraseSubject} does: all of those present when it rewrites, and, when the
|
|
1857
|
+
* current generation does not hold the id, only those holding it and any no read of the segment can open, whatever
|
|
1858
|
+
* the id. An operator who has just undone a bad load should not have the
|
|
1857
1859
|
* evidence collected out from under them, while a rollback target that still holds erased data would make the
|
|
1858
1860
|
* erasure undoable.
|
|
1859
1861
|
*
|
|
@@ -1922,10 +1924,12 @@ var CloudRoaring = class _CloudRoaring {
|
|
|
1922
1924
|
* published, a retention change, a rollback or an erasure wrote the row, or the row was deleted.
|
|
1923
1925
|
*
|
|
1924
1926
|
* A refused load deletes the object it wrote before returning — it sits above `currentGen`, where generation
|
|
1925
|
-
* collection deliberately never looks — but only while the segment's registry row is unchanged or
|
|
1926
|
-
*
|
|
1927
|
-
*
|
|
1928
|
-
*
|
|
1927
|
+
* collection deliberately never looks — but only while the segment's registry row is unchanged (or differs only
|
|
1928
|
+
* in its leases), `destroyed` or gone, or has key material when the load wrote cleartext, which has no place in an
|
|
1929
|
+
* encrypted segment's bucket. Under a row that is gone or keyed, a read of the object's footer must prove it the
|
|
1930
|
+
* load's own first. Once another write has otherwise changed the row, the generation number it holds may name
|
|
1931
|
+
* another incarnation's live object, so it leaves the orphan rather than risk deleting live data. No row's list
|
|
1932
|
+
* names it, so it takes no place in a window, and a listing deletes it once a later generation is current above it.
|
|
1929
1933
|
*
|
|
1930
1934
|
* **Collection is by name at any `keep` up to 64.** The segment's row records the generations a load keeps, so a load
|
|
1931
1935
|
* that found nothing above the pointer deletes the generations its publish pushed out of the window and lists
|
|
@@ -2138,8 +2142,8 @@ var CloudRoaring = class _CloudRoaring {
|
|
|
2138
2142
|
* Pass `purgeTombstones: false` to keep every tombstone, that row included. On a backend whose registry reports
|
|
2139
2143
|
* `conditionalDelete` (AWS S3, Azure Blob, the local filesystem and memory, by default; GCS when you set `conditionalDelete: true`)
|
|
2140
2144
|
* the purge removes the row from the bucket for good, by a delete the store applies only to the version it judged,
|
|
2141
|
-
* so a full sweep reads what is live or inside its grace rather than every name a namespace ever held; elsewhere
|
|
2142
|
-
*
|
|
2145
|
+
* so a full sweep reads what is live or inside its grace rather than every name a namespace ever held; elsewhere it
|
|
2146
|
+
* leaves a tombstone. Each retirement files a pointer in the due index
|
|
2143
2147
|
* under the day its tombstone's grace ends, so `scan: 'index'` purges as well as retires.
|
|
2144
2148
|
*
|
|
2145
2149
|
* Needs the store built with a **backend** (throws {@link UnsupportedError} otherwise),
|
|
@@ -2363,7 +2367,8 @@ var CloudRoaring = class _CloudRoaring {
|
|
|
2363
2367
|
* A segment whose pointer names a missing object is the torn restore this reports; a cold `count()` of it still
|
|
2364
2368
|
* answers the number its row records, while a read of the object throws, so the count alone never shows it. With
|
|
2365
2369
|
* `summaries: true` it also opens each segment's current object (one tail read each) and reports a segment whose
|
|
2366
|
-
* row's summary says another id count or metadata than the object holds
|
|
2370
|
+
* row's summary names another object by its fingerprint, or says another id count or metadata than the object holds,
|
|
2371
|
+
* as `summary-mismatch`, which is what a
|
|
2367
2372
|
* restore of the registry from another point than the bucket leaves a count to answer. A sealed summary is held
|
|
2368
2373
|
* against its object when this store has the key, and counted in `summariesUnchecked` when it does not.
|
|
2369
2374
|
*
|
|
@@ -2399,15 +2404,6 @@ var CloudRoaring = class _CloudRoaring {
|
|
|
2399
2404
|
const registry = this.requireRegistry("exportSegments");
|
|
2400
2405
|
return runExport(this, registry, sink, { ...opts, codec: opts.codec ?? roaringCodec });
|
|
2401
2406
|
}
|
|
2402
|
-
/**
|
|
2403
|
-
* Planning cost estimate — pure, no instance/data needed: sizing, sales, what-if. For a real, grounded report
|
|
2404
|
-
* from live segment sizes, use `store.segment(name).costReport()`. See {@link CostReport}.
|
|
2405
|
-
* @deprecated Moves to `@cloudbitmaps/tools`, a package of its own, with a `size` on `stat()` so a grounded report
|
|
2406
|
-
* needs nothing internal. It is a planning tool, and its price list is as old as the release that ships it.
|
|
2407
|
-
*/
|
|
2408
|
-
static estimateCost(input) {
|
|
2409
|
-
return estimateCost(input);
|
|
2410
|
-
}
|
|
2411
2407
|
};
|
|
2412
2408
|
var withBatches = (gen, batches) => Object.assign(gen, { batches });
|
|
2413
2409
|
var failing = (err) => {
|
|
@@ -2804,8 +2800,8 @@ var Segment = class _Segment {
|
|
|
2804
2800
|
* Cardinality of the generation this handle reads: **one registry read when cold, none when warm, and no read of the
|
|
2805
2801
|
* object**, with **zero payload reads**. The registry row records the id count of the generation it names, written
|
|
2806
2802
|
* by the write that made it current, and a count answers from that. A row with no summary it can use (one written
|
|
2807
|
-
*
|
|
2808
|
-
* `.crbm` index, summed with a tail read of the object. A segment whose pointer names a missing object (a torn
|
|
2803
|
+
* without it, as a registry of your own may, one that names another generation, a sealed one that does not open)
|
|
2804
|
+
* sends the count to the `.crbm` index, summed with a tail read of the object. A segment whose pointer names a missing object (a torn
|
|
2809
2805
|
* restore) still counts the row's number, while a read of the object throws; `checkConsistency` is what finds it.
|
|
2810
2806
|
*
|
|
2811
2807
|
* What this trusts: the row's summary, or the index's sum, and no payload is decoded to confirm it. The summary is
|
|
@@ -2824,17 +2820,30 @@ var Segment = class _Segment {
|
|
|
2824
2820
|
return this.timed("count", () => this.engine.count(this.ref));
|
|
2825
2821
|
}
|
|
2826
2822
|
/**
|
|
2827
|
-
* What the generation this handle reads is, from one resolution: its number, its id count
|
|
2828
|
-
*
|
|
2829
|
-
*
|
|
2830
|
-
*
|
|
2831
|
-
*
|
|
2832
|
-
*
|
|
2833
|
-
*
|
|
2834
|
-
*
|
|
2823
|
+
* What the generation this handle reads is, from one resolution: its number, its id count, the metadata it was
|
|
2824
|
+
* loaded with (absent when it has none), and `sizeBytes`, its object's bytes in storage. All four come from the
|
|
2825
|
+
* registry row when it has a summary this store can use, as `count()`'s do: the summary records the object's
|
|
2826
|
+
* fingerprint, its size with its checksum. That is **one registry read when cold, none when warm, and no read of the
|
|
2827
|
+
* object**. With no summary it can use, they come from the generation's object, opened once: its footer and index,
|
|
2828
|
+
* with no payload read, which is a tail read of the object more when cold (and a range read for an index longer than
|
|
2829
|
+
* the tail) and keeps the generation in the reader cache as a read does. On a pinned handle it answers for the
|
|
2830
|
+
* generation it pinned, from the pinned object. A segment with no generation answers
|
|
2831
|
+
* `{ generation: null, cardinality: 0, sizeBytes: null }`, and a store whose source cannot report a size answers
|
|
2832
|
+
* `sizeBytes: null`. A pointer that names a missing object (a torn restore) still answers from the row's summary, as
|
|
2833
|
+
* `count()` does, while a read of the object throws `NotFoundError`; with no summary to use, `stat()` throws it too.
|
|
2834
|
+
* `checkConsistency` is what finds such a row.
|
|
2835
|
+
*
|
|
2836
|
+
* Trust is as for `count()`: what the row's summary says is believed until the object is next opened. Every open of
|
|
2837
|
+
* the generation holds the object to the fingerprint the summary records, so another object under the number is
|
|
2838
|
+
* refused when it is opened, and holds its count against the summary's; a disagreement in count makes this process
|
|
2839
|
+
* stop using that summary, so `stat()` then answers from the object, whose index is checked for internal consistency
|
|
2840
|
+
* and whose count is the index's sum. A reader already open is not checked again until the row changes, it is
|
|
2841
|
+
* evicted or it is invalidated.
|
|
2842
|
+
*
|
|
2843
|
+
* `sizeBytes` is what `groundedReport` in `@cloudbitmaps/tools` prices storage from.
|
|
2835
2844
|
*
|
|
2836
2845
|
* ```ts
|
|
2837
|
-
* const { generation, cardinality, metadata } = await store.segment('active-30d').stat();
|
|
2846
|
+
* const { generation, cardinality, metadata, sizeBytes } = await store.segment('active-30d').stat();
|
|
2838
2847
|
* ```
|
|
2839
2848
|
*/
|
|
2840
2849
|
async stat() {
|
|
@@ -3124,38 +3133,8 @@ var Segment = class _Segment {
|
|
|
3124
3133
|
)
|
|
3125
3134
|
);
|
|
3126
3135
|
}
|
|
3127
|
-
/**
|
|
3128
|
-
* Grounded cost report for this segment: storage cost from its **real** `.crbm` size (exact, no payload
|
|
3129
|
-
* reads); request cost from the supplied `workload` rates. A segment with no Storage generation reports zero
|
|
3130
|
-
* storage. The pointer refresh is priced at the store's own `cache.genTtlMs`, or at none when the store never
|
|
3131
|
-
* refreshes, unless the workload sets `genTtlMs`. See {@link CostReport} — it always includes a verdict (incl.
|
|
3132
|
-
* the lose-zone).
|
|
3133
|
-
* @deprecated Moves to `@cloudbitmaps/tools`, a package of its own, with a `size` on `stat()` so a grounded report
|
|
3134
|
-
* needs nothing internal. It is a planning tool, and its price list is as old as the release that ships it.
|
|
3135
|
-
*/
|
|
3136
|
-
async costReport(options) {
|
|
3137
|
-
checkOptions(options, "costReport", CALL_KEYS.costReport);
|
|
3138
|
-
const shape = options?.workload;
|
|
3139
|
-
if (shape !== void 0 && shape !== null && (typeof shape !== "object" || Array.isArray(shape))) {
|
|
3140
|
-
throw new ValidationError2("costReport: workload must be an object");
|
|
3141
|
-
}
|
|
3142
|
-
this.assertLeases([this]);
|
|
3143
|
-
const canMeasure = this.engine.supportsStorageSize;
|
|
3144
|
-
const size = canMeasure ? await this.engine.segmentSize(this.ref) : null;
|
|
3145
|
-
const refreshMs = this.engine.pointerRefreshMs;
|
|
3146
|
-
const given = options?.workload === void 0 || options.workload === null ? void 0 : picked(options.workload, CALL_KEYS.workload);
|
|
3147
|
-
const workload = refreshMs === void 0 || given?.genTtlMs !== void 0 ? given : { ...given, genTtlMs: refreshMs };
|
|
3148
|
-
return groundedReport({
|
|
3149
|
-
storageBytes: size?.sizeBytes ?? 0,
|
|
3150
|
-
grounded: canMeasure,
|
|
3151
|
-
workload,
|
|
3152
|
-
pricing: options?.pricing,
|
|
3153
|
-
extraNotes: canMeasure ? void 0 : ["storage source has no sizeOf() \u2014 storage not measured, reported as $0."]
|
|
3154
|
-
});
|
|
3155
|
-
}
|
|
3156
3136
|
};
|
|
3157
3137
|
export {
|
|
3158
|
-
AWS_US_EAST_1_ONDEMAND,
|
|
3159
3138
|
BudgetExceededError,
|
|
3160
3139
|
BufferReader,
|
|
3161
3140
|
CapabilityError,
|
|
@@ -3165,7 +3144,6 @@ export {
|
|
|
3165
3144
|
CrbmReader,
|
|
3166
3145
|
CrbmStorageChunkSource2 as CrbmStorageChunkSource,
|
|
3167
3146
|
DEFAULT_RETRY_POLICY2 as DEFAULT_RETRY_POLICY,
|
|
3168
|
-
ELASTICACHE_REDIS_US_EAST_1_ONDEMAND,
|
|
3169
3147
|
InProcessKeystore,
|
|
3170
3148
|
IntegrityError3 as IntegrityError,
|
|
3171
3149
|
KeyUnavailableError,
|
|
@@ -3179,7 +3157,6 @@ export {
|
|
|
3179
3157
|
MemoryStorage,
|
|
3180
3158
|
NodeAead,
|
|
3181
3159
|
NotFoundError2 as NotFoundError,
|
|
3182
|
-
ONE_REDIS_HA_CLUSTER,
|
|
3183
3160
|
RecordingAuditSink,
|
|
3184
3161
|
Segment,
|
|
3185
3162
|
StaleOperandError,
|