log(convObjectId, convResult);
WaveletName convWaveletName = IdHack.convWaveletNameFromConvObjectId(convObjectId);
// The most recent version of wavelet to get list of documents from.
WaveletDataImpl convWavelet = deserializeWavelet(convWaveletName, rawConvSnapshot);
long convVersion = convResult.getVersion();
Assert.check(convVersion == convWavelet.getVersion(),
"ConnectResult revision %s does not match wavelet version %s",
convVersion, convWavelet.getVersion());
if (!enableUdw) {
return waveWithoutUdw(convObjectId, convResult, convWavelet);
} else {
// Now we go and load some of the history in order to render diffs.
// For fully read or unread blips, we don't need to load any history.
// So the approach here is to find all the blips that are partially
// read, and get the smallest version.
// TODO(ohler): This should be getOrCreateAndConnect(), so that we can avoid
// reconstructing the state of the wavelet that we just created. But
// snapshot caching would help with this as well, so we should probably do
// that first.
SlobId udwId = waveletCreator.getOrCreateUdw(convObjectId);
Pair<ConnectResult, String> udwPair;
try {
udwPair = udwStore.connect(udwId, clientId);
} catch (SlobNotFoundException e) {
throw new RuntimeException("UDW disappeared right after getOrCreateUdw(): " + udwId);
}
ConnectResult udwResult = udwPair.getFirst();
WaveletName udwWaveletName = IdHack.udwWaveletNameFromConvObjectIdAndUdwObjectId(
convObjectId, udwId);
WaveletDataImpl udw = deserializeWavelet(udwWaveletName, udwPair.getSecond());
WalkaroundWaveletSnapshot udwSnapshot = serializer.createWaveletMessage(udw);
LoadedUdw loadedUdw = new LoadedUdw(udwId, udwResult, udwSnapshot);
if (!enableDiffOnOpen) {
return waveWithoutDiffs(convObjectId, convResult, convWavelet, loadedUdw);
}
StringMap<Long> lastReadVersions = getLastReadVersions(udw, convWavelet);
// The intermediate revision we'll load our wave in, as a simple optimization
// that avoids loading most of the history in many use cases. We can try to
// be smarter about this eventually.
long intermediateVersion = getMinReadVersion(convWavelet, lastReadVersions);
if (intermediateVersion <= 0 || intermediateVersion > convVersion) {
throw new AssertionError("Invalid intermediateVersion " + intermediateVersion
+ ", conv version = " + convVersion);
}
String intermediateSnapshot;
if (intermediateVersion == convVersion) {
intermediateSnapshot = rawConvSnapshot;
} else {
try {
intermediateSnapshot = convStore.loadAtVersion(convObjectId, intermediateVersion);
} catch (SlobNotFoundException e) {
throw new RuntimeException(
"Conv object disappeared when trying to load intermediate version: " + convObjectId);
}
}
WaveletDataImpl intermediateWavelet = deserializeWavelet(convWaveletName,
intermediateSnapshot);
Assert.check(intermediateWavelet.getVersion() == intermediateVersion);
// We have to stop getting the history at conv version, because we're not
// computing the metadata again for any concurrent ops that got added
// since we loaded the convResult - so we don't want them getting added
// into our diff snapshot. We can let the client catch up instead.