package org.deuce.transaction.estmmvcc;
import org.deuce.transaction.estmmvcc.Context.LockTable;
import org.deuce.transaction.estmmvcc.field.ReadFieldAccess;
import org.deuce.transform.Exclude;
/**
* LastReadEntries implement a pool of k=2 read entries
*
* @author Vincent Gramoli
*/
@Exclude
final public class LastReadEntries {
protected ReadFieldAccess[] entries;
private int size;
private boolean first = true;
public LastReadEntries() {
// by default, record k=2 read entries
entries = new ReadFieldAccess[2];
entries[0] = new ReadFieldAccess();
entries[1] = new ReadFieldAccess();
size = 0;
}
public void clear() {
size = 0;
}
public void add(Object reference, long field, int hash, int lock) {
if (size < 2) size++;
ReadFieldAccess r = first ? entries[0] : entries[1];
r.init(reference, field, hash, lock);
first = !first;
}
public boolean isEmpty() {
return (size==0);
}
public int getSize() {
return size;
}
/**
* Check if the last-read-entries are still valid
*
* @param id the identifier of the transaction
* @param timestamp the timestamp we should compare it to
* @return the validation result
*/
public boolean validate(int id, int timestamp) {
for (int i = 0; i < size; i++) {
int lock = LockTable.checkLock(entries[i].getHash(), id);
if (lock > timestamp && lock >= 0) {
// Too recent version: cannot validate
return false;
}
}
return true;
}
/**
* Check if the last-read-entries are still valid
*
* @param id the identifier of the transaction
* @return the validation result
*/
public boolean validate(int id) {
for (int i = 0; i < size; i++) {
ReadFieldAccess r = entries[i];
int lock = LockTable.checkLock(r.getHash(), id);
if (lock >= 0 && lock != r.getLock()) {
// Other version: cannot validate
return false;
}
}
return true;
}
public boolean contains(Object obj, long field) {
for (int i = 0; i < size; i++) {
ReadFieldAccess r = entries[i];
if (r.getField() == field && r.getReference() == obj)
return true;
}
return false;
}
}