Added dirty bit cache

This commit is contained in:
Charles Haley 2010-09-24 19:41:43 +01:00
parent 47ff1ddc42
commit cf6f251b74
2 changed files with 31 additions and 1 deletions

View File

@ -533,6 +533,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
# Save the current field_metadata for applications like calibre2opds # Save the current field_metadata for applications like calibre2opds
# Goes here, because if cf is valid, db is valid. # Goes here, because if cf is valid, db is valid.
db.prefs['field_metadata'] = db.field_metadata.all_metadata() db.prefs['field_metadata'] = db.field_metadata.all_metadata()
db.commit_dirty_cache()
if DEBUG and db.gm_count > 0: if DEBUG and db.gm_count > 0:
print 'get_metadata cache: {0:d} calls, {1:4.2f}% misses'.format( print 'get_metadata cache: {0:d} calls, {1:4.2f}% misses'.format(
db.gm_count, (db.gm_missed*100.0)/db.gm_count) db.gm_count, (db.gm_missed*100.0)/db.gm_count)

View File

@ -340,6 +340,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
setattr(self, 'title_sort', functools.partial(self.get_property, setattr(self, 'title_sort', functools.partial(self.get_property,
loc=self.FIELD_MAP['sort'])) loc=self.FIELD_MAP['sort']))
self.dirtied_cache = set()
d = self.conn.get('SELECT book FROM metadata_dirtied', all=True) d = self.conn.get('SELECT book FROM metadata_dirtied', all=True)
for x in d: for x in d:
self.dirtied_queue.put(x[0]) self.dirtied_queue.put(x[0])
@ -585,12 +586,20 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if remove_from_dirtied: if remove_from_dirtied:
self.conn.execute('DELETE FROM metadata_dirtied WHERE book=?', self.conn.execute('DELETE FROM metadata_dirtied WHERE book=?',
(book_id,)) (book_id,))
# if a later exception prevents the commit, then the dirtied
# table will still have the book. No big deal, because the OPF
# is there and correct. We will simply do it again on next
# start
self.dirtied_cache.discard(book_id)
if commit: if commit:
self.conn.commit() self.conn.commit()
return True return True
def dirtied(self, book_ids, commit=True): def dirtied(self, book_ids, commit=True):
for book in book_ids: for book in book_ids:
if book in self.dirtied_cache:
print 'in dirty cache', book
continue
try: try:
self.conn.execute( self.conn.execute(
'INSERT INTO metadata_dirtied (book) VALUES (?)', 'INSERT INTO metadata_dirtied (book) VALUES (?)',
@ -598,10 +607,30 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.dirtied_queue.put(book) self.dirtied_queue.put(book)
except IntegrityError: except IntegrityError:
# Already in table # Already in table
continue pass
# If the commit doesn't happen, then our cache will be wrong. This
# could lead to a problem because we won't put the book back into
# the dirtied table. We deal with this by writing the dirty cache
# back to the table on GUI exit. Not perfect, but probably OK
self.dirtied_cache.add(book)
print 'added book', book
if commit: if commit:
self.conn.commit() self.conn.commit()
def commit_dirty_cache(self):
'''
Set the dirty indication for every book in the cache. The vast majority
of the time, the indication will already be set. However, sometimes
exceptions may have prevented a commit, which may remove some dirty
indications from the DB. This call will put them back. Note that there
is no problem with setting a dirty indication for a book that isn't in
fact dirty. Just wastes a few cycles.
'''
print 'commit cache'
book_ids = list(self.dirtied_cache)
self.dirtied_cache = set()
self.dirtied(book_ids)
def get_metadata(self, idx, index_is_id=False, get_cover=False): def get_metadata(self, idx, index_is_id=False, get_cover=False):
''' '''
Convenience method to return metadata as a :class:`Metadata` object. Convenience method to return metadata as a :class:`Metadata` object.