Skip to content

Commit

Permalink
Performance improvement: Type cast properties on demand
Browse files Browse the repository at this point in the history
  • Loading branch information
pprkut committed Mar 24, 2019
1 parent 29425ed commit 439d4c1
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 8 deletions.
32 changes: 28 additions & 4 deletions beets/dbcore/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ def __init__(self, db=None, **values):
"""
self._db = db
self._dirty = set()
self._raw_values_fixed = {}
self._raw_values_flex = {}
self._values_fixed = {}
self._values_flex = {}

Expand All @@ -193,9 +195,9 @@ def _awaken(cls, db=None, fixed_values={}, flex_values={}):
"""
obj = cls(db)
for key, value in fixed_values.items():
obj._values_fixed[key] = cls._type(key).from_sql(value)
obj._raw_values_fixed[key] = value
for key, value in flex_values.items():
obj._values_flex[key] = cls._type(key).from_sql(value)
obj._raw_values_flex[key] = value
return obj

def __repr__(self):
Expand Down Expand Up @@ -232,7 +234,9 @@ def copy(self):
"""
new = self.__class__()
new._db = self._db
new._raw_values_fixed = self._raw_values_fixed.copy()
new._values_fixed = self._values_fixed.copy()
new._raw_values_flex = self._raw_values_flex.copy()
new._values_flex = self._values_flex.copy()
new._dirty = self._dirty.copy()
return new
Expand All @@ -256,9 +260,18 @@ def __getitem__(self, key):
if key in getters: # Computed.
return getters[key](self)
elif key in self._fields: # Fixed.
return self._values_fixed.get(key, self._type(key).null)
if key in self._values_fixed:
return self._values_fixed[key]
elif key in self._raw_values_fixed:
self._values_fixed[key] = self._type(key).from_sql(self._raw_values_fixed[key])
return self._values_fixed[key]
else:
return self._type(key).null
elif key in self._values_flex: # Flexible.
return self._values_flex[key]
elif key in self._raw_values_flex: # Flexible.
self._values_flex[key] = self._type(key).from_sql(self._raw_values_flex[key])
return self._values_flex[key]
else:
raise KeyError(key)

Expand All @@ -268,8 +281,12 @@ def _setitem(self, key, value):
"""
# Choose where to place the value.
if key in self._fields:
if not key in self._values_fixed and key in self._raw_values_fixed:
self._values_fixed[key] = self._type(key).from_sql(self._raw_values_fixed[key])
source = self._values_fixed
else:
if not key in self._values_flex and key in self._raw_values_flex:
self._values_flex[key] = self._type(key).from_sql(self._raw_values_flex[key])
source = self._values_flex

# If the field has a type, filter the value.
Expand All @@ -294,6 +311,11 @@ def __delitem__(self, key):
"""
if key in self._values_flex: # Flexible.
del self._values_flex[key]
if key in self._raw_values_flex:
del self._raw_values_flex[key]
self._dirty.add(key) # Mark for dropping on store.
elif key in self._raw_values_flex: # Flexible
del self._raw_values_flex[key]
self._dirty.add(key) # Mark for dropping on store.
elif key in self._fields: # Fixed
setattr(self, key, self._type(key).null)
Expand All @@ -307,7 +329,7 @@ def keys(self, computed=False):
`computed` parameter controls whether computed (plugin-provided)
fields are included in the key list.
"""
base_keys = list(self._fields) + list(self._values_flex.keys())
base_keys = list(self._fields) + list(self._values_flex.keys()) + list(self._raw_values_flex.keys())
if computed:
return base_keys + list(self._getters().keys())
else:
Expand Down Expand Up @@ -436,7 +458,9 @@ def load(self):
self._check_db()
stored_obj = self._db._get(type(self), self.id)
assert stored_obj is not None, u"object {0} not in DB".format(self.id)
self._raw_values_fixed = {}
self._values_fixed = {}
self._raw_values_flex = {}
self._values_flex = {}
self.update(dict(stored_obj))
self.clear_dirty()
Expand Down
8 changes: 4 additions & 4 deletions beets/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -785,14 +785,14 @@ def reimport_metadata(self, lib):
replaced_album = self.replaced_albums.get(self.album.path)
if replaced_album:
self.album.added = replaced_album.added
self.album.update(replaced_album._values_flex)
self.album.update(replaced_album._raw_values_flex)
self.album.artpath = replaced_album.artpath
self.album.store()
log.debug(
u'Reimported album: added {0}, flexible '
u'attributes {1} from album {2} for {3}',
self.album.added,
replaced_album._values_flex.keys(),
replaced_album._raw_values_flex.keys(),
replaced_album.id,
displayable_path(self.album.path)
)
Expand All @@ -809,11 +809,11 @@ def reimport_metadata(self, lib):
dup_item.id,
displayable_path(item.path)
)
item.update(dup_item._values_flex)
item.update(dup_item._raw_values_flex)
log.debug(
u'Reimported item flexible attributes {0} '
u'from item {1} for {2}',
dup_item._values_flex.keys(),
dup_item._raw_values_flex.keys(),
dup_item.id,
displayable_path(item.path)
)
Expand Down

0 comments on commit 439d4c1

Please sign in to comment.