refactored object caching behaviour out from base.py to cacheable.py and renamed registry.py to objectcache.py

master
Abhinav Sarkar 2008-12-30 15:46:00 +00:00
parent 237b32c6c1
commit 26415e75bc
14 changed files with 81 additions and 66 deletions

View File

@ -7,13 +7,12 @@ __license__ = "GNU Lesser General Public License"
from album import Album
from api import Api
from artist import Artist
from base import LastfmBase
from error import LastfmError
from event import Event
from geo import Location, Country
from group import Group
from playlist import Playlist
from registry import Registry
from objectcache import ObjectCache
from tag import Tag
from tasteometer import Tasteometer
from track import Track
@ -21,4 +20,4 @@ from user import User
__all__ = ['LastfmError', 'Api', 'Album', 'Artist', 'Event',
'Location', 'Country', 'Group', 'Playlist', 'Tag',
'Tasteometer', 'Track', 'User', 'Registry']
'Tasteometer', 'Track', 'User', 'ObjectCache']

View File

@ -6,8 +6,9 @@ __license__ = "GNU Lesser General Public License"
from base import LastfmBase
from taggable import Taggable
from cacheable import Cacheable
class Album(Taggable, LastfmBase):
class Album(LastfmBase, Cacheable, Taggable):
"""A class representing an album."""
def init(self,
api,

View File

@ -5,12 +5,13 @@ __version__ = "0.2"
__license__ = "GNU Lesser General Public License"
from base import LastfmBase
from cacheable import Cacheable
from taggable import Taggable
from sharable import Sharable
from searchable import Searchable
from lazylist import lazylist
class Artist(LastfmBase, Taggable, Sharable, Searchable):
class Artist(LastfmBase, Cacheable, Sharable, Searchable, Taggable):
"""A class representing an artist."""
def init(self,
api,

View File

@ -4,55 +4,9 @@ __author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
__version__ = "0.2"
__license__ = "GNU Lesser General Public License"
try:
from threading import Lock
except ImportError:
from dummy_threading import Lock
class LastfmBase(object):
"""Base class for all the classes in this package"""
registry = {}
_lock = Lock()
def __new__(cls, *args, **kwds):
subject = None
if 'subject' in kwds and not cls.__name__.startswith('Weekly'):
subject = kwds['subject']
del kwds['subject']
if 'bypass_registry' in kwds:
del kwds['bypass_registry']
inst = object.__new__(cls)
inst.init(*args, **kwds)
return inst
key = cls._hash_func(*args, **kwds)
if subject is not None:
key = (hash(subject), key)
LastfmBase._lock.acquire()
try:
inst, already_registered = LastfmBase.register(object.__new__(cls), key)
if not already_registered:
inst.init(*args, **kwds)
finally:
LastfmBase._lock.release()
return inst
@staticmethod
def register(ob, key):
if not ob.__class__ in LastfmBase.registry:
LastfmBase.registry[ob.__class__] = {}
if key in LastfmBase.registry[ob.__class__]:
ob = LastfmBase.registry[ob.__class__][key]
#print "already registered: %s" % repr(ob)
return (ob, True)
else:
#print "not already registered: %s" % ob.__class__
LastfmBase.registry[ob.__class__][key] = ob
return (ob, False)
@staticmethod
def top_property(list_property_name):
def decorator(func):

52
src/cacheable.py Normal file
View File

@ -0,0 +1,52 @@
#!/usr/bin/env python
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
__version__ = "0.2"
__license__ = "GNU Lesser General Public License"
try:
from threading import Lock
except ImportError:
from dummy_threading import Lock
class Cacheable(object):
registry = {}
_lock = Lock()
def __new__(cls, *args, **kwds):
subject = None
if 'subject' in kwds and not cls.__name__.startswith('Weekly'):
subject = kwds['subject']
del kwds['subject']
if 'bypass_registry' in kwds:
del kwds['bypass_registry']
inst = object.__new__(cls)
inst.init(*args, **kwds)
return inst
key = cls._hash_func(*args, **kwds)
if subject is not None:
key = (hash(subject), key)
Cacheable._lock.acquire()
try:
inst, already_registered = Cacheable.register(object.__new__(cls), key)
if not already_registered:
inst.init(*args, **kwds)
finally:
Cacheable._lock.release()
return inst
@staticmethod
def register(ob, key):
if not ob.__class__ in Cacheable.registry:
Cacheable.registry[ob.__class__] = {}
if key in Cacheable.registry[ob.__class__]:
ob = Cacheable.registry[ob.__class__][key]
#print "already registered: %s" % repr(ob)
return (ob, True)
else:
#print "not already registered: %s" % ob.__class__
Cacheable.registry[ob.__class__][key] = ob
return (ob, False)

View File

@ -5,9 +5,10 @@ __version__ = "0.2"
__license__ = "GNU Lesser General Public License"
from base import LastfmBase
from cacheable import Cacheable
from sharable import Sharable
class Event(LastfmBase, Sharable):
class Event(LastfmBase, Cacheable, Sharable):
"""A class representing an event."""
STATUS_ATTENDING = 0
STATUS_MAYBE = 1

View File

@ -5,6 +5,7 @@ __version__ = "0.2"
__license__ = "GNU Lesser General Public License"
from base import LastfmBase
from cacheable import Cacheable
from lazylist import lazylist
class Geo(object):
@ -93,7 +94,7 @@ class Geo(object):
for t in data.findall('track')
]
class Venue(LastfmBase):
class Venue(LastfmBase, Cacheable):
"""A class representing a venue of an event"""
def init(self,
name = None,
@ -137,7 +138,7 @@ class Venue(LastfmBase):
def __repr__(self):
return "<lastfm.geo.Venue: %s, %s>" % (self.name, self.location.city)
class Location(LastfmBase):
class Location(LastfmBase, Cacheable):
"""A class representing a location of an event"""
XMLNS = "http://www.w3.org/2003/01/geo/wgs84_pos#"
@ -254,7 +255,7 @@ class Location(LastfmBase):
else:
return "<lastfm.geo.Location: %s>" % self.city
class Country(LastfmBase):
class Country(LastfmBase, Cacheable):
"""A class representing a country."""
def init(self,
api,

View File

@ -5,9 +5,10 @@ __version__ = "0.2"
__license__ = "GNU Lesser General Public License"
from base import LastfmBase
from cacheable import Cacheable
from lazylist import lazylist
class Group(LastfmBase):
class Group(LastfmBase, Cacheable):
"""A class representing a group on last.fm."""
def init(self,
api,

View File

@ -6,7 +6,7 @@ __license__ = "GNU Lesser General Public License"
from album import Album
from artist import Artist
from base import LastfmBase
from cacheable import Cacheable
from error import InvalidParametersError
from event import Event
from geo import Location, Country
@ -17,21 +17,21 @@ from track import Track
from user import User
from weeklychart import WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart
class Registry(object):
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, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart]]
def __getitem__(self, name):
if name not in Registry.keys:
if name not in ObjectCache.keys:
raise InvalidParametersError("Key does not correspond to a valid class")
else:
try:
vals = LastfmBase.registry[eval(name)].values()
vals = Cacheable.registry[eval(name)].values()
vals.sort()
return vals
except KeyError:
return []
def __repr__(self):
return "<lastfm.Registry>"
return "<lastfm.ObjectCache>"

View File

@ -5,8 +5,9 @@ __version__ = "0.2"
__license__ = "GNU Lesser General Public License"
from base import LastfmBase
from cacheable import Cacheable
class Playlist(LastfmBase):
class Playlist(LastfmBase, Cacheable):
"""A class representing an XPSF playlist."""
def init(self, api, url):
self._api = api

View File

@ -6,9 +6,10 @@ __license__ = "GNU Lesser General Public License"
from base import LastfmBase
from searchable import Searchable
from cacheable import Cacheable
from lazylist import lazylist
class Tag(LastfmBase, Searchable):
class Tag(LastfmBase, Cacheable, Searchable):
""""A class representing a tag."""
def init(self,
api,

View File

@ -5,12 +5,13 @@ __version__ = "0.2"
__license__ = "GNU Lesser General Public License"
from base import LastfmBase
from cacheable import Cacheable
from taggable import Taggable
from sharable import Sharable
from searchable import Searchable
from lazylist import lazylist
class Track(LastfmBase, Taggable, Sharable, Searchable):
class Track(LastfmBase, Cacheable, Sharable, Searchable, Taggable):
"""A class representing a track."""
def init(self,
api,

View File

@ -5,10 +5,11 @@ __version__ = "0.2"
__license__ = "GNU Lesser General Public License"
from base import LastfmBase
from cacheable import Cacheable
from lazylist import lazylist
import playlist
class User(LastfmBase):
class User(LastfmBase, Cacheable):
"""A class representing an user."""
def init(self,
api,

View File

@ -5,8 +5,9 @@ __version__ = "0.2"
__license__ = "GNU Lesser General Public License"
from base import LastfmBase
from cacheable import Cacheable
class WeeklyChart(LastfmBase):
class WeeklyChart(LastfmBase, Cacheable):
"""A class for representing the weekly charts"""
def init(self, subject, start, end,