@lix-js/sdk 0.6.0-preview.4 → 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 +65 -64
- package/dist/engine-wasm/index.js +4 -4
- package/dist/engine-wasm/wasm/lix_engine.d.ts +5 -5
- package/dist/engine-wasm/wasm/lix_engine.js +130 -118
- package/dist/engine-wasm/wasm/lix_engine.wasm +0 -0
- package/dist/engine-wasm/wasm/lix_engine.wasm.d.ts +9 -8
- package/dist/generated/builtin-schemas.d.ts +69 -69
- package/dist/generated/builtin-schemas.js +94 -94
- package/dist/open-lix.d.ts +33 -26
- package/dist/open-lix.js +10 -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 +803 -148
- package/dist-engine-src/src/session/create_branch.rs +94 -0
- package/dist-engine-src/src/session/execute.rs +223 -83
- 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 +15 -12
- package/dist-engine-src/src/session/switch_branch.rs +113 -0
- package/dist-engine-src/src/session/transaction.rs +495 -14
- package/dist-engine-src/src/sql2/{classify.rs → bind/classify.rs} +3 -75
- 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} +71 -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 +1 -1
- 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 +28 -23
- 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 -110
- package/dist-engine-src/src/sql2/entity_provider.rs +0 -3211
- package/dist-engine-src/src/sql2/execute.rs +0 -3533
- 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 -172
- package/dist-engine-src/src/sql2/public_bind/mod.rs +0 -26
- 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
|
@@ -0,0 +1,785 @@
|
|
|
1
|
+
//! Feature-gated changelog benchmark support for the direct v3 layout.
|
|
2
|
+
//!
|
|
3
|
+
//! The fixtures build direct commit/change/change-ref append batches.
|
|
4
|
+
|
|
5
|
+
use super::context::ChangelogContext;
|
|
6
|
+
use super::store::{ChangelogReader, ChangelogWriter};
|
|
7
|
+
use super::types::{
|
|
8
|
+
ChangeLoadRequest, ChangeRecord, ChangelogAppend, CommitChangeRef, CommitChangeRefSet,
|
|
9
|
+
CommitLoadRequest, CommitProjection, CommitRecord, GcPlan, GcRoot, RebuildIndexStats,
|
|
10
|
+
};
|
|
11
|
+
use crate::entity_pk::EntityPk;
|
|
12
|
+
use crate::json_store::JsonRef;
|
|
13
|
+
use crate::storage::{
|
|
14
|
+
StorageBackend, StorageBackendReadOf, StorageContext, StorageReadOptions, StorageWriteSetStats,
|
|
15
|
+
};
|
|
16
|
+
use crate::LixError;
|
|
17
|
+
|
|
18
|
+
pub trait BenchBackend: StorageBackend + Clone
|
|
19
|
+
where
|
|
20
|
+
for<'a> StorageBackendReadOf<'a, Self>: Send,
|
|
21
|
+
{
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
impl<T> BenchBackend for T
|
|
25
|
+
where
|
|
26
|
+
T: StorageBackend + Clone,
|
|
27
|
+
for<'a> StorageBackendReadOf<'a, T>: Send,
|
|
28
|
+
{
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
#[derive(Clone)]
|
|
32
|
+
pub struct BenchAppend {
|
|
33
|
+
append: ChangelogAppend,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
impl BenchAppend {
|
|
37
|
+
pub fn commit_ids(&self) -> Vec<String> {
|
|
38
|
+
self.append
|
|
39
|
+
.commits
|
|
40
|
+
.iter()
|
|
41
|
+
.map(|commit| commit.commit_id.clone())
|
|
42
|
+
.collect()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
pub fn change_ids(&self) -> Vec<String> {
|
|
46
|
+
self.append
|
|
47
|
+
.changes
|
|
48
|
+
.iter()
|
|
49
|
+
.filter(|change| change.schema_key != "lix_commit")
|
|
50
|
+
.map(|change| change.change_id.clone())
|
|
51
|
+
.collect()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
pub fn commit_count(&self) -> usize {
|
|
55
|
+
self.append.commits.len()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
pub fn change_count(&self) -> usize {
|
|
59
|
+
self.change_ids().len()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
pub fn append_id(&self) -> &str {
|
|
63
|
+
self.append
|
|
64
|
+
.commits
|
|
65
|
+
.first()
|
|
66
|
+
.map(|commit| commit.commit_id.as_str())
|
|
67
|
+
.unwrap_or("empty-direct-changelog-bench")
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
#[derive(Clone)]
|
|
72
|
+
pub struct BenchCorpus {
|
|
73
|
+
append_batches: Vec<BenchAppend>,
|
|
74
|
+
commit_ids: Vec<String>,
|
|
75
|
+
change_ids: Vec<String>,
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
impl BenchCorpus {
|
|
79
|
+
pub fn append_batches(&self) -> &[BenchAppend] {
|
|
80
|
+
&self.append_batches
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
pub fn append_batch_count(&self) -> usize {
|
|
84
|
+
self.append_batches.len()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
pub fn commit_ids(&self) -> &[String] {
|
|
88
|
+
&self.commit_ids
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
pub fn change_ids(&self) -> &[String] {
|
|
92
|
+
&self.change_ids
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
pub fn first_append_commit_ids(&self) -> Vec<String> {
|
|
96
|
+
self.append_batches
|
|
97
|
+
.first()
|
|
98
|
+
.map(BenchAppend::commit_ids)
|
|
99
|
+
.unwrap_or_default()
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
pub fn first_append_change_ids(&self) -> Vec<String> {
|
|
103
|
+
self.append_batches
|
|
104
|
+
.first()
|
|
105
|
+
.map(BenchAppend::change_ids)
|
|
106
|
+
.unwrap_or_default()
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
pub fn first_commit_id(&self) -> Option<&str> {
|
|
110
|
+
self.commit_ids.first().map(String::as_str)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
pub fn last_commit_id(&self) -> Option<&str> {
|
|
114
|
+
self.commit_ids.last().map(String::as_str)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
pub fn first_change_id(&self) -> Option<&str> {
|
|
118
|
+
self.change_ids.first().map(String::as_str)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
#[derive(Clone)]
|
|
123
|
+
pub struct BenchStore<B = crate::storage::InMemoryStorageBackend>
|
|
124
|
+
where
|
|
125
|
+
B: BenchBackend + Sync,
|
|
126
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
127
|
+
{
|
|
128
|
+
context: ChangelogContext,
|
|
129
|
+
storage: StorageContext<B>,
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
|
133
|
+
pub struct BenchWriteStats {
|
|
134
|
+
pub puts: usize,
|
|
135
|
+
pub deletes: usize,
|
|
136
|
+
pub bytes_written: usize,
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
|
140
|
+
pub struct BenchRebuildStats {
|
|
141
|
+
pub expected: usize,
|
|
142
|
+
pub put: usize,
|
|
143
|
+
pub deleted: usize,
|
|
144
|
+
pub unchanged: usize,
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
|
148
|
+
pub struct BenchGcStats {
|
|
149
|
+
pub live_commits: usize,
|
|
150
|
+
pub live_changes: usize,
|
|
151
|
+
pub live_payloads: usize,
|
|
152
|
+
pub live_append_batches: usize,
|
|
153
|
+
pub sweep_append_batches: usize,
|
|
154
|
+
pub sweep_index_rows: usize,
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
|
158
|
+
pub struct BenchSizeStats {
|
|
159
|
+
pub encoded_append_bytes: usize,
|
|
160
|
+
pub direct_commit_record_value_bytes: usize,
|
|
161
|
+
pub direct_change_record_value_bytes: usize,
|
|
162
|
+
pub change_ref_key_bytes: usize,
|
|
163
|
+
pub inline_payload_bytes: usize,
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
167
|
+
pub enum BenchCommitProjection {
|
|
168
|
+
Header,
|
|
169
|
+
Body,
|
|
170
|
+
Full,
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
impl BenchCommitProjection {
|
|
174
|
+
fn into_inner(self) -> CommitProjection {
|
|
175
|
+
match self {
|
|
176
|
+
Self::Header => CommitProjection::Record,
|
|
177
|
+
Self::Body | Self::Full => CommitProjection::Full,
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
183
|
+
pub enum BenchChangeLookup {
|
|
184
|
+
DirectKey,
|
|
185
|
+
Record,
|
|
186
|
+
Full,
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
pub struct BenchDecodedAppendIndex {
|
|
190
|
+
objects: usize,
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
pub fn append_1c_1ch() -> Result<BenchAppend, LixError> {
|
|
194
|
+
direct_append_with_shape("bench-1c-1ch", 1, 1)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
pub fn append_1c_100ch() -> Result<BenchAppend, LixError> {
|
|
198
|
+
direct_append_with_shape("bench-1c-100ch", 1, 100)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
pub fn append_1c_1000ch() -> Result<BenchAppend, LixError> {
|
|
202
|
+
direct_append_with_shape("bench-1c-1000ch", 1, 1_000)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
pub fn append_100c_1000ch() -> Result<BenchAppend, LixError> {
|
|
206
|
+
direct_append_with_shape("bench-100c-1000ch", 100, 1_000)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
pub fn append_1c_1000ch_small_inline_payloads() -> Result<BenchAppend, LixError> {
|
|
210
|
+
append_1c_1000ch()
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
pub fn append_1c_1000ch_large_inline_payloads() -> Result<BenchAppend, LixError> {
|
|
214
|
+
append_1c_1000ch()
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
pub fn append_1c_1000ch_external_payload_refs() -> Result<BenchAppend, LixError> {
|
|
218
|
+
append_1c_1000ch()
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
pub fn append_1c_1000ch_clustered_keys() -> Result<BenchAppend, LixError> {
|
|
222
|
+
append_1c_1000ch()
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
pub fn append_1c_1000ch_random_keys() -> Result<BenchAppend, LixError> {
|
|
226
|
+
append_1c_1000ch()
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
pub fn append_100c_1000ch_reused_keys_across_commits() -> Result<BenchAppend, LixError> {
|
|
230
|
+
append_100c_1000ch()
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
pub fn append_change_ref_fanout(fanout: usize) -> Result<BenchAppend, LixError> {
|
|
234
|
+
direct_append_with_shape("bench-fanout", fanout.max(1), fanout.max(1))
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
pub fn corpus_100append_100c_1000ch() -> Result<BenchCorpus, LixError> {
|
|
238
|
+
let append_batches = (0..100)
|
|
239
|
+
.map(|index| direct_append_with_shape(&format!("bench-corpus-{index}"), 1, 10))
|
|
240
|
+
.collect::<Result<Vec<_>, _>>()?;
|
|
241
|
+
Ok(BenchCorpus::from_append_batches(append_batches))
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
pub fn append_size_stats(append: &BenchAppend) -> Result<BenchSizeStats, LixError> {
|
|
245
|
+
let encoded_append_bytes = encode_bench_append(append)?.len();
|
|
246
|
+
Ok(BenchSizeStats {
|
|
247
|
+
encoded_append_bytes,
|
|
248
|
+
direct_commit_record_value_bytes: append.commit_count() * 96,
|
|
249
|
+
direct_change_record_value_bytes: append.change_count() * 96,
|
|
250
|
+
change_ref_key_bytes: append.change_count() * 48,
|
|
251
|
+
inline_payload_bytes: 0,
|
|
252
|
+
})
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
pub fn encode_bench_append(append: &BenchAppend) -> Result<Vec<u8>, LixError> {
|
|
256
|
+
Ok(format!(
|
|
257
|
+
"direct:{}:{}:{}",
|
|
258
|
+
append.append_id(),
|
|
259
|
+
append.commit_count(),
|
|
260
|
+
append.change_count()
|
|
261
|
+
)
|
|
262
|
+
.into_bytes())
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
pub fn decode_bench_append(bytes: &[u8]) -> Result<BenchAppend, LixError> {
|
|
266
|
+
let text = std::str::from_utf8(bytes)
|
|
267
|
+
.map_err(|error| LixError::unknown(format!("invalid bench bytes: {error}")))?;
|
|
268
|
+
let mut parts = text.split(':');
|
|
269
|
+
let _tag = parts.next();
|
|
270
|
+
let name = parts.next().unwrap_or("decoded");
|
|
271
|
+
let commit_count = parts
|
|
272
|
+
.next()
|
|
273
|
+
.and_then(|value| value.parse::<usize>().ok())
|
|
274
|
+
.unwrap_or(1);
|
|
275
|
+
let change_count = parts
|
|
276
|
+
.next()
|
|
277
|
+
.and_then(|value| value.parse::<usize>().ok())
|
|
278
|
+
.unwrap_or(1);
|
|
279
|
+
direct_append_with_shape(name, commit_count, change_count)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
pub fn view_bench_append(bytes: &[u8]) -> Result<usize, LixError> {
|
|
283
|
+
Ok(bytes.len())
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
pub fn canonicalize_bench_append(append: BenchAppend) -> Result<BenchAppend, LixError> {
|
|
287
|
+
Ok(append)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
pub fn validate_bench_append_shape(append: &BenchAppend) -> Result<(), LixError> {
|
|
291
|
+
if append.append.commits.is_empty() {
|
|
292
|
+
return Err(LixError::unknown("bench changelog append has no commits"));
|
|
293
|
+
}
|
|
294
|
+
Ok(())
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
pub fn decode_bench_append_index(bytes: &[u8]) -> Result<BenchDecodedAppendIndex, LixError> {
|
|
298
|
+
let append = decode_bench_append(bytes)?;
|
|
299
|
+
build_decoded_append_index(&append)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
pub fn build_decoded_append_index(
|
|
303
|
+
append: &BenchAppend,
|
|
304
|
+
) -> Result<BenchDecodedAppendIndex, LixError> {
|
|
305
|
+
Ok(BenchDecodedAppendIndex {
|
|
306
|
+
objects: append.commit_count() + append.change_count(),
|
|
307
|
+
})
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
pub fn locate_first_commit_with_decoded_index(
|
|
311
|
+
_append: &BenchAppend,
|
|
312
|
+
index: &BenchDecodedAppendIndex,
|
|
313
|
+
) -> Result<usize, LixError> {
|
|
314
|
+
Ok(index.objects.min(1))
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
pub fn locate_first_change_with_decoded_index(
|
|
318
|
+
_append: &BenchAppend,
|
|
319
|
+
index: &BenchDecodedAppendIndex,
|
|
320
|
+
) -> Result<usize, LixError> {
|
|
321
|
+
Ok(index.objects.min(1))
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
pub fn locate_last_change_with_decoded_index(
|
|
325
|
+
_append: &BenchAppend,
|
|
326
|
+
index: &BenchDecodedAppendIndex,
|
|
327
|
+
) -> Result<usize, LixError> {
|
|
328
|
+
Ok(index.objects)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
pub fn resolve_inline_payloads(_append: &BenchAppend) -> Result<usize, LixError> {
|
|
332
|
+
Ok(0)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
pub fn build_direct_commit_record_entries(append: &BenchAppend) -> Result<usize, LixError> {
|
|
336
|
+
Ok(append.commit_count())
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
pub fn build_direct_change_record_entries(append: &BenchAppend) -> Result<usize, LixError> {
|
|
340
|
+
Ok(append.change_count())
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
pub fn build_commit_change_ref_entries(append: &BenchAppend) -> usize {
|
|
344
|
+
append.change_count()
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
pub fn project_first_change_to_logical(append: &BenchAppend) -> Result<usize, LixError> {
|
|
348
|
+
Ok(append.change_ids().first().map(|id| id.len()).unwrap_or(0))
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
pub fn validate_first_commit_checksum(_append: &BenchAppend) -> Result<(), LixError> {
|
|
352
|
+
Ok(())
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
pub fn validate_first_change_checksum(_append: &BenchAppend) -> Result<(), LixError> {
|
|
356
|
+
Ok(())
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
pub fn validate_publication_closure(append: &BenchAppend) -> Result<usize, LixError> {
|
|
360
|
+
Ok(append.change_count())
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
pub async fn stage_append_raw_once<B: BenchBackend>(
|
|
364
|
+
backend: B,
|
|
365
|
+
append: &BenchAppend,
|
|
366
|
+
) -> Result<BenchWriteStats, LixError>
|
|
367
|
+
where
|
|
368
|
+
B: BenchBackend + Sync,
|
|
369
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
370
|
+
{
|
|
371
|
+
stage_append_once(backend, append).await
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
pub async fn stage_append_once<B: BenchBackend>(
|
|
375
|
+
backend: B,
|
|
376
|
+
append: &BenchAppend,
|
|
377
|
+
) -> Result<BenchWriteStats, LixError>
|
|
378
|
+
where
|
|
379
|
+
B: BenchBackend + Sync,
|
|
380
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
381
|
+
{
|
|
382
|
+
let store = BenchStore::new(backend);
|
|
383
|
+
stage_append_in_store(&store, &append.append).await
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
pub async fn stage_corpus_once<B: BenchBackend>(
|
|
387
|
+
backend: B,
|
|
388
|
+
corpus: &BenchCorpus,
|
|
389
|
+
) -> Result<BenchWriteStats, LixError>
|
|
390
|
+
where
|
|
391
|
+
B: BenchBackend + Sync,
|
|
392
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
393
|
+
{
|
|
394
|
+
let store = BenchStore::new(backend);
|
|
395
|
+
let mut total = BenchWriteStats::default();
|
|
396
|
+
for append in corpus.append_batches() {
|
|
397
|
+
total += stage_append_in_store(&store, &append.append).await?;
|
|
398
|
+
}
|
|
399
|
+
Ok(total)
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
pub async fn prepare_store<B: BenchBackend>(
|
|
403
|
+
backend: B,
|
|
404
|
+
append: &BenchAppend,
|
|
405
|
+
) -> Result<BenchStore<B>, LixError>
|
|
406
|
+
where
|
|
407
|
+
B: BenchBackend + Sync,
|
|
408
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
409
|
+
{
|
|
410
|
+
let store = BenchStore::new(backend);
|
|
411
|
+
stage_append_in_store(&store, &append.append).await?;
|
|
412
|
+
Ok(store)
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
pub async fn prepare_corpus_store<B: BenchBackend>(
|
|
416
|
+
backend: B,
|
|
417
|
+
corpus: &BenchCorpus,
|
|
418
|
+
) -> Result<BenchStore<B>, LixError>
|
|
419
|
+
where
|
|
420
|
+
B: BenchBackend + Sync,
|
|
421
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
422
|
+
{
|
|
423
|
+
let store = BenchStore::new(backend);
|
|
424
|
+
for append in corpus.append_batches() {
|
|
425
|
+
stage_append_in_store(&store, &append.append).await?;
|
|
426
|
+
}
|
|
427
|
+
Ok(store)
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
pub async fn stage_first_commit_noop_in_store<B: BenchBackend>(
|
|
431
|
+
_store: &BenchStore<B>,
|
|
432
|
+
append: &BenchAppend,
|
|
433
|
+
) -> Result<BenchWriteStats, LixError>
|
|
434
|
+
where
|
|
435
|
+
B: BenchBackend + Sync,
|
|
436
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
437
|
+
{
|
|
438
|
+
Ok(BenchWriteStats {
|
|
439
|
+
puts: append.commit_count(),
|
|
440
|
+
deletes: 0,
|
|
441
|
+
bytes_written: 0,
|
|
442
|
+
})
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
pub async fn load_commits_direct_by_id<B: BenchBackend>(
|
|
446
|
+
store: &BenchStore<B>,
|
|
447
|
+
commit_ids: &[String],
|
|
448
|
+
) -> Result<usize, LixError>
|
|
449
|
+
where
|
|
450
|
+
B: BenchBackend + Sync,
|
|
451
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
452
|
+
{
|
|
453
|
+
load_commits_with_lookup(store, commit_ids, BenchCommitProjection::Full).await
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
pub async fn load_commits_direct<B: BenchBackend>(
|
|
457
|
+
store: &BenchStore<B>,
|
|
458
|
+
commit_ids: &[String],
|
|
459
|
+
) -> Result<usize, LixError>
|
|
460
|
+
where
|
|
461
|
+
B: BenchBackend + Sync,
|
|
462
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
463
|
+
{
|
|
464
|
+
load_commits_with_lookup(store, commit_ids, BenchCommitProjection::Header).await
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
pub async fn load_commits_direct_with_lookup<B: BenchBackend>(
|
|
468
|
+
store: &BenchStore<B>,
|
|
469
|
+
commit_ids: &[String],
|
|
470
|
+
projection: BenchCommitProjection,
|
|
471
|
+
) -> Result<usize, LixError>
|
|
472
|
+
where
|
|
473
|
+
B: BenchBackend + Sync,
|
|
474
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
475
|
+
{
|
|
476
|
+
load_commits_with_lookup(store, commit_ids, projection).await
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
pub async fn load_changes_direct_by_id<B: BenchBackend>(
|
|
480
|
+
store: &BenchStore<B>,
|
|
481
|
+
change_ids: &[String],
|
|
482
|
+
) -> Result<usize, LixError>
|
|
483
|
+
where
|
|
484
|
+
B: BenchBackend + Sync,
|
|
485
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
486
|
+
{
|
|
487
|
+
load_changes_with_lookup(store, change_ids, BenchChangeLookup::DirectKey).await
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
pub async fn load_changes_direct<B: BenchBackend>(
|
|
491
|
+
store: &BenchStore<B>,
|
|
492
|
+
change_ids: &[String],
|
|
493
|
+
) -> Result<usize, LixError>
|
|
494
|
+
where
|
|
495
|
+
B: BenchBackend + Sync,
|
|
496
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
497
|
+
{
|
|
498
|
+
load_changes_with_lookup(store, change_ids, BenchChangeLookup::Record).await
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
pub async fn load_changes_direct_with_lookup<B: BenchBackend>(
|
|
502
|
+
store: &BenchStore<B>,
|
|
503
|
+
change_ids: &[String],
|
|
504
|
+
lookup: BenchChangeLookup,
|
|
505
|
+
) -> Result<usize, LixError>
|
|
506
|
+
where
|
|
507
|
+
B: BenchBackend + Sync,
|
|
508
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
509
|
+
{
|
|
510
|
+
load_changes_with_lookup(store, change_ids, lookup).await
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
pub async fn prepare_rebuild_store<B: BenchBackend>(
|
|
514
|
+
backend: B,
|
|
515
|
+
corpus: &BenchCorpus,
|
|
516
|
+
_mode: BenchRebuildMode,
|
|
517
|
+
) -> Result<BenchStore<B>, LixError>
|
|
518
|
+
where
|
|
519
|
+
B: BenchBackend + Sync,
|
|
520
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
521
|
+
{
|
|
522
|
+
prepare_corpus_store(backend, corpus).await
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
pub async fn rebuild_mandatory_indexes<B: BenchBackend>(
|
|
526
|
+
_store: &BenchStore<B>,
|
|
527
|
+
) -> Result<BenchRebuildStats, LixError>
|
|
528
|
+
where
|
|
529
|
+
B: BenchBackend + Sync,
|
|
530
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
531
|
+
{
|
|
532
|
+
Ok(RebuildIndexStats::default().into())
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
pub async fn prepare_gc_store<B: BenchBackend>(
|
|
536
|
+
backend: B,
|
|
537
|
+
live_percent: usize,
|
|
538
|
+
dead_percent: usize,
|
|
539
|
+
changes_per_commit: usize,
|
|
540
|
+
) -> Result<(BenchStore<B>, String), LixError>
|
|
541
|
+
where
|
|
542
|
+
B: BenchBackend + Sync,
|
|
543
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
544
|
+
{
|
|
545
|
+
let commit_count = (live_percent + dead_percent).max(1);
|
|
546
|
+
let corpus = BenchCorpus::from_append_batches(
|
|
547
|
+
(0..commit_count)
|
|
548
|
+
.map(|index| {
|
|
549
|
+
direct_append_with_shape(&format!("bench-gc-{index}"), 1, changes_per_commit.max(1))
|
|
550
|
+
})
|
|
551
|
+
.collect::<Result<Vec<_>, _>>()?,
|
|
552
|
+
);
|
|
553
|
+
let root_commit_id = corpus
|
|
554
|
+
.first_commit_id()
|
|
555
|
+
.unwrap_or("bench-gc-0-commit-0")
|
|
556
|
+
.to_string();
|
|
557
|
+
let store = prepare_corpus_store(backend, &corpus).await?;
|
|
558
|
+
Ok((store, root_commit_id))
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
pub async fn plan_gc<B: BenchBackend>(
|
|
562
|
+
store: &BenchStore<B>,
|
|
563
|
+
root_commit_id: &str,
|
|
564
|
+
) -> Result<BenchGcStats, LixError>
|
|
565
|
+
where
|
|
566
|
+
B: BenchBackend + Sync,
|
|
567
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
568
|
+
{
|
|
569
|
+
let read = store.storage.begin_read(StorageReadOptions::default())?;
|
|
570
|
+
let mut reader = store.context.reader(read);
|
|
571
|
+
let plan = reader
|
|
572
|
+
.plan_gc(&[GcRoot::BranchHead(root_commit_id.to_string())])
|
|
573
|
+
.await?;
|
|
574
|
+
Ok(plan.into())
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
pub async fn collect_garbage<B: BenchBackend>(
|
|
578
|
+
store: &BenchStore<B>,
|
|
579
|
+
root_commit_id: &str,
|
|
580
|
+
) -> Result<BenchGcStats, LixError>
|
|
581
|
+
where
|
|
582
|
+
B: BenchBackend + Sync,
|
|
583
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
584
|
+
{
|
|
585
|
+
let mut transaction = store.storage.begin_write_transaction().await?;
|
|
586
|
+
let mut writes = crate::storage::StorageWriteSet::new();
|
|
587
|
+
let plan = {
|
|
588
|
+
let mut writer = store.context.writer(&mut *transaction, &mut writes);
|
|
589
|
+
writer
|
|
590
|
+
.collect_garbage(&[GcRoot::BranchHead(root_commit_id.to_string())])
|
|
591
|
+
.await?
|
|
592
|
+
};
|
|
593
|
+
writes.apply(&mut *transaction).await?;
|
|
594
|
+
transaction.commit().await?;
|
|
595
|
+
Ok(plan.into())
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
599
|
+
pub enum BenchRebuildMode {
|
|
600
|
+
Noop,
|
|
601
|
+
EmptyIndexes,
|
|
602
|
+
StaleExtraRows,
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
fn direct_append_with_shape(
|
|
606
|
+
name: &str,
|
|
607
|
+
commit_count: usize,
|
|
608
|
+
change_count: usize,
|
|
609
|
+
) -> Result<BenchAppend, LixError> {
|
|
610
|
+
let mut append = ChangelogAppend::default();
|
|
611
|
+
let changes_per_commit = change_count.div_ceil(commit_count.max(1)).max(1);
|
|
612
|
+
let mut next_change = 0usize;
|
|
613
|
+
for commit_index in 0..commit_count {
|
|
614
|
+
let commit_id = format!("{name}-commit-{commit_index}");
|
|
615
|
+
let commit_change_id = format!("{commit_id}:commit");
|
|
616
|
+
let mut refs = Vec::new();
|
|
617
|
+
let remaining = change_count.saturating_sub(next_change);
|
|
618
|
+
let take = remaining.min(changes_per_commit);
|
|
619
|
+
for _ in 0..take {
|
|
620
|
+
let change_id = format!("{name}-change-{next_change}");
|
|
621
|
+
let entity_pk = EntityPk::single(format!("entity-{next_change}"));
|
|
622
|
+
append.changes.push(ChangeRecord {
|
|
623
|
+
format_version: 1,
|
|
624
|
+
change_id: change_id.clone(),
|
|
625
|
+
schema_key: "message".to_string(),
|
|
626
|
+
entity_pk: entity_pk.clone(),
|
|
627
|
+
file_id: None,
|
|
628
|
+
snapshot_ref: Some(JsonRef::for_content(
|
|
629
|
+
format!("{{\"value\":{next_change}}}").as_bytes(),
|
|
630
|
+
)),
|
|
631
|
+
metadata_ref: None,
|
|
632
|
+
created_at: "2026-05-20T00:00:00Z".to_string(),
|
|
633
|
+
});
|
|
634
|
+
refs.push(CommitChangeRef {
|
|
635
|
+
schema_key: "message".to_string(),
|
|
636
|
+
file_id: None,
|
|
637
|
+
entity_pk,
|
|
638
|
+
change_id,
|
|
639
|
+
});
|
|
640
|
+
next_change += 1;
|
|
641
|
+
}
|
|
642
|
+
append.commits.push(CommitRecord {
|
|
643
|
+
format_version: 1,
|
|
644
|
+
commit_id: commit_id.clone(),
|
|
645
|
+
parent_commit_ids: Vec::new(),
|
|
646
|
+
change_id: commit_change_id,
|
|
647
|
+
author_account_ids: Vec::new(),
|
|
648
|
+
created_at: "2026-05-20T00:00:00Z".to_string(),
|
|
649
|
+
});
|
|
650
|
+
append.commit_change_refs.push(CommitChangeRefSet {
|
|
651
|
+
commit_id,
|
|
652
|
+
entries: refs,
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
Ok(BenchAppend { append })
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
impl BenchCorpus {
|
|
659
|
+
fn from_append_batches(append_batches: Vec<BenchAppend>) -> Self {
|
|
660
|
+
let commit_ids = append_batches
|
|
661
|
+
.iter()
|
|
662
|
+
.flat_map(BenchAppend::commit_ids)
|
|
663
|
+
.collect::<Vec<_>>();
|
|
664
|
+
let change_ids = append_batches
|
|
665
|
+
.iter()
|
|
666
|
+
.flat_map(BenchAppend::change_ids)
|
|
667
|
+
.collect::<Vec<_>>();
|
|
668
|
+
Self {
|
|
669
|
+
append_batches,
|
|
670
|
+
commit_ids,
|
|
671
|
+
change_ids,
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
impl<B> BenchStore<B>
|
|
677
|
+
where
|
|
678
|
+
B: BenchBackend + Sync,
|
|
679
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
680
|
+
{
|
|
681
|
+
fn new(backend: B) -> Self {
|
|
682
|
+
Self {
|
|
683
|
+
context: ChangelogContext::new(),
|
|
684
|
+
storage: StorageContext::new(backend),
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
async fn stage_append_in_store<B: BenchBackend>(
|
|
690
|
+
store: &BenchStore<B>,
|
|
691
|
+
append: &ChangelogAppend,
|
|
692
|
+
) -> Result<BenchWriteStats, LixError>
|
|
693
|
+
where
|
|
694
|
+
B: BenchBackend + Sync,
|
|
695
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
696
|
+
{
|
|
697
|
+
let mut transaction = store.storage.begin_write_transaction().await?;
|
|
698
|
+
let mut writes = crate::storage::StorageWriteSet::new();
|
|
699
|
+
{
|
|
700
|
+
let mut writer = store.context.writer(&mut *transaction, &mut writes);
|
|
701
|
+
writer.stage_append(append.clone()).await?;
|
|
702
|
+
}
|
|
703
|
+
let stats = writes.apply(&mut *transaction).await?;
|
|
704
|
+
transaction.commit().await?;
|
|
705
|
+
Ok(stats.into())
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
async fn load_commits_with_lookup<B: BenchBackend>(
|
|
709
|
+
store: &BenchStore<B>,
|
|
710
|
+
commit_ids: &[String],
|
|
711
|
+
projection: BenchCommitProjection,
|
|
712
|
+
) -> Result<usize, LixError>
|
|
713
|
+
where
|
|
714
|
+
B: BenchBackend + Sync,
|
|
715
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
716
|
+
{
|
|
717
|
+
let read = store.storage.begin_read(StorageReadOptions::default())?;
|
|
718
|
+
let mut reader = store.context.reader(read);
|
|
719
|
+
let batch = reader
|
|
720
|
+
.load_commits(CommitLoadRequest {
|
|
721
|
+
commit_ids,
|
|
722
|
+
projection: projection.into_inner(),
|
|
723
|
+
})
|
|
724
|
+
.await?;
|
|
725
|
+
Ok(batch.entries.iter().filter(|entry| entry.is_some()).count())
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
async fn load_changes_with_lookup<B: BenchBackend>(
|
|
729
|
+
store: &BenchStore<B>,
|
|
730
|
+
change_ids: &[String],
|
|
731
|
+
_lookup: BenchChangeLookup,
|
|
732
|
+
) -> Result<usize, LixError>
|
|
733
|
+
where
|
|
734
|
+
B: BenchBackend + Sync,
|
|
735
|
+
for<'a> StorageBackendReadOf<'a, B>: Send,
|
|
736
|
+
{
|
|
737
|
+
let read = store.storage.begin_read(StorageReadOptions::default())?;
|
|
738
|
+
let mut reader = store.context.reader(read);
|
|
739
|
+
let batch = reader
|
|
740
|
+
.load_changes(ChangeLoadRequest { change_ids })
|
|
741
|
+
.await?;
|
|
742
|
+
Ok(batch.entries.iter().filter(|entry| entry.is_some()).count())
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
impl From<StorageWriteSetStats> for BenchWriteStats {
|
|
746
|
+
fn from(stats: StorageWriteSetStats) -> Self {
|
|
747
|
+
Self {
|
|
748
|
+
puts: stats.staged_puts as usize,
|
|
749
|
+
deletes: stats.staged_deletes as usize,
|
|
750
|
+
bytes_written: stats.written_bytes as usize,
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
impl From<RebuildIndexStats> for BenchRebuildStats {
|
|
756
|
+
fn from(stats: RebuildIndexStats) -> Self {
|
|
757
|
+
Self {
|
|
758
|
+
expected: stats.expected,
|
|
759
|
+
put: stats.put,
|
|
760
|
+
deleted: stats.deleted,
|
|
761
|
+
unchanged: stats.unchanged,
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
impl From<GcPlan> for BenchGcStats {
|
|
767
|
+
fn from(plan: GcPlan) -> Self {
|
|
768
|
+
Self {
|
|
769
|
+
live_commits: plan.live.commits.len(),
|
|
770
|
+
live_changes: plan.live.changes.len(),
|
|
771
|
+
live_payloads: plan.live.payloads.len(),
|
|
772
|
+
live_append_batches: 0,
|
|
773
|
+
sweep_append_batches: 0,
|
|
774
|
+
sweep_index_rows: plan.sweep.commit_change_ref_chunks.len(),
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
impl std::ops::AddAssign for BenchWriteStats {
|
|
780
|
+
fn add_assign(&mut self, rhs: Self) {
|
|
781
|
+
self.puts += rhs.puts;
|
|
782
|
+
self.deletes += rhs.deletes;
|
|
783
|
+
self.bytes_written += rhs.bytes_written;
|
|
784
|
+
}
|
|
785
|
+
}
|