[Zodb-checkins] CVS: ZODB3/ZEO - cache.py:1.1.2.1
Jeremy Hylton
cvs-admin at zope.org
Tue Nov 4 15:04:38 EST 2003
Update of /cvs-repository/ZODB3/ZEO
In directory cvs.zope.org:/tmp/cvs-serv12826
Added Files:
Tag: ZODB3-mvcc-2-branch
cache.py
Log Message:
Strawman implementation of new cache API and simple unit tests.
=== Added File ZODB3/ZEO/cache.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Example client cache that stores multiple revisions of an object."""
##
# A disk-based cache for ZEO clients.
# <p>
# This class provides an interface to a persistent, disk-based cache
# used by ZEO clients to store copies of database records from the
# server.
# <p>
# The details of the constructor as unspecified at this point.
class Cache:
"""A simple in-memory cache."""
def __init__(self):
self.tid = None
self.current = {}
self.current_tid = {}
self.version = {}
self.noncurrent = {}
##
# Set the last transaction seen by the cache.
# @param tid a transaction id
# @exception ValueError attempt to set a new tid less than the current tid
def setLastTid(self, tid):
if self.tid is not None:
if tid < self.tid:
raise ValueError(
"new last tid must be greater that previous one")
self.tid = tid
##
# Return the last transaction seen by the cache.
# @return a transaction id
# @defreturn string
def getLastTid(self):
return self.tid
##
# Return the current data record for oid and version
# @param oid object id
# @param version a version string
# @return data record and serial number
# @defreturn 2-tuple: (string, string)
def load(self, oid, version=""):
if version:
triple = self.version.get(oid)
if triple is not None:
stored_version, data, serial = triple
if version == stored_version:
return data, serial
return self.current.get(oid)
##
# Return a non-current revision of oid that was current before tid.
# @param oid object id
# @param tid id of transaction that wrote next revision of oid
# @return data record, serial number, start tid, and end tid
# @defreturn 4-tuple: (string, string, string, string)
def loadNonCurrent(self, oid, tid):
for lo, hi, data, serial in self.noncurrent.get(oid, []):
if lo < tid <= hi:
return data, serial, lo, hi
return None
##
# Return the version an object is modified in or None for an
# object that is not modified in a version.
# @param oid object id
# @return name of version in which the object is modified
# @defreturn string or None
def modifiedInVersion(self, oid):
pair = self.version.get(oid)
if pair is None:
return None
return pair[0]
##
# Store a new data record in the cache.
# @param oid object id
# @param version name of version that oid was modified in. The cache
# only stores current version data, so end_tid should
# be None.
# @param start_tid the id of the transaction that wrote this revision
# @param end_tid the id of the transaction that created the next
# revision of oid. If end_tid is None, the data is
# current.
# @param data the actual data
# @exception ValueError tried to store non-current version data
def store(self, oid, version, serial, start_tid, end_tid, data):
if version:
if end_tid is not None:
raise ValueError("cache only stores current version data")
self.version[oid] = version, data, serial
return
# XXX If there was a previous revision, we need to invalidate it.
if end_tid is None:
self.current[oid] = data, serial
self.current_tid[oid] = start_tid
else:
# XXX could use bisect and keep the list sorted
L = self.noncurrent.setdefault(oid, [])
L.append((start_tid, end_tid, data, serial))
##
# Mark the current data for oid as non-current. If there is no
# current data for oid, do nothing.
# @param oid object id
# @param version name of version to invalidate.
# @param tid the id of the transaction that wrote a now revision of oid
def invalidate(self, oid, version, tid):
if tid > self.tid:
self.tid = tid
if version:
if oid in self.version:
del self.version[oid]
data = self.current.get(oid)
if data is None:
return
del self.current[oid]
start_tid = self.current_tid.pop(oid)
L = self.noncurrent.setdefault(oid, [])
L.append((start_tid, tid, data[0], data[1]))
More information about the Zodb-checkins
mailing list