}
boolean success = false;
try {
final FileOutputStream fos = new FileOutputStream(f);
StringWriter sw = new StringWriter();
JSONStringer stringer = new JSONStringer();
try {
stringer.object();
stringer.key("version").value(1);
stringer.key("txnId").value(txnId);
stringer.key("timestamp").value(timestamp);
stringer.key("timestampString").value(SnapshotUtil.formatHumanReadableDate(timestamp));
stringer.key("newPartitionCount").value(newPartitionCount);
stringer.key("tables").array();
for (int ii = 0; ii < tables.size(); ii++) {
stringer.value(tables.get(ii).getTypeName());
}
stringer.endArray();
stringer.key("exportSequenceNumbers").array();
for (Map.Entry<String, Map<Integer, Pair<Long, Long>>> entry : exportSequenceNumbers.entrySet()) {
stringer.object();
stringer.key("exportTableName").value(entry.getKey());
stringer.key("sequenceNumberPerPartition").array();
for (Map.Entry<Integer, Pair<Long,Long>> sequenceNumber : entry.getValue().entrySet()) {
stringer.object();
stringer.key("partition").value(sequenceNumber.getKey());
//First value is the ack offset which matters for pauseless rejoin, but not persistence
stringer.key("exportSequenceNumber").value(sequenceNumber.getValue().getSecond());
stringer.endObject();
}
stringer.endArray();
stringer.endObject();
}
stringer.endArray();
stringer.key("partitionTransactionIds").object();
for (Map.Entry<Integer, Long> entry : partitionTransactionIds.entrySet()) {
stringer.key(entry.getKey().toString()).value(entry.getValue());
}
stringer.endObject();
stringer.key("catalogCRC").value(catalogCRC);
stringer.key("instanceId").value(instanceId.serializeToJSONObject());
stringer.endObject();
} catch (JSONException e) {
throw new IOException(e);
}
sw.append(stringer.toString());
final byte tableListBytes[] = sw.getBuffer().toString().getBytes("UTF-8");
final PureJavaCrc32 crc = new PureJavaCrc32();
crc.update(tableListBytes);
ByteBuffer fileBuffer = ByteBuffer.allocate(tableListBytes.length + 4);