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

org.apache.tephra.persist.TransactionEdit Maven / Gradle / Ivy

There is a newer version: 4.15.0-HBase-1.5
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.tephra.persist;

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

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 changes;
  /** Whether or not the COMMITTED change should be fully committed. */
  private boolean canCommit;
  private TransactionType type;
  private Set 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 changes, long commitPointer, boolean canCommit, TransactionType type,
                  Set 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.emptySet();
    this.commitPointer = commitPointer;
    this.canCommit = canCommit;
    this.type = type;
    this.truncateInvalidTx = truncateInvalidTx != null ? truncateInvalidTx : Collections.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 getChanges() {
    return changes;
  }

  void setChanges(Set 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 getTruncateInvalidTx() {
    return truncateInvalidTx;
  }

  void setTruncateInvalidTx(Set 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 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 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 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);
  }

  /**
   * Creates a new instance from {@link co.cask.tephra.persist.TransactionEdit}.
   */
  @Deprecated
  public static TransactionEdit convertCaskTxEdit(co.cask.tephra.persist.TransactionEdit txEdit) {
    if (txEdit == null) {
      return null;
    }
    return new TransactionEdit(txEdit.getWritePointer(), txEdit.getVisibilityUpperBound(),
                               TransactionEdit.State.valueOf(txEdit.getState().toString()), txEdit.getExpiration(),
                               txEdit.getChanges(), txEdit.getCommitPointer(), txEdit.getCanCommit(), txEdit.getType(),
                               txEdit.getTruncateInvalidTx(), txEdit.getTruncateInvalidTxTime(),
                               txEdit.getParentWritePointer(), txEdit.getCheckpointPointers());
  }

  @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();
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy