[Zodb-checkins] SVN: ZODB/trunk/src/ZODB/ Added a lastInvalidations
that a ZEO server can use to populate its
Jim Fulton
jim at zope.com
Mon Mar 26 18:04:47 EDT 2007
Log message for revision 73654:
Added a lastInvalidations that a ZEO server can use to populate its
invalidation queue.
Changed:
U ZODB/trunk/src/ZODB/FileStorage/FileStorage.py
U ZODB/trunk/src/ZODB/tests/testFileStorage.py
-=-
Modified: ZODB/trunk/src/ZODB/FileStorage/FileStorage.py
===================================================================
--- ZODB/trunk/src/ZODB/FileStorage/FileStorage.py 2007-03-26 22:04:44 UTC (rev 73653)
+++ ZODB/trunk/src/ZODB/FileStorage/FileStorage.py 2007-03-26 22:04:46 UTC (rev 73654)
@@ -1390,6 +1390,25 @@
"""Return transaction id for last committed transaction"""
return self._ltid
+ def lastInvalidations(self, count):
+ file = self._file
+ seek = file.seek
+ read = file.read
+ self._lock_acquire()
+ try:
+ pos = self._pos
+ while count > 0 and pos > 4:
+ count -= 1
+ seek(pos-8)
+ pos = pos - 8 - u64(read(8))
+
+ seek(0)
+ return [(trans.tid, [(r.oid, r.version) for r in trans])
+ for trans in FileIterator(self._file, pos=pos)]
+ finally:
+ self._lock_release()
+
+
def lastTid(self, oid):
"""Return last serialno committed for object oid.
@@ -1822,7 +1841,7 @@
_ltid = z64
_file = None
- def __init__(self, file, start=None, stop=None):
+ def __init__(self, file, start=None, stop=None, pos=4L):
if isinstance(file, str):
file = open(file, 'rb')
self._file = file
@@ -1830,7 +1849,7 @@
raise FileStorageFormatError(file.name)
file.seek(0,2)
self._file_size = file.tell()
- self._pos = 4L
+ self._pos = pos
assert start is None or isinstance(start, str)
assert stop is None or isinstance(stop, str)
if start:
Modified: ZODB/trunk/src/ZODB/tests/testFileStorage.py
===================================================================
--- ZODB/trunk/src/ZODB/tests/testFileStorage.py 2007-03-26 22:04:44 UTC (rev 73653)
+++ ZODB/trunk/src/ZODB/tests/testFileStorage.py 2007-03-26 22:04:46 UTC (rev 73654)
@@ -14,7 +14,9 @@
import os, unittest
import transaction
import ZODB.FileStorage
+import ZODB.tests.util
from ZODB import POSException
+from ZODB import DB
from ZODB.tests import StorageTestBase, BasicStorage, \
TransactionalUndoStorage, VersionStorage, \
@@ -192,7 +194,6 @@
# Now the cached 'oid' value is ignored: verify that this is so.
import cPickle as pickle
from ZODB.utils import z64
- from ZODB.DB import DB
# Create some data.
db = DB(self._storage)
@@ -281,7 +282,6 @@
# global.
import time
- from ZODB.DB import DB
from ZODB.utils import U64, p64
from ZODB.FileStorage.format import CorruptedError
@@ -324,7 +324,6 @@
self.fail("expected CorruptedError")
def check_record_iternext(self):
- from ZODB.DB import DB
db = DB(self._storage)
conn = db.open()
@@ -351,7 +350,6 @@
else:
self.assertNotEqual(next_oid, None)
-
class FileStorageRecoveryTest(
StorageTestBase.StorageTestBase,
RecoveryStorage.RecoveryStorage,
@@ -409,8 +407,6 @@
def testTimeTravelOnOpen():
"""
>>> from ZODB.FileStorage import FileStorage
- >>> from ZODB.DB import DB
- >>> import transaction
>>> from zope.testing.loggingsupport import InstalledHandler
Arrange to capture log messages -- they're an important part of
@@ -484,6 +480,55 @@
>>> handler.uninstall()
"""
+def lastInvalidations():
+ """
+
+The last invalidations method is used by a storage server to pupulate
+it's data structure of recent invalidations. The lastInvalidations
+method is passed a count and must return up to count number of the
+most recent transactions.
+
+We'll create a FileStorage and populate it with some data, keeping
+track of the transactions along the way:
+
+ >>> fs = ZODB.FileStorage.FileStorage('t.fs', create=True)
+ >>> db = DB(fs)
+ >>> conn = db.open()
+ >>> from persistent.dict import PersistentDict
+ >>> last = []
+ >>> for i in range(100):
+ ... conn.root()[i] = PersistentDict()
+ ... transaction.commit()
+ ... last.append(fs.lastTransaction())
+
+Now, we can call lastInvalidations on it:
+
+ >>> invalidations = fs.lastInvalidations(10)
+ >>> [t for (t, oids) in invalidations] == last[-10:]
+ True
+
+ >>> from ZODB.utils import u64
+ >>> [[u64(oid) for (oid, version) in oids]
+ ... for (i, oids) in invalidations]
+ ... # doctest: +NORMALIZE_WHITESPACE
+ [[0L, 91L], [0L, 92L], [0L, 93L], [0L, 94L], [0L, 95L],
+ [0L, 96L], [0L, 97L], [0L, 98L], [0L, 99L], [0L, 100L]]
+
+If we ask for more transactions than there are, we'll get as many as
+there are:
+
+ >>> len(fs.lastInvalidations(1000))
+ 101
+
+Of course, calling lastInvalidations on an empty storage refturns no data:
+
+ >>> fs.close()
+ >>> fs = ZODB.FileStorage.FileStorage('t.fs', create=True)
+ >>> list(fs.lastInvalidations(10))
+ []
+
+ """
+
def test_suite():
from zope.testing import doctest
@@ -491,7 +536,8 @@
for klass in [FileStorageTests, Corruption.FileStorageCorruptTests,
FileStorageRecoveryTest, SlowFileStorageTest]:
suite.addTest(unittest.makeSuite(klass, "check"))
- suite.addTest(doctest.DocTestSuite())
+ suite.addTest(doctest.DocTestSuite(setUp=ZODB.tests.util.setUp,
+ tearDown=ZODB.tests.util.tearDown))
return suite
if __name__=='__main__':
More information about the Zodb-checkins
mailing list