From 28d4368c425f8a410735c7b02997cba44f7c704b Mon Sep 17 00:00:00 2001 From: Abhinav Sarkar Date: Tue, 31 Mar 2009 15:48:04 +0000 Subject: [PATCH] * moved object registry and register function to objectcache module * changed the cache dict to a WeakReferenceDict for avoiding excessive memory usage * added stats method to ObjectCache to get current stats about cache --- lastfm/mixins/_cacheable.py | 22 ++++-------- lastfm/objectcache.py | 68 +++++++++++++++++++++++++------------ 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/lastfm/mixins/_cacheable.py b/lastfm/mixins/_cacheable.py index 6ae87d0..3100cc2 100644 --- a/lastfm/mixins/_cacheable.py +++ b/lastfm/mixins/_cacheable.py @@ -9,21 +9,9 @@ try: from threading import Lock except ImportError: from dummy_threading import Lock - -registry = {} -_lock = Lock() +from lastfm.objectcache import ObjectCache -def register(ob, key): - if not ob.__class__ in registry: - registry[ob.__class__] = {} - if key in registry[ob.__class__]: - ob = registry[ob.__class__][key] - #print "already registered: %s" % repr(ob) - return (ob, True) - else: - #print "not already registered: %s" % ob.__class__ - registry[ob.__class__][key] = ob - return (ob, False) +_lock = Lock() def cacheable(cls): @classmethod @@ -45,7 +33,7 @@ def cacheable(cls): key = (hash(subject), key) with _lock: - inst, already_registered = register(object.__new__(cls), key) + inst, already_registered = ObjectCache.register(object.__new__(cls), key) if not already_registered: inst.init(*args, **kwds) return inst @@ -58,4 +46,8 @@ def cacheable(cls): if not hasattr(cls, '_hash_func'): cls._hash_func = _hash_func + if not hasattr(cls, '_mixins'): + cls._mixins = [] + cls._mixins.append('__new__') + return cls diff --git a/lastfm/objectcache.py b/lastfm/objectcache.py index f57d92d..bb10542 100644 --- a/lastfm/objectcache.py +++ b/lastfm/objectcache.py @@ -4,36 +4,60 @@ __author__ = "Abhinav Sarkar " __version__ = "0.2" __license__ = "GNU Lesser General Public License" __package__ = "lastfm" - -from lastfm.album import Album -from lastfm.artist import Artist -from lastfm.mixins import _cacheable -from lastfm.error import InvalidParametersError -from lastfm.event import Event -from lastfm.geo import Location, Country -from lastfm.group import Group -from lastfm.playlist import Playlist -from lastfm.tag import Tag -from lastfm.track import Track -from lastfm.user import User -from lastfm.venue import Venue -from lastfm.chart import WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart + +_registry = {} class ObjectCache(object): """The registry to contain all the entities""" - keys = [c.__name__ for c in [Album, Artist, Event, Location, Country, Group, - Playlist, Tag, Track, User, Venue, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart]] + keys = ['Album', 'Artist', 'Event', 'Location', 'Country', 'Group', + 'Playlist', 'Shout', 'Tag', 'Track', 'User', 'Venue', + 'WeeklyChart', + 'WeeklyAlbumChart', 'WeeklyArtistChart', 'WeeklyTrackChart', 'WeeklyTagChart', + 'MonthlyChart', + 'MonthlyAlbumChart', 'MonthlyArtistChart', 'MonthlyTrackChart', 'MonthlyTagChart', + 'QuaterlyChart', + 'QuaterlyAlbumChart', 'QuaterlyArtistChart', 'QuaterlyTrackChart', 'QuaterlyTagChart', + 'HalfYearlyChart', + 'HalfYearlyAlbumChart', 'HalfYearlyArtistChart', 'HalfYearlyTrackChart', 'HalfYearlyTagChart', + 'YearlyChart', + 'YearlyAlbumChart', 'YearlyArtistChart', 'YearlyTrackChart', 'YearlyTagChart' + ] + + @staticmethod + def register(ob, key): + cls_name = ob.__class__.__name__ + if not cls_name in _registry: + _registry[cls_name] = WeakValueDictionary() + if key in _registry[cls_name]: + ob = _registry[cls_name][key] + print "already registered: %s" % repr(ob) + return (ob, True) + else: + print "not already registered: %s" % ob.__class__ + _registry[cls_name][key] = ob + return (ob, False) + + @property + def stats(self): + counts = {} + for k in ObjectCache.keys: + if k in _registry: + counts[k] = len(_registry[k]) + else: + counts[k] = 0 + return counts def __getitem__(self, name): if name not in ObjectCache.keys: raise InvalidParametersError("Key does not correspond to a valid class") else: - try: - vals = _cacheable.registry[eval(name)].values() - vals.sort() - return vals - except KeyError: + if name in _registry: + return sorted(_registry[name].values()) + else: return [] def __repr__(self): - return "" \ No newline at end of file + return "" + +from weakref import WeakValueDictionary +from lastfm.error import InvalidParametersError \ No newline at end of file