File: hashMultimap.sml

package info (click to toggle)
mlton 20210117%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 58,464 kB
  • sloc: ansic: 27,682; sh: 4,455; asm: 3,569; lisp: 2,879; makefile: 2,347; perl: 1,169; python: 191; pascal: 68; javascript: 7
file content (76 lines) | stat: -rw-r--r-- 1,668 bytes parent folder | download | duplicates (5)
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
(*
 * Multimap datatype that uses hashing.
 *
 * -- allen
 *)

structure HashMultimap :> HASH_MULTIMAP =
struct

   structure S = HashMap

   type ('a,'b) multimap = ('a,'b list) S.map * int ref


   fun create x n = (S.create x n, ref 0)

   fun size (_,c)    = !c
   fun bucketSize (m,_) = S.bucketSize m
   fun isEmpty (_,c) = !c = 0

   fun insert (m,c) (e as (x,y)) =
      (S.update m ((x,[y]),fn ys => y::ys); c := !c + 1)

   fun removeAll (m,c) i =
   let val stuff = S.lookup m i
   in  S.remove m i; c := !c - length stuff
   end handle _ => ()

   fun update (m,c) (e as (x,ys)) =
   let val stuff = S.lookupOrElse m [] x
   in  S.insert m e; c := !c - length stuff + length ys
   end

   fun lookup (m,_) i = S.lookup m i

   fun contains (m,_) i = S.contains m i

   fun count (m,_) i = length(S.lookupOrElse m [] i)

   fun toList (m,_) = S.toList m

   fun toDupList (m,_) =
   let fun collect (x,[],l)   = l
         | collect (x,h::t,l) = (x,h)::collect(x,t,l)
   in
       S.fold (fn ((x,ys),l) => collect (x,ys,l)) [] m 
   end

   fun clear (m,c) = (S.clear m; c := 0)

   fun dupApp f (m,_) =
   let fun call (x,[])   = ()
         | call (x,h::t) = (f(x,h); call(x,t))
   in
       S.app call m
   end

   fun app f (m,_) = S.app f m

   fun dupFold f x (m,_) =
   let fun collect((x,[]),l)   = l
         | collect((x,h::t),l) = collect((x,t),f((x,h),l))
   in
       S.fold collect x m
   end

   fun fold f x (m,_) = S.fold f x m

   fun toString (f,g) m =
      "{" ^
          dupFold (fn ((x,y),"") => "(" ^ f x ^ ", " ^ g y ^ ")"
                   | ((x,y),l)  => "(" ^ f x ^ ", " ^ g y ^ "), " ^ l) 
                   "" m ^ "}"

end