Avoid serialising state if it was already serialised (#39179)

When preparing the state to send to other nodes, we're serializing it
for each node, despite using putIfAbsent.
This commit checks if the state was already serialized for this node
version before performing the potentially expensive computation.
The map is not used by multiple threads, so computeIfAbsent is not
needed (and could not be used here easily, because IOException could
be thrown).

(cherry picked from commit c99be63b43f5250f3cd220130df73c5e9e097459)
This commit is contained in:
Andrey Ershov 2019-03-06 13:49:24 +01:00
parent 95409d3a7e
commit 52fd102e23
1 changed files with 6 additions and 2 deletions

View File

@ -320,13 +320,17 @@ public class PublicationTransportHandler {
} }
try { try {
if (sendFullVersion || !previousState.nodes().nodeExists(node)) { if (sendFullVersion || !previousState.nodes().nodeExists(node)) {
serializedStates.putIfAbsent(node.getVersion(), serializeFullClusterState(clusterState, node.getVersion())); if (serializedStates.containsKey(node.getVersion()) == false) {
serializedStates.put(node.getVersion(), serializeFullClusterState(clusterState, node.getVersion()));
}
} else { } else {
// will send a diff // will send a diff
if (diff == null) { if (diff == null) {
diff = clusterState.diff(previousState); diff = clusterState.diff(previousState);
} }
serializedDiffs.putIfAbsent(node.getVersion(), serializeDiffClusterState(diff, node.getVersion())); if (serializedDiffs.containsKey(node.getVersion()) == false) {
serializedDiffs.put(node.getVersion(), serializeDiffClusterState(diff, node.getVersion()));
}
} }
} catch (IOException e) { } catch (IOException e) {
throw new ElasticsearchException("failed to serialize cluster state for publishing to node {}", e, node); throw new ElasticsearchException("failed to serialize cluster state for publishing to node {}", e, node);