Commit 60de6f12 authored by Hanno Schlichting's avatar Hanno Schlichting

Group value indexes functions into a class

parent 8b47fab8
......@@ -28,64 +28,66 @@ REPORTS = {}
PRIORITYMAP_LOCK = allocate_lock()
PRIORITYMAP = {}
VALUE_INDEXES_LOCK = allocate_lock()
VALUE_INDEXES = frozenset()
def get_value_indexes():
return VALUE_INDEXES
def set_value_indexes(value):
with VALUE_INDEXES_LOCK:
global VALUE_INDEXES
VALUE_INDEXES = value
def clear_value_indexes():
set_value_indexes(frozenset())
class ValueIndexes(object):
lock = allocate_lock()
value = frozenset()
@classmethod
def get(cls):
return cls.value
@classmethod
def set(cls, value):
with cls.lock:
cls.value = value
@classmethod
def clear(cls):
cls.set(frozenset())
@classmethod
def determine(cls, indexes):
# This function determines all indexes whose values should be respected
# in the report key. The number of unique values for the index needs to be
# lower than the MAX_DISTINCT_VALUES watermark.
# TODO: Ideally who would only consider those indexes with a small number
# of unique values, where the number of items for each value differs a
# lot. If the number of items per value is similar, the duration of a
# query is likely similar as well.
value_indexes = cls.get()
if value_indexes:
# Calculating all the value indexes is quite slow, so we do this once
# for the first query. Since this is an optimization only, slightly
# outdated results based on index changes in the running process
# can be ignored.
return value_indexes
value_indexes = set()
for name, index in indexes.items():
if IUniqueValueIndex.providedBy(index):
values = index.uniqueValues()
if values and len(list(values)) < MAX_DISTINCT_VALUES:
# Only consider indexes which actually return a number
# greater than zero
value_indexes.add(name)
cls.set(frozenset(value_indexes))
return value_indexes
from zope.testing.cleanup import addCleanUp
addCleanUp(clear_value_indexes)
addCleanUp(ValueIndexes.clear)
del addCleanUp
def determine_value_indexes(indexes):
# This function determines all indexes whose values should be respected
# in the report key. The number of unique values for the index needs to be
# lower than the MAX_DISTINCT_VALUES watermark.
# TODO: Ideally who would only consider those indexes with a small number
# of unique values, where the number of items for each value differs a
# lot. If the number of items per value is similar, the duration of a
# query is likely similar as well.
value_indexes = get_value_indexes()
if value_indexes:
# Calculating all the value indexes is quite slow, so we do this once
# for the first query. Since this is an optimization only, slightly
# outdated results based on index changes in the running process
# can be ignored.
return value_indexes
value_indexes = set()
for name, index in indexes.items():
if IUniqueValueIndex.providedBy(index):
values = index.uniqueValues()
if values and len(list(values)) < MAX_DISTINCT_VALUES:
# Only consider indexes which actually return a number
# greater than zero
value_indexes.add(name)
set_value_indexes(frozenset(value_indexes))
return value_indexes
def make_key(catalog, query):
if not query:
return None
indexes = catalog.indexes
valueindexes = determine_value_indexes(indexes)
valueindexes = ValueIndexes.determine(indexes)
key = keys = query.keys()
values = [name for name in keys if name in valueindexes]
......
......@@ -41,8 +41,8 @@ class TestCatalogPlan(unittest.TestCase):
self.zcat.catalog_object(obj, str(i))
def tearDown(self):
from Products.ZCatalog.plan import clear_value_indexes
clear_value_indexes()
from Products.ZCatalog.plan import ValueIndexes
ValueIndexes.clear()
def test_ReportLength(self):
""" tests the report aggregation """
......
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