blob: d640e27edcbd6a9ed6b43dbf6554b3befedd0dc6 [file] [log] [blame]
/*-
* 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 java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.sleepycat.je.log.LogUtils;
import com.sleepycat.je.log.Loggable;
import com.sleepycat.je.utilint.DbLsn;
import com.sleepycat.je.utilint.Timestamp;
import com.sleepycat.je.utilint.VLSN;
/**
* This class indicates the end of a partial rollback at syncup. This is a
* non-replicated entry. Although this is a replication related class, it
* resides in the utilint package because it is referenced in
* LogEntryType.java, and is used in a general way at recovery.
*/
public class RollbackStart implements Loggable {
/* The matchpoint that is the logical start of this rollback period. */
private VLSN matchpointVLSN;
private long matchpointLSN;
/*
* The active txn list are unfinished transactions that will be rolled back
* by syncup.
*/
private Set<Long> activeTxnIds;
/* For debugging in the field */
private Timestamp time;
public RollbackStart(VLSN matchpointVLSN,
long matchpointLSN,
Set<Long> activeTxnIds) {
this.matchpointVLSN = matchpointVLSN;
this.matchpointLSN = matchpointLSN;
this.activeTxnIds = activeTxnIds;
time = new Timestamp(System.currentTimeMillis());
}
/**
* For constructing from the log.
*/
public RollbackStart() {
}
public long getMatchpoint() {
return matchpointLSN;
}
public Set<Long> getActiveTxnIds() {
return activeTxnIds;
}
public VLSN getMatchpointVLSN() {
return matchpointVLSN;
}
/**
* @see Loggable#getLogSize
*/
public int getLogSize() {
int size = LogUtils.getPackedLongLogSize(matchpointVLSN.getSequence()) +
LogUtils.getPackedLongLogSize(matchpointLSN) +
LogUtils.getTimestampLogSize(time) +
LogUtils.getPackedIntLogSize(activeTxnIds.size());
for (Long id : activeTxnIds) {
size += LogUtils.getPackedLongLogSize(id);
}
return size;
}
/**
* @see Loggable#writeToLog
*/
public void writeToLog(ByteBuffer buffer) {
LogUtils.writePackedLong(buffer, matchpointVLSN.getSequence());
LogUtils.writePackedLong(buffer, matchpointLSN);
LogUtils.writeTimestamp(buffer, time);
LogUtils.writePackedInt(buffer, activeTxnIds.size());
for (Long id : activeTxnIds) {
LogUtils.writePackedLong(buffer, id);
}
}
/**"
* @see Loggable#readFromLog
*/
public void readFromLog(ByteBuffer buffer, int entryVersion) {
matchpointVLSN = new VLSN(LogUtils.readPackedLong(buffer));
matchpointLSN = LogUtils.readPackedLong(buffer);
/* the timestamp is packed -- double negative, unpacked == false */
time = LogUtils.readTimestamp(buffer, false /* unpacked. */);
int setSize = LogUtils.readPackedInt(buffer);
activeTxnIds = new HashSet<Long>(setSize);
for (int i = 0; i < setSize; i++) {
activeTxnIds.add(LogUtils.readPackedLong(buffer));
}
}
/**
* @see Loggable#dumpLog
*/
public void dumpLog(StringBuilder sb, boolean verbose) {
sb.append(" matchpointVLSN=").append(matchpointVLSN.getSequence());
sb.append(" matchpointLSN=");
sb.append(DbLsn.getNoFormatString(matchpointLSN));
/* Make sure the active txns are listed in order, partially for the sake
* of the LoggableTest unit test, which expects the toString() for two
* equivalent objects to always display the same, and partially for
* ease of debugging.
*/
List<Long> displayTxnIds = new ArrayList<Long>(activeTxnIds);
Collections.sort(displayTxnIds);
sb.append(" activeTxnIds=") .append(displayTxnIds);
sb.append("\" time=\"").append(time);
}
/**
* @see Loggable#getTransactionId
*/
public long getTransactionId() {
return 0;
}
/**
* @see Loggable#logicalEquals
*/
public boolean logicalEquals(Loggable other) {
if (!(other instanceof RollbackStart)) {
return false;
}
RollbackStart otherRS = (RollbackStart) other;
return (matchpointVLSN.equals(otherRS.matchpointVLSN) &&
(matchpointLSN == otherRS.matchpointLSN) &&
time.equals(otherRS.time) &&
activeTxnIds.equals(otherRS.activeTxnIds));
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
dumpLog(sb, true);
return sb.toString();
}
}