[Zope-Checkins] CVS: Zope/lib/python/Products/PluginIndexes/TopicIndex - FilteredSet.py:1.1.2.2 TopicIndex.py:1.1.2.2

Andreas Jung andreas@zope.com
Mon, 15 Oct 2001 15:50:30 -0400


Update of /cvs-repository/Zope/lib/python/Products/PluginIndexes/TopicIndex
In directory cvs.zope.org:/tmp/cvs-serv4131

Modified Files:
      Tag: ajung-topicindex
	FilteredSet.py TopicIndex.py 
Log Message:
first working prototype


=== Zope/lib/python/Products/PluginIndexes/TopicIndex/FilteredSet.py 1.1.2.1 => 1.1.2.2 ===
+# 
+# Zope Public License (ZPL) Version 1.0
+# -------------------------------------
+# 
+# Copyright (c) Digital Creations.  All rights reserved.
+# 
+# This license has been certified as Open Source(tm).
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+# 
+# 1. Redistributions in source code must retain the above copyright
+#    notice, this list of conditions, and the following disclaimer.
+# 
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions, and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+# 
+# 3. Digital Creations requests that attribution be given to Zope
+#    in any manner possible. Zope includes a "Powered by Zope"
+#    button that is installed by default. While it is not a license
+#    violation to remove this button, it is requested that the
+#    attribution remain. A significant investment has been put
+#    into Zope, and this effort will continue if the Zope community
+#    continues to grow. This is one way to assure that growth.
+# 
+# 4. All advertising materials and documentation mentioning
+#    features derived from or use of this software must display
+#    the following acknowledgement:
+# 
+#      "This product includes software developed by Digital Creations
+#      for use in the Z Object Publishing Environment
+#      (http://www.zope.org/)."
+# 
+#    In the event that the product being advertised includes an
+#    intact Zope distribution (with copyright and license included)
+#    then this clause is waived.
+# 
+# 5. Names associated with Zope or Digital Creations must not be used to
+#    endorse or promote products derived from this software without
+#    prior written permission from Digital Creations.
+# 
+# 6. Modified redistributions of any form whatsoever must retain
+#    the following acknowledgment:
+# 
+#      "This product includes software developed by Digital Creations
+#      for use in the Z Object Publishing Environment
+#      (http://www.zope.org/)."
+# 
+#    Intact (re-)distributions of any official Zope release do not
+#    require an external acknowledgement.
+# 
+# 7. Modifications are encouraged but must be packaged separately as
+#    patches to official Zope releases.  Distributions that do not
+#    clearly separate the patches from the original work must be clearly
+#    labeled as unofficial distributions.  Modifications which do not
+#    carry the name Zope may be packaged in any form, as long as they
+#    conform to all of the clauses above.
+# 
+# 
+# Disclaimer
+# 
+#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
+#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
+#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+#   SUCH DAMAGE.
+# 
+# 
+# This software consists of contributions made by Digital Creations and
+# many individuals on behalf of Digital Creations.  Specific
+# attributions are listed in the accompanying credits file.
+# 
+##############################################################################
+
+__version__ = '$Id$'
+
+
 from BTrees.IIBTree import IISet
+from Persistence import Persistent
 
 
-class FilteredSet:
+class FilteredSet(Persistent):
 
     def __init__(self, id, expr):
+
         self.id   = id
         self.expr = expr
         self.ids  = IISet()
@@ -16,9 +106,10 @@
         if res:
             self.ids.insert(documentId)
 
-
-    def Ids(self):
-        return self.ids
+    def getId(self):            return self.id
+    def getExpression(self):    return self.expr
+    def getIds(self):           return self.ids
+    def Ids(self):              return self.getIds()
     
     def __repr__(self):
         return '%s: (%s) %s' % (self.id,self.expr,map(None,self.ids))


=== Zope/lib/python/Products/PluginIndexes/TopicIndex/TopicIndex.py 1.1.2.1 => 1.1.2.2 ===
 from OFS.SimpleItem import SimpleItem
 from FilteredSet import FilteredSet
+from BTrees.OOBTree import OOBTree,OOSet
 from BTrees.IIBTree import IISet,difference,intersection,union
 from types import StringType, ListType, TupleType
 import re,warnings
@@ -101,18 +102,10 @@
 
 class TopicIndex(PluggableIndex.PluggableIndex, Persistent,
     Implicit, SimpleItem):
-    """ A path index stores all path components of the physical 
-    path of an object: 
-
-    Internal datastructure:
-
-    - a physical path of an object is split into its components
-  
-    - every component is kept as a  key of a OOBTree in self._indexes
-
-    - the value is a mapping 'level of the path component' to
-      'all documentIds with this path component on this level'
-  
+    """ A TopicIndex maintains a set of FilteredSet objects.
+    Every FilteredSet object consists of an expression and 
+    and IISet with all Ids of indexed objects that eval with
+    this expression to 1.
     """
 
     __implements__ = (PluggableIndex.PluggableIndexInterface,)
@@ -123,26 +116,29 @@
         {'label': 'Settings',     
          'action': 'manage_main',
          'help': ('TopicIndex','TopicIndex_Settings.stx')},
+        {'label': 'FilteredSets',     
+         'action': 'addFilteredSetForm',
+         'help': ('TopicIndex','TopicIndex_Settings.stx')},
     )
 
-    query_options = ['query','operator']
+    addFilteredSetForm = DTMLFile('dtml/addFilteredSet',globals())
 
+    query_options = ['query','operator']
 
     def __init__(self,id,caller=None):
         self.id = id
-        self.filteredSets = {}
+        self.filteredSets = OOBTree()
+        self.uncatalogedIds = OOSet()
 
         # experimental code for specifing the operator
         self.operators = ['or','and'] 
         self.useOperator = 'or'
 
-        self.clear()
-
 
     def clear(self):
         """ clear everything """
 
-        self.filteredSets = {}
+        self.filteredSets = OOBTree()
 
             
 
@@ -157,45 +153,24 @@
 
     def unindex_object(self,documentId):
         """ hook for (Z)Catalog """
-
+        self.uncatalogedIds.insert(documentId)
         return 1
 
 
     def __len__(self):
         """ len """
-        return len(self._index)
-
-
-    def numObjects(self):
-        """ return the number of indexed objects"""
-
-        x = IISet()
-        for k,v in self._index.items():
-            for level,ids in v.items():
-                x = union(x,ids)
+        n=0
+        for fs in self.filteredSets.values():
+            n = n + len(fs.getIds())
+        return n
 
-        return len(x)
 
+    numObject = __len__
 
-    def keys(self):   
-        """ return list of all path components """
-        keys = []
-        for k in self._index.keys(): keys.append(k)
-        return keys
 
-
-    def values(self):   
-        values = []
-        for k in self._index.values(): values.append(k)
-        return values
-
-
-    def items(self):   
-        """ mapping path components : documentIds """
-
-        items = []
-        for k in self._index.items(): items.append(k)
-        return items
+    def keys(self):   pass
+    def values(self): pass  
+    def items(self):  pass   
 
 
     def search(self,filterId):
@@ -206,10 +181,7 @@
 
     def _apply_index(self, request, cid=''): 
         """ hook for (Z)Catalog
-        request   mapping type (usually {"path": "..." }
-                  additionaly a parameter "path_level" might be passed
-                  to specify the level (see search())
-
+        request   mapping type (usually {"topic": "..." }
         cid      ???
         """
 
@@ -252,26 +224,44 @@
 
         if self.filteredSets.has_key(filterId):
             raise KeyError,\
-                'A filter with this name already exists: %s' % filterId        
+                'A FilteredSet with this name already exists: %s' % filterId        
 
         self.filteredSets[filterId] = FilteredSet(filterId, expr)
 
 
+    def delFilteredSet(self,filterId):
+        
+        if not self.filteredSets.has_key(filterId):
+            raise KeyError,\
+                'no such FilteredSet:  %s' % filterId        
+
+        del self.filteredSets[filterId]
+
 
-    def manage_addFilterSet(self, filterId, expr, REQUEST):
-        """ add a new filter set """
+    def manage_addFilteredSet(self, filterId, expr, URL1, \
+            REQUEST=None,RESPONSE=None):
+        """ add a new filtered set """
 
         self.addFilteredSet(filterId, expr)
 
-    def manage_delFilterSet(self, filterId):
-        """ add a new filter set """
+        if RESPONSE:
+            RESPONSE.redirect(URL1+'/addFilteredSetForm?manage_tabs_message=FilteredSet%20added')
+
+
+    def manage_delFilteredSet(self, filterIds, URL1, \
+            REQUEST=None,RESPONSE=None):
+        """ delete a list of FilteredSets"""
 
-        self.delFilterSet(filterId)
+        for filterId in filterIds:
+            self.delFilteredSet(filterId)
 
+        if RESPONSE:
+            RESPONSE.redirect(URL1+'/addFilteredSetForm?manage_tabs_message=FilteredSet(s)%20deleted')
 
 
     index_html = DTMLFile('dtml/index', globals())
     manage_workspace = DTMLFile('dtml/manageTopicIndex', globals())
+    manage_main = DTMLFile('dtml/manageTopicIndex', globals())
 
 
 manage_addTopicIndexForm = DTMLFile('dtml/addTopicIndex', globals())