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
|
(*
* Create a version of arrays that keeps track of its versions.
*
* -- Allen
*)
functor UndoableArray
(structure Array : ARRAY
structure Log : TRANSACTION_LOG) : ARRAY =
struct
structure A = Array
type 'a vector = 'a A.vector
type 'a array = 'a A.array * Log.version ref
infix 9 sub
val maxLen = A.maxLen
fun array (n,d) = (A.array (n,d),ref(!Log.version))
fun get (a,_) = a
fun commit (a,v) = fn ver => v := ver
fun rollback (a,v) =
let val N = A.length a
val a' = A.array(N,A.sub(a,0))
in A.copy{src=a, si=0, len=NONE, dst = a', di = 0};
fn ver => (A.copy{src=a',si=0,len=NONE,dst=a,di=0}; v := ver)
end
fun get' (A as (a,v)) =
let val ver = !Log.version
in if !v <> ver then
(Log.add_object {commit = commit A,
rollback = rollback A};
v := ver
)
else ();
a
end
fun length a = A.length(get a)
fun a sub i = A.sub(get a,i)
fun update (a, i, e) = A.update(get' a, i, e)
fun extract (a, i, j) = A.extract(get a, i, j)
fun copy {src, si, len, dst, di } =
A.copy{src=get src, si=si, len=len, dst=get' dst, di=di}
fun copyVec { src, si, len, dst, di } =
A.copyVec { src = src, si = si, len = len, dst = get' dst, di = di }
fun tabulate (n, f) = (A.tabulate(n,f),ref(!Log.version))
fun fromList l = (A.fromList l,ref(!Log.version))
fun app f a = A.app f (get a)
fun foldl f u a = A.foldl f u (get a)
fun foldr f u a = A.foldr f u (get a)
fun modify f a = A.modify f (get' a)
fun appi f (a,i,j) = A.appi f (get a, i, j)
fun foldli f u (a, i, j) = A.foldli f u (get a, i, j)
fun foldri f u (a, i, j) = A.foldri f u (get a, i, j)
fun modifyi f (a, i, j) = A.modifyi f (get' a, i, j)
end
|