[Zope-CVS] CVS: Products/QueueCatalog - CatalogEventQueueSet.py:1.1
Tres Seaver
tseaver@zope.com
Wed, 4 Jun 2003 11:15:22 -0400
Update of /cvs-repository/Products/QueueCatalog
In directory cvs.zope.org:/tmp/cvs-serv22439
Added Files:
CatalogEventQueueSet.py
Log Message:
- Add a new object, CatalogEventQueueSet, which manages a hashtable
of CatalogEventQueues, and delegates update events to them. It
holds a pointer to a "delegate", which it calls to do the actual
work during its 'process'.
=== Added File Products/QueueCatalog/CatalogEventQueueSet.py ===
""" Classes: CatalogEventQueueSet
$Id: CatalogEventQueueSet.py,v 1.1 2003/06/04 15:15:21 tseaver Exp $
"""
from __future__ import generators
from Interface import Interface
from Persistence import Persistent
from Products.QueueCatalog.CatalogEventQueue import CatalogEventQueue
from Products.QueueCatalog.CatalogEventQueue import EVENT_TYPES
from Products.QueueCatalog.CatalogEventQueue import ADDED_EVENTS
from Products.QueueCatalog.CatalogEventQueue import ADDED
from Products.QueueCatalog.CatalogEventQueue import CHANGED
from Products.QueueCatalog.CatalogEventQueue import CHANGED_ADDED
from Products.QueueCatalog.CatalogEventQueue import REMOVED
class ICatalogEventQueueSetDelegate( Interface ):
""" Interface for the "store" underlying a CEQS.
"""
def hasUID( uid ):
""" Do we already have UID?
"""
def add( uid ):
""" Add UID to the store.
o Delegate is responsible for finding object using UID.
"""
def change( uid ):
""" Update UID within the store.
o Delegate is responsible for finding object using UID.
"""
def remove( uid ):
""" Remove UID from the store.
"""
class CatalogEventQueueSet( Persistent ):
""" Manage a set of CatalogEventQueue objects.
"""
def __init__( self
, delegate=None
, bucket_count=1009
):
self.setDelegate( delegate )
self.setBucketCount( bucket_count )
#
# Accessors
#
def getDelegate( self ):
""" Return the callback object used to process events.
"""
return self._delegate
def getBucketCount( self ):
""" How many buckets in our hashtable?
"""
return self._bucket_count
def listEvents( self ):
""" Return all events we currently know about.
o Each item in the returned sequence is a tuple, ( uid, event ).
o This function is a generator.
o This function does *not* drain the queues.
"""
for queue in filter( None, self._queues ):
for item in queue._data.items():
uid, ( t, event ) = item
yield uid, event
#
# Mutators
#
def setDelegate( self, delegate ):
""" Update our delegate.
o If not None, 'delegate' must implement ICatalogEventQueueSetDelegate,
else raise ValueError.
"""
if ( delegate is not None
and not ICatalogEventQueueSetDelegate.isImplementedBy( delegate )
):
raise ValueError, "'delegate' doesn't implement ICEQSD!"
self._delegate = delegate
def setBucketCount( self, bucket_count ):
""" Resize the hashtable.
o 'bucket_count' must be a positive, prime integer, else raise
ValueError.
o N.B.: If successful, we destroy any existing queues!
"""
if ( type( bucket_count ) is not type( 0 )
or bucket_count < 3
or not _isPrime( bucket_count )
):
raise ValueError, 'bucket_count must be a positive, prime int!'
self._bucket_count = bucket_count
self._clear()
def update( self, uid, event ):
""" Add an event to our queue.
o 'event' must be one of the EVENT_TYPES.
"""
if event not in EVENT_TYPES:
raise ValueError, 'Not a known event: %s' % event
self._queues[ hash( uid ) % self._bucket_count ].update( uid, event )
def process( self ):
""" Process events in the queues.
"""
for queue in filter( None, self._queues ):
for item in queue.process().items():
if not self._delegate:
continue
uid, ( t, event ) = item
if event == ADDED or event == CHANGED_ADDED:
self._delegate.add( uid )
elif event == CHANGED:
self._delegate.change( uid )
elif event == REMOVED:
self._delegate.remove( uid )
#
# Helper methods
#
def _clear( self ):
self._queues = [ CatalogEventQueue()
for i in range( self._bucket_count ) ]
def _isPrime( x ):
""" isPrime(int x) --> boolean
isPrime(x) checks if a given number x is prime. It follows the following
decision tree:
if x is 1 it is a special case (ie: not prime),
if x is either 2 or 3, it is prime,
if x is even, it is not prime.
if x is not one of these obvious cases:
check if x is divisible by the numbers in the range from 3 to
floor(sqrt(x)).
From: http://jijo.free.net.ph/programming/python/code/prime.py
"""
if (x == 1): # Special case, neither prime nor composite
return None
elif ((x == 2) or (x == 3)):
return x
elif ((x % 2) == 0):
return None
else:
flag = 0
i = 3
while 1:
if (x % i) == 0:
return 0
elif (i * i) > x:
return 1
i += 2