[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/catalog/ Optimized
reindexing.
Jürgen Kartnaller
juergen at kartnaller.at
Tue Apr 3 07:35:51 EDT 2007
Log message for revision 73989:
Optimized reindexing.
Don't use location.inside if the intid utility is located in the same site as
the catalog.
Changed:
U Zope3/trunk/src/zope/app/catalog/catalog.py
U Zope3/trunk/src/zope/app/catalog/tests.py
-=-
Modified: Zope3/trunk/src/zope/app/catalog/catalog.py
===================================================================
--- Zope3/trunk/src/zope/app/catalog/catalog.py 2007-04-03 08:40:22 UTC (rev 73988)
+++ Zope3/trunk/src/zope/app/catalog/catalog.py 2007-04-03 11:35:49 UTC (rev 73989)
@@ -72,18 +72,24 @@
"""Restricts the access to the objects that live within
the nearest site if the catalog itself is locatable.
"""
+ uidutil = None
locatable = IPhysicallyLocatable(self, None)
if locatable is not None :
- uidutil = zapi.getUtility(IIntIds, context=self)
site = locatable.getNearestSite()
- for uid in uidutil:
- obj = uidutil.getObject(uid)
- if location.inside(obj, site) :
- yield uid, obj
- else :
+ sm = site.getSiteManager()
+ uidutil = sm.queryUtility(IIntIds)
+ if uidutil not in [c.component for c in sm.registeredUtilities()]:
+ # we do not have a local inits utility
+ uidutil = zapi.getUtility(IIntIds, context=self)
+ for uid in uidutil:
+ obj = uidutil.getObject(uid)
+ if location.inside(obj, site) :
+ yield uid, obj
+ return
+ if uidutil is None:
uidutil = zapi.getUtility(IIntIds)
- for uid in uidutil:
- yield uid, uidutil.getObject(uid)
+ for uid in uidutil:
+ yield uid, uidutil.getObject(uid)
def updateIndex(self, index):
for uid, obj in self._visitSublocations() :
Modified: Zope3/trunk/src/zope/app/catalog/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/catalog/tests.py 2007-04-03 08:40:22 UTC (rev 73988)
+++ Zope3/trunk/src/zope/app/catalog/tests.py 2007-04-03 11:35:49 UTC (rev 73989)
@@ -264,8 +264,8 @@
reindexDocSubscriber(ObjectModifiedEvent(ob2))
self.assertEqual(self.cat.regs, [(1, ob)])
self.assertEqual(self.cat.unregs, [])
-
+
def test_unindexDocSubscriber(self):
from zope.app.catalog.catalog import unindexDocSubscriber
from zope.app.container.contained import ObjectRemovedEvent
@@ -288,33 +288,33 @@
class TestIndexUpdating(unittest.TestCase) :
- """Issue #466: When reindexing a catalog it takes all objects from
- the nearest IntId utility. This is a problem when IntId utility
+ """Issue #466: When reindexing a catalog it takes all objects from
+ the nearest IntId utility. This is a problem when IntId utility
lives in another site than the one.
-
+
To solve this issue we simply check whether the objects are living
within the nearest site.
"""
def setUp(self):
-
+
setup.placefulSetUp(True)
-
+
from zope.app.catalog.catalog import Catalog
from zope.app.container.contained import ContainerSublocations
-
+
self.root = setup.buildSampleFolderTree()
-
+
subfolder = self.root[u'folder1'][u'folder1_1']
root_sm = self.root_sm = setup.createSiteManager(self.root)
local_sm = self.local_sm = setup.createSiteManager(subfolder)
self.utility = setup.addUtility(root_sm, '', IIntIds, IntIdsStub())
self.cat = setup.addUtility(local_sm, '', ICatalog, Catalog())
self.cat['name'] = StubIndex('__name__', None)
-
+
for obj in self.iterAll(self.root) :
self.utility.register(obj)
-
+
def tearDown(self):
setup.placefulTearDown()
@@ -325,26 +325,43 @@
if IContainer.providedBy(value) :
for obj in self.iterAll(value) :
yield obj
-
+
def test_visitSublocations(self) :
""" Test the iterContained method which should return only the
sublocations which are registered by the IntIds.
"""
-
+
names = sorted([ob.__name__ for i, ob in self.cat._visitSublocations()])
self.assertEqual(names, [u'folder1_1', u'folder1_1_1', u'folder1_1_2'])
-
+
def test_updateIndex(self):
""" Setup a catalog deeper within the containment hierarchy
and call the updateIndexes method. The indexed objects should should
be restricted to the sublocations.
"""
-
+
self.cat.updateIndexes()
index = self.cat['name']
names = sorted([ob.__name__ for i, ob in index.doc.items()])
self.assertEqual(names, [u'folder1_1', u'folder1_1_1', u'folder1_1_2'])
+ def test_optimizedUpdateIndex(self):
+ """ Setup a catalog deeper within the containment hierarchy together
+ with its intid utility. The catalog will not visit sublocations
+ because the intid utility can not contain objects outside the site
+ where it is registered.
+ """
+ utility = setup.addUtility(self.local_sm, '', IIntIds, IntIdsStub())
+ subfolder = self.root[u'folder1'][u'folder1_1']
+ for obj in self.iterAll(subfolder) :
+ utility.register(obj)
+
+ self.cat.updateIndexes()
+ index = self.cat['name']
+ names = sorted([ob.__name__ for i, ob in index.doc.items()])
+ self.assertEqual(names, [u'folder1_1_1', u'folder1_1_2'])
+
+
class TestCatalogBugs(placelesssetup.PlacelessSetup, unittest.TestCase):
"""I found that z.a.catalog, AttributeIndex failed to remove the previous
value/object from the index IF the NEW value is None.
@@ -353,50 +370,50 @@
def test_updateIndexWithNone(self):
uidutil = IntIdsStub()
ztapi.provideUtility(IIntIds, uidutil)
-
+
catalog = Catalog()
index = FieldIndex('author', None)
catalog['author'] = index
-
+
ob1 = stoopid(author = "joe")
ob1id = uidutil.register(ob1)
catalog.index_doc(ob1id, ob1)
-
+
res = catalog.searchResults(author=('joe','joe'))
names = [x.author for x in res]
names.sort()
self.assertEqual(len(names), 1)
self.assertEqual(names, ['joe'])
-
+
ob1.author = None
catalog.index_doc(ob1id, ob1)
-
+
#the index must be empty now because None values are never indexed
res = catalog.searchResults(author=(None, None))
self.assertEqual(len(res), 0)
-
+
def test_updateIndexFromCallableWithNone(self):
uidutil = IntIdsStub()
ztapi.provideUtility(IIntIds, uidutil)
-
+
catalog = Catalog()
index = FieldIndex('getAuthor', None, field_callable=True)
catalog['author'] = index
-
+
ob1 = stoopidCallable(author = "joe")
-
+
ob1id = uidutil.register(ob1)
catalog.index_doc(ob1id, ob1)
-
+
res = catalog.searchResults(author=('joe','joe'))
names = [x.author for x in res]
names.sort()
self.assertEqual(len(names), 1)
self.assertEqual(names, ['joe'])
-
+
ob1.author = None
catalog.index_doc(ob1id, ob1)
-
+
#the index must be empty now because None values are never indexed
res = catalog.searchResults(author=(None, None))
self.assertEqual(len(res), 0)
@@ -405,7 +422,7 @@
def __init__(self, **kw):
#leave the door open to not to set self.author
self.__dict__.update(kw)
-
+
def getAuthor(self):
return self.author
@@ -418,21 +435,21 @@
That would cause index corruption -- the index would be out of sync"""
uidutil = IntIdsStub()
ztapi.provideUtility(IIntIds, uidutil)
-
+
catalog = Catalog()
index = FieldIndex('getAuthor', None, field_callable=True)
catalog['author'] = index
-
+
ob1 = stoopidCallable(author = "joe")
ob1id = uidutil.register(ob1)
catalog.index_doc(ob1id, ob1)
-
+
res = catalog.searchResults(author=('joe','joe'))
names = [x.author for x in res]
names.sort()
self.assertEqual(len(names), 1)
self.assertEqual(names, ['joe'])
-
+
ob2 = stoopidCallable() # no author here, will raise AttributeError
ob2id = uidutil.register(ob2)
try:
@@ -441,8 +458,8 @@
except AttributeError:
#this is OK, we WANT to have the exception
pass
-
+
def test_suite():
from zope.testing import doctest
suite = unittest.TestSuite()
More information about the Zope3-Checkins
mailing list