/*
* Copyright (C) 2012, 2016 higherfrequencytrading.com
* Copyright (C) 2016 Roman Leventov
*
* 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.chronicle.hash.serialization.DataAccess;
import net.openhft.chronicle.hash.serialization.impl.ExternalizableDataAccess;
import net.openhft.chronicle.hash.serialization.impl.ExternalizableReader;
import org.junit.Assert;
import org.junit.Test;
import java.io.*;
import java.nio.ByteBuffer;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
public class ConstantSizeBySampleTest {
@Test
public void testConstantKeys() throws IOException {
ChronicleMap<byte[], Long> map = ChronicleMapBuilder.of(byte[].class, Long.class)
.constantKeySizeBySample(new byte[8])
.entries(100)
.create();
byte[] zero = ByteBuffer.allocate(8).putLong(0L).array();
map.put(zero, 0L);
assertEquals(0L, (long) map.get(zero));
byte[] one = ByteBuffer.allocate(8).putLong(1L).array();
map.put(one, 1L);
assertEquals(1L, (long) map.get(one));
map.put(one, 0L);
assertEquals(0L, (long) map.get(one));
}
@Test
public void testUnexpectedlyLongConstantByteArrayValues() throws IOException {
try (ChronicleMap<Long, byte[]> map = ChronicleMapBuilder.of(Long.class, byte[].class)
.constantValueSizeBySample(new byte[512 * 1024])
.entries(100)
.actualSegments(1)
.create()) {
byte[] value = new byte[512 * 1024];
value[42] = 1;
map.put(1L, value);
Assert.assertTrue(Arrays.equals(map.get(1L), value));
}
}
static class ExternalizableData implements Externalizable {
byte[] data = new byte[512 * 1024];
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ExternalizableData))
return false;
return Arrays.equals(((ExternalizableData) obj).data, data);
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.write(data);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
in.read(data = new byte[512 * 1024]);
}
}
@Test
public void testUnexpectedlyLongConstantExternalizableValues() throws IOException {
try ( ChronicleMap<Long, ExternalizableData> map =
ChronicleMapBuilder.of(Long.class, ExternalizableData.class)
.valueReaderAndDataAccess(new ExternalizableDataReader(),
new ExternalizableDataDataAccess())
.constantValueSizeBySample(new ExternalizableData())
.entries(100)
.actualSegments(1)
.create()) {
ExternalizableData value = new ExternalizableData();
value.data[42] = 1;
map.put(1L, value);
Assert.assertEquals(map.get(1L), value);
}
}
static class SerializableData implements Serializable {
byte[] data = new byte[512 * 1024];
@Override
public boolean equals(Object obj) {
if (!(obj instanceof SerializableData))
return false;
return Arrays.equals(((SerializableData) obj).data, data);
}
}
@Test
public void testUnexpectedlyLongConstantSerializableValues() throws IOException {
try ( ChronicleMap<Long, SerializableData> map =
ChronicleMapBuilder.of(Long.class, SerializableData.class)
.constantValueSizeBySample(new SerializableData())
.entries(100)
.actualSegments(1)
.create()) {
SerializableData value = new SerializableData();
value.data[42] = 1;
map.put(1L, value);
Assert.assertEquals(map.get(1L), value);
}
}
private static class ExternalizableDataDataAccess
extends ExternalizableDataAccess<ExternalizableData> implements Serializable {
public ExternalizableDataDataAccess() {
super(ExternalizableData.class);
}
@Override
protected ExternalizableData createInstance() {
return new ExternalizableData();
}
@Override
public DataAccess<ExternalizableData> copy() {
return new ExternalizableDataDataAccess();
}
}
private static class ExternalizableDataReader extends ExternalizableReader<ExternalizableData> {
public ExternalizableDataReader() {
super(ExternalizableData.class);
}
@Override
protected ExternalizableData createInstance() {
return new ExternalizableData();
}
}
}