[Zodb-checkins] CVS: ZODB3/ZEO - ClientCache.py:1.29
Guido van Rossum
guido@python.org
Wed, 28 Aug 2002 11:48:25 -0400
Update of /cvs-repository/ZODB3/ZEO
In directory cvs.zope.org:/tmp/cvs-serv27615
Modified Files:
ClientCache.py
Log Message:
A bouquet of minor code and comment cleanups.
Note that the checkModifyAfterAbortVersion() test still fails; Jeremy
wants to change abortVersion in FileStorage and DemoStorage to revert
the serialno to the last nonversion serialno instead of assigning a
brand new serialno, so I'm holding off on invalidating the cache in
ClientStorage.abortVersion.
Also note that on Red Hat 7.2, the ZEO test suite hangs in
checkCommitLock2OnAbort or checkCommitLock2OnCommit; we'll try to
debug this later today.
=== ZODB3/ZEO/ClientCache.py 1.28 => 1.29 ===
--- ZODB3/ZEO/ClientCache.py:1.28 Tue Aug 27 15:05:42 2002
+++ ZODB3/ZEO/ClientCache.py Wed Aug 28 11:48:25 2002
@@ -20,14 +20,12 @@
Persistent cache files live in the var directory and are named
'c<storage>-<client>-<digit>.zec' where <storage> is the storage
-argument (default ''), <client> is the client argument, and <digit> is
+argument (default '1'), <client> is the client argument, and <digit> is
0 or 1. Temporary cache files are unnamed files in the standard
temporary directory as determined by the tempfile module.
-The ClientStorage overrides some of the defaults; in particular, its
-storage name defaults to '1' and its client name defaults to the value
-of the environment variable ZEO_CLIENT, if it exists, otherwise to
-None.
+The ClientStorage overrides the client name default to the value of
+the environment variable ZEO_CLIENT, if it exists.
Each cache file has a 4-byte magic number followed by a sequence of
records of the form:
@@ -37,6 +35,7 @@
0: oid -- 8-byte object id
8: status -- 1-byte status 'v': valid, 'n': non-version valid, 'i': invalid
+ ('n' means only the non-version data in the record is valid)
9: tlen -- 4-byte (unsigned) record length
@@ -96,7 +95,6 @@
__version__ = "$Revision$"[11:-2]
import os
-import sys
import tempfile
from struct import pack, unpack
from thread import allocate_lock
@@ -113,7 +111,12 @@
__implements__ = ICache
- def __init__(self, storage='', size=20000000, client=None, var=None):
+ def __init__(self, storage='1', size=20000000, client=None, var=None):
+ # Arguments:
+ # storage -- storage name (used in persistent cache file names only)
+ # size -- size limit in bytes of both files together
+ # client -- if not None, use a persistent cache file and use this name
+ # var -- directory where to create persistent cache files
# Allocate locks:
L = allocate_lock()
@@ -122,6 +125,7 @@
if client is not None:
# Create a persistent cache
+ # CLIENT_HOME and INSTANCE_HOME are builtins set by App.FindHomes
if var is None:
try:
var = CLIENT_HOME
@@ -175,8 +179,11 @@
self._current = current
def open(self):
- # XXX open is overloaded to perform two tasks for
- # optimization reasons
+ # Two tasks:
+ # - Set self._index, self._get, and self._pos.
+ # - Read and validate both cache files, returning a list of
+ # serials to be used by verify().
+ # This may be called more than once (by the cache verification code).
self._acquire()
try:
self._index=index={}
@@ -219,11 +226,11 @@
f = self._f[p < 0]
ap = abs(p)
f.seek(ap)
- h = f.read(8)
- if h != oid:
+ h = f.read(27)
+ if h[:8] != oid:
return
f.seek(p+8) # Switch from reading to writing
- if version:
+ if version and h[15:19] != '\0\0\0\0':
f.write('n')
else:
del self._index[oid]
@@ -266,16 +273,19 @@
if dlen:
seek(dlen, 1)
- v = read(vlen)
+ vheader = read(vlen+4)
+ v = vheader[:-4]
if version != v:
if dlen:
- seek(-dlen-vlen, 1)
+ seek(p+27)
return read(dlen), h[19:]
else:
return None
- dlen = unpack(">i", read(4))[0]
- return read(dlen), read(8)
+ vdlen = unpack(">i", vheader[-4:])[0]
+ vdata = read(vdlen)
+ vserial = read(8)
+ return vdata, vserial
finally:
self._release()
@@ -302,12 +312,12 @@
return self._store(oid, '', '', version, data, serial)
if dlen:
- p = read(dlen)
- s = h[19:]
+ nvdata = read(dlen)
+ nvserial = h[19:]
else:
return self._store(oid, '', '', version, data, serial)
- self._store(oid, p, s, version, data, serial)
+ self._store(oid, nvdata, nvserial, version, data, serial)
else:
# Simple case, just store new data:
self._store(oid, data, serial, '', None, None)
@@ -315,6 +325,10 @@
self._release()
def modifiedInVersion(self, oid):
+ # This should return:
+ # - The version from the record for oid, if there is one.
+ # - '', if there is no version in the record and its status is 'v'.
+ # - None, if we don't know: no valid record or status is 'n'.
self._acquire()
try:
p = self._get(oid, None)
@@ -345,10 +359,10 @@
self._release()
def checkSize(self, size):
+ # Make sure we aren't going to exceed the target size.
+ # If we are, then flip the cache.
self._acquire()
try:
- # Make sure we aren't going to exceed the target size.
- # If we are, then flip the cache.
if self._pos + size > self._limit:
current = not self._current
self._current = current
@@ -358,10 +372,9 @@
if (index[oid] < 0) == current:
del index[oid]
if self._p[current] is not None:
- # Persistent cache file:
- # Note that due to permission madness, waaa,
- # we need to remove the old file before
- # we open the new one. Waaaaaaaaaa.
+ # Persistent cache file: remove the old file
+ # before opening the new one, because the old file
+ # may be owned by root (created before setuid()).
if self._f[current] is not None:
self._f[current].close()
try:
@@ -373,7 +386,7 @@
# Temporary cache file:
self._f[current] = tempfile.TemporaryFile(suffix='.zec')
self._f[current].write(magic)
- self._pos = pos = 4
+ self._pos = 4
finally:
self._release()
@@ -417,12 +430,10 @@
self._pos += tlen
-def read_index(index, serial, f, current):
+def read_index(index, serial, f, fileindex):
seek = f.seek
read = f.read
pos = 4
- seek(0, 2)
- size = f.tell()
while 1:
f.seek(pos)
@@ -443,7 +454,7 @@
if len(vdlen) != 4:
break
vdlen = unpack(">i", vdlen)[0]
- if vlen+dlen+42+vdlen > tlen:
+ if vlen+dlen+43+vdlen != tlen:
break
seek(vdlen, 1)
vs = read(8)
@@ -453,7 +464,7 @@
vs = None
if h[8] in 'vn':
- if current:
+ if fileindex:
index[oid] = -pos
else:
index[oid] = pos