1 (* Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
4 * MLton is released under a BSD-style license.
5 * See the file MLton-LICENSE for details.
9 * Applications of Path Compression on Balanced Trees
16 functor DisjointMax(O: ORDER): DISJOINT_MAX =
21 datatype t = T of {label: O.t ref,
25 | Root of {size: int ref,
28 fun parent (T{info = ref (Parent p), ...}) = p
29 | parent _ = Error.bug "DisjointMax.parent"
30 fun setParent(T{info, ...}, p) = info := Parent p
31 fun labelRef (T{label, ...}) = label
32 val (label, setLabel) = Ref.getAndSet labelRef
33 fun sizeRef (T{info = ref(Root{size, ...}), ...}) = size
34 | sizeRef _ = Error.bug "DisjointMax.sizeRef"
35 val (size, setSize) = Ref.getAndSet sizeRef
36 fun childRef (T{info = ref(Root{child, ...}), ...}) = child
37 | childRef _ = Error.bug "DisjointMax.childRef"
38 val (childOption, setChildOption) = Ref.getAndSet childRef
39 val child = Option.projector childOption
40 fun setChild(r, c) = setChildOption(r, SOME c)
42 fun subsize r = size r - (case childOption r of
46 fun hasParent (T{info = ref (Parent _), ...}) = true
49 fun isRoot (T{info = ref (Root _), ...}) = true
52 fun singleton l = T{label = ref l,
53 info = ref (Root{size = ref 0, child = ref NONE})}
56 if not(isRoot r) then Error.error "DisjointMax.update"
57 else if O.<=(l, label r) then ()
63 if O.<=(l, label r') then r
64 else if subsize r >= subsize r'
65 then (setChildOption(r, childOption r') ;
68 else (setSize(r', size r) ;
74 | SOME r' => if O.<=(l, label r') then ()
75 else let val r' = link r'
82 if not (isRoot r andalso isRoot r') then Error.error "DisjointMax.link"
83 else let val s = size r
86 | move (SOME r') = let val r'' = childOption r'
87 in (setParent(r', r) ; move r'')
89 in (update(r', label r) ;
91 if s < s' then move (childOption r) else move (SOME r'))
94 fun compress s = (* Pre: hasParent s *)
98 setLabel(s, O.max(label s, label p)) ;
99 setParent(s, parent p))
103 fun eval s = if isRoot s then label s
105 O.max(label s, label (parent s)))