[Zodb-checkins] CVS: Packages/ZODB - BaseStorage.py:1.34.4.4
DemoStorage.py:1.18.10.2
Tim Peters
tim.one at comcast.net
Fri Apr 22 15:36:08 EDT 2005
Update of /cvs-repository/Packages/ZODB
In directory cvs.zope.org:/tmp/cvs-serv20696/ZODB
Modified Files:
Tag: Zope-2_7-branch
BaseStorage.py DemoStorage.py
Log Message:
DemoStorage: Added implementations for registerDB() and new_oid(). As
Tres discovered the hard way, wrapping a ZEO client storage as a
DemoStorage base storage yields insane behavior otherwise.
BaseStorage.new_oid(): Rewrite to eliminate recursion, and hence also the
need for the undocumented and irregular `last=` argument.
Other: removed the `last=` argument to new_oid() every place that felt
compelled to spread that insanity ;-). Seriously, it served no purpose
at all elsewhere, and looks like people just cut 'n pasted in fear.
=== Packages/ZODB/BaseStorage.py 1.34.4.3 => 1.34.4.4 ===
--- Packages/ZODB/BaseStorage.py:1.34.4.3 Mon Feb 28 16:20:41 2005
+++ Packages/ZODB/BaseStorage.py Fri Apr 22 15:36:07 2005
@@ -17,6 +17,7 @@
"""
import cPickle
import time
+from struct import pack as _structpack, unpack as _structunpack
import ThreadLock
import zLOG
@@ -48,10 +49,15 @@
t=time.time()
t=self._ts=apply(TimeStamp,(time.gmtime(t)[:5]+(t%60,)))
self._serial=`t`
+
+ # ._oid is the highest oid in use (0 is always in use -- it's
+ # a reserved oid for the root object). Our new_oid() method
+ # increments it by 1, and returns the result. It's really a
+ # 64-bit integer stored as an 8-byte big-endian string.
if base is None:
- self._oid='\0\0\0\0\0\0\0\0'
+ self._oid = '\0\0\0\0\0\0\0\0'
else:
- self._oid=base._oid
+ self._oid = base._oid
def abortVersion(self, src, transaction):
if transaction is not self._transaction:
@@ -87,24 +93,22 @@
def modifiedInVersion(self, oid):
return ''
- def new_oid(self, last=None):
- # 'last' is only for internal use, not part of the public API
+ def new_oid(self):
if self._is_read_only:
raise POSException.ReadOnlyError()
- if last is None:
- self._lock_acquire()
- try:
- last=self._oid
- d=ord(last[-1])
- if d < 255: last=last[:-1]+chr(d+1)
- else: last=self.new_oid(last[:-1])
- self._oid=last
- return last
- finally: self._lock_release()
- else:
- d=ord(last[-1])
- if d < 255: return last[:-1]+chr(d+1)+'\0'*(8-len(last))
- else: return self.new_oid(last[:-1])
+ self._lock_acquire()
+ try:
+ last = self._oid
+ d = ord(last[-1])
+ if d < 255: # fast path for the usual case
+ last = last[:-1] + chr(d+1)
+ else: # there's a carry out of the last byte
+ last_as_long, = _structunpack(">Q", last)
+ last = _structpack(">Q", last_as_long + 1)
+ self._oid = last
+ return last
+ finally:
+ self._lock_release()
# Update the maximum oid in use, under protection of a lock. The
# maximum-in-use attribute is changed only if possible_new_max_oid is
=== Packages/ZODB/DemoStorage.py 1.18.10.1 => 1.18.10.2 ===
--- Packages/ZODB/DemoStorage.py:1.18.10.1 Mon Jul 21 12:37:18 2003
+++ Packages/ZODB/DemoStorage.py Fri Apr 22 15:36:07 2005
@@ -20,7 +20,7 @@
- Provide a volatile storage that is useful for giving demonstrations.
-The demo strorage can have a "base" storage that is used in a
+The demo storage can have a "base" storage that is used in a
read-only fashion. The base storage must not not to contain version
data.
@@ -82,15 +82,16 @@
__version__='$Revision$'[11:-2]
import base64, time, string
-from ZODB import POSException, BaseStorage, utils
+from ZODB import POSException, utils
+from ZODB.BaseStorage import BaseStorage
from TimeStamp import TimeStamp
from cPickle import loads
from BTrees import OOBTree
-class DemoStorage(BaseStorage.BaseStorage):
+class DemoStorage(BaseStorage):
def __init__(self, name='Demo Storage', base=None, quota=None):
- BaseStorage.BaseStorage.__init__(self, name, base)
+ BaseStorage.__init__(self, name, base)
# We use a BTree because the items are sorted!
self._data=OOBTree.OOBTree()
@@ -104,6 +105,23 @@
raise POSException.StorageError, (
"Demo base storage has version data")
+ # While we officially don't support wrapping a non-read-only base
+ # storage, it has proved useful for test suites to wrap a ClientStorage
+ # in DemoStorage. The least we can do to help support that case is
+ # to arrange for invalidations to get delivered to the base storage.
+ def registerDB(self, db, limit):
+ if self._base is not None: # delegate
+ self._base.registerDB(db, limit)
+
+ # When DemoStorage needs to create a new oid, and there is a base
+ # storage, it must use that storage's new_oid() method. Else
+ # DemoStorage may end up assigning "new" oids that are already in use
+ # by the base storage, leading to a variety of "impossible" problems.
+ def new_oid(self):
+ if self._base is None:
+ return BaseStorage.new_oid(self)
+ else:
+ return self._base.new_oid()
def __len__(self):
base=self._base
More information about the Zodb-checkins
mailing list