Commit 0dc031aa authored by Hanno Schlichting's avatar Hanno Schlichting

Encapsulate Reports data

parent 80565a30
...@@ -22,10 +22,19 @@ from Products.PluginIndexes.interfaces import IUniqueValueIndex ...@@ -22,10 +22,19 @@ from Products.PluginIndexes.interfaces import IUniqueValueIndex
MAX_DISTINCT_VALUES = 10 MAX_DISTINCT_VALUES = 10
REFRESH_RATE = 100 REFRESH_RATE = 100
REPORTS_LOCK = allocate_lock() Duration = namedtuple('Duration', ['start', 'end'])
REPORTS = {} IndexMeasurement = namedtuple('IndexMeasurement',
['name', 'duration', 'num'])
Benchmark = namedtuple('Benchmark', ['num', 'duration', 'hits'])
RecentQuery = namedtuple('RecentQuery', ['duration', 'details'])
Report = namedtuple('Report', ['hits', 'duration', 'last'])
class PriorityMap(object):
"""This holds a query key to Benchmark mapping."""
class ThreadDict(object): lock = allocate_lock()
value = {}
@classmethod @classmethod
def get(cls, key): def get(cls, key):
...@@ -37,13 +46,53 @@ class ThreadDict(object): ...@@ -37,13 +46,53 @@ class ThreadDict(object):
cls.value[key] = value cls.value[key] = value
class PriorityMap(ThreadDict): class Reports(object):
"""This holds a structure of nested dicts.
The outer dict is a mapping of catalog id to reports. The inner dict holds
a query key to Report mapping.
"""
lock = allocate_lock() lock = allocate_lock()
value = {} value = {}
@classmethod
def get(cls, key):
outer = cls.value.get(key, None)
if outer is None:
cls.set(key, {})
outer = cls.value[key]
return outer
@classmethod
def set(cls, key, value):
with cls.lock:
cls.value[key] = value
@classmethod
def clear(cls, key):
cls.set(key, {})
@classmethod
def get_entry(cls, key, key2):
outer = cls.get(key)
inner = outer.get(key2, None)
if inner is None:
cls.set_entry(key, key2, {})
inner = outer.get(key2)
return inner
@classmethod
def set_entry(cls, key, key2, value):
outer = cls.get(key)
with cls.lock:
outer[key2] = value
class ValueIndexes(object): class ValueIndexes(object):
"""Holds a set of index names considered to have an uneven value
distribution.
"""
lock = allocate_lock() lock = allocate_lock()
value = frozenset() value = frozenset()
...@@ -125,14 +174,6 @@ def make_key(catalog, query): ...@@ -125,14 +174,6 @@ def make_key(catalog, query):
return key return key
Duration = namedtuple('Duration', ['start', 'end'])
IndexMeasurement = namedtuple('IndexMeasurement',
['name', 'duration', 'num'])
Benchmark = namedtuple('Benchmark', ['num', 'duration', 'hits'])
RecentQuery = namedtuple('RecentQuery', ['duration', 'details'])
Report = namedtuple('Report', ['hits', 'duration', 'last'])
class CatalogPlan(object): class CatalogPlan(object):
"""Catalog plan class to measure and identify catalog queries and plan """Catalog plan class to measure and identify catalog queries and plan
their execution. their execution.
...@@ -222,28 +263,23 @@ class CatalogPlan(object): ...@@ -222,28 +263,23 @@ class CatalogPlan(object):
key = self.key key = self.key
recent = RecentQuery(duration=total, details=self.res) recent = RecentQuery(duration=total, details=self.res)
with REPORTS_LOCK: previous = Reports.get_entry(self.cid, key)
if self.cid not in REPORTS: if previous:
REPORTS[self.cid] = {} counter, mean, last = previous
mean = (mean * counter + total) / float(counter + 1)
previous = REPORTS[self.cid].get(key) Reports.set_entry(self.cid, key, Report(counter + 1, mean, recent))
if previous: else:
counter, mean, last = previous Reports.set_entry(self.cid, key, Report(1, total, recent))
mean = (mean * counter + total) / float(counter + 1)
REPORTS[self.cid][key] = Report(counter + 1, mean, recent)
else:
REPORTS[self.cid][key] = Report(1, total, recent)
def reset(self): def reset(self):
with REPORTS_LOCK: Reports.clear(self.cid)
REPORTS[self.cid] = {}
def report(self): def report(self):
"""Returns a statistic report of catalog queries as list of dicts. """Returns a statistic report of catalog queries as list of dicts.
The duration is provided in millisecond. The duration is provided in millisecond.
""" """
rval = [] rval = []
for key, report in REPORTS.get(self.cid, {}).items(): for key, report in Reports.get(self.cid).items():
last = report.last last = report.last
info = { info = {
'query': key, 'query': key,
......
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