@lix-js/sdk 0.6.0-preview.3 → 0.6.0-preview.5
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/README.md +1 -1
- package/SKILL.md +105 -65
- package/dist/engine-wasm/index.js +4 -4
- package/dist/engine-wasm/wasm/lix_engine.d.ts +30 -6
- package/dist/engine-wasm/wasm/lix_engine.js +187 -117
- package/dist/engine-wasm/wasm/lix_engine.wasm +0 -0
- package/dist/engine-wasm/wasm/lix_engine.wasm.d.ts +14 -8
- package/dist/generated/builtin-schemas.d.ts +69 -69
- package/dist/generated/builtin-schemas.js +94 -94
- package/dist/open-lix.d.ts +42 -28
- package/dist/open-lix.js +49 -10
- package/dist/sqlite/index.js +86 -30
- package/dist-engine-src/README.md +3 -3
- package/dist-engine-src/src/backend/capabilities.rs +67 -0
- package/dist-engine-src/src/backend/conformance/baseline.rs +1127 -0
- package/dist-engine-src/src/backend/conformance/factory.rs +93 -0
- package/dist-engine-src/src/backend/conformance/failure_tests.rs +608 -0
- package/dist-engine-src/src/backend/conformance/fixtures.rs +26 -0
- package/dist-engine-src/src/backend/conformance/mod.rs +75 -0
- package/dist-engine-src/src/backend/conformance/model.rs +28 -0
- package/dist-engine-src/src/backend/conformance/model_based.rs +257 -0
- package/dist-engine-src/src/backend/conformance/persistence.rs +204 -0
- package/dist-engine-src/src/backend/conformance/projection.rs +21 -0
- package/dist-engine-src/src/backend/conformance/pushdown.rs +24 -0
- package/dist-engine-src/src/backend/conformance/runner.rs +90 -0
- package/dist-engine-src/src/backend/conformance/scan.rs +24 -0
- package/dist-engine-src/src/backend/conformance/write.rs +16 -0
- package/dist-engine-src/src/backend/error.rs +94 -0
- package/dist-engine-src/src/backend/in_memory.rs +670 -0
- package/dist-engine-src/src/backend/mod.rs +36 -9
- package/dist-engine-src/src/backend/predicate.rs +80 -0
- package/dist-engine-src/src/backend/traits.rs +260 -0
- package/dist-engine-src/src/backend/types.rs +224 -81
- package/dist-engine-src/src/binary_cas/context.rs +8 -8
- package/dist-engine-src/src/binary_cas/kv.rs +234 -259
- package/dist-engine-src/src/{version → branch}/context.rs +12 -12
- package/dist-engine-src/src/branch/lifecycle.rs +221 -0
- package/dist-engine-src/src/branch/mod.rs +13 -0
- package/dist-engine-src/src/branch/refs.rs +321 -0
- package/dist-engine-src/src/branch/stage_rows.rs +67 -0
- package/dist-engine-src/src/branch/types.rs +21 -0
- package/dist-engine-src/src/catalog/context.rs +18 -18
- package/dist-engine-src/src/catalog/snapshot.rs +8 -8
- package/dist-engine-src/src/changelog/bench_support.rs +785 -0
- package/dist-engine-src/src/changelog/change.rs +1 -0
- package/dist-engine-src/src/changelog/codec.rs +497 -0
- package/dist-engine-src/src/changelog/commit.rs +1 -0
- package/dist-engine-src/src/changelog/context.rs +1614 -0
- package/dist-engine-src/src/changelog/mod.rs +29 -0
- package/dist-engine-src/src/changelog/store.rs +163 -0
- package/dist-engine-src/src/changelog/test_support.rs +54 -0
- package/dist-engine-src/src/changelog/types.rs +213 -0
- package/dist-engine-src/src/commit_graph/context.rs +317 -274
- package/dist-engine-src/src/commit_graph/mod.rs +2 -4
- package/dist-engine-src/src/commit_graph/types.rs +22 -42
- package/dist-engine-src/src/commit_graph/walker.rs +133 -103
- package/dist-engine-src/src/common/error.rs +52 -18
- package/dist-engine-src/src/common/identity.rs +2 -2
- package/dist-engine-src/src/common/mod.rs +1 -1
- package/dist-engine-src/src/domain.rs +42 -46
- package/dist-engine-src/src/engine.rs +74 -96
- package/dist-engine-src/src/{entity_identity.rs → entity_pk.rs} +89 -92
- package/dist-engine-src/src/functions/context.rs +56 -52
- package/dist-engine-src/src/functions/state.rs +51 -52
- package/dist-engine-src/src/init.rs +288 -154
- package/dist-engine-src/src/json_store/context.rs +15 -266
- package/dist-engine-src/src/json_store/mod.rs +26 -0
- package/dist-engine-src/src/json_store/store.rs +103 -718
- package/dist-engine-src/src/json_store/types.rs +4 -9
- package/dist-engine-src/src/lib.rs +49 -19
- package/dist-engine-src/src/live_state/context.rs +654 -790
- package/dist-engine-src/src/live_state/mod.rs +9 -3
- package/dist-engine-src/src/live_state/overlay.rs +4 -4
- package/dist-engine-src/src/live_state/types.rs +30 -21
- package/dist-engine-src/src/live_state/visibility.rs +514 -71
- package/dist-engine-src/src/plugin/install.rs +48 -48
- package/dist-engine-src/src/plugin/manifest.rs +7 -7
- package/dist-engine-src/src/plugin/materializer.rs +0 -275
- package/dist-engine-src/src/plugin/plugin_manifest.json +4 -3
- package/dist-engine-src/src/schema/builtin/lix_binary_blob_ref.json +2 -2
- package/dist-engine-src/src/schema/builtin/lix_branch_descriptor.json +34 -0
- package/dist-engine-src/src/schema/builtin/lix_branch_ref.json +48 -0
- package/dist-engine-src/src/schema/builtin/lix_change.json +3 -3
- package/dist-engine-src/src/schema/builtin/lix_commit.json +1 -1
- package/dist-engine-src/src/schema/builtin/lix_label_assignment.json +6 -6
- package/dist-engine-src/src/schema/builtin/mod.rs +18 -20
- package/dist-engine-src/src/schema/compatibility.rs +11 -11
- package/dist-engine-src/src/schema/definition.json +2 -2
- package/dist-engine-src/src/schema/definition.rs +5 -5
- package/dist-engine-src/src/schema/key.rs +3 -3
- package/dist-engine-src/src/schema/mod.rs +1 -1
- package/dist-engine-src/src/schema/tests.rs +18 -18
- package/dist-engine-src/src/session/context.rs +819 -124
- package/dist-engine-src/src/session/create_branch.rs +94 -0
- package/dist-engine-src/src/session/execute.rs +260 -57
- package/dist-engine-src/src/session/merge/analysis.rs +9 -3
- package/dist-engine-src/src/session/merge/{version.rs → branch.rs} +119 -129
- package/dist-engine-src/src/session/merge/conflicts.rs +2 -2
- package/dist-engine-src/src/session/merge/mod.rs +5 -6
- package/dist-engine-src/src/session/merge/stats.rs +7 -11
- package/dist-engine-src/src/session/mod.rs +19 -16
- package/dist-engine-src/src/session/switch_branch.rs +113 -0
- package/dist-engine-src/src/session/transaction.rs +557 -0
- package/dist-engine-src/src/sql2/bind/classify.rs +102 -0
- package/dist-engine-src/src/sql2/bind/error.rs +5 -0
- package/dist-engine-src/src/sql2/bind/expr.rs +29 -0
- package/dist-engine-src/src/sql2/bind/mod.rs +12 -0
- package/dist-engine-src/src/sql2/{udfs/public_call.rs → bind/public_udf.rs} +98 -3
- package/dist-engine-src/src/sql2/bind/read.rs +65 -0
- package/dist-engine-src/src/sql2/bind/statement.rs +2236 -0
- package/dist-engine-src/src/sql2/bind/table.rs +273 -0
- package/dist-engine-src/src/sql2/bind/write.rs +86 -0
- package/dist-engine-src/src/sql2/branch_scope.rs +436 -0
- package/dist-engine-src/src/sql2/catalog/capability.rs +20 -0
- package/dist-engine-src/src/sql2/catalog/entity_surface.rs +296 -0
- package/dist-engine-src/src/sql2/catalog/mod.rs +15 -0
- package/dist-engine-src/src/sql2/catalog/registry.rs +556 -0
- package/dist-engine-src/src/sql2/catalog/schema.rs +88 -0
- package/dist-engine-src/src/sql2/catalog/surface.rs +41 -0
- package/dist-engine-src/src/sql2/change_materialization.rs +122 -0
- package/dist-engine-src/src/sql2/context.rs +36 -30
- package/dist-engine-src/src/sql2/error.rs +4 -5
- package/dist-engine-src/src/sql2/exec/bound_public_write.rs +1593 -0
- package/dist-engine-src/src/sql2/exec/datafusion.rs +5266 -0
- package/dist-engine-src/src/sql2/exec/fast_write.rs +82 -0
- package/dist-engine-src/src/sql2/exec/mod.rs +24 -0
- package/dist-engine-src/src/sql2/exec/write.rs +661 -0
- package/dist-engine-src/src/sql2/filesystem_planner.rs +72 -77
- package/dist-engine-src/src/sql2/filesystem_visibility.rs +21 -21
- package/dist-engine-src/src/sql2/history_projection.rs +8 -8
- package/dist-engine-src/src/sql2/history_route.rs +35 -31
- package/dist-engine-src/src/sql2/mod.rs +30 -24
- package/dist-engine-src/src/sql2/optimize/datafusion.rs +1 -0
- package/dist-engine-src/src/sql2/optimize/mod.rs +2 -0
- package/dist-engine-src/src/sql2/optimize/simple_write.rs +116 -0
- package/dist-engine-src/src/sql2/parse/mod.rs +69 -0
- package/dist-engine-src/src/sql2/parse/normalize.rs +1 -0
- package/dist-engine-src/src/sql2/plan/branch_scope.rs +24 -0
- package/dist-engine-src/src/sql2/plan/mod.rs +5 -0
- package/dist-engine-src/src/sql2/plan/predicate.rs +22 -0
- package/dist-engine-src/src/sql2/plan/write.rs +147 -0
- package/dist-engine-src/src/sql2/predicate_typecheck.rs +258 -0
- package/dist-engine-src/src/sql2/{version_provider.rs → providers/branch.rs} +218 -214
- package/dist-engine-src/src/sql2/{change_provider.rs → providers/change.rs} +156 -42
- package/dist-engine-src/src/sql2/{directory_provider.rs → providers/directory.rs} +291 -322
- package/dist-engine-src/src/sql2/{directory_history_provider.rs → providers/directory_history.rs} +56 -42
- package/dist-engine-src/src/sql2/providers/entity.rs +1484 -0
- package/dist-engine-src/src/sql2/{entity_history_provider.rs → providers/entity_history.rs} +43 -31
- package/dist-engine-src/src/sql2/{file_provider.rs → providers/file.rs} +323 -316
- package/dist-engine-src/src/sql2/{file_history_provider.rs → providers/file_history.rs} +60 -46
- package/dist-engine-src/src/sql2/{history_provider.rs → providers/history.rs} +46 -32
- package/dist-engine-src/src/sql2/{lix_state_provider.rs → providers/lix_state.rs} +359 -329
- package/dist-engine-src/src/sql2/providers/mod.rs +508 -0
- package/dist-engine-src/src/sql2/read_only.rs +2 -2
- package/dist-engine-src/src/sql2/session.rs +47 -96
- package/dist-engine-src/src/sql2/storage/constraints.rs +1 -0
- package/dist-engine-src/src/sql2/storage/mod.rs +1 -0
- package/dist-engine-src/src/sql2/test_support/differential.rs +712 -0
- package/dist-engine-src/src/sql2/test_support/generators.rs +354 -0
- package/dist-engine-src/src/sql2/test_support/mod.rs +2 -0
- package/dist-engine-src/src/sql2/udfs/{lix_active_version_commit_id.rs → lix_active_branch_commit_id.rs} +7 -7
- package/dist-engine-src/src/sql2/udfs/mod.rs +3 -6
- package/dist-engine-src/src/sql2/write_normalization.rs +45 -22
- package/dist-engine-src/src/storage/conformance.rs +399 -0
- package/dist-engine-src/src/storage/context.rs +552 -288
- package/dist-engine-src/src/storage/mod.rs +48 -10
- package/dist-engine-src/src/storage/point.rs +440 -0
- package/dist-engine-src/src/storage/read_scope.rs +43 -64
- package/dist-engine-src/src/storage/reader.rs +867 -0
- package/dist-engine-src/src/storage/scan.rs +784 -0
- package/dist-engine-src/src/storage/spaces.rs +236 -0
- package/dist-engine-src/src/storage/stats.rs +80 -0
- package/dist-engine-src/src/storage/write_set.rs +962 -0
- package/dist-engine-src/src/storage_bench.rs +136 -4828
- package/dist-engine-src/src/test_support.rs +360 -138
- package/dist-engine-src/src/tracked_state/bench_support.rs +394 -0
- package/dist-engine-src/src/tracked_state/codec.rs +155 -1057
- package/dist-engine-src/src/tracked_state/commit_root_rebuild.rs +358 -0
- package/dist-engine-src/src/tracked_state/context.rs +1927 -993
- package/dist-engine-src/src/tracked_state/diff.rs +1715 -261
- package/dist-engine-src/src/tracked_state/merge.rs +74 -88
- package/dist-engine-src/src/tracked_state/mod.rs +19 -16
- package/dist-engine-src/src/tracked_state/{materialization.rs → row_materialization.rs} +50 -178
- package/dist-engine-src/src/tracked_state/storage.rs +243 -191
- package/dist-engine-src/src/tracked_state/tree.rs +247 -371
- package/dist-engine-src/src/tracked_state/types.rs +49 -42
- package/dist-engine-src/src/transaction/bench_support.rs +407 -0
- package/dist-engine-src/src/transaction/commit.rs +821 -713
- package/dist-engine-src/src/transaction/context.rs +705 -600
- package/dist-engine-src/src/transaction/mod.rs +13 -2
- package/dist-engine-src/src/transaction/normalization.rs +63 -76
- package/dist-engine-src/src/transaction/prep.rs +13 -13
- package/dist-engine-src/src/transaction/schema_resolver.rs +19 -5
- package/dist-engine-src/src/transaction/staging.rs +228 -434
- package/dist-engine-src/src/transaction/types.rs +41 -98
- package/dist-engine-src/src/transaction/validation.rs +382 -446
- package/dist-engine-src/src/untracked_state/codec.rs +337 -29
- package/dist-engine-src/src/untracked_state/context.rs +7 -7
- package/dist-engine-src/src/untracked_state/materialization.rs +2 -2
- package/dist-engine-src/src/untracked_state/mod.rs +1 -1
- package/dist-engine-src/src/untracked_state/storage.rs +659 -157
- package/dist-engine-src/src/untracked_state/types.rs +21 -21
- package/package.json +71 -68
- package/dist-engine-src/src/backend/kv.rs +0 -358
- package/dist-engine-src/src/backend/testing.rs +0 -658
- package/dist-engine-src/src/commit_store/codec.rs +0 -887
- package/dist-engine-src/src/commit_store/context.rs +0 -944
- package/dist-engine-src/src/commit_store/materialization.rs +0 -84
- package/dist-engine-src/src/commit_store/mod.rs +0 -16
- package/dist-engine-src/src/commit_store/storage.rs +0 -600
- package/dist-engine-src/src/commit_store/types.rs +0 -215
- package/dist-engine-src/src/schema/builtin/lix_version_descriptor.json +0 -34
- package/dist-engine-src/src/schema/builtin/lix_version_ref.json +0 -48
- package/dist-engine-src/src/session/create_version.rs +0 -88
- package/dist-engine-src/src/session/merge/apply.rs +0 -23
- package/dist-engine-src/src/session/optimization9_sql2_bench.rs +0 -100
- package/dist-engine-src/src/session/switch_version.rs +0 -109
- package/dist-engine-src/src/sql2/classify.rs +0 -182
- package/dist-engine-src/src/sql2/entity_provider.rs +0 -3211
- package/dist-engine-src/src/sql2/execute.rs +0 -3440
- package/dist-engine-src/src/sql2/public_bind/assignment.rs +0 -46
- package/dist-engine-src/src/sql2/public_bind/capability.rs +0 -41
- package/dist-engine-src/src/sql2/public_bind/dml.rs +0 -166
- package/dist-engine-src/src/sql2/public_bind/mod.rs +0 -25
- package/dist-engine-src/src/sql2/public_bind/table.rs +0 -168
- package/dist-engine-src/src/sql2/version_scope.rs +0 -394
- package/dist-engine-src/src/storage/types.rs +0 -501
- package/dist-engine-src/src/tracked_state/by_file_index.rs +0 -98
- package/dist-engine-src/src/tracked_state/materializer.rs +0 -488
- package/dist-engine-src/src/transaction/live_state_overlay.rs +0 -35
- package/dist-engine-src/src/version/lifecycle.rs +0 -221
- package/dist-engine-src/src/version/mod.rs +0 -13
- package/dist-engine-src/src/version/refs.rs +0 -330
- package/dist-engine-src/src/version/stage_rows.rs +0 -67
- package/dist-engine-src/src/version/types.rs +0 -21
|
@@ -10,15 +10,26 @@ use crate::binary_cas::{
|
|
|
10
10
|
BlobBytesBatch, BlobExistsBatch, BlobHash, BlobLayout, BlobMetadata, BlobMetadataBatch,
|
|
11
11
|
BlobWrite, BlobWriteReceipt,
|
|
12
12
|
};
|
|
13
|
+
use crate::storage::{PointReadPlan, ScanPlan, StorageRead, StorageSpace, StorageWriteSet};
|
|
13
14
|
use crate::storage::{
|
|
14
|
-
|
|
15
|
+
StorageGetOptions, StorageKey, StoragePrefix, StorageProjectedValue, StorageScanOptions,
|
|
16
|
+
StorageSpaceId, StorageValue,
|
|
15
17
|
};
|
|
16
18
|
use crate::LixError;
|
|
19
|
+
use bytes::Bytes;
|
|
17
20
|
use std::collections::{HashMap, HashSet};
|
|
18
21
|
|
|
19
22
|
pub(crate) const BINARY_CAS_MANIFEST_NAMESPACE: &str = "binary_cas.manifest";
|
|
20
23
|
pub(crate) const BINARY_CAS_MANIFEST_CHUNK_NAMESPACE: &str = "binary_cas.manifest_chunk";
|
|
21
24
|
pub(crate) const BINARY_CAS_CHUNK_NAMESPACE: &str = "binary_cas.chunk";
|
|
25
|
+
pub(crate) const BINARY_CAS_MANIFEST_SPACE: StorageSpace =
|
|
26
|
+
StorageSpace::new(StorageSpaceId(0x0005_0001), BINARY_CAS_MANIFEST_NAMESPACE);
|
|
27
|
+
pub(crate) const BINARY_CAS_MANIFEST_CHUNK_SPACE: StorageSpace = StorageSpace::new(
|
|
28
|
+
StorageSpaceId(0x0005_0002),
|
|
29
|
+
BINARY_CAS_MANIFEST_CHUNK_NAMESPACE,
|
|
30
|
+
);
|
|
31
|
+
pub(crate) const BINARY_CAS_CHUNK_SPACE: StorageSpace =
|
|
32
|
+
StorageSpace::new(StorageSpaceId(0x0005_0003), BINARY_CAS_CHUNK_NAMESPACE);
|
|
22
33
|
|
|
23
34
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
24
35
|
pub(crate) struct KvBlobManifestChunk {
|
|
@@ -34,15 +45,10 @@ pub(crate) struct KvChunk {
|
|
|
34
45
|
}
|
|
35
46
|
|
|
36
47
|
pub(crate) async fn load_manifest(
|
|
37
|
-
store: &
|
|
48
|
+
store: &impl StorageRead,
|
|
38
49
|
blob_hash: BlobHash,
|
|
39
50
|
) -> Result<Option<BinaryCasManifest>, LixError> {
|
|
40
|
-
let Some(bytes) = get_one(
|
|
41
|
-
store,
|
|
42
|
-
BINARY_CAS_MANIFEST_NAMESPACE,
|
|
43
|
-
manifest_key(blob_hash),
|
|
44
|
-
)
|
|
45
|
-
.await?
|
|
51
|
+
let Some(bytes) = get_one(store, BINARY_CAS_MANIFEST_SPACE, manifest_key(blob_hash)).await?
|
|
46
52
|
else {
|
|
47
53
|
return Ok(None);
|
|
48
54
|
};
|
|
@@ -50,14 +56,12 @@ pub(crate) async fn load_manifest(
|
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
#[cfg(feature = "storage-benches")]
|
|
53
|
-
pub(crate) async fn count_manifests(store: &
|
|
54
|
-
Ok(
|
|
55
|
-
store,
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
pub(crate) async fn count_manifests(store: &impl StorageRead) -> Result<usize, LixError> {
|
|
60
|
+
Ok(
|
|
61
|
+
scan_all_values(store, BINARY_CAS_MANIFEST_SPACE, Vec::new())
|
|
62
|
+
.await?
|
|
63
|
+
.len(),
|
|
58
64
|
)
|
|
59
|
-
.await?
|
|
60
|
-
.len())
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
pub(crate) fn stage_manifest(
|
|
@@ -66,20 +70,20 @@ pub(crate) fn stage_manifest(
|
|
|
66
70
|
manifest: &BinaryCasManifest,
|
|
67
71
|
) {
|
|
68
72
|
writes.put(
|
|
69
|
-
|
|
70
|
-
manifest_key(blob_hash),
|
|
71
|
-
encode_binary_cas_manifest(manifest),
|
|
73
|
+
BINARY_CAS_MANIFEST_SPACE,
|
|
74
|
+
key(manifest_key(blob_hash)),
|
|
75
|
+
value(encode_binary_cas_manifest(manifest)),
|
|
72
76
|
);
|
|
73
77
|
}
|
|
74
78
|
|
|
75
79
|
pub(crate) async fn scan_manifest_chunks(
|
|
76
|
-
store: &
|
|
80
|
+
store: &impl StorageRead,
|
|
77
81
|
blob_hash: BlobHash,
|
|
78
82
|
) -> Result<Vec<KvBlobManifestChunk>, LixError> {
|
|
79
83
|
scan_all_values(
|
|
80
84
|
store,
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
BINARY_CAS_MANIFEST_CHUNK_SPACE,
|
|
86
|
+
manifest_chunk_prefix(blob_hash),
|
|
83
87
|
)
|
|
84
88
|
.await?
|
|
85
89
|
.into_iter()
|
|
@@ -100,18 +104,20 @@ pub(crate) fn stage_manifest_chunk(
|
|
|
100
104
|
chunk: &KvBlobManifestChunk,
|
|
101
105
|
) {
|
|
102
106
|
writes.put(
|
|
103
|
-
|
|
104
|
-
manifest_chunk_key(blob_hash, chunk_index),
|
|
105
|
-
encode_binary_cas_manifest_chunk(
|
|
107
|
+
BINARY_CAS_MANIFEST_CHUNK_SPACE,
|
|
108
|
+
key(manifest_chunk_key(blob_hash, chunk_index)),
|
|
109
|
+
value(encode_binary_cas_manifest_chunk(
|
|
110
|
+
&chunk.chunk_hash,
|
|
111
|
+
chunk.chunk_size,
|
|
112
|
+
)),
|
|
106
113
|
);
|
|
107
114
|
}
|
|
108
115
|
|
|
109
116
|
pub(crate) async fn load_chunk(
|
|
110
|
-
store: &
|
|
117
|
+
store: &impl StorageRead,
|
|
111
118
|
chunk_hash: BlobHash,
|
|
112
119
|
) -> Result<Option<KvChunk>, LixError> {
|
|
113
|
-
let Some(bytes) = get_one(store,
|
|
114
|
-
else {
|
|
120
|
+
let Some(bytes) = get_one(store, BINARY_CAS_CHUNK_SPACE, chunk_key(chunk_hash)).await? else {
|
|
115
121
|
return Ok(None);
|
|
116
122
|
};
|
|
117
123
|
let (codec, uncompressed_len, payload) = decode_binary_cas_chunk(&bytes)?;
|
|
@@ -124,73 +130,78 @@ pub(crate) async fn load_chunk(
|
|
|
124
130
|
|
|
125
131
|
pub(crate) fn stage_chunk(writes: &mut StorageWriteSet, chunk_hash: BlobHash, chunk: &KvChunk) {
|
|
126
132
|
writes.put(
|
|
127
|
-
|
|
128
|
-
chunk_key(chunk_hash),
|
|
129
|
-
encode_binary_cas_chunk(
|
|
133
|
+
BINARY_CAS_CHUNK_SPACE,
|
|
134
|
+
key(chunk_key(chunk_hash)),
|
|
135
|
+
value(encode_binary_cas_chunk(
|
|
136
|
+
chunk.codec,
|
|
137
|
+
chunk.uncompressed_len,
|
|
138
|
+
&chunk.data,
|
|
139
|
+
)),
|
|
130
140
|
);
|
|
131
141
|
}
|
|
132
142
|
|
|
133
143
|
async fn get_one(
|
|
134
|
-
store: &
|
|
135
|
-
|
|
144
|
+
store: &impl StorageRead,
|
|
145
|
+
space: StorageSpace,
|
|
136
146
|
key: Vec<u8>,
|
|
137
147
|
) -> Result<Option<Vec<u8>>, LixError> {
|
|
138
|
-
|
|
139
|
-
.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
keys: vec![key],
|
|
143
|
-
}],
|
|
144
|
-
})
|
|
145
|
-
.await?
|
|
146
|
-
.groups
|
|
148
|
+
let result = PointReadPlan::new(space, &[StorageKey(Bytes::from(key))])
|
|
149
|
+
.materialize(store, StorageGetOptions::default())?;
|
|
150
|
+
Ok(result
|
|
151
|
+
.value
|
|
147
152
|
.into_iter()
|
|
148
153
|
.next()
|
|
149
|
-
.
|
|
154
|
+
.flatten()
|
|
155
|
+
.and_then(full_value))
|
|
150
156
|
}
|
|
151
157
|
|
|
152
158
|
async fn scan_all_values(
|
|
153
|
-
store: &
|
|
154
|
-
|
|
155
|
-
|
|
159
|
+
store: &impl StorageRead,
|
|
160
|
+
space: StorageSpace,
|
|
161
|
+
prefix: Vec<u8>,
|
|
156
162
|
) -> Result<Vec<Vec<u8>>, LixError> {
|
|
157
|
-
let
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
163
|
+
let plan = ScanPlan::prefix(
|
|
164
|
+
space,
|
|
165
|
+
StoragePrefix {
|
|
166
|
+
bytes: Bytes::from(prefix),
|
|
167
|
+
},
|
|
168
|
+
);
|
|
169
|
+
let mut values = Vec::new();
|
|
170
|
+
let mut resume_after = None;
|
|
171
|
+
loop {
|
|
172
|
+
let page = plan.collect(
|
|
173
|
+
store,
|
|
174
|
+
StorageScanOptions {
|
|
175
|
+
resume_after: resume_after.as_ref(),
|
|
176
|
+
..StorageScanOptions::default()
|
|
177
|
+
},
|
|
178
|
+
)?;
|
|
179
|
+
resume_after = page.value.entries.last().map(|entry| entry.key.clone());
|
|
180
|
+
values.extend(
|
|
181
|
+
page.value
|
|
182
|
+
.entries
|
|
183
|
+
.into_iter()
|
|
184
|
+
.filter_map(|entry| full_value(entry.value)),
|
|
185
|
+
);
|
|
186
|
+
if !page.value.has_more || resume_after.is_none() {
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
Ok(values)
|
|
167
191
|
}
|
|
168
192
|
|
|
169
193
|
pub(crate) async fn load_metadata_many(
|
|
170
|
-
store: &
|
|
194
|
+
store: &impl StorageRead,
|
|
171
195
|
hashes: &[BlobHash],
|
|
172
196
|
) -> Result<BlobMetadataBatch, LixError> {
|
|
173
197
|
if hashes.is_empty() {
|
|
174
198
|
return Ok(BlobMetadataBatch::new(Vec::new()));
|
|
175
199
|
}
|
|
176
|
-
let rows =
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}],
|
|
182
|
-
})
|
|
183
|
-
.await?
|
|
184
|
-
.groups
|
|
185
|
-
.into_iter()
|
|
186
|
-
.next()
|
|
187
|
-
.map(|group| {
|
|
188
|
-
group
|
|
189
|
-
.values_iter()
|
|
190
|
-
.map(|value| value.map(<[u8]>::to_vec))
|
|
191
|
-
.collect::<Vec<_>>()
|
|
192
|
-
})
|
|
193
|
-
.unwrap_or_default();
|
|
200
|
+
let rows = point_values(
|
|
201
|
+
store,
|
|
202
|
+
BINARY_CAS_MANIFEST_SPACE,
|
|
203
|
+
hashes.iter().map(|hash| manifest_key(*hash)).collect(),
|
|
204
|
+
)?;
|
|
194
205
|
if rows.len() != hashes.len() {
|
|
195
206
|
return Err(LixError::new(
|
|
196
207
|
"LIX_ERROR_UNKNOWN",
|
|
@@ -216,7 +227,7 @@ pub(crate) async fn load_metadata_many(
|
|
|
216
227
|
}
|
|
217
228
|
|
|
218
229
|
pub(crate) async fn exists_many(
|
|
219
|
-
store: &
|
|
230
|
+
store: &impl StorageRead,
|
|
220
231
|
hashes: &[BlobHash],
|
|
221
232
|
) -> Result<BlobExistsBatch, LixError> {
|
|
222
233
|
Ok(BlobExistsBatch::new(
|
|
@@ -230,7 +241,7 @@ pub(crate) async fn exists_many(
|
|
|
230
241
|
}
|
|
231
242
|
|
|
232
243
|
pub(crate) async fn load_bytes_many(
|
|
233
|
-
store: &
|
|
244
|
+
store: &impl StorageRead,
|
|
234
245
|
hashes: &[BlobHash],
|
|
235
246
|
) -> Result<BlobBytesBatch, LixError> {
|
|
236
247
|
let metadata = load_metadata_many(store, hashes).await?.into_vec();
|
|
@@ -301,30 +312,52 @@ pub(crate) async fn load_bytes_many(
|
|
|
301
312
|
}
|
|
302
313
|
|
|
303
314
|
async fn load_chunk_rows(
|
|
304
|
-
store: &
|
|
315
|
+
store: &impl StorageRead,
|
|
305
316
|
hashes: &[BlobHash],
|
|
306
317
|
) -> Result<Vec<Option<Vec<u8>>>, LixError> {
|
|
307
318
|
if hashes.is_empty() {
|
|
308
319
|
return Ok(Vec::new());
|
|
309
320
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
321
|
+
point_values(
|
|
322
|
+
store,
|
|
323
|
+
BINARY_CAS_CHUNK_SPACE,
|
|
324
|
+
hashes.iter().map(|hash| chunk_key(*hash)).collect(),
|
|
325
|
+
)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
fn point_values(
|
|
329
|
+
store: &impl StorageRead,
|
|
330
|
+
space: StorageSpace,
|
|
331
|
+
keys: Vec<Vec<u8>>,
|
|
332
|
+
) -> Result<Vec<Option<Vec<u8>>>, LixError> {
|
|
333
|
+
let keys = keys
|
|
319
334
|
.into_iter()
|
|
320
|
-
.
|
|
321
|
-
.
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
.
|
|
335
|
+
.map(|key| StorageKey(Bytes::from(key)))
|
|
336
|
+
.collect::<Vec<_>>();
|
|
337
|
+
let result =
|
|
338
|
+
PointReadPlan::new(space, &keys).materialize(store, StorageGetOptions::default())?;
|
|
339
|
+
Ok(result
|
|
340
|
+
.value
|
|
341
|
+
.into_iter()
|
|
342
|
+
.map(|value| value.and_then(full_value))
|
|
343
|
+
.collect())
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
fn key(bytes: Vec<u8>) -> StorageKey {
|
|
347
|
+
StorageKey(Bytes::from(bytes))
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
fn value(bytes: Vec<u8>) -> StorageValue {
|
|
351
|
+
StorageValue {
|
|
352
|
+
bytes: Bytes::from(bytes),
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
fn full_value(value: StorageProjectedValue) -> Option<Vec<u8>> {
|
|
357
|
+
match value {
|
|
358
|
+
StorageProjectedValue::FullValue(bytes) => Some(bytes.to_vec()),
|
|
359
|
+
StorageProjectedValue::KeyOnly => None,
|
|
360
|
+
}
|
|
328
361
|
}
|
|
329
362
|
|
|
330
363
|
fn assemble_blob_bytes(
|
|
@@ -653,28 +686,19 @@ fn persisted_size_to_usize(size: u64, label: &str) -> Result<usize, LixError> {
|
|
|
653
686
|
#[cfg(test)]
|
|
654
687
|
mod tests {
|
|
655
688
|
use super::*;
|
|
656
|
-
use crate::backend::testing::UnitTestBackend;
|
|
657
689
|
use crate::binary_cas::BinaryCasContext;
|
|
658
|
-
use crate::storage::
|
|
659
|
-
|
|
660
|
-
fn stage_blob_to_writes(writes: &mut StorageWriteSet, data: &[u8]) {
|
|
661
|
-
let mut writer = BinaryCasContext::new().writer(writes);
|
|
662
|
-
writer.stage_bytes(data).expect("blob write should persist");
|
|
663
|
-
}
|
|
690
|
+
use crate::storage::StorageContext;
|
|
691
|
+
use crate::storage::{InMemoryStorageBackend, StorageReadOptions, StorageWriteOptions};
|
|
664
692
|
|
|
665
693
|
#[tokio::test]
|
|
666
694
|
async fn stores_manifest_chunks_in_scan_order() {
|
|
667
|
-
let storage = StorageContext::new(
|
|
668
|
-
let mut transaction = storage
|
|
669
|
-
.begin_write_transaction()
|
|
670
|
-
.await
|
|
671
|
-
.expect("transaction should open");
|
|
695
|
+
let storage = StorageContext::new(InMemoryStorageBackend::new());
|
|
672
696
|
let blob_hash = BlobHash::from_content(b"blob-a");
|
|
673
697
|
let chunk_a_hash = BlobHash::from_content(b"chunk-a").into_bytes();
|
|
674
698
|
let chunk_b_hash = BlobHash::from_content(b"chunk-b").into_bytes();
|
|
675
699
|
|
|
676
700
|
{
|
|
677
|
-
let mut writes =
|
|
701
|
+
let mut writes = storage.new_write_set();
|
|
678
702
|
stage_manifest(
|
|
679
703
|
&mut writes,
|
|
680
704
|
blob_hash,
|
|
@@ -701,19 +725,16 @@ mod tests {
|
|
|
701
725
|
chunk_size: 6,
|
|
702
726
|
},
|
|
703
727
|
);
|
|
704
|
-
|
|
705
|
-
.
|
|
706
|
-
.
|
|
707
|
-
.expect("manifest writes should apply");
|
|
728
|
+
storage
|
|
729
|
+
.commit_write_set(writes, StorageWriteOptions::default())
|
|
730
|
+
.expect("manifest writes should commit");
|
|
708
731
|
}
|
|
709
|
-
transaction.commit().await.expect("commit should succeed");
|
|
710
732
|
|
|
711
|
-
let
|
|
712
|
-
.
|
|
713
|
-
.
|
|
714
|
-
.expect("read transaction should open");
|
|
733
|
+
let store = storage
|
|
734
|
+
.begin_read(StorageReadOptions::default())
|
|
735
|
+
.expect("read should open");
|
|
715
736
|
assert_eq!(
|
|
716
|
-
load_manifest(&
|
|
737
|
+
load_manifest(&store, blob_hash)
|
|
717
738
|
.await
|
|
718
739
|
.expect("manifest should load"),
|
|
719
740
|
Some(BinaryCasManifest::Chunked {
|
|
@@ -721,12 +742,11 @@ mod tests {
|
|
|
721
742
|
chunk_count: 2,
|
|
722
743
|
})
|
|
723
744
|
);
|
|
724
|
-
let
|
|
725
|
-
.
|
|
726
|
-
.
|
|
727
|
-
.expect("read transaction should open");
|
|
745
|
+
let store = storage
|
|
746
|
+
.begin_read(StorageReadOptions::default())
|
|
747
|
+
.expect("read should open");
|
|
728
748
|
assert_eq!(
|
|
729
|
-
scan_manifest_chunks(&
|
|
749
|
+
scan_manifest_chunks(&store, blob_hash)
|
|
730
750
|
.await
|
|
731
751
|
.expect("manifest chunks should scan"),
|
|
732
752
|
vec![
|
|
@@ -744,11 +764,7 @@ mod tests {
|
|
|
744
764
|
|
|
745
765
|
#[tokio::test]
|
|
746
766
|
async fn stores_encoded_chunks_by_chunk_hash() {
|
|
747
|
-
let storage = StorageContext::new(
|
|
748
|
-
let mut transaction = storage
|
|
749
|
-
.begin_write_transaction()
|
|
750
|
-
.await
|
|
751
|
-
.expect("transaction should open");
|
|
767
|
+
let storage = StorageContext::new(InMemoryStorageBackend::new());
|
|
752
768
|
let chunk = KvChunk {
|
|
753
769
|
codec: BinaryChunkCodec::Raw,
|
|
754
770
|
uncompressed_len: 5,
|
|
@@ -757,21 +773,18 @@ mod tests {
|
|
|
757
773
|
let chunk_hash = BlobHash::from_content(b"chunk-a");
|
|
758
774
|
|
|
759
775
|
{
|
|
760
|
-
let mut writes =
|
|
776
|
+
let mut writes = storage.new_write_set();
|
|
761
777
|
stage_chunk(&mut writes, chunk_hash, &chunk);
|
|
762
|
-
|
|
763
|
-
.
|
|
764
|
-
.
|
|
765
|
-
.expect("chunk should apply");
|
|
778
|
+
storage
|
|
779
|
+
.commit_write_set(writes, StorageWriteOptions::default())
|
|
780
|
+
.expect("chunk should commit");
|
|
766
781
|
}
|
|
767
|
-
transaction.commit().await.expect("commit should succeed");
|
|
768
782
|
|
|
769
|
-
let
|
|
770
|
-
.
|
|
771
|
-
.
|
|
772
|
-
.expect("read transaction should open");
|
|
783
|
+
let store = storage
|
|
784
|
+
.begin_read(StorageReadOptions::default())
|
|
785
|
+
.expect("read should open");
|
|
773
786
|
assert_eq!(
|
|
774
|
-
load_chunk(&
|
|
787
|
+
load_chunk(&store, chunk_hash)
|
|
775
788
|
.await
|
|
776
789
|
.expect("chunk should load"),
|
|
777
790
|
Some(chunk)
|
|
@@ -796,41 +809,34 @@ mod tests {
|
|
|
796
809
|
|
|
797
810
|
#[tokio::test]
|
|
798
811
|
async fn public_kv_api_roundtrips_blob_bytes() {
|
|
799
|
-
let storage = StorageContext::new(
|
|
812
|
+
let storage = StorageContext::new(InMemoryStorageBackend::new());
|
|
800
813
|
let data = b"hello chunked kv cas";
|
|
801
814
|
let blob_hash = BlobHash::from_content(data);
|
|
802
|
-
let mut transaction = storage
|
|
803
|
-
.begin_write_transaction()
|
|
804
|
-
.await
|
|
805
|
-
.expect("transaction should open");
|
|
806
815
|
|
|
807
816
|
{
|
|
808
|
-
let mut writes =
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
.
|
|
813
|
-
.expect("blob write should
|
|
817
|
+
let mut writes = storage.new_write_set();
|
|
818
|
+
let mut writer = BinaryCasContext::new().writer(&mut writes);
|
|
819
|
+
writer.stage_bytes(data).expect("blob write should stage");
|
|
820
|
+
storage
|
|
821
|
+
.commit_write_set(writes, StorageWriteOptions::default())
|
|
822
|
+
.expect("blob write should commit");
|
|
814
823
|
}
|
|
815
|
-
transaction.commit().await.expect("commit should succeed");
|
|
816
824
|
|
|
817
|
-
let
|
|
818
|
-
.
|
|
819
|
-
.
|
|
820
|
-
.expect("read transaction should open");
|
|
825
|
+
let store = storage
|
|
826
|
+
.begin_read(StorageReadOptions::default())
|
|
827
|
+
.expect("read should open");
|
|
821
828
|
assert_eq!(
|
|
822
|
-
load_bytes_many(&
|
|
829
|
+
load_bytes_many(&store, &[blob_hash])
|
|
823
830
|
.await
|
|
824
831
|
.expect("blob should load")
|
|
825
832
|
.into_vec(),
|
|
826
833
|
vec![Some(data.to_vec())]
|
|
827
834
|
);
|
|
828
|
-
let
|
|
829
|
-
.
|
|
830
|
-
.
|
|
831
|
-
.expect("read transaction should open");
|
|
835
|
+
let store = storage
|
|
836
|
+
.begin_read(StorageReadOptions::default())
|
|
837
|
+
.expect("read should open");
|
|
832
838
|
assert_eq!(
|
|
833
|
-
load_manifest(&
|
|
839
|
+
load_manifest(&store, blob_hash)
|
|
834
840
|
.await
|
|
835
841
|
.expect("manifest should load"),
|
|
836
842
|
Some(BinaryCasManifest::SingleChunk {
|
|
@@ -838,22 +844,20 @@ mod tests {
|
|
|
838
844
|
chunk_hash: BlobHash::from_content(data).into_bytes(),
|
|
839
845
|
})
|
|
840
846
|
);
|
|
841
|
-
let
|
|
842
|
-
.
|
|
843
|
-
.
|
|
844
|
-
.expect("read transaction should open");
|
|
847
|
+
let store = storage
|
|
848
|
+
.begin_read(StorageReadOptions::default())
|
|
849
|
+
.expect("read should open");
|
|
845
850
|
assert_eq!(
|
|
846
|
-
scan_manifest_chunks(&
|
|
851
|
+
scan_manifest_chunks(&store, blob_hash)
|
|
847
852
|
.await
|
|
848
853
|
.expect("single-chunk blob should not spill manifest chunks"),
|
|
849
854
|
Vec::<KvBlobManifestChunk>::new()
|
|
850
855
|
);
|
|
851
|
-
let
|
|
852
|
-
.
|
|
853
|
-
.
|
|
854
|
-
.expect("read transaction should open");
|
|
856
|
+
let store = storage
|
|
857
|
+
.begin_read(StorageReadOptions::default())
|
|
858
|
+
.expect("read should open");
|
|
855
859
|
assert_eq!(
|
|
856
|
-
exists_many(&
|
|
860
|
+
exists_many(&store, &[blob_hash])
|
|
857
861
|
.await
|
|
858
862
|
.expect("blob exists should succeed")
|
|
859
863
|
.into_vec(),
|
|
@@ -863,48 +867,40 @@ mod tests {
|
|
|
863
867
|
|
|
864
868
|
#[tokio::test]
|
|
865
869
|
async fn read_rejects_chunk_bytes_that_do_not_match_manifest_hash() {
|
|
866
|
-
let storage = StorageContext::new(
|
|
870
|
+
let storage = StorageContext::new(InMemoryStorageBackend::new());
|
|
867
871
|
let data = b"same length";
|
|
868
872
|
let corrupted = b"SAME length";
|
|
869
873
|
let blob_hash = BlobHash::from_content(data);
|
|
870
874
|
|
|
871
|
-
let mut transaction = storage
|
|
872
|
-
.begin_write_transaction()
|
|
873
|
-
.await
|
|
874
|
-
.expect("transaction should open");
|
|
875
875
|
{
|
|
876
|
-
let mut writes =
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
.
|
|
881
|
-
.expect("blob write should
|
|
876
|
+
let mut writes = storage.new_write_set();
|
|
877
|
+
let mut writer = BinaryCasContext::new().writer(&mut writes);
|
|
878
|
+
writer.stage_bytes(data).expect("blob write should stage");
|
|
879
|
+
storage
|
|
880
|
+
.commit_write_set(writes, StorageWriteOptions::default())
|
|
881
|
+
.expect("blob write should commit");
|
|
882
882
|
}
|
|
883
|
-
transaction.commit().await.expect("commit should succeed");
|
|
884
883
|
|
|
885
|
-
let mut transaction = storage
|
|
886
|
-
.begin_write_transaction()
|
|
887
|
-
.await
|
|
888
|
-
.expect("transaction should open");
|
|
889
884
|
{
|
|
890
|
-
let mut writes =
|
|
885
|
+
let mut writes = storage.new_write_set();
|
|
891
886
|
writes.put(
|
|
892
|
-
|
|
893
|
-
chunk_key(blob_hash),
|
|
894
|
-
encode_binary_cas_chunk(
|
|
887
|
+
BINARY_CAS_CHUNK_SPACE,
|
|
888
|
+
key(chunk_key(blob_hash)),
|
|
889
|
+
value(encode_binary_cas_chunk(
|
|
890
|
+
BinaryChunkCodec::Raw,
|
|
891
|
+
corrupted.len() as u64,
|
|
892
|
+
corrupted,
|
|
893
|
+
)),
|
|
895
894
|
);
|
|
896
|
-
|
|
897
|
-
.
|
|
898
|
-
.await
|
|
895
|
+
storage
|
|
896
|
+
.commit_write_set(writes, StorageWriteOptions::default())
|
|
899
897
|
.expect("corrupt chunk should overwrite");
|
|
900
898
|
}
|
|
901
|
-
transaction.commit().await.expect("commit should succeed");
|
|
902
899
|
|
|
903
|
-
let
|
|
904
|
-
.
|
|
905
|
-
.
|
|
906
|
-
|
|
907
|
-
let error = load_bytes_many(&mut store, &[blob_hash])
|
|
900
|
+
let store = storage
|
|
901
|
+
.begin_read(StorageReadOptions::default())
|
|
902
|
+
.expect("read should open");
|
|
903
|
+
let error = load_bytes_many(&store, &[blob_hash])
|
|
908
904
|
.await
|
|
909
905
|
.expect_err("corrupt chunk should be rejected");
|
|
910
906
|
assert!(error
|
|
@@ -914,19 +910,15 @@ mod tests {
|
|
|
914
910
|
|
|
915
911
|
#[tokio::test]
|
|
916
912
|
async fn read_rejects_manifest_that_assembles_wrong_blob_hash() {
|
|
917
|
-
let storage = StorageContext::new(
|
|
913
|
+
let storage = StorageContext::new(InMemoryStorageBackend::new());
|
|
918
914
|
let expected = b"expected bytes";
|
|
919
915
|
let substituted = b"different byte";
|
|
920
916
|
assert_eq!(expected.len(), substituted.len());
|
|
921
917
|
let expected_blob_hash = BlobHash::from_content(expected);
|
|
922
918
|
let substituted_chunk_hash = BlobHash::from_content(substituted);
|
|
923
919
|
|
|
924
|
-
let mut transaction = storage
|
|
925
|
-
.begin_write_transaction()
|
|
926
|
-
.await
|
|
927
|
-
.expect("transaction should open");
|
|
928
920
|
{
|
|
929
|
-
let mut writes =
|
|
921
|
+
let mut writes = storage.new_write_set();
|
|
930
922
|
stage_manifest(
|
|
931
923
|
&mut writes,
|
|
932
924
|
expected_blob_hash,
|
|
@@ -953,18 +945,15 @@ mod tests {
|
|
|
953
945
|
data: substituted.to_vec(),
|
|
954
946
|
},
|
|
955
947
|
);
|
|
956
|
-
|
|
957
|
-
.
|
|
958
|
-
.
|
|
959
|
-
.expect("wrong manifest fixture should apply");
|
|
948
|
+
storage
|
|
949
|
+
.commit_write_set(writes, StorageWriteOptions::default())
|
|
950
|
+
.expect("wrong manifest fixture should commit");
|
|
960
951
|
}
|
|
961
|
-
transaction.commit().await.expect("commit should succeed");
|
|
962
952
|
|
|
963
|
-
let
|
|
964
|
-
.
|
|
965
|
-
.
|
|
966
|
-
|
|
967
|
-
let error = load_bytes_many(&mut store, &[expected_blob_hash])
|
|
953
|
+
let store = storage
|
|
954
|
+
.begin_read(StorageReadOptions::default())
|
|
955
|
+
.expect("read should open");
|
|
956
|
+
let error = load_bytes_many(&store, &[expected_blob_hash])
|
|
968
957
|
.await
|
|
969
958
|
.expect_err("wrong assembled blob should be rejected");
|
|
970
959
|
assert!(error
|
|
@@ -974,41 +963,34 @@ mod tests {
|
|
|
974
963
|
|
|
975
964
|
#[tokio::test]
|
|
976
965
|
async fn public_kv_api_roundtrips_empty_blob() {
|
|
977
|
-
let storage = StorageContext::new(
|
|
966
|
+
let storage = StorageContext::new(InMemoryStorageBackend::new());
|
|
978
967
|
let data = b"";
|
|
979
968
|
let blob_hash = BlobHash::from_content(data);
|
|
980
|
-
let mut transaction = storage
|
|
981
|
-
.begin_write_transaction()
|
|
982
|
-
.await
|
|
983
|
-
.expect("transaction should open");
|
|
984
969
|
|
|
985
970
|
{
|
|
986
|
-
let mut writes =
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
.
|
|
991
|
-
.expect("blob write should
|
|
971
|
+
let mut writes = storage.new_write_set();
|
|
972
|
+
let mut writer = BinaryCasContext::new().writer(&mut writes);
|
|
973
|
+
writer.stage_bytes(data).expect("blob write should stage");
|
|
974
|
+
storage
|
|
975
|
+
.commit_write_set(writes, StorageWriteOptions::default())
|
|
976
|
+
.expect("blob write should commit");
|
|
992
977
|
}
|
|
993
|
-
transaction.commit().await.expect("commit should succeed");
|
|
994
978
|
|
|
995
|
-
let
|
|
996
|
-
.
|
|
997
|
-
.
|
|
998
|
-
.expect("read transaction should open");
|
|
979
|
+
let store = storage
|
|
980
|
+
.begin_read(StorageReadOptions::default())
|
|
981
|
+
.expect("read should open");
|
|
999
982
|
assert_eq!(
|
|
1000
|
-
load_bytes_many(&
|
|
983
|
+
load_bytes_many(&store, &[blob_hash])
|
|
1001
984
|
.await
|
|
1002
985
|
.expect("empty blob should load")
|
|
1003
986
|
.into_vec(),
|
|
1004
987
|
vec![Some(Vec::new())]
|
|
1005
988
|
);
|
|
1006
|
-
let
|
|
1007
|
-
.
|
|
1008
|
-
.
|
|
1009
|
-
.expect("read transaction should open");
|
|
989
|
+
let store = storage
|
|
990
|
+
.begin_read(StorageReadOptions::default())
|
|
991
|
+
.expect("read should open");
|
|
1010
992
|
assert_eq!(
|
|
1011
|
-
scan_manifest_chunks(&
|
|
993
|
+
scan_manifest_chunks(&store, blob_hash)
|
|
1012
994
|
.await
|
|
1013
995
|
.expect("empty blob chunks should scan"),
|
|
1014
996
|
Vec::<KvBlobManifestChunk>::new()
|
|
@@ -1017,43 +999,36 @@ mod tests {
|
|
|
1017
999
|
|
|
1018
1000
|
#[tokio::test]
|
|
1019
1001
|
async fn public_kv_api_roundtrips_multi_chunk_blob() {
|
|
1020
|
-
let storage = StorageContext::new(
|
|
1002
|
+
let storage = StorageContext::new(InMemoryStorageBackend::new());
|
|
1021
1003
|
let data = (0..600_000)
|
|
1022
1004
|
.map(|index| (index % 251) as u8)
|
|
1023
1005
|
.collect::<Vec<_>>();
|
|
1024
1006
|
let blob_hash = BlobHash::from_content(&data);
|
|
1025
|
-
let mut transaction = storage
|
|
1026
|
-
.begin_write_transaction()
|
|
1027
|
-
.await
|
|
1028
|
-
.expect("transaction should open");
|
|
1029
1007
|
|
|
1030
1008
|
{
|
|
1031
|
-
let mut writes =
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
.
|
|
1036
|
-
.expect("blob write should
|
|
1009
|
+
let mut writes = storage.new_write_set();
|
|
1010
|
+
let mut writer = BinaryCasContext::new().writer(&mut writes);
|
|
1011
|
+
writer.stage_bytes(&data).expect("blob write should stage");
|
|
1012
|
+
storage
|
|
1013
|
+
.commit_write_set(writes, StorageWriteOptions::default())
|
|
1014
|
+
.expect("blob write should commit");
|
|
1037
1015
|
}
|
|
1038
|
-
transaction.commit().await.expect("commit should succeed");
|
|
1039
1016
|
|
|
1040
|
-
let
|
|
1041
|
-
.
|
|
1042
|
-
.
|
|
1043
|
-
.expect("read transaction should open");
|
|
1017
|
+
let store = storage
|
|
1018
|
+
.begin_read(StorageReadOptions::default())
|
|
1019
|
+
.expect("read should open");
|
|
1044
1020
|
assert_eq!(
|
|
1045
|
-
load_bytes_many(&
|
|
1021
|
+
load_bytes_many(&store, &[blob_hash])
|
|
1046
1022
|
.await
|
|
1047
1023
|
.expect("large blob should load")
|
|
1048
1024
|
.into_vec(),
|
|
1049
1025
|
vec![Some(data.clone())]
|
|
1050
1026
|
);
|
|
1051
|
-
let
|
|
1052
|
-
.
|
|
1053
|
-
.
|
|
1054
|
-
.expect("read transaction should open");
|
|
1027
|
+
let store = storage
|
|
1028
|
+
.begin_read(StorageReadOptions::default())
|
|
1029
|
+
.expect("read should open");
|
|
1055
1030
|
assert!(
|
|
1056
|
-
scan_manifest_chunks(&
|
|
1031
|
+
scan_manifest_chunks(&store, blob_hash)
|
|
1057
1032
|
.await
|
|
1058
1033
|
.expect("large blob chunks should scan")
|
|
1059
1034
|
.len()
|