Apply FileOps for a single file.
(
txn: &mut T,
change_id: NodeId,
ops: &FileOps,
stats: &mut ApplyFileOpsStats,
next_leaf_idx: &mut u32,
)
| 480 | |
| 481 | /// Apply FileOps for a single file. |
| 482 | fn apply_single_file_ops<T: MutTxnT>( |
| 483 | txn: &mut T, |
| 484 | change_id: NodeId, |
| 485 | ops: &FileOps, |
| 486 | stats: &mut ApplyFileOpsStats, |
| 487 | next_leaf_idx: &mut u32, |
| 488 | ) -> PristineResult<()> { |
| 489 | // Resolve the TrunkId placeholder. The recorder stores TrunkIds |
| 490 | // with `change_id = NodeId::ROOT` as a placeholder meaning "this |
| 491 | // change — fill in the real id at apply time" (same convention as |
| 492 | // BranchId, see `apply_line_ops_with_position`). Without this |
| 493 | // resolution every file recorded in a single change shares |
| 494 | // `TrunkId(ROOT, 0)` in the CRDT tables, so queries like |
| 495 | // `get_file_content_via_crdt` return branches from every file |
| 496 | // concatenated. |
| 497 | let raw_trunk_id = ops.trunk_id(); |
| 498 | let trunk_id = if raw_trunk_id.change_id().is_root() { |
| 499 | TrunkId::new(change_id, raw_trunk_id.file_idx()) |
| 500 | } else { |
| 501 | raw_trunk_id |
| 502 | }; |
| 503 | let path = ops.path(); |
| 504 | |
| 505 | // Apply trunk operation if present |
| 506 | if let Some(trunk_op) = ops.trunk_op() { |
| 507 | apply_trunk_op(txn, change_id, trunk_id, path, trunk_op, stats)?; |
| 508 | } |
| 509 | |
| 510 | // Apply line operations |
| 511 | for line_ops in ops.line_ops() { |
| 512 | apply_line_ops_with_position(txn, change_id, trunk_id, line_ops, stats, next_leaf_idx)?; |
| 513 | } |
| 514 | |
| 515 | Ok(()) |
| 516 | } |
| 517 | |
| 518 | /// Apply a TrunkOp (file-level operation). |
| 519 | fn apply_trunk_op<T: MutTxnT>( |
no test coverage detected