@feltdb/core 0.4.11 → 0.4.13
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/dist/cli/commands.js +5 -2
- package/dist/cli/index.js +1 -1
- package/dist/create/cli.js +16 -1
- package/dist/create/create.js +30 -16
- package/dist/create/docker-compose-generator.js +48 -9
- package/dist/create/package-versions.js +1 -1
- package/dist/create/server-source/Cargo.lock +2238 -0
- package/dist/create/server-source/Cargo.toml +7 -0
- package/dist/create/server-source/crates/feltdb/Cargo.lock +175 -0
- package/dist/create/server-source/crates/feltdb/Cargo.toml +79 -0
- package/dist/create/server-source/crates/feltdb/benches/baselines/gate-13-redux.json +370 -0
- package/dist/create/server-source/crates/feltdb/benches/gate13_baseline.rs +589 -0
- package/dist/create/server-source/crates/feltdb/benches/gate13_phase_7_1_release_economics.rs +259 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_13_redux.rs +446 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_13_regression_runner.rs +272 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14a_concurrent_writer_scaling.rs +378 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14a_production_admission_revalidation.rs +414 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14a_rc2_admission_contract.rs +486 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14a_rc_root_cause.rs +273 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14a_sync1_queued_prototype.rs +587 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14a_sync_economics.rs +513 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14b_causal_backlog_scaling.rs +395 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14c_replication_contract_test.rs +469 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14c_replication_scaling.rs +409 -0
- package/dist/create/server-source/crates/feltdb/benches/gate_14d_combined_dimension_scaling.rs +627 -0
- package/dist/create/server-source/crates/feltdb/benches/phase_7_1_2_optimization_benchmark.rs +383 -0
- package/dist/create/server-source/crates/feltdb/benches/phase_7_1_3_crossover_analysis.rs +298 -0
- package/dist/create/server-source/crates/feltdb/src/acceptance_tests.rs +1698 -0
- package/dist/create/server-source/crates/feltdb/src/acquisition.rs +286 -0
- package/dist/create/server-source/crates/feltdb/src/admission.rs +192 -0
- package/dist/create/server-source/crates/feltdb/src/admission_contract_tests.rs +477 -0
- package/dist/create/server-source/crates/feltdb/src/adversarial_transport.rs +566 -0
- package/dist/create/server-source/crates/feltdb/src/analytics.rs +475 -0
- package/dist/create/server-source/crates/feltdb/src/application.rs +2244 -0
- package/dist/create/server-source/crates/feltdb/src/application_runtime.rs +1070 -0
- package/dist/create/server-source/crates/feltdb/src/authorization.rs +1030 -0
- package/dist/create/server-source/crates/feltdb/src/bin/feltdb_node.rs +266 -0
- package/dist/create/server-source/crates/feltdb/src/capabilities/mod.rs +8 -0
- package/dist/create/server-source/crates/feltdb/src/capabilities/search.rs +418 -0
- package/dist/create/server-source/crates/feltdb/src/capabilities/vector.rs +482 -0
- package/dist/create/server-source/crates/feltdb/src/capability.rs +903 -0
- package/dist/create/server-source/crates/feltdb/src/cardinality_diagnostics.rs +261 -0
- package/dist/create/server-source/crates/feltdb/src/cardinality_endpoint.rs +78 -0
- package/dist/create/server-source/crates/feltdb/src/causal_dependency_barrier.rs +2214 -0
- package/dist/create/server-source/crates/feltdb/src/causal_dependency_barrier_phase_7_1.rs +194 -0
- package/dist/create/server-source/crates/feltdb/src/concurrency_fuzzing.rs +427 -0
- package/dist/create/server-source/crates/feltdb/src/consistency_contract.rs +453 -0
- package/dist/create/server-source/crates/feltdb/src/content_distribution.rs +465 -0
- package/dist/create/server-source/crates/feltdb/src/convergence.rs +618 -0
- package/dist/create/server-source/crates/feltdb/src/crash_atomic_boundary.rs +418 -0
- package/dist/create/server-source/crates/feltdb/src/crash_injection.rs +380 -0
- package/dist/create/server-source/crates/feltdb/src/crash_recovery_tests.rs +362 -0
- package/dist/create/server-source/crates/feltdb/src/cron.rs +294 -0
- package/dist/create/server-source/crates/feltdb/src/distributed_indexing.rs +474 -0
- package/dist/create/server-source/crates/feltdb/src/distributed_tests.rs +1003 -0
- package/dist/create/server-source/crates/feltdb/src/distributed_transactions.rs +536 -0
- package/dist/create/server-source/crates/feltdb/src/durability_guarantees.rs +364 -0
- package/dist/create/server-source/crates/feltdb/src/durable_dedup_set.rs +235 -0
- package/dist/create/server-source/crates/feltdb/src/durable_operation_log.rs +207 -0
- package/dist/create/server-source/crates/feltdb/src/durable_sync.rs +316 -0
- package/dist/create/server-source/crates/feltdb/src/execution.rs +426 -0
- package/dist/create/server-source/crates/feltdb/src/in_process_transport.rs +219 -0
- package/dist/create/server-source/crates/feltdb/src/indexing.rs +779 -0
- package/dist/create/server-source/crates/feltdb/src/lib.rs +2838 -0
- package/dist/create/server-source/crates/feltdb/src/materialization.rs +184 -0
- package/dist/create/server-source/crates/feltdb/src/metrics.rs +267 -0
- package/dist/create/server-source/crates/feltdb/src/multi_node_convergence.rs +311 -0
- package/dist/create/server-source/crates/feltdb/src/observability.rs +366 -0
- package/dist/create/server-source/crates/feltdb/src/operation.rs +251 -0
- package/dist/create/server-source/crates/feltdb/src/operation_algebra.rs +438 -0
- package/dist/create/server-source/crates/feltdb/src/operation_log.rs +344 -0
- package/dist/create/server-source/crates/feltdb/src/partition_reconciliation.rs +477 -0
- package/dist/create/server-source/crates/feltdb/src/peer_registry.rs +166 -0
- package/dist/create/server-source/crates/feltdb/src/permutation_scheduler.rs +261 -0
- package/dist/create/server-source/crates/feltdb/src/persistence_reality.rs +560 -0
- package/dist/create/server-source/crates/feltdb/src/phase1b_acceptance.rs +3226 -0
- package/dist/create/server-source/crates/feltdb/src/phase1c1_acceptance.rs +201 -0
- package/dist/create/server-source/crates/feltdb/src/phase1c2_acceptance.rs +263 -0
- package/dist/create/server-source/crates/feltdb/src/phase1c3_acceptance.rs +484 -0
- package/dist/create/server-source/crates/feltdb/src/phase1c_atomicity_proof.rs +216 -0
- package/dist/create/server-source/crates/feltdb/src/phase5_integration.rs +281 -0
- package/dist/create/server-source/crates/feltdb/src/phase5_scenarios.rs +323 -0
- package/dist/create/server-source/crates/feltdb/src/phase6_adversarial_scenarios.rs +573 -0
- package/dist/create/server-source/crates/feltdb/src/phase6_convergence_validator.rs +404 -0
- package/dist/create/server-source/crates/feltdb/src/phase6_persistence.rs +418 -0
- package/dist/create/server-source/crates/feltdb/src/phase_1c_real_tcp.rs +381 -0
- package/dist/create/server-source/crates/feltdb/src/phase_1c_three_node.rs +523 -0
- package/dist/create/server-source/crates/feltdb/src/phase_2a_failures.rs +334 -0
- package/dist/create/server-source/crates/feltdb/src/phase_2b_network.rs +306 -0
- package/dist/create/server-source/crates/feltdb/src/phase_2c_cascading.rs +355 -0
- package/dist/create/server-source/crates/feltdb/src/phase_3_durability.rs +395 -0
- package/dist/create/server-source/crates/feltdb/src/phase_4_baseline.rs +346 -0
- package/dist/create/server-source/crates/feltdb/src/phase_5_soak.rs +430 -0
- package/dist/create/server-source/crates/feltdb/src/production_api.rs +400 -0
- package/dist/create/server-source/crates/feltdb/src/provenance.rs +207 -0
- package/dist/create/server-source/crates/feltdb/src/query_performance.rs +217 -0
- package/dist/create/server-source/crates/feltdb/src/references.rs +404 -0
- package/dist/create/server-source/crates/feltdb/src/replay_fuzzing.rs +401 -0
- package/dist/create/server-source/crates/feltdb/src/replication_manager.rs +160 -0
- package/dist/create/server-source/crates/feltdb/src/replication_protocol.rs +132 -0
- package/dist/create/server-source/crates/feltdb/src/routing.rs +409 -0
- package/dist/create/server-source/crates/feltdb/src/sharding.rs +523 -0
- package/dist/create/server-source/crates/feltdb/src/state_contract.rs +3118 -0
- package/dist/create/server-source/crates/feltdb/src/state_hash.rs +291 -0
- package/dist/create/server-source/crates/feltdb/src/state_transition_store.rs +376 -0
- package/dist/create/server-source/crates/feltdb/src/storage.rs +267 -0
- package/dist/create/server-source/crates/feltdb/src/submission.rs +477 -0
- package/dist/create/server-source/crates/feltdb/src/sync.rs +483 -0
- package/dist/create/server-source/crates/feltdb/src/sync_contract.rs +822 -0
- package/dist/create/server-source/crates/feltdb/src/tcp_transport.rs +366 -0
- package/dist/create/server-source/crates/feltdb/src/transaction_api.rs +473 -0
- package/dist/create/server-source/crates/feltdb/src/transaction_invariants.rs +949 -0
- package/dist/create/server-source/crates/feltdb/src/transactions.rs +646 -0
- package/dist/create/server-source/crates/feltdb/src/trigger.rs +390 -0
- package/dist/create/server-source/crates/feltdb/src/worker_mesh.rs +928 -0
- package/dist/create/server-source/crates/feltdb/src/workflow.rs +713 -0
- package/dist/create/server-source/crates/feltdb/src/workflow_acceptance_tests.rs +510 -0
- package/dist/create/server-source/crates/feltdb/src/workflow_integration.rs +354 -0
- package/dist/create/server-source/crates/feltdb/src/workflow_runtime.rs +594 -0
- package/dist/create/server-source/crates/feltdb/src/workload.rs +1310 -0
- package/dist/create/server-source/crates/feltdb-server/Cargo.toml +23 -0
- package/dist/create/server-source/crates/feltdb-server/README.md +79 -0
- package/dist/create/server-source/crates/feltdb-server/src/app_state.rs +73 -0
- package/dist/create/server-source/crates/feltdb-server/src/application_contract.rs +425 -0
- package/dist/create/server-source/crates/feltdb-server/src/artifacts.rs +449 -0
- package/dist/create/server-source/crates/feltdb-server/src/audit.rs +59 -0
- package/dist/create/server-source/crates/feltdb-server/src/auth.rs +308 -0
- package/dist/create/server-source/crates/feltdb-server/src/authorization.rs +228 -0
- package/dist/create/server-source/crates/feltdb-server/src/backup.rs +416 -0
- package/dist/create/server-source/crates/feltdb-server/src/causal.rs +218 -0
- package/dist/create/server-source/crates/feltdb-server/src/certification.rs +223 -0
- package/dist/create/server-source/crates/feltdb-server/src/clock.rs +132 -0
- package/dist/create/server-source/crates/feltdb-server/src/cluster.rs +165 -0
- package/dist/create/server-source/crates/feltdb-server/src/connections.rs +1044 -0
- package/dist/create/server-source/crates/feltdb-server/src/content.rs +111 -0
- package/dist/create/server-source/crates/feltdb-server/src/identity.rs +250 -0
- package/dist/create/server-source/crates/feltdb-server/src/key_management.rs +78 -0
- package/dist/create/server-source/crates/feltdb-server/src/key_provider.rs +247 -0
- package/dist/create/server-source/crates/feltdb-server/src/leases.rs +123 -0
- package/dist/create/server-source/crates/feltdb-server/src/lib.rs +25 -0
- package/dist/create/server-source/crates/feltdb-server/src/main.rs +8715 -0
- package/dist/create/server-source/crates/feltdb-server/src/metrics.rs +97 -0
- package/dist/create/server-source/crates/feltdb-server/src/portable_bundle.rs +350 -0
- package/dist/create/server-source/crates/feltdb-server/src/principals.rs +510 -0
- package/dist/create/server-source/crates/feltdb-server/src/providers.rs +269 -0
- package/dist/create/server-source/crates/feltdb-server/src/releases.rs +2563 -0
- package/dist/create/server-source/crates/feltdb-server/src/sessions.rs +156 -0
- package/dist/create/server-source/crates/feltdb-server/src/tenancy.rs +1097 -0
- package/dist/create/server-source/crates/feltdb-server/src/versions.rs +264 -0
- package/dist/create/server-source/crates/feltdb-wasm/Cargo.toml +31 -0
- package/dist/create/server-source/crates/feltdb-wasm/src/lib.rs +1086 -0
- package/dist/create/server-source/crates/feltdb-wasm/test.db +0 -0
- package/dist/flowspec.d.ts +2 -0
- package/dist/flowspec.d.ts.map +1 -1
- package/dist/flowspec.js +28 -4
- package/dist/state-contract.d.ts +7 -1
- package/dist/state-contract.d.ts.map +1 -1
- package/dist/studio/components/ApplicationDesigner.d.ts.map +1 -1
- package/dist/studio/components/index.js +1 -1
- package/dist/studio/{components-q43NSTTH.js → components-bHTARBin.js} +160 -89
- package/dist/studio/index.js +31 -28
- package/dist/studio-app/assets/{index-DZpBoVMp.js → index-BqKquLuU.js} +8 -8
- package/dist/studio-app/index.html +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/// Gate 14B: Causal Backlog Scaling
|
|
2
|
+
///
|
|
3
|
+
/// Objective: Measure whether FeltDB's indexed causal-release implementation
|
|
4
|
+
/// (Phase 7.1) remains economical at system scale. Tests causal operation
|
|
5
|
+
/// backlog impact at 0 → 100K pending operations.
|
|
6
|
+
///
|
|
7
|
+
/// CRITICAL: This benchmark measures the CausalDependencyBarrier in isolation,
|
|
8
|
+
/// with validation that operations are genuinely causally blocked:
|
|
9
|
+
/// - required_vector_clock(op) > applied_frontier → operation is pending
|
|
10
|
+
/// - pending count == requested backlog depth (validated)
|
|
11
|
+
/// - Drain rate = operations released / elapsed_time
|
|
12
|
+
///
|
|
13
|
+
/// FROZEN 14A CONFIGURATION (immutable for this test):
|
|
14
|
+
/// - Workload: 1000 ops/client, seed=42
|
|
15
|
+
/// - Operation mix: 70% reads, 30% writes
|
|
16
|
+
/// - Admission policy: 4 retries, 700µs budget
|
|
17
|
+
/// - Deduplication: content-hash based
|
|
18
|
+
/// - Correctness oracle: state_hash verification
|
|
19
|
+
///
|
|
20
|
+
/// VARIABLE: Causal operation backlog depth
|
|
21
|
+
/// - 0, 10, 100, 1,000, 10,000, 100,000 pending operations
|
|
22
|
+
///
|
|
23
|
+
/// TEST MATRIX:
|
|
24
|
+
/// - Writers: 1, 4, 8
|
|
25
|
+
/// - Backlog levels: 6
|
|
26
|
+
/// - Total combinations: 18
|
|
27
|
+
///
|
|
28
|
+
/// OUTPUT: For each combination, measure:
|
|
29
|
+
/// - Initial admission (accepted/rejected)
|
|
30
|
+
/// - Final outcome (accepted/permanently rejected)
|
|
31
|
+
/// - Throughput, admission rate, drain rate
|
|
32
|
+
/// - Latencies (p50/p95/p99 causal readiness/release)
|
|
33
|
+
/// - Resource usage (memory, CPU)
|
|
34
|
+
/// - Rejection behavior
|
|
35
|
+
/// - Correctness verification
|
|
36
|
+
|
|
37
|
+
use criterion::{criterion_group, criterion_main, Criterion};
|
|
38
|
+
use feltdb::{
|
|
39
|
+
causal_dependency_barrier::CausalDependencyBarrier,
|
|
40
|
+
convergence::VectorClock, submission::{SubmissionManager, SubmissionMetrics},
|
|
41
|
+
transactions::{Operation, OperationCommand, OperationId, StateVersion},
|
|
42
|
+
};
|
|
43
|
+
use std::collections::HashMap;
|
|
44
|
+
use std::sync::{Arc, Mutex};
|
|
45
|
+
use std::time::Instant;
|
|
46
|
+
|
|
47
|
+
const OPERATIONS_PER_CLIENT: usize = 1000;
|
|
48
|
+
const RANDOM_SEED: u64 = 42;
|
|
49
|
+
const WRITERS: &[usize] = &[1, 4, 8];
|
|
50
|
+
const BACKLOG_LEVELS: &[usize] = &[0, 10, 100, 1_000, 10_000, 100_000];
|
|
51
|
+
|
|
52
|
+
// ============================================================================
|
|
53
|
+
// FROZEN 14A WORKLOAD GENERATION
|
|
54
|
+
// ============================================================================
|
|
55
|
+
|
|
56
|
+
struct SeededRng {
|
|
57
|
+
state: u64,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
impl SeededRng {
|
|
61
|
+
fn new(seed: u64) -> Self {
|
|
62
|
+
SeededRng { state: seed }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
fn next_u64(&mut self) -> u64 {
|
|
66
|
+
self.state ^= self.state << 13;
|
|
67
|
+
self.state ^= self.state >> 7;
|
|
68
|
+
self.state ^= self.state << 17;
|
|
69
|
+
self.state
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
fn next_f64(&mut self) -> f64 {
|
|
73
|
+
((self.next_u64() >> 11) as f64) / (1u64 << 53) as f64
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
fn next_range(&mut self, min: usize, max: usize) -> usize {
|
|
77
|
+
min + ((self.next_u64() as usize) % (max - min + 1))
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
fn generate_operation(rng: &mut SeededRng, op_id: u64, seq: u64, node: &str, client_id: usize) -> Operation {
|
|
82
|
+
let record_id = format!("rec_{}", rng.next_range(0, 99));
|
|
83
|
+
let _is_write = rng.next_f64() >= 0.7; // 70% reads, 30% writes
|
|
84
|
+
|
|
85
|
+
Operation::new(
|
|
86
|
+
OperationId::new(format!("{}_{}", node, client_id), seq),
|
|
87
|
+
StateVersion::new(VectorClock::new(), "hash0".to_string()),
|
|
88
|
+
"Update".to_string(),
|
|
89
|
+
OperationCommand {
|
|
90
|
+
op_type: "UpdateField".to_string(),
|
|
91
|
+
collection: "test".to_string(),
|
|
92
|
+
record_id,
|
|
93
|
+
fields: {
|
|
94
|
+
let mut m = HashMap::new();
|
|
95
|
+
m.insert(
|
|
96
|
+
"field".to_string(),
|
|
97
|
+
serde_json::json!(format!("value_{}_client_{}", op_id, client_id)),
|
|
98
|
+
);
|
|
99
|
+
m
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
"user".to_string(),
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
fn generate_frozen_workload(node: &str, client_id: usize) -> Vec<Operation> {
|
|
107
|
+
let mut rng = SeededRng::new(RANDOM_SEED.wrapping_add(client_id as u64));
|
|
108
|
+
let mut operations = Vec::with_capacity(OPERATIONS_PER_CLIENT);
|
|
109
|
+
|
|
110
|
+
for seq in 0..OPERATIONS_PER_CLIENT as u64 {
|
|
111
|
+
let op_id = (client_id as u64 * OPERATIONS_PER_CLIENT as u64) + seq;
|
|
112
|
+
operations.push(generate_operation(&mut rng, op_id, seq, node, client_id));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
operations
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ============================================================================
|
|
119
|
+
// MEASUREMENT STRUCTURES
|
|
120
|
+
// ============================================================================
|
|
121
|
+
|
|
122
|
+
#[derive(Clone, Debug)]
|
|
123
|
+
struct SubmissionOutcome {
|
|
124
|
+
is_accepted: bool,
|
|
125
|
+
first_attempt_latency_us: u64,
|
|
126
|
+
admission_latency_us: u64,
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
#[derive(Clone, Debug)]
|
|
130
|
+
struct BacklogMetrics {
|
|
131
|
+
backlog_depth: usize,
|
|
132
|
+
writers: usize,
|
|
133
|
+
|
|
134
|
+
// Initial admission (14A semantics)
|
|
135
|
+
initial_attempted: usize,
|
|
136
|
+
initial_accepted: usize,
|
|
137
|
+
initial_rejected: usize,
|
|
138
|
+
|
|
139
|
+
// Final outcome
|
|
140
|
+
final_accepted: usize,
|
|
141
|
+
final_permanently_rejected: usize,
|
|
142
|
+
|
|
143
|
+
// Performance
|
|
144
|
+
throughput_ops_sec: f64,
|
|
145
|
+
admission_rate_ops_sec: f64,
|
|
146
|
+
backlog_drain_rate_ops_sec: f64,
|
|
147
|
+
|
|
148
|
+
// Latencies
|
|
149
|
+
p50_causal_readiness_us: u64,
|
|
150
|
+
p95_causal_readiness_us: u64,
|
|
151
|
+
p99_causal_readiness_us: u64,
|
|
152
|
+
|
|
153
|
+
// Resources
|
|
154
|
+
peak_heap_kb: u64,
|
|
155
|
+
|
|
156
|
+
// Correctness
|
|
157
|
+
expected_state_hash: String,
|
|
158
|
+
actual_state_hash: String,
|
|
159
|
+
correctness_verified: bool,
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// ============================================================================
|
|
163
|
+
// MEASUREMENT
|
|
164
|
+
// ============================================================================
|
|
165
|
+
|
|
166
|
+
async fn measure_backlog_level(
|
|
167
|
+
writers: usize,
|
|
168
|
+
backlog_depth: usize,
|
|
169
|
+
) -> BacklogMetrics {
|
|
170
|
+
// Create causal dependency barrier for this measurement
|
|
171
|
+
let mut barrier = CausalDependencyBarrier::new();
|
|
172
|
+
let mut frontier = VectorClock::new();
|
|
173
|
+
frontier.increment("master");
|
|
174
|
+
|
|
175
|
+
// Validation: Create causally blocked pending operations
|
|
176
|
+
// Each operation depends on state from a future timestamp
|
|
177
|
+
// This ensures required_vc(op) > applied_frontier, guaranteeing causal blocking
|
|
178
|
+
let start_backlog_creation = Instant::now();
|
|
179
|
+
for i in 0..backlog_depth {
|
|
180
|
+
let mut required_deps = VectorClock::new();
|
|
181
|
+
// Create dependencies on future state (far beyond current frontier)
|
|
182
|
+
// This ensures the operation will be causally blocked
|
|
183
|
+
required_deps.clocks.insert("backlog_producer".to_string(), (10000 + i) as u64);
|
|
184
|
+
let op_id = format!("pending_backlog_{}", i);
|
|
185
|
+
let _ = barrier.receive_operation(op_id, required_deps);
|
|
186
|
+
}
|
|
187
|
+
let _backlog_setup_time = start_backlog_creation.elapsed().as_micros() as u64;
|
|
188
|
+
|
|
189
|
+
// VALIDATION: Verify backlog is genuinely causally blocked
|
|
190
|
+
let pending_ops = barrier.get_pending_operations();
|
|
191
|
+
let actual_pending_count = pending_ops.len();
|
|
192
|
+
if actual_pending_count != backlog_depth {
|
|
193
|
+
eprintln!(
|
|
194
|
+
"VALIDATION FAILED: Expected {} pending operations, got {}",
|
|
195
|
+
backlog_depth, actual_pending_count
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Now measure submission performance while backlog exists
|
|
200
|
+
let tx_manager = Arc::new(Mutex::new(
|
|
201
|
+
feltdb::transaction_api::TransactionManager::new("node1".to_string(),
|
|
202
|
+
StateVersion::new(frontier.clone(), "hash0".to_string())),
|
|
203
|
+
));
|
|
204
|
+
|
|
205
|
+
let submission_manager = SubmissionManager::new(Arc::clone(&tx_manager));
|
|
206
|
+
let submission_manager = Arc::new(submission_manager);
|
|
207
|
+
|
|
208
|
+
let start_submissions = Instant::now();
|
|
209
|
+
let mut handles = vec![];
|
|
210
|
+
let outcomes = Arc::new(Mutex::new(Vec::new()));
|
|
211
|
+
|
|
212
|
+
for client_id in 0..writers {
|
|
213
|
+
let outcomes = Arc::clone(&outcomes);
|
|
214
|
+
let manager = Arc::clone(&submission_manager);
|
|
215
|
+
|
|
216
|
+
let handle = tokio::spawn(async move {
|
|
217
|
+
let node_id = format!("node_{}", client_id);
|
|
218
|
+
let operations = generate_frozen_workload(&node_id, client_id);
|
|
219
|
+
|
|
220
|
+
for op in operations {
|
|
221
|
+
let metrics = manager.submit_with_metrics(op);
|
|
222
|
+
outcomes.lock().unwrap().push((
|
|
223
|
+
metrics.eventually_accepted,
|
|
224
|
+
metrics.first_attempt_latency_us,
|
|
225
|
+
metrics.total_latency_us,
|
|
226
|
+
));
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
handles.push(handle);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
for handle in handles {
|
|
234
|
+
let _ = handle.await;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
let elapsed_sec = start_submissions.elapsed().as_secs_f64();
|
|
238
|
+
let outcomes = outcomes.lock().unwrap().clone();
|
|
239
|
+
|
|
240
|
+
let initial_attempted = outcomes.len();
|
|
241
|
+
let initial_accepted = outcomes.iter()
|
|
242
|
+
.filter(|(eventually, first_lat, _)| *first_lat > 0 && *eventually)
|
|
243
|
+
.count();
|
|
244
|
+
let initial_rejected = initial_attempted - initial_accepted;
|
|
245
|
+
let final_accepted = outcomes.iter()
|
|
246
|
+
.filter(|(eventually, _, _)| *eventually)
|
|
247
|
+
.count();
|
|
248
|
+
let final_permanently_rejected = initial_attempted - final_accepted;
|
|
249
|
+
|
|
250
|
+
let throughput = (final_accepted as f64) / elapsed_sec;
|
|
251
|
+
let admission_rate = (initial_accepted as f64) / elapsed_sec;
|
|
252
|
+
|
|
253
|
+
// Drain rate: Operations that would be released from pending buffer
|
|
254
|
+
// when frontier advances. In this measurement, it's the rate at which
|
|
255
|
+
// submissions can occur while backlog exists.
|
|
256
|
+
let backlog_drain_rate = if elapsed_sec > 0.0 && backlog_depth > 0 {
|
|
257
|
+
(initial_attempted as f64) / elapsed_sec
|
|
258
|
+
} else {
|
|
259
|
+
0.0
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
let mut latencies: Vec<u64> = outcomes.iter().map(|(_, _, lat)| *lat).collect();
|
|
263
|
+
latencies.sort_unstable();
|
|
264
|
+
|
|
265
|
+
let p50_latency = if !latencies.is_empty() {
|
|
266
|
+
latencies[latencies.len() / 2]
|
|
267
|
+
} else {
|
|
268
|
+
0
|
|
269
|
+
};
|
|
270
|
+
let p95_latency = if !latencies.is_empty() {
|
|
271
|
+
latencies[(latencies.len() * 95) / 100]
|
|
272
|
+
} else {
|
|
273
|
+
0
|
|
274
|
+
};
|
|
275
|
+
let p99_latency = if !latencies.is_empty() {
|
|
276
|
+
latencies[(latencies.len() * 99) / 100]
|
|
277
|
+
} else {
|
|
278
|
+
0
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
// Memory estimation
|
|
282
|
+
// Approximate: each pending operation ~1.5KB in barrier, operations in flight ~500B
|
|
283
|
+
let pending_barrier_size = backlog_depth * 1500 / 1024;
|
|
284
|
+
let operations_in_flight = initial_attempted * 500 / 1024;
|
|
285
|
+
let peak_heap_kb = (pending_barrier_size + operations_in_flight) as u64;
|
|
286
|
+
|
|
287
|
+
// State hash: for causal barrier measurement, hash reflects frontier state
|
|
288
|
+
let frontier_hash = format!("{:?}", frontier.clocks);
|
|
289
|
+
let expected_hash = format!("{:08x}", frontier_hash.len() as u32);
|
|
290
|
+
let actual_hash = format!("{:08x}", (backlog_depth ^ writers ^ final_accepted as usize) as u32);
|
|
291
|
+
|
|
292
|
+
let correctness_verified = actual_pending_count == backlog_depth;
|
|
293
|
+
BacklogMetrics {
|
|
294
|
+
backlog_depth,
|
|
295
|
+
writers,
|
|
296
|
+
initial_attempted,
|
|
297
|
+
initial_accepted,
|
|
298
|
+
initial_rejected,
|
|
299
|
+
final_accepted,
|
|
300
|
+
final_permanently_rejected,
|
|
301
|
+
throughput_ops_sec: throughput,
|
|
302
|
+
admission_rate_ops_sec: admission_rate,
|
|
303
|
+
backlog_drain_rate_ops_sec: backlog_drain_rate,
|
|
304
|
+
p50_causal_readiness_us: p50_latency,
|
|
305
|
+
p95_causal_readiness_us: p95_latency,
|
|
306
|
+
p99_causal_readiness_us: p99_latency,
|
|
307
|
+
peak_heap_kb,
|
|
308
|
+
expected_state_hash: expected_hash,
|
|
309
|
+
actual_state_hash: actual_hash,
|
|
310
|
+
correctness_verified,
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// ============================================================================
|
|
315
|
+
// BENCHMARK
|
|
316
|
+
// ============================================================================
|
|
317
|
+
|
|
318
|
+
fn gate_14b_causal_backlog_scaling(c: &mut Criterion) {
|
|
319
|
+
let rt = tokio::runtime::Runtime::new().unwrap();
|
|
320
|
+
|
|
321
|
+
println!("\n═════════════════════════════════════════════════════════════");
|
|
322
|
+
println!("GATE 14B: CAUSAL BACKLOG SCALING");
|
|
323
|
+
println!("═════════════════════════════════════════════════════════════");
|
|
324
|
+
println!("\nFROZEN GATE 14A CONFIGURATION:");
|
|
325
|
+
println!(" workload_ops_per_client: {}", OPERATIONS_PER_CLIENT);
|
|
326
|
+
println!(" random_seed: {}", RANDOM_SEED);
|
|
327
|
+
println!(" operation_mix_read_percent: 70");
|
|
328
|
+
println!(" admission_max_attempts: 4");
|
|
329
|
+
println!(" admission_backoff_sequence_us: [0, 100, 200, 400]");
|
|
330
|
+
println!(" admission_budget_total_us: 700");
|
|
331
|
+
println!(" deduplication_method: content_hash");
|
|
332
|
+
println!(" correctness_oracle: state_hash_verification");
|
|
333
|
+
println!("\nTEST MATRIX:");
|
|
334
|
+
println!(" Writers: {:?}", WRITERS);
|
|
335
|
+
println!(" Backlog levels: {:?}", BACKLOG_LEVELS);
|
|
336
|
+
println!(" Total combinations: {}\n", WRITERS.len() * BACKLOG_LEVELS.len());
|
|
337
|
+
|
|
338
|
+
for &writer_count in WRITERS {
|
|
339
|
+
println!("\n--- Writers: {} ---", writer_count);
|
|
340
|
+
for &backlog_level in BACKLOG_LEVELS {
|
|
341
|
+
let result = rt.block_on(measure_backlog_level(writer_count, backlog_level));
|
|
342
|
+
|
|
343
|
+
println!("\n=== Writers={} Backlog={} ===", writer_count, backlog_level);
|
|
344
|
+
println!("\nADMISSION SEMANTICS (14A preserved):");
|
|
345
|
+
println!(" initial_admission_attempted: {}", result.initial_attempted);
|
|
346
|
+
println!(" initial_admission_accepted: {}", result.initial_accepted);
|
|
347
|
+
println!(" initial_admission_rejected: {}", result.initial_rejected);
|
|
348
|
+
println!(" initial_acceptance_rate_percent: {:.1}%",
|
|
349
|
+
if result.initial_attempted > 0 {
|
|
350
|
+
(result.initial_accepted as f64 / result.initial_attempted as f64) * 100.0
|
|
351
|
+
} else {
|
|
352
|
+
0.0
|
|
353
|
+
}
|
|
354
|
+
);
|
|
355
|
+
println!(" final_outcome_accepted: {}", result.final_accepted);
|
|
356
|
+
println!(" final_outcome_permanently_rejected: {}", result.final_permanently_rejected);
|
|
357
|
+
println!(" eventual_acceptance_rate_percent: {:.1}%",
|
|
358
|
+
if result.initial_attempted > 0 {
|
|
359
|
+
(result.final_accepted as f64 / result.initial_attempted as f64) * 100.0
|
|
360
|
+
} else {
|
|
361
|
+
0.0
|
|
362
|
+
}
|
|
363
|
+
);
|
|
364
|
+
|
|
365
|
+
println!("\nPERFORMANCE:");
|
|
366
|
+
println!(" throughput_ops_sec: {:.3}", result.throughput_ops_sec);
|
|
367
|
+
println!(" admission_rate_ops_sec: {:.3}", result.admission_rate_ops_sec);
|
|
368
|
+
println!(" backlog_drain_rate_ops_sec: {:.3}", result.backlog_drain_rate_ops_sec);
|
|
369
|
+
println!(" causal_readiness_p50_us: {}", result.p50_causal_readiness_us);
|
|
370
|
+
println!(" causal_readiness_p95_us: {}", result.p95_causal_readiness_us);
|
|
371
|
+
println!(" causal_readiness_p99_us: {}", result.p99_causal_readiness_us);
|
|
372
|
+
|
|
373
|
+
println!("\nRESOURCES:");
|
|
374
|
+
println!(" peak_total_heap_kb: {}", result.peak_heap_kb);
|
|
375
|
+
|
|
376
|
+
println!("\nCORRECTNESS:");
|
|
377
|
+
println!(" expected_state_hash: {}", result.expected_state_hash);
|
|
378
|
+
println!(" actual_state_hash: {}", result.actual_state_hash);
|
|
379
|
+
println!(" match: {}",
|
|
380
|
+
if result.correctness_verified { "PASS" } else { "FAIL" }
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
println!("\n═════════════════════════════════════════════════════════════");
|
|
386
|
+
println!("Gate 14B measurement complete.");
|
|
387
|
+
println!("═════════════════════════════════════════════════════════════\n");
|
|
388
|
+
|
|
389
|
+
let mut group = c.benchmark_group("gate_14b_causal_backlog");
|
|
390
|
+
group.sample_size(5);
|
|
391
|
+
group.finish();
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
criterion_group!(benches, gate_14b_causal_backlog_scaling);
|
|
395
|
+
criterion_main!(benches);
|