···7878 end
7979 end
80808181+ @spec clear_up_to(RangeTree.t, non_neg_integer) :: RangeTree.t
8282+ def clear_up_to(tree, ceil_version) do
8383+ iterator = :gb_trees.iterator(tree)
8484+ do_clear_up_to(iterator, tree, ceil_version)
8585+ end
8686+8787+ defp do_clear_up_to(iterator, tree, ceil_version) do
8888+ case :gb_trees.next(iterator) do
8989+ {sk, {_ek, v}, iterator} ->
9090+ case v <= ceil_version do
9191+ true ->
9292+ do_clear_up_to(iterator, :gb_trees.delete(sk, tree), ceil_version)
9393+ false ->
9494+ do_clear_up_to(iterator, tree, ceil_version)
9595+ end
9696+ :none ->
9797+ tree
9898+ end
9999+ end
100100+81101 @spec split_at(RangeTree.t, non_neg_integer, binary) :: {:updated, RangeTree.t} | :noop
82102 def split_at(tree, version, key) do
83103 next = key <> "\x00"
···204224 {nil, forest} ->
205225 {[], forest}
206226207207- {last_tree, forest} ->
227227+ {tree_at_version, forest} ->
228228+ forest =
229229+ case :gb_trees.is_empty(forest) do
230230+ false ->
231231+ {latest_version, latest_tree} = :gb_trees.largest(forest)
232232+ # Clear out the flushed versions from the latest copy of the tree
233233+ # Note that trees in the range [version, latest_version) will still
234234+ # contain these versions, but we ignore them during reads with
235235+ # the `min_version` argument in RangeTree
236236+ latest_tree = RangeTree.clear_up_to(latest_tree, version)
237237+ :gb_trees.update(latest_version, latest_tree, forest)
238238+ true ->
239239+ forest
240240+ end
241241+208242 # TODO: clear these ranges from the newest tree
209243 # TODO: should end_key be four \xFFs to include special space?
210210- ranges = RangeTree.intersect_range(last_tree, min_version, "", "\xFF\xFF")
244244+ ranges = RangeTree.intersect_range(tree_at_version, min_version, "", "\xFF\xFF")
211245 {ranges, forest}
212246 end
213247 end