[Zodb-checkins] CVS: ZODB3/ZEO1 - ClientCache.py:1.3
Guido van Rossum
guido@python.org
Fri, 30 Aug 2002 16:03:37 -0400
Update of /cvs-repository/ZODB3/ZEO1
In directory cvs.zope.org:/tmp/cvs-serv24426
Modified Files:
ClientCache.py
Log Message:
Add tracing code (same as ZEO2 tracing code).
=== ZODB3/ZEO1/ClientCache.py 1.2 => 1.3 ===
--- ZODB3/ZEO1/ClientCache.py:1.2 Wed Aug 28 18:10:48 2002
+++ ZODB3/ZEO1/ClientCache.py Fri Aug 30 16:03:36 2002
@@ -76,9 +76,10 @@
__version__ = "$Revision$"[11:-2]
-import os, tempfile
+import os, time, tempfile
from struct import pack, unpack
from thread import allocate_lock
+from ZODB.utils import U64
import zLOG
magic='ZEC0'
@@ -143,6 +144,7 @@
self._limit=size/2
self._current=current
+ self._setup_trace()
def close(self):
try:
@@ -169,7 +171,9 @@
self._acquire()
try:
p=self._get(oid, None)
- if p is None: return None
+ if p is None:
+ self._trace(0x10, oid, version)
+ return None
f=self._f[p < 0]
ap=abs(p)
f.seek(ap)
@@ -177,8 +181,10 @@
if h != oid: return
f.seek(p+8) # Switch from reading to writing
if version:
+ self._trace(0x1A, oid, version)
f.write('n')
else:
+ self._trace(0x1C, oid, version)
del self._index[oid]
f.write('i')
finally: self._release()
@@ -187,7 +193,9 @@
self._acquire()
try:
p=self._get(oid, None)
- if p is None: return None
+ if p is None:
+ self._trace(0x20, oid, version)
+ return None
f=self._f[p < 0]
ap=abs(p)
seek=f.seek
@@ -202,31 +210,47 @@
return None
if h[8]=='n':
- if version: return None
+ if version:
+ self._trace(0x22, oid, version)
+ return None
if not dlen:
del self._index[oid]
+ self._trace(0x24, oid, version)
return None
if not vlen or not version:
- if dlen: return read(dlen), h[19:]
- else: return None
+ if dlen:
+ data = read(dlen)
+ self._trace(0x2A, oid, version, h[19:], dlen)
+ return data, h[19:]
+ else:
+ self._trace(0x26, oid, version)
+ return None
if dlen: seek(dlen, 1)
v=read(vlen)
if version != v:
if dlen:
- seek(-dlen-vlen, 1)
- return read(dlen), h[19:]
+ seek(p+27)
+ data = read(dlen)
+ self._trace(0x2C, oid, version, h[19:], dlen)
+ return data, h[19:]
else:
+ self._trace(0x28, oid, version)
return None
- dlen=unpack(">i", read(4))[0]
- return read(dlen), read(8)
- finally: self._release()
+ vdlen = unpack(">i", read(4))[0]
+ vdata = read(vdlen)
+ vserial = read(8)
+ self._trace(0x2E, oid, version, vserial, vdlen)
+ return vdata, vserial
+ finally:
+ self._release()
def update(self, oid, serial, version, data):
self._acquire()
try:
+ self._trace(0x3A, oid, version, serial, len(data))
if version:
# We need to find and include non-version data
p=self._get(oid, None)
@@ -262,7 +286,9 @@
self._acquire()
try:
p=self._get(oid, None)
- if p is None: return None
+ if p is None:
+ self._trace(0x40, oid)
+ return None
f=self._f[p < 0]
ap=abs(p)
seek=f.seek
@@ -276,12 +302,19 @@
del self._index[oid]
return None
- if h[8]=='n': return None
+ if h[8]=='n':
+ self._trace(0x4A, oid)
+ return None
- if not vlen: return ''
+ if not vlen:
+ self._trace(0x4C, oid)
+ return ''
seek(dlen, 1)
- return read(vlen)
- finally: self._release()
+ version = read(vlen)
+ self._trace(0x4E, oid, version)
+ return version
+ finally:
+ self._release()
def checkSize(self, size):
self._acquire()
@@ -291,6 +324,7 @@
if self._pos+size > self._limit:
current=not self._current
self._current=current
+ self._trace(0x70)
# Delete the half of the index that's no longer valid
index = self._index
for oid in index.keys():
@@ -315,9 +349,12 @@
self._pos=pos=4
finally: self._release()
-
def store(self, oid, p, s, version, pv, sv):
self._acquire()
+ if s:
+ self._trace(0x5A, oid, version, s, len(p))
+ else:
+ self._trace(0x5C, oid, version, sv, len(pv))
try: self._store(oid, p, s, version, pv, sv)
finally: self._release()
@@ -352,6 +389,44 @@
else: self._index[oid]=pos
self._pos=pos+tlen
+
+ def _setup_trace(self):
+ # See if cache tracing is requested through $ZEO_CACHE_TRACE.
+ # If not, or if we can't write to the trace file,
+ # disable tracing by setting self._trace to a dummy function.
+ self._tracefile = None
+ tfn = os.environ.get("ZEO_CACHE_TRACE")
+ if tfn:
+ try:
+ self._tracefile = open(tfn, "ab")
+ self._trace(0x00)
+ except IOError, msg:
+ self._tracefile = None
+ LOG("cannot write tracefile %s (%s)" % (tfn, msg))
+ else:
+ LOG("opened tracefile %s" % tfn)
+ if self._tracefile is None:
+ def notrace(*args):
+ pass
+ self._trace = notrace
+
+ def _trace(self, code, oid='', version='', serial='', dlen=0,
+ # Remaining arguments are speed hacks
+ time_time=time.time, struct_pack=pack):
+ # The code argument is two hex digits; bits 0 and 7 must be zero.
+ # The first hex digit shows the operation, the second the outcome.
+ # If the second digit is in "02468" then it is a 'miss'.
+ # If it is in "ACE" then it is a 'hit'.
+ # This method has been carefully tuned to be as fast as possible.
+ # Note: when tracing is disabled, this method is hidden by a dummy.
+ if version:
+ code |= 0x80
+ self._tracefile.write(
+ struct_pack(">ii8s8s",
+ time_time(),
+ (dlen+255) & 0x7fffff00 | code | self._current,
+ oid,
+ serial))
def read_index(index, serial, f, current):
LOG("read_index(%s)" % f.name)