Commit a5c0f41a authored by Jeremy Hylton's avatar Jeremy Hylton

Change TransactionBuffer to use a real iterator.

This eliminates a bunch of checks that weren't exercised by the test
suite.  Not sure if they were superstition or not, but I'm willing to
risk it.
parent 82d1310d
...@@ -985,22 +985,7 @@ class ClientStorage(object): ...@@ -985,22 +985,7 @@ class ClientStorage(object):
if self._cache is None: if self._cache is None:
return return
try: for oid, version, data in self._tbuf:
self._tbuf.begin_iterate()
except ValueError, msg:
raise ClientStorageError, (
"Unexpected error reading temporary file in "
"client storage: %s" % msg)
while 1:
try:
t = self._tbuf.next()
except ValueError, msg:
raise ClientStorageError, (
"Unexpected error reading temporary file in "
"client storage: %s" % msg)
if t is None:
break
oid, version, data = t
self._cache.invalidate(oid, version, tid) self._cache.invalidate(oid, version, tid)
# If data is None, we just invalidate. # If data is None, we just invalidate.
if data is not None: if data is not None:
......
...@@ -116,41 +116,33 @@ class TransactionBuffer: ...@@ -116,41 +116,33 @@ class TransactionBuffer:
finally: finally:
self.lock.release() self.lock.release()
# unchecked constraints: def __iter__(self):
# 1. can't call store() after begin_iterate()
# 2. must call clear() after iteration finishes
def begin_iterate(self):
"""Move the file pointer in advance of iteration"""
self.lock.acquire() self.lock.acquire()
try: try:
if self.closed: if self.closed:
return return
self.file.flush() self.file.flush()
self.file.seek(0) self.file.seek(0)
self.unpickler = cPickle.Unpickler(self.file) return TBIterator(self.file, self.count)
finally: finally:
self.lock.release() self.lock.release()
def next(self): class TBIterator(object):
self.lock.acquire()
try: def __init__(self, f, count):
return self._next() self.file = f
finally: self.count = count
self.lock.release() self.unpickler = cPickle.Unpickler(f)
def _next(self): def __iter__(self):
return self
def next(self):
"""Return next tuple of data or None if EOF""" """Return next tuple of data or None if EOF"""
if self.closed:
return None
if self.count == 0: if self.count == 0:
del self.unpickler self.file.seek(0)
return None self.size = 0
raise StopIteration
oid_ver_data = self.unpickler.load() oid_ver_data = self.unpickler.load()
self.count -= 1 self.count -= 1
return oid_ver_data return oid_ver_data
def get_size(self):
"""Return size of data stored in buffer (just a hint)."""
return self.size
...@@ -35,13 +35,9 @@ class TransBufTests(unittest.TestCase): ...@@ -35,13 +35,9 @@ class TransBufTests(unittest.TestCase):
tbuf = TransactionBuffer() tbuf = TransactionBuffer()
tbuf.store(*new_store_data()) tbuf.store(*new_store_data())
tbuf.invalidate(*new_invalidate_data()) tbuf.invalidate(*new_invalidate_data())
tbuf.begin_iterate() for o in tbuf:
while 1: pass
o = tbuf.next()
if o is None:
break
tbuf.clear()
def doUpdates(self, tbuf): def doUpdates(self, tbuf):
data = [] data = []
for i in range(10): for i in range(10):
...@@ -52,9 +48,7 @@ class TransBufTests(unittest.TestCase): ...@@ -52,9 +48,7 @@ class TransBufTests(unittest.TestCase):
tbuf.invalidate(*d) tbuf.invalidate(*d)
data.append(d) data.append(d)
tbuf.begin_iterate() for i, x in enumerate(tbuf):
for i in range(len(data)):
x = tbuf.next()
if x[2] is None: if x[2] is None:
# the tbuf add a dummy None to invalidates # the tbuf add a dummy None to invalidates
x = x[:2] x = x[:2]
......
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