@@ -419,13 +419,23 @@ treeInvariant :: MergingTree s -> ST s ()
419419treeInvariant tree@ (MergingTree treeState) = do
420420 readSTRef treeState >>= \ case
421421 CompletedTreeMerge _ ->
422+ -- We don't require the completed merges to be non-empty, since even
423+ -- a (last-level) merge of non-empty runs can end up being empty.
424+ -- In the prototype it would be possible to ensure that empty runs are
425+ -- immediately trimmed from the tree, but this kind of normalisation
426+ -- is complicated with sharing. For example, merging runs and
427+ -- trees are shared, so if one of them completes as an empty run,
428+ -- all tables referencing it suddenly contain an empty run and would
429+ -- need to be updated immediately.
422430 return ()
423431
424432 OngoingTreeMerge mr ->
425433 mergeInvariant mr
426434
427435 PendingTreeMerge (PendingLevelMerge irs t) -> do
428436 -- Non-empty, but can be just one input (see 'newPendingLevelMerge').
437+ -- Note that children of a pending merge can be empty runs, as noted
438+ -- above for 'CompletedTreeMerge'.
429439 assertST $ length irs + length t > 0
430440 for_ irs $ \ case
431441 Single _ -> return ()
@@ -447,7 +457,7 @@ mergeInvariant (MergingRun _ ref) =
447457 readSTRef ref >>= \ case
448458 CompletedMerge _ -> return ()
449459 OngoingMerge _ rs _ -> do
450- -- Inputs to ongoing merges aren't empty (but can while pending!) .
460+ -- Inputs to ongoing merges aren't empty.
451461 assertST $ all (\ r -> runSize r > 0 ) rs
452462 -- Merges are non-trivial (at least two inputs).
453463 assertST $ length rs > 1
@@ -1087,7 +1097,11 @@ remainingDebtPendingMerge (PendingMerge _ irs trees) = do
10871097 , traverse remainingDebtMergingTree trees
10881098 ]
10891099 let totalSize = sum sizes
1090- let totalDebt = sum debts + totalSize
1100+ -- A pending merge should never have 0 remaining debt. It needs some work to
1101+ -- complete it, even if all its inputs are empty. It's not enought to use
1102+ -- @max 1@, as this would violate the property that supplying N credits
1103+ -- reduces the remaining debt by at least N.
1104+ let totalDebt = sum debts + totalSize + 1
10911105 return (totalDebt, totalSize)
10921106 where
10931107 remainingDebtIncomingRun = \ case
0 commit comments