use of org.apache.cassandra.db.transaction.PendingTransactionColumn in project eiger by wlloyd.
the class ThriftConverter method applyCheckTransactionUpdate.
//Assumes the lock on currentlyVisibleColumn is already held, so we can update it's previousVersions
private static void applyCheckTransactionUpdate(org.apache.cassandra.db.Column currentlyVisibleColumn, long transactionId, CommitOrNotYetTime checkResult) {
long newEarliestValidTime = checkResult.commitTime != null ? checkResult.commitTime : checkResult.notYetCommittedTime;
//To simplify this code I'll temporarily add the current versions to previousVersions to get all versions
//but it must be removed before the function returns
NavigableSet<IColumn> allVersions = currentlyVisibleColumn.previousVersions();
allVersions.add(currentlyVisibleColumn);
//first pass, find the update PTC and determine the minimumPendingTransactionTIme
PendingTransactionColumn updatedColumn = null;
Long minPendingTransactionTime = Long.MAX_VALUE;
for (IColumn column : allVersions.descendingSet()) {
if (column instanceof PendingTransactionColumn) {
if (((PendingTransactionColumn) column).getTransactionId() == transactionId) {
updatedColumn = (PendingTransactionColumn) column;
if (checkResult.commitTime == null) {
minPendingTransactionTime = Math.min(checkResult.notYetCommittedTime, minPendingTransactionTime);
}
} else {
minPendingTransactionTime = Math.min(column.earliestValidTime(), minPendingTransactionTime);
}
}
}
//TODO just return if updatedColumn is null
assert updatedColumn != null : "This is actually fine, but don't expect this initially";
//only do the update if we're actually moving the evt forward
if (updatedColumn != null && newEarliestValidTime > updatedColumn.earliestValidTime()) {
//remove the updatedColumn and reinsert it with its new EVT
boolean removed = allVersions.remove(updatedColumn);
assert removed == true;
updatedColumn.setEarliestValidTime(newEarliestValidTime);
allVersions.add(updatedColumn);
//second pass, update all LVTs
Long previousEVT = null;
for (IColumn column : allVersions) {
if (minPendingTransactionTime == Long.MAX_VALUE) {
column.setLatestValidTime(previousEVT);
} else if (minPendingTransactionTime <= column.earliestValidTime()) {
column.setLatestValidTime(column.earliestValidTime());
} else {
assert minPendingTransactionTime > column.earliestValidTime();
column.setLatestValidTime(Math.min(minPendingTransactionTime, previousEVT));
}
previousEVT = column.earliestValidTime();
}
}
//remove the visible version from previousVersion before returning
allVersions.remove(currentlyVisibleColumn);
}
use of org.apache.cassandra.db.transaction.PendingTransactionColumn in project eiger by wlloyd.
the class ThriftConverter method findAndUpdatePendingTransactions.
/** Find the transactionIds of all pending transaction that could affect this column at the chosenTime
* Also update any checked transactions ids that can affect this transaction
* @param chosenColumn
* @param chosenTime
* @param currentlyVisibleColumn This is not necessary the chosen column, it contains the list of previousVersions
* @return Relevant pending transactionIds, or null if none
*/
private static Set<Long> findAndUpdatePendingTransactions(org.apache.cassandra.db.Column chosenColumn, long chosenTime, org.apache.cassandra.db.Column currentlyVisibleColumn) {
if (!(chosenColumn instanceof PendingTransactionColumn) && (!chosenColumn.isSetLatestValidTime() || chosenTime <= chosenColumn.latestValidTime())) {
//if the chosenColumn isn't a PTC and EVT < chosen < LVT then no pending transactions
assert chosenColumn.earliestValidTime() <= chosenTime;
return null;
} else {
Set<Long> pendingTransactionIds = new HashSet<Long>();
//lock for use of previousVersions
synchronized (currentlyVisibleColumn) {
for (IColumn oldColumn : currentlyVisibleColumn.previousVersions()) {
if (oldColumn.earliestValidTime() > chosenTime) {
continue;
} else {
if (oldColumn instanceof PendingTransactionColumn) {
long transactionId = ((PendingTransactionColumn) oldColumn).getTransactionId();
CommitOrNotYetTime checkResult = BatchMutateTransactionUtil.findCheckedTransactionResult(transactionId);
if (checkResult == null) {
pendingTransactionIds.add(transactionId);
} else {
applyCheckTransactionUpdate(currentlyVisibleColumn, transactionId, checkResult);
}
}
}
}
}
return pendingTransactionIds.size() == 0 ? null : pendingTransactionIds;
}
}
use of org.apache.cassandra.db.transaction.PendingTransactionColumn in project eiger by wlloyd.
the class ThriftConverter method thriftifyColumn.
private static Column thriftifyColumn(org.apache.cassandra.db.Column column) {
if (column instanceof PendingTransactionColumn) {
return thriftifyPendingTransactionColumn((PendingTransactionColumn) column);
} else if (column instanceof org.apache.cassandra.db.DeletedColumn) {
return thriftifyDeletedColumn((DeletedColumn) column);
}
Column thrift_column = new Column(column.name()).setValue(column.value()).setTimestamp(column.timestamp());
thrift_column.setEarliest_valid_time(column.earliestValidTime());
thrift_column.setLatest_valid_time(column.isSetLatestValidTime() ? column.latestValidTime() : LamportClock.getVersion());
if (column instanceof ExpiringColumn) {
thrift_column.setTtl(((ExpiringColumn) column).getTimeToLive());
}
ByteBuffer transactionCoordinatorKey = column.transactionCoordinatorKey();
if (transactionCoordinatorKey != null) {
thrift_column.setTransactionCoordinatorKey(transactionCoordinatorKey);
}
return thrift_column;
}
use of org.apache.cassandra.db.transaction.PendingTransactionColumn in project eiger by wlloyd.
the class ColumnSerializer method deserialize.
@Override
public Column deserialize(DataInput dis, IColumnSerializer.Flag flag, int expireBefore) throws IOException {
ByteBuffer name = ByteBufferUtil.readWithShortLength(dis);
if (name.remaining() <= 0) {
String format = "invalid column name length %d%s";
String details = "";
if (dis instanceof FileDataInput) {
FileDataInput fdis = (FileDataInput) dis;
details = String.format(" (%s, %d bytes remaining)", fdis.getPath(), fdis.bytesRemaining());
}
throw new CorruptColumnException(String.format(format, name.remaining(), details));
}
int b = dis.readUnsignedByte();
if ((b & COUNTER_MASK) != 0) {
long timestampOfLastDelete = dis.readLong();
long ts = dis.readLong();
ByteBuffer value = ByteBufferUtil.readWithLength(dis);
Long lastAccessTime = dis.readLong();
if (lastAccessTime == Long.MIN_VALUE) {
lastAccessTime = null;
}
Long previousVersionLastAccessTime = dis.readLong();
if (previousVersionLastAccessTime == Long.MIN_VALUE) {
previousVersionLastAccessTime = null;
}
Long earliestValidTime = dis.readLong();
if (earliestValidTime == Long.MIN_VALUE) {
earliestValidTime = null;
}
Long latestValidTime = dis.readLong();
if (latestValidTime == Long.MIN_VALUE) {
latestValidTime = null;
}
NavigableSet<IColumn> previousVersions;
int previousVersionsLength = dis.readInt();
if (previousVersionsLength == -1) {
previousVersions = null;
} else {
previousVersions = new TreeSet<IColumn>(new EVTComparator());
for (int i = 0; i < previousVersionsLength; ++i) {
previousVersions.add(deserialize(dis));
}
}
int transactionCoordinatorKeyLength = dis.readInt();
ByteBuffer transactionCoordinatorKey = null;
if (transactionCoordinatorKeyLength > 0) {
ByteBufferUtil.readWithLength(dis);
}
return CounterColumn.create(name, value, ts, timestampOfLastDelete, flag, lastAccessTime, previousVersionLastAccessTime, earliestValidTime, latestValidTime, previousVersions);
} else if ((b & EXPIRATION_MASK) != 0) {
int ttl = dis.readInt();
int expiration = dis.readInt();
long ts = dis.readLong();
ByteBuffer value = ByteBufferUtil.readWithLength(dis);
Long lastAccessTime = dis.readLong();
if (lastAccessTime == Long.MIN_VALUE) {
lastAccessTime = null;
}
Long previousVersionLastAccessTime = dis.readLong();
if (previousVersionLastAccessTime == Long.MIN_VALUE) {
previousVersionLastAccessTime = null;
}
Long earliestValidTime = dis.readLong();
if (earliestValidTime == Long.MIN_VALUE) {
earliestValidTime = null;
}
Long latestValidTime = dis.readLong();
if (latestValidTime == Long.MIN_VALUE) {
latestValidTime = null;
}
SortedSet<IColumn> previousVersions;
int previousVersionsLength = dis.readInt();
if (previousVersionsLength == -1) {
previousVersions = null;
} else {
previousVersions = new TreeSet<IColumn>(new EVTComparator());
for (int i = 0; i < previousVersionsLength; ++i) {
previousVersions.add(deserialize(dis));
}
}
int transactionCoordinatorKeyLength = dis.readInt();
ByteBuffer transactionCoordinatorKey = null;
if (transactionCoordinatorKeyLength > 0) {
ByteBufferUtil.readWithLength(dis);
}
return ExpiringColumn.create(name, value, ts, ttl, expiration, expireBefore, flag);
} else {
long ts = dis.readLong();
ByteBuffer value = ByteBufferUtil.readWithLength(dis);
Long lastAccessTime = dis.readLong();
if (lastAccessTime == Long.MIN_VALUE) {
lastAccessTime = null;
}
Long previousVersionLastAccessTime = dis.readLong();
if (previousVersionLastAccessTime == Long.MIN_VALUE) {
previousVersionLastAccessTime = null;
}
Long earliestValidTime = dis.readLong();
if (earliestValidTime == Long.MIN_VALUE) {
earliestValidTime = null;
}
Long latestValidTime = dis.readLong();
if (latestValidTime == Long.MIN_VALUE) {
latestValidTime = null;
}
NavigableSet<IColumn> previousVersions;
int previousVersionsLength = dis.readInt();
if (previousVersionsLength == -1) {
previousVersions = null;
} else {
previousVersions = new TreeSet<IColumn>(new EVTComparator());
for (int i = 0; i < previousVersionsLength; ++i) {
previousVersions.add(deserialize(dis));
}
}
int transactionCoordinatorKeyLength = dis.readInt();
ByteBuffer transactionCoordinatorKey = null;
if (transactionCoordinatorKeyLength > 0) {
ByteBufferUtil.readWithLength(dis);
}
return (b & COUNTER_UPDATE_MASK) != 0 ? new CounterUpdateColumn(name, value, ts, lastAccessTime, previousVersionLastAccessTime, earliestValidTime, latestValidTime, previousVersions, transactionCoordinatorKey) : ((b & DELETION_MASK) != 0) ? new DeletedColumn(name, value, ts, lastAccessTime, previousVersionLastAccessTime, earliestValidTime, latestValidTime, previousVersions, transactionCoordinatorKey) : ((b & PENDING_TRANSACTION_MASK) != 0) ? new PendingTransactionColumn(name, value, ts, lastAccessTime, previousVersionLastAccessTime, earliestValidTime, latestValidTime, previousVersions, transactionCoordinatorKey) : new Column(name, value, ts, lastAccessTime, previousVersionLastAccessTime, earliestValidTime, latestValidTime, previousVersions, transactionCoordinatorKey);
}
}
use of org.apache.cassandra.db.transaction.PendingTransactionColumn in project eiger by wlloyd.
the class ColumnFamily method addPendingTransactionColumn.
public void addPendingTransactionColumn(QueryPath path, long transactionId, long pendingTime) {
if (path.superColumnName == null && path.columnName == null) {
assert false : "deleting entire columnFamilies in a transction is not yet supported";
// columnFamily.delete(localDeleteTime, timestamp);
} else if (path.columnName == null) {
assert false : "deleting SuperColumns in a transction is not yet supported";
// SuperColumn sc = new SuperColumn(path.superColumnName, columnFamily.getSubComparator());
// sc.delete(localDeleteTime, timestamp);
// columnFamily.addColumn(sc);
}
PendingTransactionColumn column = new PendingTransactionColumn(path.columnName, transactionId, pendingTime);
addColumn(path.superColumnName, column);
}
Aggregations