Skip to content

Commit 0bcbdbc

Browse files
committed
prototype: add 1 to debt of each pending merge
This fixes bug #550
1 parent 0b29a3d commit 0bcbdbc

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

prototypes/ScheduledMerges.hs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,13 +419,23 @@ treeInvariant :: MergingTree s -> ST s ()
419419
treeInvariant 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

Comments
 (0)