On Sun, 3 Sep 2006, Trans wrote:

>> Or if I just used LRUCache instead of Iowa::Caches::LRUCache, and someone
>> decided to use the Facets LRUCache in an app, it would cause bad things to
>> happen (I like the Facets LRUCache's simplicity; I hate that it requires
>> extending anything that is to be stored in it, BTW).
>
> Hmm... If you have a fix for that I'd love to incorporate it.

Well, let me tell you what I did.

The mixin is used to turn the desired class into something that can be a 
linked list node.  It's a neat idea, but I don't like having to pollute my 
namespace, and it breaks down messily in some instances (try using the 
cache to cache fixnums...).

So, I took a couple ideas from the implementation and built a doubly 
linked list implementation that doesn't need the mixin and also provides 
fast random access by using a hash in conjunction with the list.  So data 
access, modification, inserts, and deletes are all pretty fast, and no 
penalty is paid for having large numbers of items in the cache.

I then used this as the basis for an LRU cache implementation.  Mine will 
also expire elements based on age.  So, for example, a cache with a max 
ttl of 1800 seconds will expire elements that haven't been accessed in 
more than half an hour, even if the cache isn't full.  I pay a small cost 
for this capability, though, in terms of speed, so it may not be something 
you would want in your implementation.

The cache should be threadsafe, and I also have a capability in mine for 
finalizers -- blocks of code that are invoked immediately before something 
is expired from the cache -- which also does not come for free.

I can happily make a version of the cache which doesn't include the TTL 
stuff or the finalizers, though, if you want it.  Note that the mixin 
approach of your current LRU cache definitely makes for the fastest cache, 
though, so I guess it depends on what one is selecting for.  I'm using a 
modified version of your LRUCache (I added finalizer support) in a place 
where I need a basic LRU cache, can live with the mixin, and just want it 
to be as fast as possible.

You might also be able to use the raw linked list?

>> So yes, if one of my users wants to take advantage of something I have
>> in one of the extensions, they have to type a few more characters to
>> create the object.  I am quite willing to sacrafice a few characters for
>> the relative security against namespace collisions, though.  The cost is
>> very small, and the benefit is large.
>
> But then how will I use Kirk's String extensions and Tom's string
> extensions?

I suppose I could make Iowa::String delegate any method it doesn't know 
down to the original string it was initialized with.  That requires that 
it keep a reference to that original string, though, which is also a 
tradeoff.


Kirk Haines