From b59c0849a858300efefc5c1a979fe9c865c41b08 Mon Sep 17 00:00:00 2001 From: Dorian Lesbre Date: Tue, 30 Apr 2024 17:40:13 +0200 Subject: [PATCH 1/2] Remove Dissappeared exception --- patriciaTree.ml | 52 +++++++++++++++++++------------------------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/patriciaTree.ml b/patriciaTree.ml index 65621f1..cae95fe 100644 --- a/patriciaTree.ml +++ b/patriciaTree.ml @@ -754,41 +754,29 @@ module MakeCustomHeterogeneous let remove to_remove m = removeint (Key.to_int to_remove) m - (* This exception is triggered if an operation cannot be completed - because a weak key disappeared. Probably the simplest way to deal - with this operation is to "compact" (remove the dead keys) and - retry. *) - exception Disappeared - - let rec pop_min_nonempty m = match NODE.view m with - | Leaf{key;value} -> KeyValue(key,value),empty - | Branch{prefix;branching_bit;tree0;tree1} -> - let res,tree0' = pop_min_nonempty tree0 in - let restree = - if tree0' == empty then tree1 - else branch ~prefix ~branching_bit ~tree0:tree0' ~tree1 - in (res,restree) - | Empty -> - (* Can only happen in weak sets and maps. *) - raise Disappeared - let pop_unsigned_minimum m = match NODE.view m with + let rec pop_unsigned_minimum m = match NODE.view m with | Empty -> None - | _ -> Some(pop_min_nonempty m) - - let rec pop_max_nonempty m = match NODE.view m with - | Leaf{key;value} -> KeyValue(key,value),empty + | Leaf{key;value} -> Some (KeyValue(key,value),empty) | Branch{prefix;branching_bit;tree0;tree1} -> - let res,tree1' = pop_max_nonempty tree1 in - let restree = - if tree1' == empty then tree0 - else branch ~prefix ~branching_bit ~tree0 ~tree1:tree1' - in (res,restree) - (* Can only happen in weak sets and maps. *) - | Empty -> raise Disappeared - - let pop_unsigned_maximum m = match NODE.view m with + match pop_unsigned_minimum tree0 with + | None -> pop_unsigned_minimum tree1 + | Some(res,tree0') -> + let restree = + if is_empty tree0' then tree1 + else branch ~prefix ~branching_bit ~tree0:tree0' ~tree1 + in Some(res,restree) + + let rec pop_unsigned_maximum m = match NODE.view m with | Empty -> None - | _ -> Some(pop_max_nonempty m) + | Leaf{key;value} -> Some (KeyValue(key,value),empty) + | Branch{prefix;branching_bit;tree0;tree1} -> + match pop_unsigned_maximum tree1 with + | None -> pop_unsigned_maximum tree0 + | Some(res,tree1') -> + let restree = + if is_empty tree1' then tree0 + else branch ~prefix ~branching_bit ~tree0 ~tree1:tree1' + in Some(res,restree) let insert: type a map. a Key.t -> ((a,map) Value.t option -> (a,map) Value.t) -> map t -> map t = fun thekey f t -> From c9bcae2ae5dbc1961ecdf7ec8777fcd8f944d6bc Mon Sep 17 00:00:00 2001 From: Dorian Lesbre Date: Tue, 30 Apr 2024 17:44:09 +0200 Subject: [PATCH 2/2] Changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9262dad..06dd05b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ - Fixed a bug where NodeWithId wasn't incrementing ids properly - `zarith` is no longer a dependency, used GCC's `__builtin_clz` as a faster method of finding an integer's highest bit. +- Fixed a bug where `pop_minimum` and `pop_maximum` could throw a private exception + `Dissappeared` when using `WeakNode`. # v0.9.0 - 2024-04-18