[Zope-Checkins] CVS: Zope3/lib/python/Zope/ObjectHub - ObjectHub.py:1.1.2.2

Steve Alexander steve@cat-box.net
Fri, 22 Feb 2002 15:36:47 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/ObjectHub
In directory cvs.zope.org:/tmp/cvs-serv14496

Modified Files:
      Tag: Zope-3x-branch
	ObjectHub.py 
Log Message:
Replaced noddy uid generation with better uid generation
Replaced mickey mouse dictionary implementation with better BTrees implementation


=== Zope3/lib/python/Zope/ObjectHub/ObjectHub.py 1.1.2.1 => 1.1.2.2 ===
 from Zope.Exceptions import NotFoundError
 from Persistence import Persistent
-
 from Interface import objectImplements
-
 from types import StringTypes
+from Persistence.BTrees.IOBTree import IOBTree
+from Persistence.BTrees.OIBTree import OIBTree
+
+# Code taken from PluginIndexes/common/randid.py
+import whrandom
+def randid(randint=whrandom.randint, choice=whrandom.choice, signs=(-1,1)):
+    return choice(signs)*randint(1,2000000000)
+del whrandom
 
 class ObjectHubError(Exception): pass
 
@@ -35,8 +41,8 @@
     __implements__ =  IObjectHub
 
     def __init__(self):
-        self.__lookup={}
-        self.__uid=0
+        self.__ruid_to_location=IOBTree()
+        self.__location_to_ruid=OIBTree()
         
 
     ############################################################
@@ -69,25 +75,28 @@
     def lookupRuid(self, location):
         '''See interface IObjectHub'''
         try:
-            return self.__lookup[self._canonical(location)]
+            return self.__location_to_ruid[self._canonical(location)]
         except KeyError:
             raise NotFoundError, self._canonical(location)
     
     def lookupLocation(self, ruid):
         '''See interface IObjectHub'''
         try:
-            return self.__lookup[ruid]
+            return self.__ruid_to_location[ruid]
         except KeyError:
             raise NotFoundError, ruid
         
     #
     ############################################################
 
-    def _generateRuid(self):
-        # XXX: bad default implementation. Change me!
-        self.__uid += 1
-        self._p_changed = 1
-        return self.__uid
+    def _generateRuid(self, location):
+        index=getattr(self, '_v_nextid', 0)
+        if index%4000 == 0: index = randid()
+        ruid_to_location=self.__ruid_to_location
+        while not ruid_to_location.insert(index, location):
+            index=randid()
+        self._v_nextid=index+1
+        return index
 
     def _canonical(location):
         if not isinstance(location, StringTypes):
@@ -98,47 +107,50 @@
     _canonical=staticmethod(_canonical)
 
     def _objectAdded(self, location):
-        ruid = self._generateRuid()
         canonical_location = self._canonical(location)
-        lookup = self.__lookup
-        if lookup.has_key(canonical_location):
+        
+        location_to_ruid = self.__location_to_ruid
+        
+        if location_to_ruid.has_key(canonical_location):
             raise ObjectHubError, 'location %s already in object hub' % \
                 canonical_location
-        lookup[canonical_location] = ruid
-        lookup[ruid] = canonical_location
-        self._p_changed = 1
+        ruid = self._generateRuid(canonical_location)
+        location_to_ruid[canonical_location] = ruid
     
     def _objectModified(self, location):
         pass
         
     
     def _objectMoved(self, old_location, new_location):
-        lookup = self.__lookup
+        location_to_ruid = self.__location_to_ruid
         canonical_location = self._canonical(old_location)
         canonical_new_location = self._canonical(new_location)
-        if lookup.has_key(canonical_new_location):
+        if location_to_ruid.has_key(canonical_new_location):
             raise ObjectHubError, \
                 'Cannot move to location %s, '\
                 'as there is already something there' % canonical_new_location
-        if not lookup.has_key(canonical_location):
+        if not location_to_ruid.has_key(canonical_location):
             # we're not interested in this event
             return
 
-        ruid = lookup[canonical_location]
-        del lookup[canonical_location]
-        lookup[canonical_new_location]=ruid
-        lookup[ruid]=canonical_new_location
-        self._p_changed = 1
+        ruid = location_to_ruid[canonical_location]
+        del location_to_ruid[canonical_location]
+        location_to_ruid[canonical_new_location] = ruid
+        self.__ruid_to_location[ruid] = canonical_new_location
             
     
     def _objectRemoved(self, location):
-        lookup = self.__lookup
+        location_to_ruid = self.__location_to_ruid
+        ruid_to_location = self.__ruid_to_location
         canonical_location = self._canonical(location)
         try:
-            ruid = lookup[canonical_location]
-            del lookup[ruid]
-            del lookup[canonical_location]
-            self._p_changed = 1
+            ruid = location_to_ruid[canonical_location]
         except KeyError:
-            pass
+            # we don't know about this location, so we
+            # can ignore this event
+            return
             
+        del ruid_to_location[ruid]
+        del location_to_ruid[canonical_location]
+            
+