[Zope3-checkins] CVS: Zope3/src/zodb - connection.py:1.7.4.7
Jeremy Hylton
jeremy@zope.com
Thu, 13 Mar 2003 11:05:44 -0500
Update of /cvs-repository/Zope3/src/zodb
In directory cvs.zope.org:/tmp/cvs-serv7707
Modified Files:
Tag: opaque-pickles-branch
connection.py
Log Message:
Eliminate use of findrefs by making TmpStore store refs explicitly.
=== Zope3/src/zodb/connection.py 1.7.4.6 => 1.7.4.7 ===
--- Zope3/src/zodb/connection.py:1.7.4.6 Wed Mar 12 18:22:06 2003
+++ Zope3/src/zodb/connection.py Thu Mar 13 11:05:42 2003
@@ -38,6 +38,7 @@
"""
import logging
+import struct
import tempfile
import threading
from types import StringType, ClassType, TupleType
@@ -48,6 +49,7 @@
from zodb.interfaces import *
from zodb.serialize import ConnectionObjectReader, ObjectWriter, findrefs
from zodb.storage.interfaces import IStorage
+from zodb.storage.base import splitrefs
from zodb.utils import p64, u64, Set
from transaction import get_transaction
@@ -353,10 +355,9 @@
def savepoint(self, txn):
if self._tmp is None:
- tmp = TmpStore(self._version)
+ tmp = TmpStore(self._db, self._storage, self._version)
self._tmp = self._storage
self._storage = tmp
- tmp.registerDB(self._db)
self._modified = Set()
self._created = Set()
self._storage.tpcBegin(txn)
@@ -492,11 +493,11 @@
self._created |= tmp._created
for oid in tmp._index:
- data, serial = tmp.load(oid, tmp._bver)
- refs = findrefs(data)
+ data, refs, serial = tmp.loadrefs(oid, tmp._bver)
s = self._storage.store(oid, serial, (data, refs),
self._version, txn)
self._handle_serial(s, oid, change=False)
+ tmp.close()
def _abort_sub(self):
# Abort work done in subtransactions.
@@ -508,6 +509,7 @@
self._cache.invalidateMany(tmp._index)
self._invalidate_created(tmp._created)
+ tmp.close()
class Rollback:
"""Rollback changes associated with savepoint"""
@@ -557,7 +559,16 @@
_bver = ''
- def __init__(self, base_version):
+ # The header format is oid, serial, nrefs, len(data). Following
+ # the header are the refs and the data, where the size of refs is
+ # nrefs * 8.
+
+ _fmt = ">8s8sQQ"
+ _header_size = 32
+
+ def __init__(self, db, storage, base_version):
+ self._db = db
+ self._storage = storage
self._transaction = None
if base_version:
self._bver = base_version
@@ -576,52 +587,40 @@
# XXX Is this necessary?
self._file.close()
- def getName(self):
- return self._db.getName()
-
- def getSize(self):
- return self._pos
-
def load(self, oid, version):
pos = self._index.get(oid, None)
if pos is None:
return self._storage.load(oid, self._bver)
+ data, refs, serial = self.loadrefs(oid, version)
+ return data, serial
+
+ def loadrefs(self, oid, version):
+ # A version of load the returns data, refs, and serial.
+ pos = self._index.get(oid)
+ # We only call loadrefs() for objects in the TmpStore.
+ assert pos is not None
self._file.seek(pos)
- h = self._file.read(24)
- if h[:8] != oid:
- raise interfaces.StorageSystemError('Bad temporary storage')
- size = u64(h[16:])
- serial = h[8:16]
- return self._file.read(size), serial
-
- # XXX clarify difference between self._storage & self._db._storage
-
- def modifiedInVersion(self, oid):
- if self._index.has_key(oid):
- return self._bver
- return self._db._storage.modifiedInVersion(oid)
+ buf = self._file.read(self._header_size)
+ oid, serial, nrefs, size = struct.unpack(">8s8sQQ", buf)
+ refs = self._file.read(nrefs * 8)
+ data = self._file.read(size)
+ return data, splitrefs(refs), serial
def newObjectId(self):
- return self._db._storage.newObjectId()
-
- def registerDB(self, db):
- self._db = db
- self._storage = db._storage
+ return self._storage.newObjectId()
- def store(self, oid, serial, data, version, transaction):
+ def store(self, oid, serial, (data, refs), version, transaction):
if transaction is not self._transaction:
raise interfaces.StorageTransactionError(self, transaction)
- # XXX Store this natively and get rid of the conditional split
- if isinstance(data, tuple):
- data, refs = data
self._file.seek(self._pos)
- l = len(data)
if serial is None:
serial = ZERO
- self._file.write(oid + serial + p64(l))
+ buf = struct.pack(">8s8sQQ", oid, serial, len(refs), len(data))
+ self._file.write(buf)
+ self._file.write("".join(refs))
self._file.write(data)
self._tindex[oid] = self._pos
- self._pos += l + 24
+ self._pos += len(refs) * 8 + len(data) + self._header_size
return serial
def tpcAbort(self, transaction):