[MLton-commit] r5195
Vesa Karvonen
vesak at mlton.org
Wed Feb 14 18:07:53 PST 2007
Smarter cache for callbacks.
----------------------------------------------------------------------
A mltonlib/trunk/com/ssh/misc-util/unstable/cee-cache-test.sml
A mltonlib/trunk/com/ssh/misc-util/unstable/cee-cache.sml
U mltonlib/trunk/com/ssh/misc-util/unstable/lib.mlb
----------------------------------------------------------------------
Added: mltonlib/trunk/com/ssh/misc-util/unstable/cee-cache-test.sml
===================================================================
--- mltonlib/trunk/com/ssh/misc-util/unstable/cee-cache-test.sml 2007-02-14 18:06:39 UTC (rev 5194)
+++ mltonlib/trunk/com/ssh/misc-util/unstable/cee-cache-test.sml 2007-02-15 02:07:53 UTC (rev 5195)
@@ -0,0 +1,36 @@
+(* Copyright (C) 2007 SSH Communications Security, Helsinki, Finland
+ *
+ * This code is released under the MLton license, a BSD-style license.
+ * See the LICENSE file or http://mlton.org/License for details.
+ *)
+
+val () = let
+ open Type UnitTest
+ val verifyNotFound =
+ verifyFailsWith (fn CeeCache.NotFound => true | _ => false)
+in
+ unitTests
+ (title "CeeCache")
+ (test (fn () => let
+ open CeeCache
+ val c = new ()
+ val () = verifyTrue (0 = size c)
+ val k5 = put c 5
+ val () = verifyTrue (1 = size c)
+ val k2 = put c 2
+ val () = verifyTrue (2 = size c)
+ val () = verifyTrue (5 = use c k5)
+ val () = verifyNotFound (fn () => get c k5)
+ val () = verifyTrue (1 = size c)
+ val k3 = put c 3
+ val () = verifyTrue (2 = use c k2)
+ val () = verifyNotFound (fn () => use c k2)
+ val () = verifyTrue (1 = size c)
+ val () = verifyTrue (3 = use c k3)
+ val () = verifyNotFound (fn () => get c k3)
+ val () = verifyTrue (0 = size c)
+ in
+ ()
+ end))
+ $
+end
Property changes on: mltonlib/trunk/com/ssh/misc-util/unstable/cee-cache-test.sml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: mltonlib/trunk/com/ssh/misc-util/unstable/cee-cache.sml
===================================================================
--- mltonlib/trunk/com/ssh/misc-util/unstable/cee-cache.sml 2007-02-14 18:06:39 UTC (rev 5194)
+++ mltonlib/trunk/com/ssh/misc-util/unstable/cee-cache.sml 2007-02-15 02:07:53 UTC (rev 5195)
@@ -0,0 +1,85 @@
+(* Copyright (C) 2007 SSH Communications Security, Helsinki, Finland
+ *
+ * This code is released under the MLton license, a BSD-style license.
+ * See the LICENSE file or http://mlton.org/License for details.
+ *)
+
+structure CeeCache :> CACHE where type Key.t = C.voidptr = struct
+ structure Key = struct
+ type t = C.voidptr
+
+ val unused = ref [] (* XXX free these at some point *)
+ fun new () =
+ case List.pop unused of
+ SOME v => v
+ | NONE => C.Ptr.inject' (C.Ptr.|&! (C.new' C.S.sint))
+ val free = unused <\ List.push
+ val get = C.Get.sint' o C.Ptr.|*! o C.Ptr.cast'
+ fun set k = C.Ptr.|*! (C.Ptr.cast' k) <\ C.Set.sint'
+ end
+
+ datatype 'a t =
+ IN of {size : Int.t Ref.t,
+ table : {key : Key.t, value : 'a} Option.t Array.t Ref.t}
+ fun get s (IN r) = ! (s r)
+ fun set s (IN r) v = s r := v
+
+ exception NotFound
+
+ fun size c = get #size c
+
+ fun sub c i = valOf (Array.sub (get#table c, i))
+ fun update c (i, v) = Array.update (get#table c, i, v)
+
+ fun new () = IN {size = ref 0, table = ref (Array.tabulate (0, undefined))}
+
+ fun ensureCapacity (IN {size, table}) reqCap = let
+ val curCap = Array.length (!table)
+ in
+ if reqCap <= curCap
+ then ()
+ else table := Array.tabulate
+ (Int.max (reqCap, curCap*2+1),
+ fn i => if i < !size
+ then Array.sub (!table, i)
+ else NONE)
+ end
+
+ fun putWith c k2v = let
+ val n = size c
+ val k = Key.new ()
+ in
+ (ensureCapacity c (n+1)
+ ; let val v = k2v k
+ in set#size c (n+1)
+ ; update c (n, SOME {key = k, value = v})
+ ; Key.set k n
+ ; (k, v)
+ end)
+ handle e => (Key.free k ; raise e)
+ end
+
+ fun put c = #1 o putWith c o const
+ fun get c k = let
+ val i = Key.get k
+ in
+ if size c <= i then raise NotFound else let
+ val {value, key} = sub c i
+ in
+ if k <> key then raise NotFound else value
+ end
+ end
+ fun rem c k = let
+ val n = size c - 1
+ val i = Key.get k
+ val r = sub c n
+ in
+ if n < i orelse #key (sub c i) <> k then raise NotFound else ()
+ ; Key.free k
+ ; update c (i, SOME r)
+ ; Key.set (#key r) i
+ ; update c (n, NONE)
+ ; set#size c n
+ end
+ fun use c k = get c k before rem c k
+end
Property changes on: mltonlib/trunk/com/ssh/misc-util/unstable/cee-cache.sml
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: mltonlib/trunk/com/ssh/misc-util/unstable/lib.mlb
===================================================================
--- mltonlib/trunk/com/ssh/misc-util/unstable/lib.mlb 2007-02-14 18:06:39 UTC (rev 5194)
+++ mltonlib/trunk/com/ssh/misc-util/unstable/lib.mlb 2007-02-15 02:07:53 UTC (rev 5195)
@@ -47,6 +47,7 @@
$(SML_LIB)/mlnlffi-lib/mlnlffi-lib.mlb
in
cache.sml
+ cee-cache.sml
end
(* SML *)
More information about the MLton-commit
mailing list