1 (***************************************************************************)
2 (* Implementation for sets of positive integers implemented as deeply hash-*)
3 (* consed Patricia trees. Provide fast set operations, fast membership as *)
4 (* well as fast min and max elements. Hash consing provides O(1) equality *)
7 (***************************************************************************)
18 | Branch of int * int * t * t
25 let hash_node = function
28 (* power of 2 +/- 1 are fast ! *)
30 (b lsl 1)+ b + i+(i lsl 4) + (l.key lsl 5)-l.key
31 + (r.key lsl 7) - r.key
32 let hash_node x = (hash_node x) land max_int
33 let equal x y = match (x.node,y.node) with
35 | Leaf k1, Leaf k2 when k1 == k2 -> true
36 | Branch(p1,m1,l1,r1), Branch(p2,m2,l2,r2) when m1==m2 && p1==p2 &&
37 (l1.id == l2.id) && (r1.id == r2.id) -> true
41 module WH = Weak.Make(Node)
43 let pool = WH.create 4093
45 (* Neat trick thanks to Alain Frisch ! *)
47 let gen_uid () = Oo.id (object end)
49 let empty = { id = gen_uid ();
53 let _ = WH.add pool empty
55 let is_empty = function { id = 0 } -> true | _ -> false
58 let v = { id = gen_uid ();
59 key = Node.hash_node n;
66 let branch (p,m,l,r) = norm (Branch(p,m,l,r))
67 let leaf k = norm (Leaf k)
69 (* To enforce the invariant that a branch contains two non empty sub-trees *)
70 let branch_ne = function
71 | (_,_,e,t) when is_empty e -> t
72 | (_,_,t,e) when is_empty e -> t
73 | (p,m,t0,t1) -> branch (p,m,t0,t1)
75 (********** from here on, only use the smart constructors *************)
77 let zero_bit k m = (k land m) == 0
79 let singleton k = if k < 0 then failwith "singleton" else leaf k
81 let rec mem k n = match n.node with
84 | Branch (p, _, l, r) -> if k <= p then mem k l else mem k r
86 let rec min_elt n = match n.node with
87 | Empty -> raise Not_found
89 | Branch (_,_,s,_) -> min_elt s
91 let rec max_elt n = match n.node with
92 | Empty -> raise Not_found
94 | Branch (_,_,_,t) -> max_elt t
97 let rec elements_aux acc n = match n.node with
100 | Branch (_,_,l,r) -> elements_aux (elements_aux acc r) l
104 let mask k m = (k lor (m-1)) land (lnot m)
106 let naive_highest_bit x =
109 if i = 0 then 1 else if x lsr i = 1 then 1 lsl i else loop (i-1)
113 let hbit = Array.init 256 naive_highest_bit
115 let highest_bit_32 x =
116 let n = x lsr 24 in if n != 0 then hbit.(n) lsl 24
117 else let n = x lsr 16 in if n != 0 then hbit.(n) lsl 16
118 else let n = x lsr 8 in if n != 0 then hbit.(n) lsl 8
121 let highest_bit_64 x =
122 let n = x lsr 32 in if n != 0 then (highest_bit_32 n) lsl 32
123 else highest_bit_32 x
125 let highest_bit = match Sys.word_size with
126 | 32 -> highest_bit_32
127 | 64 -> highest_bit_64
130 let branching_bit p0 p1 = highest_bit (p0 lxor p1)
132 let join (p0,t0,p1,t1) =
133 let m = branching_bit p0 p1 in
134 if zero_bit p0 m then
135 branch (mask p0 m, m, t0, t1)
137 branch (mask p0 m, m, t1, t0)
139 let match_prefix k p m = (mask k m) == p
142 let rec ins n = match n.node with
144 | Leaf j -> if j == k then n else join (k, leaf k, j, n)
145 | Branch (p,m,t0,t1) ->
146 if match_prefix k p m then
148 branch (p, m, ins t0, t1)
150 branch (p, m, t0, ins t1)
152 join (k, leaf k, p, n)
157 let rec rmv n = match n.node with
159 | Leaf j -> if k == j then empty else n
160 | Branch (p,m,t0,t1) ->
161 if match_prefix k p m then
163 branch_ne (p, m, rmv t0, t1)
165 branch_ne (p, m, t0, rmv t1)
171 (* should run in O(1) thanks to Hash consing *)
175 let compare = compare
178 let rec merge (s,t) =
179 if (equal s t) (* This is cheap thanks to hash-consing *)
182 match s.node,t.node with
185 | Leaf k, _ -> add k t
186 | _, Leaf k -> add k s
187 | Branch (p,m,s0,s1), Branch (q,n,t0,t1) ->
188 if m == n && match_prefix q p m then
189 branch (p, m, merge (s0,t0), merge (s1,t1))
190 else if m > n && match_prefix q p m then
192 branch (p, m, merge (s0,t), s1)
194 branch (p, m, s0, merge (s1,t))
195 else if m < n && match_prefix p q n then
198 branch (q, n, merge (s,t0), t1)
200 branch (q, n, t0, merge (s,t1))
202 (* The prefixes disagree. *)
205 let union s t = merge (s,t)
207 let rec subset s1 s2 = (equal s1 s2) ||
208 match (s1.node,s2.node) with
211 | Leaf k1, _ -> mem k1 s2
212 | Branch _, Leaf _ -> false
213 | Branch (p1,m1,l1,r1), Branch (p2,m2,l2,r2) ->
214 if m1 == m2 && p1 == p2 then
215 subset l1 l2 && subset r1 r2
216 else if m1 < m2 && match_prefix p1 p2 m2 then
217 if zero_bit p1 m2 then
218 subset l1 l2 && subset r1 l2
220 subset l1 r2 && subset r1 r2
224 let rec inter s1 s2 =
228 match (s1.node,s2.node) with
231 | Leaf k1, _ -> if mem k1 s2 then s1 else empty
232 | _, Leaf k2 -> if mem k2 s1 then s2 else empty
233 | Branch (p1,m1,l1,r1), Branch (p2,m2,l2,r2) ->
234 if m1 == m2 && p1 == p2 then
235 merge (inter l1 l2, inter r1 r2)
236 else if m1 > m2 && match_prefix p2 p1 m1 then
237 inter (if zero_bit p2 m1 then l1 else r1) s2
238 else if m1 < m2 && match_prefix p1 p2 m2 then
239 inter s1 (if zero_bit p1 m2 then l2 else r2)
247 match (s1.node,s2.node) with
250 | Leaf k1, _ -> if mem k1 s2 then empty else s1
251 | _, Leaf k2 -> remove k2 s1
252 | Branch (p1,m1,l1,r1), Branch (p2,m2,l2,r2) ->
253 if m1 == m2 && p1 == p2 then
254 merge (diff l1 l2, diff r1 r2)
255 else if m1 > m2 && match_prefix p2 p1 m1 then
256 if zero_bit p2 m1 then
257 merge (diff l1 s2, r1)
259 merge (l1, diff r1 s2)
260 else if m1 < m2 && match_prefix p1 p2 m2 then
261 if zero_bit p1 m2 then diff s1 l2 else diff s1 r2
268 (*s All the following operations ([cardinal], [iter], [fold], [for_all],
269 [exists], [filter], [partition], [choose], [elements]) are
270 implemented as for any other kind of binary trees. *)
272 let rec cardinal n = match n.node with
275 | Branch (_,_,t0,t1) -> cardinal t0 + cardinal t1
277 let rec iter f n = match n.node with
280 | Branch (_,_,t0,t1) -> iter f t0; iter f t1
282 let rec fold f s accu = match s.node with
285 | Branch (_,_,t0,t1) -> fold f t0 (fold f t1 accu)
287 let rec for_all p n = match n.node with
290 | Branch (_,_,t0,t1) -> for_all p t0 && for_all p t1
292 let rec exists p n = match n.node with
295 | Branch (_,_,t0,t1) -> exists p t0 || exists p t1
297 let rec filter pr n = match n.node with
299 | Leaf k -> if pr k then n else empty
300 | Branch (p,m,t0,t1) -> branch_ne (p, m, filter pr t0, filter pr t1)
303 let rec part (t,f as acc) n = match n.node with
305 | Leaf k -> if p k then (add k t, f) else (t, add k f)
306 | Branch (_,_,t0,t1) -> part (part acc t0) t1
308 part (empty, empty) s
310 let rec choose n = match n.node with
311 | Empty -> raise Not_found
313 | Branch (_, _,t0,_) -> choose t0 (* we know that [t0] is non-empty *)
317 let coll k (l, b, r) =
318 if k < x then add k l, b, r
319 else if k > x then l, b, add k r
322 fold coll s (empty, false, empty)
327 Printf.eprintf "{ id = %i; key = %i ; node=" n.id n.key;
329 | Empty -> Printf.eprintf "Empty; }\n"
330 | Leaf k -> Printf.eprintf "Leaf %i; }\n" k
331 | Branch (p,m,l,r) ->
332 Printf.eprintf "Branch(%i,%i,id=%i,id=%i); }\n"
338 let make l = List.fold_left (fun acc e -> add e acc ) empty l
341 (*s Additional functions w.r.t to [Set.S]. *)
343 let rec intersect s1 s2 = (equal s1 s2) ||
344 match (s1.node,s2.node) with
347 | Leaf k1, _ -> mem k1 s2
348 | _, Leaf k2 -> mem k2 s1
349 | Branch (p1,m1,l1,r1), Branch (p2,m2,l2,r2) ->
350 if m1 == m2 && p1 == p2 then
351 intersect l1 l2 || intersect r1 r2
352 else if m1 < m2 && match_prefix p2 p1 m1 then
353 intersect (if zero_bit p2 m1 then l1 else r1) s2
354 else if m1 > m2 && match_prefix p1 p2 m2 then
355 intersect s1 (if zero_bit p1 m2 then l2 else r2)
362 let from_list l = List.fold_left (fun acc i -> add i acc) empty l