[Zope-Checkins] SVN: Zope/branches/andig-catalog-report/src/Products/ZCatalog/ Store the value_indexes result in a module global. It is too expensive to calculate for each query

Hanno Schlichting hannosch at hannosch.eu
Sat Jul 24 13:34:37 EDT 2010


Log message for revision 115038:
  Store the value_indexes result in a module global. It is too expensive to calculate for each query
  

Changed:
  U   Zope/branches/andig-catalog-report/src/Products/ZCatalog/CatalogReport.py
  U   Zope/branches/andig-catalog-report/src/Products/ZCatalog/tests/testCatalog.py

-=-
Modified: Zope/branches/andig-catalog-report/src/Products/ZCatalog/CatalogReport.py
===================================================================
--- Zope/branches/andig-catalog-report/src/Products/ZCatalog/CatalogReport.py	2010-07-24 17:18:18 UTC (rev 115037)
+++ Zope/branches/andig-catalog-report/src/Products/ZCatalog/CatalogReport.py	2010-07-24 17:34:36 UTC (rev 115038)
@@ -18,9 +18,12 @@
 from Acquisition import aq_parent
 from Products.PluginIndexes.interfaces import IUniqueValueIndex
 
-reportlock = allocate_lock()
+reports_lock = allocate_lock()
 reports = {}
 
+value_indexes_lock = allocate_lock()
+value_indexes = frozenset()
+
 MAX_DISTINCT_VALUES = 10
 
 
@@ -33,17 +36,45 @@
     # 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.
-    valueindexes = []
+    global 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
+
+    new_value_indexes = set()
     for name, index in catalog.indexes.items():
         if IUniqueValueIndex.providedBy(index):
             values = index.uniqueValues()
             if values and len(values) < MAX_DISTINCT_VALUES:
                 # Only consider indexes which actually return a number
                 # greater than zero
-                valueindexes.append(name)
-    return frozenset(valueindexes)
+                new_value_indexes.add(name)
+    try:
+        value_indexes_lock.acquire()
+        value_indexes = frozenset(new_value_indexes)
+    finally:
+        value_indexes_lock.release()
 
+    return value_indexes
 
+
+def clear_value_indexes():
+    global value_indexes
+    try:
+        value_indexes_lock.acquire()
+        value_indexes = frozenset()
+    finally:
+        value_indexes_lock.release()
+
+
+from zope.testing.cleanup import addCleanUp
+addCleanUp(clear_value_indexes)
+del addCleanUp
+
+
 def make_key(catalog, request):
     valueindexes = determine_value_indexes(catalog)
 
@@ -142,7 +173,7 @@
         if res[0] < self.threshold:
             return
 
-        reportlock.acquire()
+        reports_lock.acquire()
         try:
             if self.cid not in reports:
                 reports[self.cid] = {}
@@ -156,14 +187,14 @@
                 reports[self.cid][key] = (1, res[0], res)
 
         finally:
-            reportlock.release()
+            reports_lock.release()
 
     def reset(self):
-        reportlock.acquire()
+        reports_lock.acquire()
         try:
             reports[self.cid] = {}
         finally:
-            reportlock.release()
+            reports_lock.release()
 
     def report(self):
         """Returns a statistic report of catalog queries as list of dicts as

Modified: Zope/branches/andig-catalog-report/src/Products/ZCatalog/tests/testCatalog.py
===================================================================
--- Zope/branches/andig-catalog-report/src/Products/ZCatalog/tests/testCatalog.py	2010-07-24 17:18:18 UTC (rev 115037)
+++ Zope/branches/andig-catalog-report/src/Products/ZCatalog/tests/testCatalog.py	2010-07-24 17:34:36 UTC (rev 115038)
@@ -855,9 +855,9 @@
         self.assertEqual(brain._unrestrictedGetObject(), None)
 
 
+class TestCatalogReport(unittest.TestCase):
 
-class TestCatalogReport(unittest.TestCase):
-     def setUp(self):
+    def setUp(self):
         from Products.ZCatalog.ZCatalog import ZCatalog
         vocabulary = Vocabulary.Vocabulary(
             'Vocabulary','Vocabulary', globbing=1)
@@ -875,7 +875,11 @@
             obj.big = i > 5
             self.zcat.catalog_object(obj, str(i))
 
-     def test_ReportLength(self):
+    def tearDown(self):
+        from Products.ZCatalog.CatalogReport import clear_value_indexes
+        clear_value_indexes()
+
+    def test_ReportLength(self):
          """ tests the report aggregation """
          
          self.zcat.manage_resetCatalogReport()
@@ -894,7 +898,7 @@
 
 
          self.assertEqual(4, len(self.zcat.getCatalogReport()))
-         
+
      def test_ReportCounter(self):
          """ tests the counter of equal queries """
 



More information about the Zope-Checkins mailing list