Zero out contents of a newly-created persisted ChronicleHash

This commit is contained in:
leventov
2015-08-06 03:46:54 +03:00
parent 2b6c871562
commit b5cf817b2a
4 changed files with 27 additions and 5 deletions
@@ -56,6 +56,10 @@ public abstract class VanillaChronicleHash<K, KI, MKI extends MetaBytesInterop<K
// Version
public final String dataFileVersion;
/////////////////////////////////////////////////
// If the hash was created in the first place, or read from disk
public transient boolean created = false;
/////////////////////////////////////////////////
// Key Data model
public final Class<K> kClass;
@@ -110,10 +114,15 @@ public abstract class VanillaChronicleHash<K, KI, MKI extends MetaBytesInterop<K
public transient CompactOffHeapLinearHashTable hashLookup;
public VanillaChronicleHash(ChronicleMapBuilder<K, ?> builder, boolean replicated) {
public VanillaChronicleHash(
ChronicleMapBuilder<K, ?> builder, boolean replicated) {
// Version
dataFileVersion = BuildVersion.version();
// Because we are in constructor. If the Hash is not created, deserialization bypasses
// the constructor and created = false
this.created = true;
@SuppressWarnings("deprecation")
ChronicleHashBuilderPrivateAPI<K> privateAPI = builder.privateAPI();
@@ -205,6 +214,9 @@ public abstract class VanillaChronicleHash<K, KI, MKI extends MetaBytesInterop<K
//OS.warnOnWindows(sizeInBytes());
createMappedStoreAndSegments(new MappedStore(file, FileChannel.MapMode.READ_WRITE,
sizeInBytes(), BytesMarshallableSerializer.create()));
// newly-extended file contents are not guaranteed to be zero
if (created)
bytes.zeroOut(headerSize, bytes.capacity(), true);
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
@@ -1358,7 +1358,8 @@ public final class ChronicleMapBuilder<K, V> implements
File file, SingleChronicleHashReplication singleHashReplication,
ReplicationChannel channel) throws IOException {
for (int i = 0; i < 10; i++) {
if (file.exists() && file.length() > 0) {
long fileLength = file.length();
if (fileLength > 0) {
try (FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis)) {
Object m;
@@ -1379,6 +1380,12 @@ public final class ChronicleMapBuilder<K, V> implements
(VanillaChronicleMap<K, ?, ?, V, ?, ?, ?>) m;
map.initTransientsFromBuilder(this);
map.headerSize = roundUpMapHeaderSize(fis.getChannel().position());
long sizeInBytes = map.sizeInBytes();
if (sizeInBytes != fileLength) {
throw new IOException("The file " + file + "the map is serialized from " +
"has unexpected length " + fileLength + ", probably corrupted. " +
"Expected length is " + sizeInBytes);
}
map.createMappedStoreAndSegments(file);
// This is needed to property initialize key and value serialization builders,
// which are later used in replication
@@ -1388,7 +1395,7 @@ public final class ChronicleMapBuilder<K, V> implements
return establishReplication(map, singleHashReplication, channel);
}
}
if (file.createNewFile() || file.length() == 0) {
if (file.createNewFile() || fileLength == 0) {
break;
}
try {
@@ -208,10 +208,10 @@ public class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? sup
public void onHeaderCreated() {
long offset = super.mapHeaderInnerSize();
identifierUpdatedBytes = ms.bytes(offset, LAST_UPDATED_HEADER_SIZE).zeroOut();
identifierUpdatedBytes = ms.bytes(offset, LAST_UPDATED_HEADER_SIZE);
offset += LAST_UPDATED_HEADER_SIZE;
Bytes modDelBytes = ms.bytes(offset, assignedModIterBitSetSizeInBytes()).zeroOut();
Bytes modDelBytes = ms.bytes(offset, assignedModIterBitSetSizeInBytes());
offset += assignedModIterBitSetSizeInBytes();
startOfModificationIterators = offset;
modIterSet = new ATSDirectBitSet(modDelBytes);