|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: structure IntStrMap : INTSTRMAP = ! 3: struct ! 4: datatype 'a bucket = NIL | B of (int * string * 'a * 'a bucket) ! 5: datatype 'a intstrmap = ! 6: H of {table: 'a bucket array ref,elems: int ref,exn: exn,name: string option} ! 7: fun bucketapp f = ! 8: let fun loop NIL = () ! 9: | loop(B(i,s,j,r)) = (f(i,s,j); loop r) ! 10: in loop ! 11: end ! 12: fun namednew(name, size, exn) = ! 13: H {table=ref(array(size,NIL)),elems=ref 0,exn=exn,name=SOME name} ! 14: fun new(size, exn) = ! 15: H {table=ref(array(size,NIL)),elems=ref 0,exn=exn,name=NONE} ! 16: fun map (H{table,exn,...}) = ! 17: let fun find(i,s,NIL) = raise exn ! 18: | find(i,s,B(i',s',j,r)) = if i=i' andalso s=s' then j else find(i,s,r) ! 19: fun map' (i,s) = let val ref a = table ! 20: in find (i,s,a sub Bits.andb(i,(Array.length a)-1)) ! 21: end ! 22: in map' ! 23: end ! 24: fun rem (H{table=ref a,elems,...}) (i,s) = ! 25: let fun f(B(i',s',j,r)) = ! 26: if i=i' andalso s=s' then (dec elems; r) else B(i',s',j,f r) ! 27: | f x = x ! 28: val index = Bits.andb(i,(Array.length a)-1) ! 29: in update(a, index, f(a sub index)) ! 30: end ! 31: fun app f (H{table=ref a,...}) = ! 32: let fun zap 0 = () ! 33: | zap n = let val m = n-1 in bucketapp f (a sub m); zap m end ! 34: in zap(Array.length a) ! 35: end ! 36: fun add (m as H{table as ref a, elems, name, ...}) (v as (i,s,j)) = ! 37: let val size = Array.length a ! 38: in if !elems <> size ! 39: then let val index = Bits.andb(i, size-1) ! 40: fun f(B(i',s',j',r)) = ! 41: if i=i' andalso s=s' then B(i,s,j,r) else B(i',s',j',f r) ! 42: | f x = (inc elems; B(i,s,j,x)) ! 43: in update(a,index,f(a sub index)) ! 44: end ! 45: else let val newsize = size+size ! 46: val newsize1 = newsize-1 ! 47: val new = array(newsize,NIL) ! 48: fun bucket n = ! 49: let fun add'(a,b,B(i,s,j,r)) = ! 50: if Bits.andb(i,newsize1) = n ! 51: then add'(B(i,s,j,a),b,r) ! 52: else add'(a,B(i,s,j,b),r) ! 53: | add'(a,b,NIL) = ! 54: (update(new,n,a); ! 55: update(new,n+size,b); ! 56: bucket(n+1)) ! 57: in add'(NIL,NIL,a sub n) ! 58: end ! 59: in (case name of ! 60: NONE => () ! 61: | SOME name => ! 62: (print("\nIncreasing size of intmap " ^ name ^ " to: "); ! 63: print newsize; print "\n"; ())); ! 64: bucket 0 handle Subscript => (); ! 65: table := new; ! 66: add m v ! 67: end ! 68: end ! 69: fun intStrMapToList(H{table,...})= ! 70: let val a = !table; ! 71: val last = Array.length a - 1 ! 72: fun loop (0, NIL, acc) = acc ! 73: | loop (n, B(i,s,j,r), acc) = loop(n, r, (i,s,j)::acc) ! 74: | loop (n, NIL, acc) = loop(n-1, a sub (n-1), acc) ! 75: in loop(last,a sub last,[]) ! 76: end ! 77: fun transform (f:'a -> '2b) (H{table=ref a, elems=ref n, exn, name}) = ! 78: let val newa = array(Array.length a,NIL) ! 79: fun mapbucket NIL = NIL ! 80: | mapbucket(B(i,s,x,b)) = B(i,s,f x,mapbucket b) ! 81: fun loop i = (update(newa,i,mapbucket(a sub i)); loop(i+1)) ! 82: in loop 0 handle Subscript => (); ! 83: H{table=ref newa, elems=ref n, exn=exn, name=name} ! 84: end ! 85: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.