@@ -53,7 +53,6 @@ module MakeCustomHeterogeneousMap
53
53
| Leaf {key;value} -> KeyValue (key,value)
54
54
| Branch {tree1;_} -> unsigned_max_binding tree1
55
55
56
-
57
56
(* Merge trees whose prefix disagree. *)
58
57
let join pa treea pb treeb =
59
58
(* Printf.printf "join %d %d\n" pa pb; *)
@@ -64,9 +63,6 @@ module MakeCustomHeterogeneousMap
64
63
else
65
64
branch ~prefix: p ~branching_bit: m ~tree0: treeb ~tree1: treea
66
65
67
-
68
-
69
-
70
66
let singleton = leaf
71
67
72
68
let rec cardinal m =
@@ -400,6 +396,47 @@ module MakeCustomHeterogeneousMap
400
396
(* Any other case: there are elements in ta that are unmatched in tb. *)
401
397
else false
402
398
399
+ type 'map polycompare =
400
+ { f : 'a . 'a key -> ('a , 'map ) value -> ('a , 'map ) value -> int ; } [@@ unboxed]
401
+
402
+ let compare_aux : type a b m. m polycompare -> a key -> (a,m) value -> b key -> (b,m) value -> int -> int =
403
+ fun f ka va kb vb default ->
404
+ let cmp = Int. compare (Key. to_int ka) (Key. to_int kb) in
405
+ if cmp <> 0 then cmp else
406
+ match Key. polyeq ka kb with
407
+ | Eq -> let cmp = f.f ka va vb in
408
+ if cmp <> 0 then cmp else default
409
+ | Diff -> default (* Should not happen since same Key.to_int values should imply equality *)
410
+
411
+ let rec reflexive_compare f ta tb = match (NODE. view ta),(NODE. view tb) with
412
+ | _ when ta == tb -> 0
413
+ | Empty , _ -> 1
414
+ | _ , Empty -> - 1
415
+ | Branch _ , Leaf {key;value} ->
416
+ let KeyValue (k,v) = unsigned_min_binding ta in
417
+ compare_aux f k v key value 1
418
+ | Leaf {key;value} , Branch _ ->
419
+ let KeyValue (k,v) = unsigned_min_binding tb in
420
+ compare_aux f key value k v (- 1 )
421
+ | Leaf {key;value} , Leaf {key =keyb ;value =valueb } ->
422
+ compare_aux f key value keyb valueb 0
423
+ | Branch {prefix= pa;branching_bit= ma;tree0= ta0;tree1= ta1},
424
+ Branch {prefix= pb;branching_bit= mb;tree0= tb0;tree1= tb1} ->
425
+ if ma == mb && pa == pb
426
+ (* Same prefix: divide the search. *)
427
+ then
428
+ let cmp = reflexive_compare f ta0 tb0 in
429
+ if cmp <> 0 then cmp else
430
+ reflexive_compare f ta1 tb1
431
+ else if branches_before pb mb pa ma (* ta has to be included in tb0 or tb1. *)
432
+ then if (mb :> int ) land (pa :> int ) == 0
433
+ then let cmp = reflexive_compare f ta tb0 in if cmp <> 0 then cmp else - 1
434
+ else - 1 (* ta included in tb1, so there are elements of tb that appear before any elements of ta *)
435
+ else if branches_before pa ma pb mb (* tb has to be included in ta0 or ta1. *)
436
+ then if (mb :> int ) land (pa :> int ) == 0
437
+ then let cmp = reflexive_compare f ta0 tb in if cmp <> 0 then cmp else 1
438
+ else 1 (* tb included in ta1, so there are elements of ta that appear before any elements of tb *)
439
+ else Int. compare (pa :> int ) (pb :> int )
403
440
404
441
let rec disjoint ta tb =
405
442
if ta == tb then is_empty ta
@@ -1098,6 +1135,8 @@ module MakeCustomHeterogeneousSet
1098
1135
let of_seq s = add_seq s empty
1099
1136
let of_list l = of_seq (List. to_seq l)
1100
1137
let to_list s = List. of_seq (to_seq s)
1138
+
1139
+ let compare s1 s2 = BaseMap. reflexive_compare {f= fun _ () () -> 0 } s1 s2
1101
1140
end
1102
1141
1103
1142
module MakeHeterogeneousMap (Key :HETEROGENEOUS_KEY )(Value :HETEROGENEOUS_VALUE ) =
@@ -1225,6 +1264,9 @@ module MakeCustomMap
1225
1264
let of_seq s = add_seq s empty
1226
1265
let of_list l = of_seq (List. to_seq l)
1227
1266
let to_list s = List. of_seq (to_seq s)
1267
+
1268
+ let reflexive_equal f m1 m2 = reflexive_same_domain_for_all2 (fun _ -> f) m1 m2
1269
+ let reflexive_compare f m1 m2 = reflexive_compare {f= fun _ (Snd v1) (Snd v2) -> f v1 v2} m1 m2
1228
1270
end
1229
1271
1230
1272
0 commit comments