proc cached {arrName key args} { upvar #0 $arrName arr if {![info exists arr($key)]} { set arr($key) [eval $args] if {[llength $arr()]>=$arr(maxSize)} { unset arr([lindex $arr() 0]) set arr() [lrange $arr() 1 end] } } else { set pos [lsearch $arr() $key] set arr() [lreplace $arr() $pos $pos] } lappend arr() $key ;# LRU list set arr($key) }
Testing: initialize a cache, fill with some data
% array set Cache {maxSize 4 {} {}} % cached Cache a clock seconds 1100702390 % cached Cache b clock seconds 1100702440 % cached Cache c clock seconds 1100702443 % cached Cache d clock seconds 1100702445 % parray Cache Cache() = a b c d Cache(a) = 1100702390 Cache(b) = 1100702440 Cache(c) = 1100702443 Cache(d) = 1100702445 Cache(maxSize) = 4Ask for the element "a" again (moves it to end of LRU list):
% cached Cache a clock seconds 1100702390 % parray Cache Cache() = b c d a Cache(a) = 1100702390 Cache(b) = 1100702440 Cache(c) = 1100702443 Cache(d) = 1100702445 Cache(maxSize) = 4 % cached Cache c clock seconds 1100702443 % parray Cache Cache() = b d a c Cache(a) = 1100702390 Cache(b) = 1100702440 Cache(c) = 1100702443 Cache(d) = 1100702445 Cache(maxSize) = 4As maxSize is reached, the least-recently-used "b" will be decached:
% cached Cache x clock seconds 1100704105 % parray Cache Cache() = d a c x Cache(a) = 1100702390 Cache(c) = 1100702443 Cache(d) = 1100702445 Cache(maxSize) = 4 Cache(x) = 1100704105
TV (17 Nov 04) The cache of the processor chip involved in these test is hard to put in the same beginning state to actually test these kinds of scenarios. Maybe except starting the the machine up again in the same sequence.