C
Cristiano Paris
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
Thanks for your replies.
Cristiano
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
Thanks for your replies.
Cristiano