@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.
Files changed (234) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +65 -64
  3. package/dist/engine-wasm/index.js +4 -4
  4. package/dist/engine-wasm/wasm/lix_engine.d.ts +5 -5
  5. package/dist/engine-wasm/wasm/lix_engine.js +130 -118
  6. package/dist/engine-wasm/wasm/lix_engine.wasm +0 -0
  7. package/dist/engine-wasm/wasm/lix_engine.wasm.d.ts +9 -8
  8. package/dist/generated/builtin-schemas.d.ts +69 -69
  9. package/dist/generated/builtin-schemas.js +94 -94
  10. package/dist/open-lix.d.ts +33 -26
  11. package/dist/open-lix.js +10 -10
  12. package/dist/sqlite/index.js +86 -30
  13. package/dist-engine-src/README.md +3 -3
  14. package/dist-engine-src/src/backend/capabilities.rs +67 -0
  15. package/dist-engine-src/src/backend/conformance/baseline.rs +1127 -0
  16. package/dist-engine-src/src/backend/conformance/factory.rs +93 -0
  17. package/dist-engine-src/src/backend/conformance/failure_tests.rs +608 -0
  18. package/dist-engine-src/src/backend/conformance/fixtures.rs +26 -0
  19. package/dist-engine-src/src/backend/conformance/mod.rs +75 -0
  20. package/dist-engine-src/src/backend/conformance/model.rs +28 -0
  21. package/dist-engine-src/src/backend/conformance/model_based.rs +257 -0
  22. package/dist-engine-src/src/backend/conformance/persistence.rs +204 -0
  23. package/dist-engine-src/src/backend/conformance/projection.rs +21 -0
  24. package/dist-engine-src/src/backend/conformance/pushdown.rs +24 -0
  25. package/dist-engine-src/src/backend/conformance/runner.rs +90 -0
  26. package/dist-engine-src/src/backend/conformance/scan.rs +24 -0
  27. package/dist-engine-src/src/backend/conformance/write.rs +16 -0
  28. package/dist-engine-src/src/backend/error.rs +94 -0
  29. package/dist-engine-src/src/backend/in_memory.rs +670 -0
  30. package/dist-engine-src/src/backend/mod.rs +36 -9
  31. package/dist-engine-src/src/backend/predicate.rs +80 -0
  32. package/dist-engine-src/src/backend/traits.rs +260 -0
  33. package/dist-engine-src/src/backend/types.rs +224 -81
  34. package/dist-engine-src/src/binary_cas/context.rs +8 -8
  35. package/dist-engine-src/src/binary_cas/kv.rs +234 -259
  36. package/dist-engine-src/src/{version → branch}/context.rs +12 -12
  37. package/dist-engine-src/src/branch/lifecycle.rs +221 -0
  38. package/dist-engine-src/src/branch/mod.rs +13 -0
  39. package/dist-engine-src/src/branch/refs.rs +321 -0
  40. package/dist-engine-src/src/branch/stage_rows.rs +67 -0
  41. package/dist-engine-src/src/branch/types.rs +21 -0
  42. package/dist-engine-src/src/catalog/context.rs +18 -18
  43. package/dist-engine-src/src/catalog/snapshot.rs +8 -8
  44. package/dist-engine-src/src/changelog/bench_support.rs +785 -0
  45. package/dist-engine-src/src/changelog/change.rs +1 -0
  46. package/dist-engine-src/src/changelog/codec.rs +497 -0
  47. package/dist-engine-src/src/changelog/commit.rs +1 -0
  48. package/dist-engine-src/src/changelog/context.rs +1614 -0
  49. package/dist-engine-src/src/changelog/mod.rs +29 -0
  50. package/dist-engine-src/src/changelog/store.rs +163 -0
  51. package/dist-engine-src/src/changelog/test_support.rs +54 -0
  52. package/dist-engine-src/src/changelog/types.rs +213 -0
  53. package/dist-engine-src/src/commit_graph/context.rs +317 -274
  54. package/dist-engine-src/src/commit_graph/mod.rs +2 -4
  55. package/dist-engine-src/src/commit_graph/types.rs +22 -42
  56. package/dist-engine-src/src/commit_graph/walker.rs +133 -103
  57. package/dist-engine-src/src/common/error.rs +52 -18
  58. package/dist-engine-src/src/common/identity.rs +2 -2
  59. package/dist-engine-src/src/common/mod.rs +1 -1
  60. package/dist-engine-src/src/domain.rs +42 -46
  61. package/dist-engine-src/src/engine.rs +74 -96
  62. package/dist-engine-src/src/{entity_identity.rs → entity_pk.rs} +89 -92
  63. package/dist-engine-src/src/functions/context.rs +56 -52
  64. package/dist-engine-src/src/functions/state.rs +51 -52
  65. package/dist-engine-src/src/init.rs +288 -154
  66. package/dist-engine-src/src/json_store/context.rs +15 -266
  67. package/dist-engine-src/src/json_store/mod.rs +26 -0
  68. package/dist-engine-src/src/json_store/store.rs +103 -718
  69. package/dist-engine-src/src/json_store/types.rs +4 -9
  70. package/dist-engine-src/src/lib.rs +49 -19
  71. package/dist-engine-src/src/live_state/context.rs +654 -790
  72. package/dist-engine-src/src/live_state/mod.rs +9 -3
  73. package/dist-engine-src/src/live_state/overlay.rs +4 -4
  74. package/dist-engine-src/src/live_state/types.rs +30 -21
  75. package/dist-engine-src/src/live_state/visibility.rs +514 -71
  76. package/dist-engine-src/src/plugin/install.rs +48 -48
  77. package/dist-engine-src/src/plugin/manifest.rs +7 -7
  78. package/dist-engine-src/src/plugin/materializer.rs +0 -275
  79. package/dist-engine-src/src/plugin/plugin_manifest.json +4 -3
  80. package/dist-engine-src/src/schema/builtin/lix_binary_blob_ref.json +2 -2
  81. package/dist-engine-src/src/schema/builtin/lix_branch_descriptor.json +34 -0
  82. package/dist-engine-src/src/schema/builtin/lix_branch_ref.json +48 -0
  83. package/dist-engine-src/src/schema/builtin/lix_change.json +3 -3
  84. package/dist-engine-src/src/schema/builtin/lix_commit.json +1 -1
  85. package/dist-engine-src/src/schema/builtin/lix_label_assignment.json +6 -6
  86. package/dist-engine-src/src/schema/builtin/mod.rs +18 -20
  87. package/dist-engine-src/src/schema/compatibility.rs +11 -11
  88. package/dist-engine-src/src/schema/definition.json +2 -2
  89. package/dist-engine-src/src/schema/definition.rs +5 -5
  90. package/dist-engine-src/src/schema/key.rs +3 -3
  91. package/dist-engine-src/src/schema/mod.rs +1 -1
  92. package/dist-engine-src/src/schema/tests.rs +18 -18
  93. package/dist-engine-src/src/session/context.rs +803 -148
  94. package/dist-engine-src/src/session/create_branch.rs +94 -0
  95. package/dist-engine-src/src/session/execute.rs +223 -83
  96. package/dist-engine-src/src/session/merge/analysis.rs +9 -3
  97. package/dist-engine-src/src/session/merge/{version.rs → branch.rs} +119 -129
  98. package/dist-engine-src/src/session/merge/conflicts.rs +2 -2
  99. package/dist-engine-src/src/session/merge/mod.rs +5 -6
  100. package/dist-engine-src/src/session/merge/stats.rs +7 -11
  101. package/dist-engine-src/src/session/mod.rs +15 -12
  102. package/dist-engine-src/src/session/switch_branch.rs +113 -0
  103. package/dist-engine-src/src/session/transaction.rs +495 -14
  104. package/dist-engine-src/src/sql2/{classify.rs → bind/classify.rs} +3 -75
  105. package/dist-engine-src/src/sql2/bind/error.rs +5 -0
  106. package/dist-engine-src/src/sql2/bind/expr.rs +29 -0
  107. package/dist-engine-src/src/sql2/bind/mod.rs +12 -0
  108. package/dist-engine-src/src/sql2/{udfs/public_call.rs → bind/public_udf.rs} +71 -3
  109. package/dist-engine-src/src/sql2/bind/read.rs +65 -0
  110. package/dist-engine-src/src/sql2/bind/statement.rs +2236 -0
  111. package/dist-engine-src/src/sql2/bind/table.rs +273 -0
  112. package/dist-engine-src/src/sql2/bind/write.rs +86 -0
  113. package/dist-engine-src/src/sql2/branch_scope.rs +436 -0
  114. package/dist-engine-src/src/sql2/catalog/capability.rs +20 -0
  115. package/dist-engine-src/src/sql2/catalog/entity_surface.rs +296 -0
  116. package/dist-engine-src/src/sql2/catalog/mod.rs +15 -0
  117. package/dist-engine-src/src/sql2/catalog/registry.rs +556 -0
  118. package/dist-engine-src/src/sql2/catalog/schema.rs +88 -0
  119. package/dist-engine-src/src/sql2/catalog/surface.rs +41 -0
  120. package/dist-engine-src/src/sql2/change_materialization.rs +122 -0
  121. package/dist-engine-src/src/sql2/context.rs +36 -30
  122. package/dist-engine-src/src/sql2/error.rs +1 -1
  123. package/dist-engine-src/src/sql2/exec/bound_public_write.rs +1593 -0
  124. package/dist-engine-src/src/sql2/exec/datafusion.rs +5266 -0
  125. package/dist-engine-src/src/sql2/exec/fast_write.rs +82 -0
  126. package/dist-engine-src/src/sql2/exec/mod.rs +24 -0
  127. package/dist-engine-src/src/sql2/exec/write.rs +661 -0
  128. package/dist-engine-src/src/sql2/filesystem_planner.rs +72 -77
  129. package/dist-engine-src/src/sql2/filesystem_visibility.rs +21 -21
  130. package/dist-engine-src/src/sql2/history_projection.rs +8 -8
  131. package/dist-engine-src/src/sql2/history_route.rs +35 -31
  132. package/dist-engine-src/src/sql2/mod.rs +28 -23
  133. package/dist-engine-src/src/sql2/optimize/datafusion.rs +1 -0
  134. package/dist-engine-src/src/sql2/optimize/mod.rs +2 -0
  135. package/dist-engine-src/src/sql2/optimize/simple_write.rs +116 -0
  136. package/dist-engine-src/src/sql2/parse/mod.rs +69 -0
  137. package/dist-engine-src/src/sql2/parse/normalize.rs +1 -0
  138. package/dist-engine-src/src/sql2/plan/branch_scope.rs +24 -0
  139. package/dist-engine-src/src/sql2/plan/mod.rs +5 -0
  140. package/dist-engine-src/src/sql2/plan/predicate.rs +22 -0
  141. package/dist-engine-src/src/sql2/plan/write.rs +147 -0
  142. package/dist-engine-src/src/sql2/predicate_typecheck.rs +258 -0
  143. package/dist-engine-src/src/sql2/{version_provider.rs → providers/branch.rs} +218 -214
  144. package/dist-engine-src/src/sql2/{change_provider.rs → providers/change.rs} +156 -42
  145. package/dist-engine-src/src/sql2/{directory_provider.rs → providers/directory.rs} +291 -322
  146. package/dist-engine-src/src/sql2/{directory_history_provider.rs → providers/directory_history.rs} +56 -42
  147. package/dist-engine-src/src/sql2/providers/entity.rs +1484 -0
  148. package/dist-engine-src/src/sql2/{entity_history_provider.rs → providers/entity_history.rs} +43 -31
  149. package/dist-engine-src/src/sql2/{file_provider.rs → providers/file.rs} +323 -316
  150. package/dist-engine-src/src/sql2/{file_history_provider.rs → providers/file_history.rs} +60 -46
  151. package/dist-engine-src/src/sql2/{history_provider.rs → providers/history.rs} +46 -32
  152. package/dist-engine-src/src/sql2/{lix_state_provider.rs → providers/lix_state.rs} +359 -329
  153. package/dist-engine-src/src/sql2/providers/mod.rs +508 -0
  154. package/dist-engine-src/src/sql2/read_only.rs +2 -2
  155. package/dist-engine-src/src/sql2/session.rs +47 -96
  156. package/dist-engine-src/src/sql2/storage/constraints.rs +1 -0
  157. package/dist-engine-src/src/sql2/storage/mod.rs +1 -0
  158. package/dist-engine-src/src/sql2/test_support/differential.rs +712 -0
  159. package/dist-engine-src/src/sql2/test_support/generators.rs +354 -0
  160. package/dist-engine-src/src/sql2/test_support/mod.rs +2 -0
  161. package/dist-engine-src/src/sql2/udfs/{lix_active_version_commit_id.rs → lix_active_branch_commit_id.rs} +7 -7
  162. package/dist-engine-src/src/sql2/udfs/mod.rs +3 -6
  163. package/dist-engine-src/src/sql2/write_normalization.rs +45 -22
  164. package/dist-engine-src/src/storage/conformance.rs +399 -0
  165. package/dist-engine-src/src/storage/context.rs +552 -288
  166. package/dist-engine-src/src/storage/mod.rs +48 -10
  167. package/dist-engine-src/src/storage/point.rs +440 -0
  168. package/dist-engine-src/src/storage/read_scope.rs +43 -64
  169. package/dist-engine-src/src/storage/reader.rs +867 -0
  170. package/dist-engine-src/src/storage/scan.rs +784 -0
  171. package/dist-engine-src/src/storage/spaces.rs +236 -0
  172. package/dist-engine-src/src/storage/stats.rs +80 -0
  173. package/dist-engine-src/src/storage/write_set.rs +962 -0
  174. package/dist-engine-src/src/storage_bench.rs +136 -4828
  175. package/dist-engine-src/src/test_support.rs +360 -138
  176. package/dist-engine-src/src/tracked_state/bench_support.rs +394 -0
  177. package/dist-engine-src/src/tracked_state/codec.rs +155 -1057
  178. package/dist-engine-src/src/tracked_state/commit_root_rebuild.rs +358 -0
  179. package/dist-engine-src/src/tracked_state/context.rs +1927 -993
  180. package/dist-engine-src/src/tracked_state/diff.rs +1715 -261
  181. package/dist-engine-src/src/tracked_state/merge.rs +74 -88
  182. package/dist-engine-src/src/tracked_state/mod.rs +19 -16
  183. package/dist-engine-src/src/tracked_state/{materialization.rs → row_materialization.rs} +50 -178
  184. package/dist-engine-src/src/tracked_state/storage.rs +243 -191
  185. package/dist-engine-src/src/tracked_state/tree.rs +247 -371
  186. package/dist-engine-src/src/tracked_state/types.rs +49 -42
  187. package/dist-engine-src/src/transaction/bench_support.rs +407 -0
  188. package/dist-engine-src/src/transaction/commit.rs +821 -713
  189. package/dist-engine-src/src/transaction/context.rs +705 -600
  190. package/dist-engine-src/src/transaction/mod.rs +13 -2
  191. package/dist-engine-src/src/transaction/normalization.rs +63 -76
  192. package/dist-engine-src/src/transaction/prep.rs +13 -13
  193. package/dist-engine-src/src/transaction/schema_resolver.rs +19 -5
  194. package/dist-engine-src/src/transaction/staging.rs +228 -434
  195. package/dist-engine-src/src/transaction/types.rs +41 -98
  196. package/dist-engine-src/src/transaction/validation.rs +382 -446
  197. package/dist-engine-src/src/untracked_state/codec.rs +337 -29
  198. package/dist-engine-src/src/untracked_state/context.rs +7 -7
  199. package/dist-engine-src/src/untracked_state/materialization.rs +2 -2
  200. package/dist-engine-src/src/untracked_state/mod.rs +1 -1
  201. package/dist-engine-src/src/untracked_state/storage.rs +659 -157
  202. package/dist-engine-src/src/untracked_state/types.rs +21 -21
  203. package/package.json +71 -68
  204. package/dist-engine-src/src/backend/kv.rs +0 -358
  205. package/dist-engine-src/src/backend/testing.rs +0 -658
  206. package/dist-engine-src/src/commit_store/codec.rs +0 -887
  207. package/dist-engine-src/src/commit_store/context.rs +0 -944
  208. package/dist-engine-src/src/commit_store/materialization.rs +0 -84
  209. package/dist-engine-src/src/commit_store/mod.rs +0 -16
  210. package/dist-engine-src/src/commit_store/storage.rs +0 -600
  211. package/dist-engine-src/src/commit_store/types.rs +0 -215
  212. package/dist-engine-src/src/schema/builtin/lix_version_descriptor.json +0 -34
  213. package/dist-engine-src/src/schema/builtin/lix_version_ref.json +0 -48
  214. package/dist-engine-src/src/session/create_version.rs +0 -88
  215. package/dist-engine-src/src/session/merge/apply.rs +0 -23
  216. package/dist-engine-src/src/session/optimization9_sql2_bench.rs +0 -100
  217. package/dist-engine-src/src/session/switch_version.rs +0 -110
  218. package/dist-engine-src/src/sql2/entity_provider.rs +0 -3211
  219. package/dist-engine-src/src/sql2/execute.rs +0 -3533
  220. package/dist-engine-src/src/sql2/public_bind/assignment.rs +0 -46
  221. package/dist-engine-src/src/sql2/public_bind/capability.rs +0 -41
  222. package/dist-engine-src/src/sql2/public_bind/dml.rs +0 -172
  223. package/dist-engine-src/src/sql2/public_bind/mod.rs +0 -26
  224. package/dist-engine-src/src/sql2/public_bind/table.rs +0 -168
  225. package/dist-engine-src/src/sql2/version_scope.rs +0 -394
  226. package/dist-engine-src/src/storage/types.rs +0 -501
  227. package/dist-engine-src/src/tracked_state/by_file_index.rs +0 -98
  228. package/dist-engine-src/src/tracked_state/materializer.rs +0 -488
  229. package/dist-engine-src/src/transaction/live_state_overlay.rs +0 -35
  230. package/dist-engine-src/src/version/lifecycle.rs +0 -221
  231. package/dist-engine-src/src/version/mod.rs +0 -13
  232. package/dist-engine-src/src/version/refs.rs +0 -330
  233. package/dist-engine-src/src/version/stage_rows.rs +0 -67
  234. package/dist-engine-src/src/version/types.rs +0 -21
@@ -1,501 +0,0 @@
1
- use async_trait::async_trait;
2
-
3
- use crate::backend;
4
- use crate::backend::BytePage;
5
- use crate::LixError;
6
-
7
- #[derive(Debug, Clone, PartialEq, Eq)]
8
- pub(crate) enum KvScanRange {
9
- Prefix(Vec<u8>),
10
- Range { start: Vec<u8>, end: Vec<u8> },
11
- }
12
-
13
- impl KvScanRange {
14
- pub(crate) fn prefix(prefix: impl Into<Vec<u8>>) -> Self {
15
- Self::Prefix(prefix.into())
16
- }
17
-
18
- pub(crate) fn range(start: impl Into<Vec<u8>>, end: impl Into<Vec<u8>>) -> Self {
19
- Self::Range {
20
- start: start.into(),
21
- end: end.into(),
22
- }
23
- }
24
- }
25
-
26
- impl From<KvScanRange> for backend::BackendKvScanRange {
27
- fn from(range: KvScanRange) -> Self {
28
- match range {
29
- KvScanRange::Prefix(prefix) => Self::Prefix(prefix),
30
- KvScanRange::Range { start, end } => Self::Range { start, end },
31
- }
32
- }
33
- }
34
-
35
- #[async_trait]
36
- pub(crate) trait StorageReader: Send {
37
- async fn get_values(&mut self, request: KvGetRequest) -> Result<KvValueBatch, LixError>;
38
-
39
- async fn exists_many(&mut self, request: KvGetRequest) -> Result<KvExistsBatch, LixError>;
40
-
41
- async fn scan_keys(&mut self, request: KvScanRequest) -> Result<KvKeyPage, LixError>;
42
-
43
- async fn scan_values(&mut self, request: KvScanRequest) -> Result<KvValuePage, LixError>;
44
-
45
- async fn scan_entries(&mut self, request: KvScanRequest) -> Result<KvEntryPage, LixError>;
46
- }
47
-
48
- #[async_trait]
49
- pub(crate) trait StorageWriter: StorageReader {
50
- async fn write_kv_batch(&mut self, batch: KvWriteBatch) -> Result<KvWriteStats, LixError>;
51
- }
52
-
53
- #[async_trait]
54
- pub(crate) trait StorageReadTransaction: StorageReader + Send + Sync {
55
- async fn rollback(self: Box<Self>) -> Result<(), LixError>;
56
- }
57
-
58
- #[async_trait]
59
- pub(crate) trait StorageWriteTransaction:
60
- StorageReadTransaction + StorageWriter + Send + Sync
61
- {
62
- async fn commit(self: Box<Self>) -> Result<(), LixError>;
63
- }
64
-
65
- #[async_trait]
66
- impl<T> StorageReader for &mut T
67
- where
68
- T: StorageReader + ?Sized,
69
- {
70
- async fn get_values(&mut self, request: KvGetRequest) -> Result<KvValueBatch, LixError> {
71
- (**self).get_values(request).await
72
- }
73
-
74
- async fn exists_many(&mut self, request: KvGetRequest) -> Result<KvExistsBatch, LixError> {
75
- (**self).exists_many(request).await
76
- }
77
-
78
- async fn scan_keys(&mut self, request: KvScanRequest) -> Result<KvKeyPage, LixError> {
79
- (**self).scan_keys(request).await
80
- }
81
-
82
- async fn scan_values(&mut self, request: KvScanRequest) -> Result<KvValuePage, LixError> {
83
- (**self).scan_values(request).await
84
- }
85
-
86
- async fn scan_entries(&mut self, request: KvScanRequest) -> Result<KvEntryPage, LixError> {
87
- (**self).scan_entries(request).await
88
- }
89
- }
90
-
91
- #[async_trait]
92
- impl<T> StorageReader for Box<T>
93
- where
94
- T: StorageReader + ?Sized,
95
- {
96
- async fn get_values(&mut self, request: KvGetRequest) -> Result<KvValueBatch, LixError> {
97
- (**self).get_values(request).await
98
- }
99
-
100
- async fn exists_many(&mut self, request: KvGetRequest) -> Result<KvExistsBatch, LixError> {
101
- (**self).exists_many(request).await
102
- }
103
-
104
- async fn scan_keys(&mut self, request: KvScanRequest) -> Result<KvKeyPage, LixError> {
105
- (**self).scan_keys(request).await
106
- }
107
-
108
- async fn scan_values(&mut self, request: KvScanRequest) -> Result<KvValuePage, LixError> {
109
- (**self).scan_values(request).await
110
- }
111
-
112
- async fn scan_entries(&mut self, request: KvScanRequest) -> Result<KvEntryPage, LixError> {
113
- (**self).scan_entries(request).await
114
- }
115
- }
116
-
117
- #[async_trait]
118
- impl<T> StorageWriter for &mut T
119
- where
120
- T: StorageWriter + ?Sized,
121
- {
122
- async fn write_kv_batch(&mut self, batch: KvWriteBatch) -> Result<KvWriteStats, LixError> {
123
- (**self).write_kv_batch(batch).await
124
- }
125
- }
126
-
127
- #[async_trait]
128
- impl<T> StorageWriter for Box<T>
129
- where
130
- T: StorageWriter + ?Sized,
131
- {
132
- async fn write_kv_batch(&mut self, batch: KvWriteBatch) -> Result<KvWriteStats, LixError> {
133
- (**self).write_kv_batch(batch).await
134
- }
135
- }
136
-
137
- #[derive(Debug, Clone, PartialEq, Eq)]
138
- pub(crate) struct KvGetRequest {
139
- pub(crate) groups: Vec<KvGetGroup>,
140
- }
141
-
142
- impl From<KvGetRequest> for backend::BackendKvGetRequest {
143
- fn from(request: KvGetRequest) -> Self {
144
- Self {
145
- groups: request.groups.into_iter().map(Into::into).collect(),
146
- }
147
- }
148
- }
149
-
150
- #[derive(Debug, Clone, PartialEq, Eq)]
151
- pub(crate) struct KvGetGroup {
152
- pub(crate) namespace: String,
153
- pub(crate) keys: Vec<Vec<u8>>,
154
- }
155
-
156
- impl From<KvGetGroup> for backend::BackendKvGetGroup {
157
- fn from(group: KvGetGroup) -> Self {
158
- Self {
159
- namespace: group.namespace,
160
- keys: group.keys,
161
- }
162
- }
163
- }
164
-
165
- #[derive(Debug, Clone, PartialEq, Eq)]
166
- pub(crate) struct KvValueBatch {
167
- pub(crate) groups: Vec<KvValueGroup>,
168
- }
169
-
170
- impl From<backend::BackendKvValueBatch> for KvValueBatch {
171
- fn from(result: backend::BackendKvValueBatch) -> Self {
172
- Self {
173
- groups: result.groups.into_iter().map(Into::into).collect(),
174
- }
175
- }
176
- }
177
-
178
- #[derive(Debug, Clone, PartialEq, Eq)]
179
- pub(crate) struct KvValueGroup {
180
- namespace: String,
181
- values: BytePage,
182
- present: Vec<bool>,
183
- }
184
-
185
- impl From<backend::BackendKvValueGroup> for KvValueGroup {
186
- fn from(group: backend::BackendKvValueGroup) -> Self {
187
- let (namespace, values, present) = group.into_parts();
188
- Self {
189
- namespace,
190
- values,
191
- present,
192
- }
193
- }
194
- }
195
-
196
- impl KvValueGroup {
197
- pub(crate) fn len(&self) -> usize {
198
- self.present.len()
199
- }
200
-
201
- pub(crate) fn value(&self, index: usize) -> Option<Option<&[u8]>> {
202
- let present = *self.present.get(index)?;
203
- if present {
204
- Some(Some(
205
- self.values
206
- .get(index)
207
- .expect("storage value batch invariant violated"),
208
- ))
209
- } else {
210
- Some(None)
211
- }
212
- }
213
-
214
- pub(crate) fn values_iter(&self) -> impl Iterator<Item = Option<&[u8]>> {
215
- (0..self.len()).filter_map(|index| self.value(index))
216
- }
217
-
218
- pub(crate) fn single_value_owned(&self) -> Option<Vec<u8>> {
219
- if self.len() != 1 {
220
- return None;
221
- }
222
- self.value(0).flatten().map(<[u8]>::to_vec)
223
- }
224
- }
225
-
226
- #[derive(Debug, Clone, PartialEq, Eq)]
227
- pub(crate) struct KvExistsBatch {
228
- pub(crate) groups: Vec<KvExistsGroup>,
229
- }
230
-
231
- impl From<backend::BackendKvExistsBatch> for KvExistsBatch {
232
- fn from(result: backend::BackendKvExistsBatch) -> Self {
233
- Self {
234
- groups: result.groups.into_iter().map(Into::into).collect(),
235
- }
236
- }
237
- }
238
-
239
- #[derive(Debug, Clone, PartialEq, Eq)]
240
- pub(crate) struct KvExistsGroup {
241
- pub(crate) namespace: String,
242
- pub(crate) exists: Vec<bool>,
243
- }
244
-
245
- impl From<backend::BackendKvExistsGroup> for KvExistsGroup {
246
- fn from(group: backend::BackendKvExistsGroup) -> Self {
247
- Self {
248
- namespace: group.namespace,
249
- exists: group.exists,
250
- }
251
- }
252
- }
253
-
254
- #[derive(Debug, Clone, PartialEq, Eq)]
255
- pub(crate) struct KvScanRequest {
256
- pub(crate) namespace: String,
257
- pub(crate) range: KvScanRange,
258
- pub(crate) after: Option<Vec<u8>>,
259
- pub(crate) limit: usize,
260
- }
261
-
262
- impl From<KvScanRequest> for backend::BackendKvScanRequest {
263
- fn from(request: KvScanRequest) -> Self {
264
- Self {
265
- namespace: request.namespace,
266
- range: request.range.into(),
267
- after: request.after,
268
- limit: request.limit,
269
- }
270
- }
271
- }
272
-
273
- #[derive(Debug, Clone, PartialEq, Eq)]
274
- pub(crate) struct KvKeyPage {
275
- pub(crate) keys: BytePage,
276
- pub(crate) resume_after: Option<Vec<u8>>,
277
- }
278
-
279
- impl From<backend::BackendKvKeyPage> for KvKeyPage {
280
- fn from(result: backend::BackendKvKeyPage) -> Self {
281
- Self {
282
- keys: result.keys,
283
- resume_after: result.resume_after,
284
- }
285
- }
286
- }
287
-
288
- #[derive(Debug, Clone, PartialEq, Eq)]
289
- pub(crate) struct KvValuePage {
290
- pub(crate) values: BytePage,
291
- pub(crate) resume_after: Option<Vec<u8>>,
292
- }
293
-
294
- impl From<backend::BackendKvValuePage> for KvValuePage {
295
- fn from(result: backend::BackendKvValuePage) -> Self {
296
- Self {
297
- values: result.values,
298
- resume_after: result.resume_after,
299
- }
300
- }
301
- }
302
-
303
- #[derive(Debug, Clone, PartialEq, Eq)]
304
- pub(crate) struct KvEntryPage {
305
- pub(crate) keys: BytePage,
306
- pub(crate) values: BytePage,
307
- pub(crate) resume_after: Option<Vec<u8>>,
308
- }
309
-
310
- impl From<backend::BackendKvEntryPage> for KvEntryPage {
311
- fn from(result: backend::BackendKvEntryPage) -> Self {
312
- Self {
313
- keys: result.keys,
314
- values: result.values,
315
- resume_after: result.resume_after,
316
- }
317
- }
318
- }
319
-
320
- impl KvEntryPage {
321
- pub(crate) fn len(&self) -> usize {
322
- self.keys.len()
323
- }
324
-
325
- pub(crate) fn is_empty(&self) -> bool {
326
- self.keys.is_empty()
327
- }
328
-
329
- pub(crate) fn key(&self, index: usize) -> Option<&[u8]> {
330
- self.keys.get(index)
331
- }
332
-
333
- pub(crate) fn value(&self, index: usize) -> Option<&[u8]> {
334
- self.values.get(index)
335
- }
336
- }
337
-
338
- #[derive(Debug, Default)]
339
- pub(crate) struct StorageWriteSet {
340
- batch: KvWriteBatch,
341
- }
342
-
343
- impl StorageWriteSet {
344
- pub(crate) fn new() -> Self {
345
- Self::default()
346
- }
347
-
348
- pub(crate) fn put(&mut self, namespace: &'static str, key: Vec<u8>, value: Vec<u8>) {
349
- self.batch.put(namespace, key, value);
350
- }
351
-
352
- pub(crate) fn delete(&mut self, namespace: &'static str, key: Vec<u8>) {
353
- self.batch.delete(namespace, key);
354
- }
355
-
356
- pub(crate) fn is_empty(&self) -> bool {
357
- self.batch.is_empty()
358
- }
359
-
360
- pub(crate) async fn apply(
361
- self,
362
- writer: &mut (impl StorageWriter + ?Sized),
363
- ) -> Result<KvWriteStats, LixError> {
364
- writer.write_kv_batch(self.batch).await
365
- }
366
- }
367
-
368
- #[derive(Debug, Clone, PartialEq, Eq, Default)]
369
- pub(crate) struct KvWriteBatch {
370
- pub(crate) groups: Vec<KvWriteGroup>,
371
- }
372
-
373
- impl KvWriteBatch {
374
- pub(crate) fn new() -> Self {
375
- Self::default()
376
- }
377
-
378
- pub(crate) fn put(
379
- &mut self,
380
- namespace: impl Into<String>,
381
- key: impl Into<Vec<u8>>,
382
- value: impl Into<Vec<u8>>,
383
- ) {
384
- let namespace = namespace.into();
385
- let group = self.group_mut(namespace);
386
- group.put(key.into(), value.into());
387
- }
388
-
389
- pub(crate) fn delete(&mut self, namespace: impl Into<String>, key: impl Into<Vec<u8>>) {
390
- let namespace = namespace.into();
391
- let group = self.group_mut(namespace);
392
- group.delete(key.into());
393
- }
394
-
395
- pub(crate) fn is_empty(&self) -> bool {
396
- self.groups
397
- .iter()
398
- .all(|group| group.put_count() == 0 && group.delete_count() == 0)
399
- }
400
-
401
- fn group_mut(&mut self, namespace: String) -> &mut KvWriteGroup {
402
- if let Some(index) = self
403
- .groups
404
- .iter()
405
- .position(|group| group.namespace == namespace)
406
- {
407
- return &mut self.groups[index];
408
- }
409
- self.groups.push(KvWriteGroup {
410
- namespace,
411
- put_keys: backend::BytePageBuilder::new(),
412
- put_values: backend::BytePageBuilder::new(),
413
- deletes: backend::BytePageBuilder::new(),
414
- });
415
- self.groups.last_mut().expect("group just pushed")
416
- }
417
- }
418
-
419
- impl From<KvWriteBatch> for backend::BackendKvWriteBatch {
420
- fn from(batch: KvWriteBatch) -> Self {
421
- Self {
422
- groups: batch.groups.into_iter().map(Into::into).collect(),
423
- }
424
- }
425
- }
426
-
427
- #[derive(Debug, Clone, PartialEq, Eq)]
428
- pub(crate) struct KvWriteGroup {
429
- namespace: String,
430
- put_keys: backend::BytePageBuilder,
431
- put_values: backend::BytePageBuilder,
432
- deletes: backend::BytePageBuilder,
433
- }
434
-
435
- impl From<KvWriteGroup> for backend::BackendKvWriteGroup {
436
- fn from(group: KvWriteGroup) -> Self {
437
- Self::from_pages(
438
- group.namespace,
439
- group.put_keys.finish(),
440
- group.put_values.finish(),
441
- group.deletes.finish(),
442
- )
443
- }
444
- }
445
-
446
- impl KvWriteGroup {
447
- pub(crate) fn new(namespace: impl Into<String>) -> Self {
448
- Self {
449
- namespace: namespace.into(),
450
- put_keys: backend::BytePageBuilder::new(),
451
- put_values: backend::BytePageBuilder::new(),
452
- deletes: backend::BytePageBuilder::new(),
453
- }
454
- }
455
-
456
- pub(crate) fn put(&mut self, key: impl AsRef<[u8]>, value: impl AsRef<[u8]>) {
457
- self.put_keys.push(key);
458
- self.put_values.push(value);
459
- }
460
-
461
- pub(crate) fn delete(&mut self, key: impl AsRef<[u8]>) {
462
- self.deletes.push(key);
463
- }
464
-
465
- pub(crate) fn put_count(&self) -> usize {
466
- self.put_keys.len()
467
- }
468
-
469
- pub(crate) fn delete_count(&self) -> usize {
470
- self.deletes.len()
471
- }
472
-
473
- pub(crate) fn put_key(&self, index: usize) -> Option<&[u8]> {
474
- self.put_keys.get(index)
475
- }
476
-
477
- pub(crate) fn put_value(&self, index: usize) -> Option<&[u8]> {
478
- self.put_values.get(index)
479
- }
480
-
481
- pub(crate) fn delete_key(&self, index: usize) -> Option<&[u8]> {
482
- self.deletes.get(index)
483
- }
484
- }
485
-
486
- #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
487
- pub(crate) struct KvWriteStats {
488
- pub(crate) puts: usize,
489
- pub(crate) deletes: usize,
490
- pub(crate) bytes_written: usize,
491
- }
492
-
493
- impl From<backend::BackendKvWriteStats> for KvWriteStats {
494
- fn from(stats: backend::BackendKvWriteStats) -> Self {
495
- Self {
496
- puts: stats.puts,
497
- deletes: stats.deletes,
498
- bytes_written: stats.bytes_written,
499
- }
500
- }
501
- }
@@ -1,98 +0,0 @@
1
- use crate::tracked_state::codec::{
2
- encode_key_ref as encode_tracked_key_ref, encode_value_ref as encode_tracked_value_ref,
3
- };
4
- use crate::tracked_state::types::{
5
- TrackedStateIndexValueRef, TrackedStateKey, TrackedStateKeyRef, TrackedStateTreeScanRequest,
6
- };
7
- use crate::tracked_state::TrackedStateScanRequest;
8
- use crate::NullableKeyFilter;
9
-
10
- const NULL_COMPONENT: &str = "\0";
11
- const VALUE_PREFIX: &str = "\u{1}";
12
-
13
- pub(crate) struct ByFileIndex;
14
-
15
- impl ByFileIndex {
16
- pub(crate) fn should_use(request: &TrackedStateScanRequest) -> bool {
17
- !request.filter.file_ids.is_empty()
18
- && request
19
- .filter
20
- .file_ids
21
- .iter()
22
- .all(|filter| matches!(filter, NullableKeyFilter::Value(_)))
23
- }
24
-
25
- pub(crate) fn scan_request_from_tracked(
26
- request: &TrackedStateScanRequest,
27
- ) -> TrackedStateTreeScanRequest {
28
- debug_assert!(Self::should_use(request));
29
- let schema_keys = request
30
- .filter
31
- .file_ids
32
- .iter()
33
- .filter_map(|filter| match filter {
34
- NullableKeyFilter::Any | NullableKeyFilter::Null => None,
35
- NullableKeyFilter::Value(file_id) => Some(value_component(file_id)),
36
- })
37
- .collect();
38
- let file_ids = request
39
- .filter
40
- .schema_keys
41
- .iter()
42
- .cloned()
43
- .map(NullableKeyFilter::Value)
44
- .collect();
45
- TrackedStateTreeScanRequest {
46
- schema_keys,
47
- entity_ids: request.filter.entity_ids.clone(),
48
- file_ids,
49
- include_tombstones: request.filter.include_tombstones,
50
- limit: None,
51
- }
52
- }
53
-
54
- pub(crate) fn encode_key_ref(row: TrackedStateKeyRef<'_>) -> Vec<u8> {
55
- debug_assert!(row.file_id.is_some());
56
- let schema_key = component(row.file_id);
57
- encode_tracked_key_ref(TrackedStateKeyRef {
58
- schema_key: &schema_key,
59
- file_id: Some(row.schema_key),
60
- entity_id: row.entity_id,
61
- })
62
- }
63
-
64
- pub(crate) fn primary_key_from_index_key(
65
- index_key: TrackedStateKey,
66
- ) -> Option<TrackedStateKey> {
67
- let schema_key = index_key.file_id?;
68
- Some(TrackedStateKey {
69
- schema_key,
70
- file_id: file_id_from_component(&index_key.schema_key)?,
71
- entity_id: index_key.entity_id,
72
- })
73
- }
74
-
75
- pub(crate) fn encode_header_value_ref(value: TrackedStateIndexValueRef<'_>) -> Vec<u8> {
76
- encode_tracked_value_ref(value)
77
- }
78
- }
79
-
80
- fn component(file_id: Option<&str>) -> String {
81
- match file_id {
82
- Some(file_id) => value_component(file_id),
83
- None => NULL_COMPONENT.to_string(),
84
- }
85
- }
86
-
87
- fn value_component(file_id: &str) -> String {
88
- format!("{VALUE_PREFIX}{file_id}")
89
- }
90
-
91
- fn file_id_from_component(component: &str) -> Option<Option<String>> {
92
- if component == NULL_COMPONENT {
93
- return Some(None);
94
- }
95
- component
96
- .strip_prefix(VALUE_PREFIX)
97
- .map(|file_id| Some(file_id.to_string()))
98
- }