package org.radargun.stages.cache.background;
/**
* Checker used for {@link org.radargun.stages.cache.background.PrivateLogValue shared log values}
*
* @author Radim Vansa <rvansa@redhat.com>
*/
public class SharedLogChecker extends LogChecker {
public SharedLogChecker(int id, BackgroundOpsManager manager) {
super(manager.getName() + "-Checker-" + id, manager);
}
@Override
protected StressorRecord newRecord(StressorRecord record, long operationId, long seed) {
return new StressorRecord(record, operationId, seed);
}
@Override
protected Object findValue(StressorRecord record) throws Exception {
// The value can always be moved so that we can't read it directly. However, if the value has not changed
// since previous read, the complement could not have been removed - the operation definitely is not
// in any entry.
Object value = null, prevValue = null, prev2Value;
long keyId = record.getKeyId();
for (int i = 0; i < 100; ++i) {
prev2Value = prevValue;
prevValue = value;
value = basicCache.get(keyGenerator.generateKey(keyId));
if (containsOperation(value, record) || (value != null && value.equals(prev2Value))) {
break;
}
if (keyId < 0 && record.getCurrentConfirmationTimestamp() < 0) {
// do not poll it 100x when we're not sure that the operation is written, try just twice
break;
}
keyId = ~keyId;
}
return value;
}
@Override
protected boolean containsOperation(Object value, StressorRecord record) {
if (value == null) {
return false;
}
if (!(value instanceof SharedLogValue)) {
log.error("Key " + record.getKeyId() + " has unexpected value " + value);
return false;
}
SharedLogValue logValue = (SharedLogValue) value;
if (logValue.contains(record.getThreadId(), record.getOperationId())) {
return true;
}
return false;
}
}