[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