All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sleepycat.je.txn.WriteLockInfo Maven / Gradle / Ivy

The newest version!
/*-
 * Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
 *
 * This file was distributed by Oracle as part of a version of Oracle Berkeley
 * DB Java Edition made available at:
 *
 * http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
 *
 * Please see the LICENSE file included in the top-level directory of the
 * appropriate version of Oracle Berkeley DB Java Edition for a copy of the
 * license and additional information.
 */

package com.sleepycat.je.txn;

import com.sleepycat.je.dbi.DatabaseImpl;
import com.sleepycat.je.tree.Key;
import com.sleepycat.je.utilint.DbLsn;
import com.sleepycat.je.utilint.VLSN;

/*
 * Given a locker T and a record R, a WriteLockInfo stores the info needed to
 * undo the write ops (insertions, deletions, or updates) performed by T on
 * R, if T aborts. Specifically, it stores the info needed to restore R to its
 * "abort" version, i.e., the version of R that existed at the time when T
 * locked R for the 1st time (and before T actually performed its 1st write
 * op on R). Given that only transactional lockers may abort, WriteLockInfo
 * are used by Txn lockers only.
 *
 * Notice that, conceptually, to write R, T locks R in exclusive mode and
 * retains that lock until it terminates (commits or aborts). In other words,
 * T locks R only once. However, because locks are acquired on LSNs and LSNs
 * change every time a record is written, T may actually lock R multiple times,
 * Everytime T locks a new LSN of R, it creates a new WriteLockIno. However,
 * care is taken so that all WriteLockInfos for the same logical record and
 * the same txn store the same info about the abort version (for details see
 * CursorImpl.LockStanding, CursorImpl.lockLN(), and LN.logInternals()). In
 * fact, if T writes R multiple times and then aborts, only one of the logrecs
 * generated by T for R will be undone, restoring R to its abort version; the
 * rest will be skipped. 
 *
 * Info about the aort version is needed during commit as well. Specifically,
 * its LSN and on-disk size are needed to count the abort version obsolete
 * when T commits.
 */
public class WriteLockInfo {

    /*
     * The LSN of the record's abort version. This is stored persistently in
     * each logrec renerated by T on R. May be null if R was created by T
     * (will definitely be null if the txn did not reuse an existing slot for
     * the new record).
     */
    private long abortLsn;

    /*
     * Whether the record's abort version is a deletion version or not.
     * It is stored persistently in each logrec renerated by T on R.
     */
    private boolean abortKnownDeleted;

    /*
     * See comment for abortData field below.
     */
    private byte[] abortKey;

    /*
     * If the record's abort version was embedded in a BIN, the associated
     * logrec that contains that version may have been cleaned away by the
     * time the txn aborts. So, we must save in each logrec the data portion
     * of the abort version. abortdata serves this purpose. If key updates
     * are allowed in the containing DB, the key of the abort version is
     * saved in abortKey as well. Finally, if VLSN caching in BINs is enabled,
     * the VLSN of the abort version is saved in abortVLSN as well.
     */
    private byte[] abortData;

    /*
     * See comment for abortData field above.
     */
    private long abortVLSN = VLSN.NULL_VLSN_SEQUENCE;

    /*
     * The on-disk size of the abort version, or zero if abortLsn is NULL_LSN
     * or if the size is not known. Used for obsolete counting during commit.
     * Not stored persistently.
     */
    private int abortLogSize;

    /* Abort expiration time. Is negative if in hours, positive if in days. */
    private int abortExpiration;

    /*
     * The containing database, or null if abortLsn is NULL_LSN.  Used for
     * obsolete counting during a commit.
     */
    private DatabaseImpl db;

    /*
     * True if the LSN has never been locked before by this Txn. Used so we
     * can determine when to set abortLsn.
     */
    private boolean neverLocked;

    static final WriteLockInfo basicWriteLockInfo = new WriteLockInfo();

    // public for Sizeof
    public WriteLockInfo() {
        abortLsn = DbLsn.NULL_LSN;
        abortKnownDeleted = false;
        neverLocked = true;
    }

    public boolean getAbortKnownDeleted() {
        return abortKnownDeleted;
    }

    public void setAbortKnownDeleted(boolean v) {
        abortKnownDeleted = v;
    }

    public long getAbortLsn() {
        return abortLsn;
    }

    public void setAbortLsn(long abortLsn) {
        this.abortLsn = abortLsn;
    }

    public byte[] getAbortKey() {
        return abortKey;
    }

    public void setAbortKey(byte[] v) {
        abortKey = v;
    }

    public byte[] getAbortData() {
        return abortData;
    }

    public void setAbortData(byte[] v) {
        abortData = v;
    }

   public long getAbortVLSN() {
        return abortVLSN;
    }

   public void setAbortVLSN(long v) {
        abortVLSN = v;
    }

    public int getAbortLogSize() {
        return abortLogSize;
    }

    public void setAbortLogSize(int logSize) {
        abortLogSize = logSize;
    }

    public void setAbortExpiration(int expiration, boolean expirationInHours) {
        abortExpiration = expirationInHours ? (-expiration) : expiration;
    }

    public int getAbortExpiration() {
        return Math.abs(abortExpiration);
    }

    public boolean isAbortExpirationInHours() {
        return abortExpiration < 0;
    }

    public DatabaseImpl getDb() {
        return db;
    }

    public void setDb(DatabaseImpl db) {
        this.db = db;
    }

    public boolean getNeverLocked() {
        return neverLocked;
    }

    public void setNeverLocked(boolean neverLocked) {
        this.neverLocked = neverLocked;
    }

    /*
     * Copy all the information needed to create a clone of the lock.
     */    
    public void copyAllInfo(WriteLockInfo source) {
        abortLsn = source.abortLsn;
        abortKnownDeleted = source.abortKnownDeleted;
        abortKey = source.abortKey;
        abortData = source.abortData;
        abortVLSN = source.abortVLSN;
        abortLogSize = source.abortLogSize;
        abortExpiration = source.abortExpiration;
        db = source.db;
        neverLocked = source.neverLocked;
    }

    @Override
    public String toString() {
        return "abortLsn=" +
            DbLsn.getNoFormatString(abortLsn) +
            " abortKnownDeleted=" + abortKnownDeleted +
            " abortKey=" + Key.getNoFormatString(abortKey) +
            " abortData=" + Key.getNoFormatString(abortData) +
            " abortLogSize=" + abortLogSize +
            " abortVLSN=" + String.format("%,d", abortVLSN) +
            " abortExpiration=" + getAbortExpiration() +
            " abortExpirationInHours=" + isAbortExpirationInHours() +
            " neverLocked=" + neverLocked;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy