forked from rescript-lang/rescript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbelt_internalSetInt.ml
129 lines (101 loc) · 3.2 KB
/
belt_internalSetInt.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# 5 "internal_set.cppo.ml"
type value = int
module S = Belt_SortArrayInt
# 12 "internal_set.cppo.ml"
module N = Belt_internalAVLset
module A = Belt_Array
type t = value N.t
let rec has (t : t) (x : value) =
match N.toOpt t with
| None -> false
| Some n ->
let v = N.valueGet n in
x = v || has (if x < v then N.leftGet n else N.rightGet n) x
let rec compareAux e1 e2 =
match e1,e2 with
| h1::t1, h2::t2 ->
let (k1 : value) ,k2 = N.valueGet h1, N.valueGet h2 in
if k1 = k2 then
compareAux
(N.stackAllLeft (N.rightGet h1) t1 )
(N.stackAllLeft (N.rightGet h2) t2)
else if k1 < k2 then -1
else 1
| _, _ -> 0
let cmp s1 s2 =
let len1, len2 = N.size s1, N.size s2 in
if len1 = len2 then
compareAux (N.stackAllLeft s1 []) (N.stackAllLeft s2 [])
else if len1 < len2 then -1 else 1
let eq (s1 : t) s2 =
cmp s1 s2 = 0
(* This algorithm applies to BST, it does not need to be balanced tree *)
let rec subset (s1 : t) (s2 : t) =
match N.(toOpt s1, toOpt s2) with
None, _ ->
true
| _, None ->
false
| Some t1, Some t2 (* Node (l1, v1, r1, _), (Node (l2, v2, r2, _) as t2) *) ->
let l1,v1,r1 = N.(leftGet t1, valueGet t1, rightGet t1) in
let l2,v2,r2 = N.(leftGet t2, valueGet t2, rightGet t2) in
if v1 = v2 then
subset l1 l2 && subset r1 r2
else if v1 < v2 then
subset N.(create l1 v1 empty ) l2 && subset r1 s2
else
subset N.(create empty v1 r1 ) r2 && subset l1 s2
let rec get (n :t) (x : value) =
match N.toOpt n with
| None -> None
| Some t ->
let v = N.valueGet t in
if x = v then Some v
else get (if x < v then N.leftGet t else N.rightGet t) x
let rec getUndefined (n :t) (x : value) =
match N.toOpt n with
| None -> Js.undefined
| Some t ->
let v = N.valueGet t in
if x = v then Js.Undefined.return v
else getUndefined (if x < v then N.leftGet t else N.rightGet t) x
let rec getExn (n :t) (x : value) =
match N.toOpt n with
| None -> [%assert "getExn"]
| Some t ->
let v = N.valueGet t in
if x = v then v
else getExn (if x < v then N.leftGet t else N.rightGet t) x
(****************************************************************************)
let rec addMutate t (x : value)=
match N.toOpt t with
| None -> N.singleton x
| Some nt ->
let k = N.valueGet nt in
if x = k then t
else
let l, r = N.(leftGet nt, rightGet nt) in
(if x < k then
N.leftSet nt (addMutate l x)
else
N.rightSet nt (addMutate r x);
);
N.return (N.balMutate nt)
let fromArray (xs : value array) =
let len = A.length xs in
if len = 0 then N.empty
else
let next = ref (S.strictlySortedLength xs ) in
let result =
ref (
if !next >= 0 then
N.fromSortedArrayAux xs 0 !next
else begin
next := - !next ;
N.fromSortedArrayRevAux xs (!next - 1) !next
end
) in
for i = !next to len - 1 do
result := addMutate !result (A.getUnsafe xs i)
done ;
!result