Speed up in the search cache by avoiding construction of the set of all book ids when the cache hits

Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
Kovid Goyal 2014-11-01 19:04:39 +05:30
commit d9ac4fcfcf
2 changed files with 18 additions and 12 deletions

View File

@ -715,7 +715,7 @@ class LRUCache(object): # {{{
'A simple Least-Recently-Used cache' 'A simple Least-Recently-Used cache'
def __init__(self, limit=30): def __init__(self, limit=50):
self.item_map = {} self.item_map = {}
self.age_map = deque() self.age_map = deque()
self.limit = limit self.limit = limit
@ -854,6 +854,14 @@ class Search(object):
search is on the full library and no virtual field is searched on ''' search is on the full library and no virtual field is searched on '''
if isinstance(search_restriction, bytes): if isinstance(search_restriction, bytes):
search_restriction = search_restriction.decode('utf-8') search_restriction = search_restriction.decode('utf-8')
if isinstance(query, bytes):
query = query.decode('utf-8')
query = query.strip()
if book_ids is None and query and not search_restriction:
cached = self.cache.get(query)
if cached is not None:
return cached
restricted_ids = all_book_ids = dbcache._all_book_ids(type=set) restricted_ids = all_book_ids = dbcache._all_book_ids(type=set)
if search_restriction and search_restriction.strip(): if search_restriction and search_restriction.strip():
@ -870,14 +878,11 @@ class Search(object):
elif book_ids is not None: elif book_ids is not None:
restricted_ids = book_ids restricted_ids = book_ids
if isinstance(query, bytes): if not query:
query = query.decode('utf-8')
if not query or not query.strip():
return restricted_ids return restricted_ids
if restricted_ids is all_book_ids: if restricted_ids is all_book_ids:
cached = self.cache.get(query.strip()) cached = self.cache.get(query)
if cached is not None: if cached is not None:
return cached return cached
@ -885,7 +890,7 @@ class Search(object):
result = sqp.parse(query) result = sqp.parse(query)
if not sqp.virtual_field_used and sqp.all_book_ids is all_book_ids: if not sqp.virtual_field_used and sqp.all_book_ids is all_book_ids:
self.cache.add(query.strip(), result) self.cache.add(query, result)
return result return result

View File

@ -495,10 +495,11 @@ class ReadingTest(BaseTest):
ae = self.assertEqual ae = self.assertEqual
def test(hit, result, *args): def test(hit, result, *args, **kw):
c.cc c.cc
num = kw.get('num', 2)
ae(cache.search(*args), result) ae(cache.search(*args), result)
ae(c.counts, (1, 0) if hit else (0, 1)) ae(c.counts, (num, 0) if hit else (0, num))
c.cc c.cc
test(False, {3}, 'Unknown') test(False, {3}, 'Unknown')
@ -512,9 +513,9 @@ class ReadingTest(BaseTest):
for i in range(6): for i in range(6):
test(False, set(), 'nomatch_%s' % i) test(False, set(), 'nomatch_%s' % i)
test(False, {3}, 'Unknown') # cached search expired test(False, {3}, 'Unknown') # cached search expired
test(False, {3}, '', 'unknown') test(False, {3}, '', 'unknown', num=1)
test(True, {3}, '', 'unknown') test(True, {3}, '', 'unknown', num=1)
test(True, {3}, 'Unknown', 'unknown') test(True, {3}, 'Unknown', 'unknown', num=1)
cache._search_api.MAX_CACHE_UPDATE = 100 cache._search_api.MAX_CACHE_UPDATE = 100
test(False, {2, 3}, 'title:=xxx or title:"=Title One"') test(False, {2, 3}, 'title:=xxx or title:"=Title One"')
cache.set_field('publisher', {3:'ppppp', 2:'other'}) cache.set_field('publisher', {3:'ppppp', 2:'other'})