blob: 560d69ad5c2eb0df3440b267fd24252140765b36 [file] [log] [blame]
/*
* Copyright © 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.util;
import co.cask.tephra.Transaction;
import co.cask.tephra.TransactionManager;
import co.cask.tephra.TransactionType;
import co.cask.tephra.TxConstants;
import co.cask.tephra.persist.TransactionSnapshot;
import com.google.common.primitives.Longs;
import java.util.Map;
/**
* Utility methods supporting transaction operations.
*/
public class TxUtils {
private static final long EARLIEST_TX_TIMESTAMP = System.currentTimeMillis() * TxConstants.MAX_TX_PER_MS / 1000;
/**
* Returns the oldest visible timestamp for the given transaction, based on the TTLs configured for each column
* family. If no TTL is set on any column family, the oldest visible timestamp will be {@code 0}.
* @param ttlByFamily A map of column family name to TTL value (in milliseconds)
* @param tx The current transaction
* @return The oldest timestamp that will be visible for the given transaction and TTL configuration
*/
public static long getOldestVisibleTimestamp(Map<byte[], Long> ttlByFamily, Transaction tx) {
long oldestVisible = tx.getVisibilityUpperBound();
// we know that data will not be cleaned up while this tx is running up to this point as janitor uses it
for (Long familyTTL : ttlByFamily.values()) {
oldestVisible =
Math.min(familyTTL <= 0 ? 0 : tx.getVisibilityUpperBound() - familyTTL * TxConstants.MAX_TX_PER_MS,
oldestVisible);
}
return oldestVisible;
}
/**
* Returns the maximum timestamp to use for time-range operations, based on the given transaction.
* @param tx The current transaction
* @return The maximum timestamp (exclusive) to use for time-range operations
*/
public static long getMaxVisibleTimestamp(Transaction tx) {
// NOTE: +1 here because we want read up to writepointer inclusive, but timerange's end is exclusive
// however, we also need to guard against overflow in the case write pointer is set to MAX_VALUE
return tx.getWritePointer() < Long.MAX_VALUE ?
tx.getWritePointer() + 1 : tx.getWritePointer();
}
/**
* Creates a "dummy" transaction based on the given snapshot's state. This is not a "real" transaction in the
* sense that it has not been started, data should not be written with it, and it cannot be committed. However,
* this can still be useful for filtering data according to the snapshot's state. Instead of the actual
* write pointer from the snapshot, however, we use {@code Long.MAX_VALUE} to avoid mis-identifying any cells as
* being written by this transaction (and therefore visible).
*/
public static Transaction createDummyTransaction(TransactionSnapshot snapshot) {
return new Transaction(snapshot.getReadPointer(), Long.MAX_VALUE,
Longs.toArray(snapshot.getInvalid()),
Longs.toArray(snapshot.getInProgress().keySet()),
TxUtils.getFirstShortInProgress(snapshot.getInProgress()), TransactionType.SHORT);
}
/**
* Returns the write pointer for the first "short" transaction that in the in-progress set, or
* {@link Transaction#NO_TX_IN_PROGRESS} if none.
*/
public static long getFirstShortInProgress(Map<Long, TransactionManager.InProgressTx> inProgress) {
long firstShort = Transaction.NO_TX_IN_PROGRESS;
for (Map.Entry<Long, TransactionManager.InProgressTx> entry : inProgress.entrySet()) {
if (!entry.getValue().isLongRunning()) {
firstShort = entry.getKey();
break;
}
}
return firstShort;
}
public static long cellTimestampToTxTimestamp(long cellTs) {
System.out.println("111111111 CellTs = " + cellTs + " EarliestTxTs = " + EARLIEST_TX_TIMESTAMP);
return cellTs > EARLIEST_TX_TIMESTAMP ? cellTs : cellTs * TxConstants.MAX_TX_PER_MS;
}
}