[CORE] Add cluster and index state checksums

This commit adds checksumming for cluster and index states. It moves
from a plain XContent based on-disk format to a more structured binary
format including a header and footer as well as a CRC32 checksum for
each of these files. Since previous versions didn't write any format
identifier etc. this commit adds a file extension `.st` for states
that have header/footer and checksum.
This commit also moves over to write temporary files and moves them into
place with an atomic move operation. This commit also serializes and
deserializes the states without materilazing them into opaque memory.

Closes #7586
I think here we can skip looping through all the different `fileAndVersion` candidates, if the first (meaning the highest version) file doesn't parse successfully, we are going to throw an exception and halt operations anyway, so we shouldn't bother continuing to read the older state files. It looks like this already breaks once one has been read anyway, so the loop isn't actually doing much other than potentially adding exceptions for older state files.

The only thing I could think of would be that maybe the latest version state file would be empty, so we should go to the next-latest version? If not, it should be replaceable with:

```java
CollectionUtil.timSort(files); // sort to get the highest version first
if (files.size() > 0) {
  FileAndVersion fileAndVersion = files[0];
  try {
    ... parse file ...
  } catch (Throwable e) {
    throw new ElasticsearchException("failed to read state from: " + fileAndVersion.file, e);
  }
}
```

and skip the looping with `break`.