module Make (X : Set.OrderedType)
= struct
module Set = Set.Make(X)
module Map = MyMap.Make(X)
module IntMap = struct
module M = MyMap.Make (struct
type t = int
let compare = compare
end)
include M
module H = SetMap.MakeHetero(Set)(M)
let update = H.update
end
type t = {
priority: int Map.t;
level: Set.t IntMap.t
}
let empty =
{
priority = Map.empty;
level = IntMap.empty
}
let priority x s =
try
Map.find x s.priority
with Not_found ->
assert false
let add x p s =
assert (not (Map.mem x s.priority));
{
priority = Map.add x p s.priority;
level = IntMap.update p (Set.add x) s.level
}
let remove x s =
let p, priority =
try
Map.find_remove x s.priority
with Not_found ->
assert false
in
let level =
IntMap.update p (function xs ->
assert (Set.mem x xs);
Set.remove x xs
) s.level
in
{
priority = priority;
level = level
}
let change x p1 s =
let p0 = priority x s in
if p0 = p1 then
s
else
{
priority = Map.add x p1 s.priority;
level = IntMap.update p1 (Set.add x) (IntMap.update p0 (Set.remove x) s.level)
}
let increment x d s =
change x (priority x s + d) s
let incrementifx x d s =
if Map.mem x s.priority then
increment x d s
else
s
let lowest s =
try
let p, xs = IntMap.minimum s.level in
try
Some (Set.choose xs, p)
with Not_found ->
assert false
with Not_found ->
None
let fold f s accu =
IntMap.fold (fun p xs accu ->
Set.fold (fun x accu ->
f x p accu
) xs accu
) s.level accu
end