Commit 1014b154 authored by Casey Duncan's avatar Casey Duncan

Refactor PathIndex:

  - Exterminate bare excepts
  - Port performance fixes from 2.6 branch
  - Add some comments to questionable areas
  - Simplify where possible
  - Add some spacing for readability (hahahahahah, sorry I crack myself up)
TODO: Fix inefficient __len__ and numObjects implementations
parent 053276cf
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
############################################################################## ##############################################################################
__version__ = '$Id: PathIndex.py,v 1.33 2003/02/20 19:48:03 jeremy Exp $' __version__ = '$Id: PathIndex.py,v 1.34 2003/05/27 05:31:21 caseman Exp $'
from Products.PluginIndexes import PluggableIndex from Products.PluginIndexes import PluggableIndex
from Products.PluginIndexes.common.util import parseIndexRequest from Products.PluginIndexes.common.util import parseIndexRequest
...@@ -25,7 +25,7 @@ from BTrees.IIBTree import IITreeSet, IISet, intersection, union ...@@ -25,7 +25,7 @@ from BTrees.IIBTree import IITreeSet, IISet, intersection, union
from OFS.SimpleItem import SimpleItem from OFS.SimpleItem import SimpleItem
from zLOG import LOG, ERROR from zLOG import LOG, ERROR
from types import StringType, ListType, TupleType from types import StringType, ListType, TupleType
import re, warnings import warnings
_marker = [] _marker = []
...@@ -54,7 +54,7 @@ class PathIndex(Persistent, Implicit, SimpleItem): ...@@ -54,7 +54,7 @@ class PathIndex(Persistent, Implicit, SimpleItem):
'help': ('PathIndex','PathIndex_Settings.stx')}, 'help': ('PathIndex','PathIndex_Settings.stx')},
) )
query_options = ["query","level","operator"] query_options = ["query", "level", "operator"]
def __init__(self,id,caller=None): def __init__(self,id,caller=None):
...@@ -65,9 +65,7 @@ class PathIndex(Persistent, Implicit, SimpleItem): ...@@ -65,9 +65,7 @@ class PathIndex(Persistent, Implicit, SimpleItem):
self.useOperator = 'or' self.useOperator = 'or'
self.clear() self.clear()
def getId(self): return self.id
def clear(self): def clear(self):
""" clear everything """ """ clear everything """
...@@ -75,7 +73,7 @@ class PathIndex(Persistent, Implicit, SimpleItem): ...@@ -75,7 +73,7 @@ class PathIndex(Persistent, Implicit, SimpleItem):
self._depth = 0 self._depth = 0
self._index = OOBTree() self._index = OOBTree()
self._unindex = IOBTree() self._unindex = IOBTree()
def insertEntry(self, comp, id, level): def insertEntry(self, comp, id, level):
"""Insert an entry. """Insert an entry.
...@@ -85,10 +83,10 @@ class PathIndex(Persistent, Implicit, SimpleItem): ...@@ -85,10 +83,10 @@ class PathIndex(Persistent, Implicit, SimpleItem):
level is the level of the component inside the path level is the level of the component inside the path
""" """
if self._index.has_key(comp) == 0: if not self._index.has_key(comp):
self._index[comp] = IOBTree() self._index[comp] = IOBTree()
if self._index[comp].has_key(level) == 0: if not self._index[comp].has_key(level):
self._index[comp][level] = IITreeSet() self._index[comp][level] = IITreeSet()
self._index[comp][level].insert(id) self._index[comp][level].insert(id)
...@@ -102,43 +100,40 @@ class PathIndex(Persistent, Implicit, SimpleItem): ...@@ -102,43 +100,40 @@ class PathIndex(Persistent, Implicit, SimpleItem):
# first we check if the object provide an attribute or # first we check if the object provide an attribute or
# method to be used as hook for the PathIndex # method to be used as hook for the PathIndex
if hasattr(obj,self.id): if hasattr(obj, self.id):
f = getattr(obj,self.id) f = getattr(obj, self.id)
try: if callable(f):
if callable(f): path = f() try:
else: path = f path = f()
except: except AttributeError:
return 0 return 0
else:
if not (isinstance(path,StringType) or path = f
isinstance(path,TupleType)):
raise TypeError, "attribute/method must be/return string or tuple" if not (isinstance(path, StringType) or
isinstance(path, TupleType)):
raise TypeError('path value must be string or tuple of strings')
else: else:
try: try:
path = obj.getPhysicalPath() path = obj.getPhysicalPath()
except: except AttributeError:
return 0 return 0
if type(path) in (ListType,TupleType): if type(path) in (ListType, TupleType):
path = '/'+ '/'.join(path[1:]) path = '/'+ '/'.join(path[1:])
comps = self.splitPath(path,obj) comps = self.splitPath(path, obj)
# if obj.meta_type != 'Folder':
# comps = comps[:-1]
for i in range(len(comps)): for i in range(len(comps)):
self.insertEntry( comps[i],documentId,i) self.insertEntry(comps[i], documentId, i)
self._unindex[documentId] = path self._unindex[documentId] = path
return 1 return 1
def unindex_object(self,documentId): def unindex_object(self, documentId):
""" hook for (Z)Catalog """ """ hook for (Z)Catalog """
if not self._unindex.has_key(documentId): if not self._unindex.has_key(documentId):
...@@ -156,17 +151,16 @@ class PathIndex(Persistent, Implicit, SimpleItem): ...@@ -156,17 +151,16 @@ class PathIndex(Persistent, Implicit, SimpleItem):
try: try:
self._index[comp][level].remove(documentId) self._index[comp][level].remove(documentId)
if len(self._index[comp][level])==0: if not self._index[comp][level]:
del self._index[comp][level] del self._index[comp][level]
if len(self._index[comp])==0: if not self._index[comp]:
del self._index[comp] del self._index[comp]
except KeyError: except KeyError:
LOG(self.__class__.__name__, ERROR, LOG(self.__class__.__name__, ERROR,
'Attempt to unindex document' 'Attempt to unindex document'
' with id %s failed' % documentId) ' with id %s failed' % documentId)
del self._unindex[documentId] del self._unindex[documentId]
...@@ -180,21 +174,21 @@ class PathIndex(Persistent, Implicit, SimpleItem): ...@@ -180,21 +174,21 @@ class PathIndex(Persistent, Implicit, SimpleItem):
print print
def splitPath(self,path,obj=None): def splitPath(self, path, obj=None):
""" split physical path of object. If the object has """ split physical path of object. If the object has
as function splitPath() we use this user-defined function as function splitPath() we use this user-defined function
to split the path to split the path
""" """
if hasattr(obj,"splitPath"): if hasattr(obj, "splitPath"):
comps = obj.splitPath(path) comps = obj.splitPath(path)
else: else:
comps = filter(lambda x: x , re.split("/",path)) comps = filter(None, path.split('/'))
return comps return comps
def search(self,path,default_level=0): def search(self, path, default_level=0):
""" """
path is either a string representing a path is either a string representing a
relative URL or a part of a relative URL or relative URL or a part of a relative URL or
...@@ -259,33 +253,31 @@ class PathIndex(Persistent, Implicit, SimpleItem): ...@@ -259,33 +253,31 @@ class PathIndex(Persistent, Implicit, SimpleItem):
def __len__(self): def __len__(self):
""" len """ """ len """
# XXX REALLY inefficient
return len(self._index) return len(self._index)
def numObjects(self): def numObjects(self):
""" return the number of indexed objects""" """ return the number of indexed objects"""
# XXX REALLY inefficient
return len(self._unindex) return len(self._unindex)
def keys(self): def keys(self):
""" return list of all path components """ """ return list of all path components """
keys = [] # XXX Could this be lazy, does it need to be a list?
for k in self._index.keys(): keys.append(k) return list(self._index.keys())
return keys
def values(self): def values(self):
values = [] # XXX Could this be lazy, does it need to be a list?
for k in self._index.values(): values.append(k) return list(self._index.values())
return values
def items(self): def items(self):
""" mapping path components : documentIds """ """ mapping path components : documentIds """
# XXX Could this be lazy, does it need to be a list?
items = [] return list(self._index.items())
for k in self._index.items(): items.append(k)
return items
def _apply_index(self, request, cid=''): def _apply_index(self, request, cid=''):
...@@ -330,14 +322,11 @@ class PathIndex(Persistent, Implicit, SimpleItem): ...@@ -330,14 +322,11 @@ class PathIndex(Persistent, Implicit, SimpleItem):
def hasUniqueValuesFor(self, name): def hasUniqueValuesFor(self, name):
"""has unique values for column name""" """has unique values for column name"""
if name == self.id: return name == self.id
return 1
else:
return 0 def uniqueValues(self, name=None, withLength=0):
def uniqueValues(self,name=None,withLength=0):
""" needed to be consistent with the interface """ """ needed to be consistent with the interface """
return self._index.keys() return self._index.keys()
...@@ -346,13 +335,13 @@ class PathIndex(Persistent, Implicit, SimpleItem): ...@@ -346,13 +335,13 @@ class PathIndex(Persistent, Implicit, SimpleItem):
return ('getPhysicalPath', ) return ('getPhysicalPath', )
def getEntryForObject(self,documentId,default=_marker): def getEntryForObject(self, documentId, default=_marker):
""" Takes a document ID and returns all the information we have """ Takes a document ID and returns all the information we have
on that specific object. """ on that specific object. """
try: try:
return self._unindex[documentId] return self._unindex[documentId]
except: except KeyError:
# XXX Why is default ignored?
return None return None
......
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