use of org.corfudb.protocols.wireprotocol.ILogData 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.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.
the class OptimisticTransactionalContext method tryCommitAllProxies.
/** Try to commit the optimistic updates to each proxy. */
protected void tryCommitAllProxies() {
// First, get the committed entry
// in order to get the backpointers
// and the underlying SMREntries.
ILogData committedEntry = this.builder.getRuntime().getAddressSpaceView().read(commitAddress);
updateAllProxies(x -> {
log.trace("Commit[{}] Committing {}", this, x);
x.getUnderlyingObject().optimisticCommitUnsafe();
x.getUnderlyingObject().syncObjectUnsafe(commitAddress - 1);
List<SMREntry> committedWrites = getWriteSetEntryList(x.getStreamID());
List<SMREntry> entryWrites = ((ISMRConsumable) committedEntry.getPayload(this.getBuilder().runtime)).getSMRUpdates(x.getStreamID());
if (committedWrites.size() == entryWrites.size()) {
IntStream.range(0, committedWrites.size()).forEach(i -> {
if (committedWrites.get(i).isUndoable()) {
entryWrites.get(i).setUndoRecord(committedWrites.get(i).getUndoRecord());
}
});
}
x.getUnderlyingObject().seek(commitAddress + 1);
log.trace("Commit[{}] Committed {}", this, x);
});
}
use of org.corfudb.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.
the class AddressSpaceView method cacheFetch.
/**
* Fetch an address for insertion into the cache.
*
* @param address An address to read from.
* @return A result to be cached. If the readresult is empty,
* This entry will be scheduled to self invalidate.
*/
@Nonnull
private ILogData cacheFetch(long address) {
log.trace("Cache miss @ {}, fetching.", address);
ILogData result = fetch(address);
if (result.getType() == DataType.EMPTY) {
throw new RuntimeException("Unexpected empty return at " + address + " from fetch");
}
return result;
}
use of org.corfudb.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.
the class ChainReplicationProtocol method peek.
/** {@inheritDoc} */
@Override
public ILogData peek(Layout layout, long globalAddress) {
int numUnits = layout.getSegmentLength(globalAddress);
log.trace("Read[{}]: chain {}/{}", globalAddress, numUnits, numUnits);
// In chain replication, we read from the last unit, though we can optimize if we
// know where the committed tail is.
ILogData ret = CFUtils.getUninterruptibly(layout.getLogUnitClient(globalAddress, numUnits - 1).read(globalAddress)).getReadSet().getOrDefault(globalAddress, null);
return ret == null || ret.isEmpty() ? null : ret;
}
use of org.corfudb.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.
the class ChainReplicationProtocol method recover.
/** Recover a failed write at the given global address,
* driving it to completion by invoking the recovery
* protocol.
*
* When this function returns the given globalAddress
* is guaranteed to contain a committed value.
*
* If there was no data previously written at the address,
* this function will throw a runtime exception. The
* recovery protocol should -only- be invoked if we
* previously were overwritten.
*
* @oaram layout The layout to use for the recovery.
* @param globalAddress The global address to drive
* the recovery protocol
*
*/
protected void recover(Layout layout, long globalAddress) {
// In chain replication, we started writing from the head,
// and propagated down to the tail. To recover, we start
// reading from the head, which should have the data
// we are trying to recover
int numUnits = layout.getSegmentLength(globalAddress);
log.debug("Recover[{}]: read chain head {}/{}", globalAddress, 1, numUnits);
ILogData ld = CFUtils.getUninterruptibly(layout.getLogUnitClient(globalAddress, 0).read(globalAddress)).getReadSet().getOrDefault(globalAddress, null);
// write was successful or not.
if (ld == null || ld.isEmpty()) {
throw new RecoveryException("Failed to read data during recovery at chain head.");
}
// now we go down the chain and write, ignoring any overwrite exception we get.
for (int i = 1; i < numUnits; i++) {
log.debug("Recover[{}]: write chain {}/{}", layout, i + 1, numUnits);
// in the chain.
try {
CFUtils.getUninterruptibly(layout.getLogUnitClient(globalAddress, i).write(ld), OverwriteException.class);
// We successfully recovered a write to this member of the chain
log.debug("Recover[{}]: recovered write at chain {}/{}", layout, i + 1, numUnits);
} catch (OverwriteException oe) {
// This member already had this data (in some cases, the write might have
// been committed to all members, so this is normal).
log.debug("Recover[{}]: overwritten at chain {}/{}", layout, i + 1, numUnits);
}
}
}
Aggregations