Commit e502e223 authored by Tim Peters's avatar Tim Peters

Give WeakSet a direct map() implementation.

This spares clients from having to do it themselves repeatedly.
A dubious consequences is that Transaction.__init__ now requires a
WeakSet of synchronizer objects (or None -- so it's not a
catastrophic requirement, just irksome).
parent 1e730a8c
...@@ -132,10 +132,7 @@ class _ConnectionPool(object): ...@@ -132,10 +132,7 @@ class _ConnectionPool(object):
# For every live connection c, invoke f(c). # For every live connection c, invoke f(c).
def map(self, f): def map(self, f):
for wr in self.all.as_weakref_list(): self.all.map(f)
c = wr()
if c is not None:
f(c)
class DB(object): class DB(object):
"""The Object Database """The Object Database
......
...@@ -221,6 +221,14 @@ class WeakSet(object): ...@@ -221,6 +221,14 @@ class WeakSet(object):
def remove(self, obj): def remove(self, obj):
del self.data[id(obj)] del self.data[id(obj)]
# f is a one-argument function. Execute f(elt) for each elt in the
# set. f's return value is ignored.
def map(self, f):
for wr in self.as_weakref_list():
elt = wr()
if elt is not None:
f(elt)
# Return a list of weakrefs to all the objects in the collection. # Return a list of weakrefs to all the objects in the collection.
# Because a weak dict is used internally, iteration is dicey (the # Because a weak dict is used internally, iteration is dicey (the
# underlying dict may change size during iteration, due to gc or # underlying dict may change size during iteration, due to gc or
......
...@@ -43,12 +43,12 @@ class TransactionManager(object): ...@@ -43,12 +43,12 @@ class TransactionManager(object):
def begin(self): def begin(self):
if self._txn is not None: if self._txn is not None:
self._txn.abort() self._txn.abort()
self._txn = Transaction(self._synchs.as_weakref_list(), self) self._txn = Transaction(self._synchs, self)
return self._txn return self._txn
def get(self): def get(self):
if self._txn is None: if self._txn is None:
self._txn = Transaction(self._synchs.as_weakref_list(), self) self._txn = Transaction(self._synchs, self)
return self._txn return self._txn
def free(self, txn): def free(self, txn):
...@@ -71,8 +71,8 @@ class ThreadTransactionManager(object): ...@@ -71,8 +71,8 @@ class ThreadTransactionManager(object):
# _threads maps thread ids to transactions # _threads maps thread ids to transactions
self._txns = {} self._txns = {}
# _synchs maps a thread id to a WeakSet of registered synchronizers. # _synchs maps a thread id to a WeakSet of registered synchronizers.
# The set elements are passed to the Transaction constructor, # The WeakSet is passed to the Transaction constructor, because the
# because the latter needs to call the synchronizers when it commits. # latter needs to call the synchronizers when it commits.
self._synchs = {} self._synchs = {}
def begin(self): def begin(self):
...@@ -81,8 +81,6 @@ class ThreadTransactionManager(object): ...@@ -81,8 +81,6 @@ class ThreadTransactionManager(object):
if txn is not None: if txn is not None:
txn.abort() txn.abort()
synchs = self._synchs.get(tid) synchs = self._synchs.get(tid)
if synchs is not None:
synchs = synchs.as_weakref_list()
txn = self._txns[tid] = Transaction(synchs, self) txn = self._txns[tid] = Transaction(synchs, self)
return txn return txn
...@@ -91,8 +89,6 @@ class ThreadTransactionManager(object): ...@@ -91,8 +89,6 @@ class ThreadTransactionManager(object):
txn = self._txns.get(tid) txn = self._txns.get(tid)
if txn is None: if txn is None:
synchs = self._synchs.get(tid) synchs = self._synchs.get(tid)
if synchs is not None:
synchs = synchs.as_weakref_list()
txn = self._txns[tid] = Transaction(synchs, self) txn = self._txns[tid] = Transaction(synchs, self)
return txn return txn
......
...@@ -138,7 +138,6 @@ import sys ...@@ -138,7 +138,6 @@ import sys
import thread import thread
import warnings import warnings
import traceback import traceback
import weakref
from cStringIO import StringIO from cStringIO import StringIO
# Sigh. In the maze of __init__.py's, ZODB.__init__.py takes 'get' # Sigh. In the maze of __init__.py's, ZODB.__init__.py takes 'get'
...@@ -173,8 +172,15 @@ class Transaction(object): ...@@ -173,8 +172,15 @@ class Transaction(object):
self.status = Status.ACTIVE self.status = Status.ACTIVE
# List of resource managers, e.g. MultiObjectResourceAdapters. # List of resource managers, e.g. MultiObjectResourceAdapters.
self._resources = [] self._resources = []
self._synchronizers = synchronizers or []
# Weak set of synchronizer objects to call.
if synchronizers is None:
from ZODB.utils import WeakSet
synchronizers = WeakSet()
self._synchronizers = synchronizers
self._manager = manager self._manager = manager
# _adapters: Connection/_p_jar -> MultiObjectResourceAdapter[Sub] # _adapters: Connection/_p_jar -> MultiObjectResourceAdapter[Sub]
self._adapters = {} self._adapters = {}
self._voted = {} # id(Connection) -> boolean, True if voted self._voted = {} # id(Connection) -> boolean, True if voted
...@@ -204,14 +210,6 @@ class Transaction(object): ...@@ -204,14 +210,6 @@ class Transaction(object):
# raised, incorporating this traceback. # raised, incorporating this traceback.
self._failure_traceback = None self._failure_traceback = None
# Invoke f(synch) for each synch in self._synchronizers.
def _synch_map(self, f):
for wr in self._synchronizers:
assert isinstance(wr, weakref.ref)
synch = wr()
if synch is not None:
f(synch)
# Raise TransactionFailedError, due to commit()/join()/register() # Raise TransactionFailedError, due to commit()/join()/register()
# getting called when the current transaction has already suffered # getting called when the current transaction has already suffered
# a commit failure. # a commit failure.
...@@ -295,7 +293,7 @@ class Transaction(object): ...@@ -295,7 +293,7 @@ class Transaction(object):
self.commit(True) self.commit(True)
if not subtransaction: if not subtransaction:
self._synch_map(lambda s: s.beforeCompletion(self)) self._synchronizers.map(lambda s: s.beforeCompletion(self))
self.status = Status.COMMITTING self.status = Status.COMMITTING
try: try:
...@@ -319,7 +317,7 @@ class Transaction(object): ...@@ -319,7 +317,7 @@ class Transaction(object):
self.status = Status.COMMITTED self.status = Status.COMMITTED
if self._manager: if self._manager:
self._manager.free(self) self._manager.free(self)
self._synch_map(lambda s: s.afterCompletion(self)) self._synchronizers.map(lambda s: s.afterCompletion(self))
self.log.debug("commit") self.log.debug("commit")
def _commitResources(self, subtransaction): def _commitResources(self, subtransaction):
...@@ -367,7 +365,7 @@ class Transaction(object): ...@@ -367,7 +365,7 @@ class Transaction(object):
self._cleanup(L) self._cleanup(L)
finally: finally:
if not subtransaction: if not subtransaction:
self._synch_map(lambda s: s.afterCompletion(self)) self._synchronizers.map(lambda s: s.afterCompletion(self))
raise t, v, tb raise t, v, tb
def _cleanup(self, L): def _cleanup(self, L):
...@@ -433,7 +431,7 @@ class Transaction(object): ...@@ -433,7 +431,7 @@ class Transaction(object):
def abort(self, subtransaction=False): def abort(self, subtransaction=False):
if not subtransaction: if not subtransaction:
self._synch_map(lambda s: s.beforeCompletion(self)) self._synchronizers.map(lambda s: s.beforeCompletion(self))
if subtransaction and self._nonsub: if subtransaction and self._nonsub:
from ZODB.POSException import TransactionError from ZODB.POSException import TransactionError
...@@ -463,7 +461,7 @@ class Transaction(object): ...@@ -463,7 +461,7 @@ class Transaction(object):
if not subtransaction: if not subtransaction:
if self._manager: if self._manager:
self._manager.free(self) self._manager.free(self)
self._synch_map(lambda s: s.afterCompletion(self)) self._synchronizers.map(lambda s: s.afterCompletion(self))
self.log.debug("abort") self.log.debug("abort")
if tb is not None: if tb is not 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