Commit bb5b83eb authored by Hanno Schlichting's avatar Hanno Schlichting

Respect the ILimitedResultIndex interface in the query plan

parent 445e294b
...@@ -521,7 +521,8 @@ class Catalog(Persistent, Acquisition.Implicit, ExtensionClass.Base): ...@@ -521,7 +521,8 @@ class Catalog(Persistent, Acquisition.Implicit, ExtensionClass.Base):
continue continue
cr.start_split(i) cr.start_split(i)
if ILimitedResultIndex.providedBy(index): limit_result = ILimitedResultIndex.providedBy(index)
if limit_result:
r = _apply_index(query, rs) r = _apply_index(query, rs)
else: else:
r = _apply_index(query) r = _apply_index(query)
...@@ -533,15 +534,15 @@ class Catalog(Persistent, Acquisition.Implicit, ExtensionClass.Base): ...@@ -533,15 +534,15 @@ class Catalog(Persistent, Acquisition.Implicit, ExtensionClass.Base):
# once we don't need to support the "return everything" case # once we don't need to support the "return everything" case
# anymore # anymore
if r is not None and not r: if r is not None and not r:
cr.stop_split(i, None) cr.stop_split(i, result=None, limit=limit_result)
return LazyCat([]) return LazyCat([])
cr.stop_split(i, r) cr.stop_split(i, result=r, limit=limit_result)
w, rs = weightedIntersection(rs, r) w, rs = weightedIntersection(rs, r)
if not rs: if not rs:
break break
else: else:
cr.stop_split(i, None) cr.stop_split(i, result=None, limit=limit_result)
if rs is None: if rs is None:
# None of the indexes found anything to do with the query # None of the indexes found anything to do with the query
......
...@@ -27,8 +27,8 @@ REFRESH_RATE = 100 ...@@ -27,8 +27,8 @@ REFRESH_RATE = 100
Duration = namedtuple('Duration', ['start', 'end']) Duration = namedtuple('Duration', ['start', 'end'])
IndexMeasurement = namedtuple('IndexMeasurement', IndexMeasurement = namedtuple('IndexMeasurement',
['name', 'duration', 'num']) ['name', 'duration', 'num', 'limit'])
Benchmark = namedtuple('Benchmark', ['num', 'duration', 'hits']) Benchmark = namedtuple('Benchmark', ['num', 'duration', 'hits', 'limit'])
RecentQuery = namedtuple('RecentQuery', ['duration', 'details']) RecentQuery = namedtuple('RecentQuery', ['duration', 'details'])
Report = namedtuple('Report', ['hits', 'duration', 'last']) Report = namedtuple('Report', ['hits', 'duration', 'last'])
...@@ -237,7 +237,7 @@ class CatalogPlan(object): ...@@ -237,7 +237,7 @@ class CatalogPlan(object):
return None return None
# sort indexes on (mean result length, mean search time) # sort indexes on (mean result length, mean search time)
ranking = [((value.num, value.duration), name) ranking = [((value.limit, value.num, value.duration), name)
for name, value in benchmark.items()] for name, value in benchmark.items()]
ranking.sort() ranking.sort()
return [r[1] for r in ranking] return [r[1] for r in ranking]
...@@ -249,7 +249,7 @@ class CatalogPlan(object): ...@@ -249,7 +249,7 @@ class CatalogPlan(object):
def start_split(self, name, result=None): def start_split(self, name, result=None):
self.interim[name] = Duration(time.time(), None) self.interim[name] = Duration(time.time(), None)
def stop_split(self, name, result=None): def stop_split(self, name, result=None, limit=False):
current = time.time() current = time.time()
start_time, stop_time = self.interim.get(name, Duration(None, None)) start_time, stop_time = self.interim.get(name, Duration(None, None))
length = 0 length = 0
...@@ -259,7 +259,7 @@ class CatalogPlan(object): ...@@ -259,7 +259,7 @@ class CatalogPlan(object):
self.interim[name] = Duration(start_time, current) self.interim[name] = Duration(start_time, current)
dt = current - start_time dt = current - start_time
self.res.append(IndexMeasurement( self.res.append(IndexMeasurement(
name=name, duration=current - start_time, num=length)) name=name, duration=dt, num=length, limit=limit))
if name == 'sort_on': if name == 'sort_on':
# sort_on isn't an index. We only do time reporting on it # sort_on isn't an index. We only do time reporting on it
...@@ -268,16 +268,17 @@ class CatalogPlan(object): ...@@ -268,16 +268,17 @@ class CatalogPlan(object):
# remember index's hits, search time and calls # remember index's hits, search time and calls
benchmark = self.benchmark benchmark = self.benchmark
if name not in benchmark: if name not in benchmark:
benchmark[name] = Benchmark(num=length, duration=dt, hits=1) benchmark[name] = Benchmark(num=length, duration=dt,
hits=1, limit=limit)
else: else:
num, duration, hits = benchmark[name] num, duration, hits, limit = benchmark[name]
num = int(((num * hits) + length) / float(hits + 1)) num = int(((num * hits) + length) / float(hits + 1))
duration = ((duration * hits) + dt) / float(hits + 1) duration = ((duration * hits) + dt) / float(hits + 1)
# reset adaption # reset adaption
if hits % REFRESH_RATE == 0: if hits % REFRESH_RATE == 0:
hits = 0 hits = 0
hits += 1 hits += 1
benchmark[name] = Benchmark(num, duration, hits) benchmark[name] = Benchmark(num, duration, hits, limit)
def stop(self): def stop(self):
self.end_time = time.time() self.end_time = time.time()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment