use of org.corfudb.runtime.exceptions.ValueAdoptedException in project CorfuDB by CorfuDB.
the class LogUnitClientTest method valueCanBeAdopted.
@Test
public void valueCanBeAdopted() throws ExecutionException, InterruptedException {
byte[] testString = "hello world".getBytes();
client.write(0, Collections.<UUID>emptySet(), new IMetadata.DataRank(1), testString, Collections.emptyMap()).get();
LogData r = client.read(0).get().getReadSet().get(0L);
assertThat(r.getType()).isEqualTo(DataType.DATA);
assertThat(r.getPayload(new CorfuRuntime())).isEqualTo(testString);
try {
ILogData data = createEmptyData(0, DataType.RANK_ONLY, new IMetadata.DataRank(2)).getSerialized();
client.write(data).get();
fail();
} catch (Exception e) {
// expected
assertEquals(ValueAdoptedException.class, e.getCause().getClass());
ValueAdoptedException ex = (ValueAdoptedException) e.getCause();
ReadResponse read = ex.getReadResponse();
LogData log = read.getReadSet().get(0l);
assertThat(log.getType()).isEqualTo(DataType.DATA);
assertThat(log.getPayload(new CorfuRuntime())).isEqualTo(testString);
;
}
r = client.read(0).get().getReadSet().get(0L);
assertThat(r.getType()).isEqualTo(DataType.DATA);
assertThat(r.getPayload(new CorfuRuntime())).isEqualTo(testString);
}
use of org.corfudb.runtime.exceptions.ValueAdoptedException in project CorfuDB by CorfuDB.
the class StreamLogWithRankedAddressSpaceTest method testProposalWithHigherRankAgainstData.
@Test
public void testProposalWithHigherRankAgainstData() {
StreamLogFiles log = new StreamLogFiles(getContext(), false);
long address = 0;
writeToLog(log, address, DataType.DATA, "v-1", 1);
LogData value1 = log.read(address);
assertTrue(new String(value1.getData()).contains("v-1"));
try {
writeToLog(log, address, DataType.RANK_ONLY, "v-2", 2);
fail();
} catch (ValueAdoptedException e) {
LogData logData = e.getReadResponse().getReadSet().get(0l);
assertTrue(new String(logData.getData()).contains("v-1"));
}
LogData value2 = log.read(address);
assertTrue(new String(value2.getData()).contains("v-1"));
log.close();
}
use of org.corfudb.runtime.exceptions.ValueAdoptedException in project CorfuDB by CorfuDB.
the class QuorumReplicationProtocol method getAdoptedValueWithHighestRankIfPresent.
private ReadResponse getAdoptedValueWithHighestRankIfPresent(Long position, Set<Throwable> throwables) {
ReadResponse result = null;
IMetadata.DataRank maxRank = null;
for (Throwable t : throwables) {
if (t instanceof ValueAdoptedException) {
ValueAdoptedException ve = (ValueAdoptedException) t;
ReadResponse r = ve.getReadResponse();
LogData ld = r.getReadSet().get(position);
if (maxRank == null || maxRank.compareTo(ld.getRank()) < 0) {
maxRank = ld.getRank();
result = r;
}
}
}
return result;
}
use of org.corfudb.runtime.exceptions.ValueAdoptedException in project CorfuDB by CorfuDB.
the class StreamLogWithRankedAddressSpace method assertAppendPermittedUnsafe.
/**
* Check whether the data can be appended to a given log address.
* Note that it is not permitted multiple threads to access the same log address
* concurrently through this method, this method does not lock or synchronize.
* This method needs
* @param address
* @param newEntry
* @throws DataOutrankedException if the log entry cannot be assigned to this log address as there is a data with higher rank
* @throws ValueAdoptedException if the new message is a proposal during the two phase recovery write and there is an existing
* data at this log address already.
* @throw OverwriteException if the new data is with rank 0 (not from recovery write). This can happen only if there is a bug in the client implementation.
*/
default default void assertAppendPermittedUnsafe(long address, LogData newEntry) throws DataOutrankedException, ValueAdoptedException {
LogData oldEntry = read(address);
if (oldEntry.getType() == DataType.EMPTY) {
return;
}
if (newEntry.getRank().getRank() == 0) {
// data consistency in danger
throw new OverwriteException();
}
int compare = newEntry.getRank().compareTo(oldEntry.getRank());
if (compare < 0) {
throw new DataOutrankedException();
}
if (compare > 0) {
if (newEntry.getType() == DataType.RANK_ONLY && oldEntry.getType() != DataType.RANK_ONLY) {
// the new data is a proposal, the other data is not, so the old value should be adopted
ReadResponse resp = new ReadResponse();
resp.put(address, oldEntry);
throw new ValueAdoptedException(resp);
} else {
return;
}
}
}
Aggregations