co.cask.tephra.persist.TransactionEdit.java Source code

Java tutorial

Introduction

Here is the source code for co.cask.tephra.persist.TransactionEdit.java

Source

/*
 * Copyright  2012-2014 Cask Data, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package co.cask.tephra.persist;

import co.cask.tephra.ChangeId;
import co.cask.tephra.TransactionManager;
import co.cask.tephra.TransactionType;
import com.google.common.base.Objects;
import com.google.common.collect.Sets;
import org.apache.hadoop.io.Writable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;

/**
 * Represents a transaction state change in the {@link TransactionLog}.
 */
public class TransactionEdit implements Writable {

    /**
     * The possible state changes for a transaction.
     */
    public enum State {
        INPROGRESS, COMMITTING, COMMITTED, INVALID, ABORTED, MOVE_WATERMARK, TRUNCATE_INVALID_TX, CHECKPOINT
    }

    private long writePointer;

    /**
     * stores the value of visibility upper bound
     * (see {@link TransactionManager.InProgressTx#getVisibilityUpperBound()})
     * for edit of {@link State#INPROGRESS} only
     */
    private long visibilityUpperBound;
    private long commitPointer;
    private long expirationDate;
    private State state;
    private Set<ChangeId> changes;
    /** Whether or not the COMMITTED change should be fully committed. */
    private boolean canCommit;
    private TransactionType type;
    private Set<Long> truncateInvalidTx;
    private long truncateInvalidTxTime;
    private long parentWritePointer;
    private long[] checkpointPointers;

    // for Writable
    public TransactionEdit() {
        this.changes = Sets.newHashSet();
        this.truncateInvalidTx = Sets.newHashSet();
    }

    // package private for testing
    TransactionEdit(long writePointer, long visibilityUpperBound, State state, long expirationDate,
            Set<ChangeId> changes, long commitPointer, boolean canCommit, TransactionType type,
            Set<Long> truncateInvalidTx, long truncateInvalidTxTime, long parentWritePointer,
            long[] checkpointPointers) {
        this.writePointer = writePointer;
        this.visibilityUpperBound = visibilityUpperBound;
        this.state = state;
        this.expirationDate = expirationDate;
        this.changes = changes != null ? changes : Collections.<ChangeId>emptySet();
        this.commitPointer = commitPointer;
        this.canCommit = canCommit;
        this.type = type;
        this.truncateInvalidTx = truncateInvalidTx != null ? truncateInvalidTx : Collections.<Long>emptySet();
        this.truncateInvalidTxTime = truncateInvalidTxTime;
        this.parentWritePointer = parentWritePointer;
        this.checkpointPointers = checkpointPointers;
    }

    /**
     * Returns the transaction write pointer assigned for the state change.
     */
    public long getWritePointer() {
        return writePointer;
    }

    void setWritePointer(long writePointer) {
        this.writePointer = writePointer;
    }

    public long getVisibilityUpperBound() {
        return visibilityUpperBound;
    }

    void setVisibilityUpperBound(long visibilityUpperBound) {
        this.visibilityUpperBound = visibilityUpperBound;
    }

    /**
     * Returns the type of state change represented.
     */
    public State getState() {
        return state;
    }

    void setState(State state) {
        this.state = state;
    }

    /**
     * Returns any expiration timestamp (in milliseconds) associated with the state change.  This should only
     * be populated for changes of type {@link State#INPROGRESS}.
     */
    public long getExpiration() {
        return expirationDate;
    }

    void setExpiration(long expirationDate) {
        this.expirationDate = expirationDate;
    }

    /**
     * @return the set of changed row keys associated with the state change.  This is only populated for edits
     * of type {@link State#COMMITTING} or {@link State#COMMITTED}.
     */
    public Set<ChangeId> getChanges() {
        return changes;
    }

    void setChanges(Set<ChangeId> changes) {
        this.changes = changes;
    }

    /**
     * Returns the write pointer used to commit the row key change set.  This is only populated for edits of type
     * {@link State#COMMITTED}.
     */
    public long getCommitPointer() {
        return commitPointer;
    }

    void setCommitPointer(long commitPointer) {
        this.commitPointer = commitPointer;
    }

    /**
     * Returns whether or not the transaction should be moved to the committed set.  This is only populated for edits
     * of type {@link State#COMMITTED}.
     */
    public boolean getCanCommit() {
        return canCommit;
    }

    void setCanCommit(boolean canCommit) {
        this.canCommit = canCommit;
    }

    /**
     * Returns the transaction type. This is only populated for edits of type {@link State#INPROGRESS} or 
     * {@link State#ABORTED}.
     */
    public TransactionType getType() {
        return type;
    }

    void setType(TransactionType type) {
        this.type = type;
    }

    /**
     * Returns the transaction ids to be removed from invalid transaction list. This is only populated for
     * edits of type {@link State#TRUNCATE_INVALID_TX} 
     */
    public Set<Long> getTruncateInvalidTx() {
        return truncateInvalidTx;
    }

    void setTruncateInvalidTx(Set<Long> truncateInvalidTx) {
        this.truncateInvalidTx = truncateInvalidTx;
    }

    /**
     * Returns the time until which the invalid transactions need to be truncated from invalid transaction list.
     * This is only populated for  edits of type {@link State#TRUNCATE_INVALID_TX}
     */
    public long getTruncateInvalidTxTime() {
        return truncateInvalidTxTime;
    }

    void setTruncateInvalidTxTime(long truncateInvalidTxTime) {
        this.truncateInvalidTxTime = truncateInvalidTxTime;
    }

    /**
     * Returns the parent write pointer for a checkpoint operation.  This is only populated for edits of type
     * {@link State#CHECKPOINT}
     */
    public long getParentWritePointer() {
        return parentWritePointer;
    }

    void setParentWritePointer(long parentWritePointer) {
        this.parentWritePointer = parentWritePointer;
    }

    /**
     * Returns the checkpoint write pointers for the edit.  This is only populated for edits of type
     * {@link State#ABORTED}.
     */
    public long[] getCheckpointPointers() {
        return checkpointPointers;
    }

    void setCheckpointPointers(long[] checkpointPointers) {
        this.checkpointPointers = checkpointPointers;
    }

    /**
     * Creates a new instance in the {@link State#INPROGRESS} state.
     */
    public static TransactionEdit createStarted(long writePointer, long visibilityUpperBound, long expirationDate,
            TransactionType type) {
        return new TransactionEdit(writePointer, visibilityUpperBound, State.INPROGRESS, expirationDate, null, 0L,
                false, type, null, 0L, 0L, null);
    }

    /**
     * Creates a new instance in the {@link State#COMMITTING} state.
     */
    public static TransactionEdit createCommitting(long writePointer, Set<ChangeId> changes) {
        return new TransactionEdit(writePointer, 0L, State.COMMITTING, 0L, changes, 0L, false, null, null, 0L, 0L,
                null);
    }

    /**
     * Creates a new instance in the {@link State#COMMITTED} state.
     */
    public static TransactionEdit createCommitted(long writePointer, Set<ChangeId> changes, long nextWritePointer,
            boolean canCommit) {
        return new TransactionEdit(writePointer, 0L, State.COMMITTED, 0L, changes, nextWritePointer, canCommit,
                null, null, 0L, 0L, null);
    }

    /**
     * Creates a new instance in the {@link State#ABORTED} state.
     */
    public static TransactionEdit createAborted(long writePointer, TransactionType type,
            long[] checkpointPointers) {
        return new TransactionEdit(writePointer, 0L, State.ABORTED, 0L, null, 0L, false, type, null, 0L, 0L,
                checkpointPointers);
    }

    /**
     * Creates a new instance in the {@link State#INVALID} state.
     */
    public static TransactionEdit createInvalid(long writePointer) {
        return new TransactionEdit(writePointer, 0L, State.INVALID, 0L, null, 0L, false, null, null, 0L, 0L, null);
    }

    /**
     * Creates a new instance in the {@link State#MOVE_WATERMARK} state.
     */
    public static TransactionEdit createMoveWatermark(long writePointer) {
        return new TransactionEdit(writePointer, 0L, State.MOVE_WATERMARK, 0L, null, 0L, false, null, null, 0L, 0L,
                null);
    }

    /**
     * Creates a new instance in the {@link State#TRUNCATE_INVALID_TX} state.
     */
    public static TransactionEdit createTruncateInvalidTx(Set<Long> truncateInvalidTx) {
        return new TransactionEdit(0L, 0L, State.TRUNCATE_INVALID_TX, 0L, null, 0L, false, null, truncateInvalidTx,
                0L, 0L, null);
    }

    /**
     * Creates a new instance in the {@link State#TRUNCATE_INVALID_TX} state.
     */
    public static TransactionEdit createTruncateInvalidTxBefore(long truncateInvalidTxTime) {
        return new TransactionEdit(0L, 0L, State.TRUNCATE_INVALID_TX, 0L, null, 0L, false, null, null,
                truncateInvalidTxTime, 0L, null);
    }

    /**
     * Creates a new instance in the {@link State#CHECKPOINT} state.
     */
    public static TransactionEdit createCheckpoint(long writePointer, long parentWritePointer) {
        return new TransactionEdit(writePointer, 0L, State.CHECKPOINT, 0L, null, 0L, false, null, null, 0L,
                parentWritePointer, null);
    }

    @Override
    public void write(DataOutput out) throws IOException {
        TransactionEditCodecs.encode(this, out);
    }

    @Override
    public void readFields(DataInput in) throws IOException {
        TransactionEditCodecs.decode(this, in);
    }

    @Override
    public final boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof TransactionEdit)) {
            return false;
        }

        TransactionEdit that = (TransactionEdit) o;

        return Objects.equal(this.writePointer, that.writePointer)
                && Objects.equal(this.visibilityUpperBound, that.visibilityUpperBound)
                && Objects.equal(this.commitPointer, that.commitPointer)
                && Objects.equal(this.expirationDate, that.expirationDate) && Objects.equal(this.state, that.state)
                && Objects.equal(this.changes, that.changes) && Objects.equal(this.canCommit, that.canCommit)
                && Objects.equal(this.type, that.type)
                && Objects.equal(this.truncateInvalidTx, that.truncateInvalidTx)
                && Objects.equal(this.truncateInvalidTxTime, that.truncateInvalidTxTime)
                && Objects.equal(this.parentWritePointer, that.parentWritePointer)
                && Arrays.equals(this.checkpointPointers, that.checkpointPointers);
    }

    @Override
    public final int hashCode() {
        return Objects.hashCode(writePointer, visibilityUpperBound, commitPointer, expirationDate, state, changes,
                canCommit, type, parentWritePointer, checkpointPointers);
    }

    @Override
    public String toString() {
        return Objects.toStringHelper(this).add("writePointer", writePointer)
                .add("visibilityUpperBound", visibilityUpperBound).add("commitPointer", commitPointer)
                .add("expiration", expirationDate).add("state", state)
                .add("changesSize", changes != null ? changes.size() : 0).add("canCommit", canCommit)
                .add("type", type).add("truncateInvalidTx", truncateInvalidTx)
                .add("truncateInvalidTxTime", truncateInvalidTxTime).add("parentWritePointer", parentWritePointer)
                .add("checkpointPointers", checkpointPointers).toString();
    }

}