package org.deuce.transaction.estmstats;
import org.deuce.transaction.estmstats.Context.LockTable;
import org.deuce.transaction.estmstats.field.ReadFieldAccess;
import org.deuce.transform.Exclude;
/**
* LastReadEntries implement a rotating buffer of k read entries
*
* @author Vincent Gramoli
*/
@Exclude
final public class LastReadEntries {
protected ReadFieldAccess[] entries;
private int size;
//private boolean first = true;
// the elasticity parameter (capacity of the elastic rotating buffer)
private final int elasticity = 2;
private int marker = 0;
public LastReadEntries() {
// by default, record k=2 read entries
entries = new ReadFieldAccess[elasticity];
for (int i=0; i<elasticity; i++) {
entries[i] = new ReadFieldAccess();
}
size = 0;
}
public void clear() {
size = 0;
}
public void add(Object reference, long field, int hash, int lock) {
if (size < elasticity) size++;
//ReadFieldAccess r = first ? entries[0] : entries[1];
ReadFieldAccess r = entries[marker];
marker = ++marker % elasticity;
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;
}
}