mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Remove buggy optimization in DirectBytesBuffer #58
This commit is contained in:
+28
-32
@@ -90,25 +90,23 @@ class DirectBytesBuffer
|
||||
}
|
||||
|
||||
void init(M writer, E e, boolean mutable, long maxSize, boolean checked) {
|
||||
if (mutable || writer != this.writer || e != cur) {
|
||||
this.writer = writer;
|
||||
cur = e;
|
||||
while (true) {
|
||||
try {
|
||||
Bytes buffer = this.buffer.obtain(maxSize, true);
|
||||
if (checked)
|
||||
buffer = new BoundsCheckingDirectBytes(buffer, null);
|
||||
writer.write(buffer, e);
|
||||
buffer.flip();
|
||||
long size = this.size = buffer.remaining();
|
||||
this.buffer.buffer.position(0L);
|
||||
this.buffer.buffer.limit(size);
|
||||
hash = 0L;
|
||||
return;
|
||||
} catch (Exception ex) {
|
||||
checkMaxSizeStillReasonable(maxSize, ex);
|
||||
maxSize *= 2L;
|
||||
}
|
||||
this.writer = writer;
|
||||
cur = e;
|
||||
while (true) {
|
||||
try {
|
||||
Bytes buffer = this.buffer.obtain(maxSize, true);
|
||||
if (checked)
|
||||
buffer = new BoundsCheckingDirectBytes(buffer, null);
|
||||
writer.write(buffer, e);
|
||||
buffer.flip();
|
||||
long size = this.size = buffer.remaining();
|
||||
this.buffer.buffer.position(0L);
|
||||
this.buffer.buffer.limit(size);
|
||||
hash = 0L;
|
||||
return;
|
||||
} catch (Exception ex) {
|
||||
checkMaxSizeStillReasonable(maxSize, ex);
|
||||
maxSize *= 2L;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,19 +121,17 @@ class DirectBytesBuffer
|
||||
}
|
||||
|
||||
void init(W writer, E e, boolean mutable, boolean checked) {
|
||||
if (mutable || writer != this.writer || e != cur) {
|
||||
this.writer = writer;
|
||||
cur = e;
|
||||
long size = writer.size(e);
|
||||
Bytes buffer = this.buffer.obtain(size, true);
|
||||
if (checked)
|
||||
buffer = new BoundsCheckingDirectBytes(buffer, null);
|
||||
writer.write(buffer, e);
|
||||
buffer.flip();
|
||||
this.size = size;
|
||||
assert size == buffer.remaining();
|
||||
hash = 0L;
|
||||
}
|
||||
this.writer = writer;
|
||||
cur = e;
|
||||
long size = writer.size(e);
|
||||
Bytes buffer = this.buffer.obtain(size, true);
|
||||
if (checked)
|
||||
buffer = new BoundsCheckingDirectBytes(buffer, null);
|
||||
writer.write(buffer, e);
|
||||
buffer.flip();
|
||||
this.size = size;
|
||||
assert size == buffer.remaining();
|
||||
hash = 0L;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (C) 2015 higherfrequencytrading.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.openhft.chronicle.map;
|
||||
|
||||
import net.openhft.lang.io.Bytes;
|
||||
import net.openhft.lang.io.serialization.BytesMarshaller;
|
||||
import net.openhft.lang.model.constraints.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
public class Issue58 {
|
||||
File mapFile = new File("string-to-uuid.dat");
|
||||
File reverseMapFile = new File("uuid-to-string.dat");
|
||||
|
||||
public static void main(String... args) {
|
||||
Map<String, UUID> map = new HashMap<>();
|
||||
map.put("AA", UUID.randomUUID());
|
||||
map.put("AB", UUID.randomUUID());
|
||||
map.put("BA", UUID.randomUUID());
|
||||
map.put("BB", UUID.randomUUID());
|
||||
try {
|
||||
Issue58 test = new Issue58();
|
||||
test.writeMapAndReverseMap(map);
|
||||
test.test1(map);
|
||||
test.test2(map);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeMapAndReverseMap(Map<String, UUID> data) throws IOException {
|
||||
if (mapFile.exists())
|
||||
mapFile.delete();
|
||||
if (reverseMapFile.exists())
|
||||
reverseMapFile.delete();
|
||||
|
||||
try (
|
||||
ChronicleMap<String, UUID> map = ChronicleMap.of(String.class, UUID.class)
|
||||
.averageKeySize(2)
|
||||
.valueMarshaller(UuidMarshaller.INSTANCE)
|
||||
.constantValueSizeBySample(UUID.randomUUID())
|
||||
.entries(data.size())
|
||||
.createPersistedTo(mapFile);
|
||||
ChronicleMap<UUID, String> reverseMap = ChronicleMap.of(UUID.class, String.class)
|
||||
.keyMarshaller(UuidMarshaller.INSTANCE)
|
||||
.averageValueSize(2)
|
||||
.constantKeySizeBySample(UUID.randomUUID())
|
||||
.entries(data.size())
|
||||
.createPersistedTo(reverseMapFile);
|
||||
) {
|
||||
|
||||
map.putAll(data);
|
||||
Map<UUID, String> reverse = data.keySet().stream()
|
||||
.collect(toMap(k -> data.get(k), k -> k));
|
||||
reverseMap.putAll(reverse);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void test1(Map<String, UUID> data) throws IOException {
|
||||
try (
|
||||
ChronicleMap<String, UUID> map = ChronicleMap.of(String.class, UUID.class)
|
||||
.averageKeySize(2)
|
||||
.valueMarshaller(UuidMarshaller.INSTANCE)
|
||||
.constantValueSizeBySample(UUID.randomUUID())
|
||||
.entries(data.size())
|
||||
.createPersistedTo(mapFile);
|
||||
ChronicleMap<UUID, String> reverseMap = ChronicleMap.of(UUID.class, String.class)
|
||||
.keyMarshaller(UuidMarshaller.INSTANCE)
|
||||
.constantKeySizeBySample(UUID.randomUUID())
|
||||
.averageValueSize(2)
|
||||
.entries(data.size())
|
||||
.createPersistedTo(reverseMapFile)
|
||||
) {
|
||||
System.out.println("first test passes:");
|
||||
UUID uuid = data.get("BB");
|
||||
System.out.println("BB" + " == " + reverseMap.get(uuid));
|
||||
System.out.println(uuid + " == " + map.get("BB"));
|
||||
}
|
||||
}
|
||||
|
||||
public void test2(Map<String, UUID> data) throws IOException {
|
||||
try (
|
||||
ChronicleMap<String, UUID> map = ChronicleMap.of(String.class, UUID.class)
|
||||
.averageKeySize(2)
|
||||
.valueMarshaller(UuidMarshaller.INSTANCE)
|
||||
.constantValueSizeBySample(UUID.randomUUID())
|
||||
.entries(data.size())
|
||||
.createPersistedTo(mapFile);
|
||||
ChronicleMap<UUID, String> reverseMap = ChronicleMap.of(UUID.class, String.class)
|
||||
.keyMarshaller(UuidMarshaller.INSTANCE)
|
||||
.constantKeySizeBySample(UUID.randomUUID())
|
||||
.averageValueSize(2)
|
||||
.entries(data.size())
|
||||
.createPersistedTo(reverseMapFile)
|
||||
) {
|
||||
System.out.println("second identical test also passes:");
|
||||
UUID uuid = data.get("BB");
|
||||
System.out.println("BB" + " == " + reverseMap.get(uuid));
|
||||
System.out.println(uuid + " == " + map.get("BB")); //returns null
|
||||
System.out.println("despite all data being present:");
|
||||
map.entrySet().forEach(e -> System.out.println(e.getKey() + "->" + e.getValue()));
|
||||
reverseMap.forEach((k, v) -> System.out.println(k + " -> " + v));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum UuidMarshaller implements BytesMarshaller<UUID> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public void write(Bytes bytes, UUID uuid) {
|
||||
bytes.writeLong(uuid.getMostSignificantBits());
|
||||
bytes.writeLong(uuid.getLeastSignificantBits());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID read(Bytes bytes) {
|
||||
return new UUID(bytes.readLong(), bytes.readLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID read(Bytes bytes, @Nullable UUID uuid) {
|
||||
return read(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user