Lazy container

Cristiano Paris frodo at theshire.org
Tue Feb 13 08:15:07 EST 2007


Hi everyone,

I'm trying to write a Container which should mimic a list. Basically, 
the container pulls items on the fly from an unspecified source through 
a function and returns an instance of a given class over the pulled item.

That is:

class lazy(object):
   def __getitem__(self,index):
     return Foo(f(index))

lc = lazy()

Here I see a problem: two consecutive accesses to lc for the same index 
would retrieve two different instances of Foo.

In some scenarios this is not desirable since one wants to have all the 
accessors to share the same instance for the same index so as to reduce 
memory consumption.

So, I thought to use an internal dictionary of all the Foo instances 
given away so far. Something like:

class lazy(object):
   def __init__(self):
     self.cache = {}

   def __getitem__(self,index):
     if not self.cache.has_key(index):
       value = Foo(f(index))   # MISS
       self.cache[index] = value
     else:                     # HIT
       value = self.cache[index]

     return value

This is acceptable as it reduces the number of instances living in the 
system at any given time.

The problem with this implementation is that the cache never decreases 
in length as Foo instances are no longer referenced by the lc accessor 
since they're all referenced by the internal cache.

There are scenarios in which f() retrieves items from a very huge source 
(i.e. a database) and threads sharing the lazing container and consuming 
Foo instances to use them for a very short time and then discardi them: 
after a while you'll eventually end up having a whole copy of the source 
in memory, which is unacceptable.

One solution may be to use gc.get_referrers() to search the cache for 
unused instances every time we have a cache miss so as to see if we 
could discard some instance before inserting the new one in the cache.

But this comes at a cost.

May be someone has faced this problem before and came up with some 
obscure language feature to solve this elegantly :D

Thanks for your replies.

Cristiano



More information about the Python-list mailing list