mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
HCOLL-256 Fixed a bug in CharArrayMarshaller and made some other marshallers more robust
This commit is contained in:
@@ -42,6 +42,8 @@ import java.io.Serializable;
|
||||
*
|
||||
* @Override
|
||||
* public LongPair[] read(Bytes bytes, long size, LongPair[] toReuse) {
|
||||
* if (size > Integer.MAX_VALUE * 16L)
|
||||
* throw new IllegalStateException("LongPair[] size couldn't be " + (size / 16L));
|
||||
* int resLen = (int) (size / 16L);
|
||||
* LongPair[] res;
|
||||
* if (toReuse != null) {
|
||||
|
||||
+11
-6
@@ -55,19 +55,24 @@ public enum ByteArrayMarshaller implements BytesInterop<byte[]>, BytesReader<byt
|
||||
|
||||
@Override
|
||||
public byte[] read(Bytes bytes, long size) {
|
||||
byte[] ba = new byte[(int) size];
|
||||
byte[] ba = new byte[resLen(size)];
|
||||
bytes.read(ba);
|
||||
return ba;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] read(Bytes bytes, long size, byte[] toReuse) {
|
||||
if (size < 0L || size > (long) Integer.MAX_VALUE)
|
||||
throw new IllegalArgumentException("byte[] size should be non-negative int, " +
|
||||
size + " given. Memory corruption?");
|
||||
if (toReuse == null || size != toReuse.length)
|
||||
toReuse = new byte[(int) size];
|
||||
int resLen = resLen(size);
|
||||
if (toReuse == null || resLen != toReuse.length)
|
||||
toReuse = new byte[resLen];
|
||||
bytes.read(toReuse);
|
||||
return toReuse;
|
||||
}
|
||||
|
||||
private int resLen(long size) {
|
||||
if (size < 0L || size > (long) Integer.MAX_VALUE)
|
||||
throw new IllegalArgumentException("byte[] size should be non-negative int, " +
|
||||
size + " given. Memory corruption?");
|
||||
return (int) size;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-3
@@ -45,19 +45,28 @@ public enum CharArrayMarshaller implements BytesInterop<char[]>, BytesReader<cha
|
||||
|
||||
@Override
|
||||
public char[] read(Bytes bytes, long size) {
|
||||
char[] chars = new char[(int) size];
|
||||
char[] chars = new char[resLen(size)];
|
||||
bytes.readFully(chars);
|
||||
return chars;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] read(Bytes bytes, long size, char[] toReuse) {
|
||||
if (toReuse == null || toReuse.length != size)
|
||||
toReuse = new char[(int) size];
|
||||
int resLen = resLen(size);
|
||||
if (toReuse == null || toReuse.length != resLen)
|
||||
toReuse = new char[resLen];
|
||||
bytes.readFully(toReuse);
|
||||
return toReuse;
|
||||
}
|
||||
|
||||
private int resLen(long size) {
|
||||
long resLen = size / 2L;
|
||||
if (resLen < 0 || resLen > Integer.MAX_VALUE)
|
||||
throw new IllegalArgumentException("char[] size should be non-negative int, " +
|
||||
resLen + " given. Memory corruption?");
|
||||
return (int) resLen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long size(char[] chars) {
|
||||
return chars.length * 2L;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.openhft.chronicle.map;
|
||||
|
||||
import com.google.common.primitives.Chars;
|
||||
import junit.framework.Assert;
|
||||
import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig;
|
||||
import net.openhft.lang.io.ByteBufferBytes;
|
||||
@@ -21,6 +22,7 @@ import java.util.*;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
@@ -36,7 +38,7 @@ public class CHMUseCasesTest {
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<Object[]> data() {
|
||||
return Arrays.asList(new Object[][]{
|
||||
return asList(new Object[][]{
|
||||
{
|
||||
TypeOfMap.SIMPLE
|
||||
},
|
||||
@@ -76,7 +78,6 @@ public class CHMUseCasesTest {
|
||||
|
||||
|
||||
@Test
|
||||
@Ignore("HCOLL-256 Maps containing Value as char[], get() returns too many char[]'s")
|
||||
public void testCharArrayValue() throws ExecutionException, InterruptedException, IOException {
|
||||
|
||||
int valueSize = 10;
|
||||
@@ -92,8 +93,7 @@ public class CHMUseCasesTest {
|
||||
|
||||
char[] actual = map.get("Key");
|
||||
System.out.println(actual);
|
||||
assertTrue(Arrays.equals(expected, map.get("Key")));
|
||||
|
||||
assertEquals(Chars.asList(expected), Chars.asList(map.get("Key")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2063,33 +2063,33 @@ public class CHMUseCasesTest {
|
||||
|
||||
try (ChronicleMap<String, List<String>> map = newInstance(builder)) {
|
||||
map.put("1", Collections.<String>emptyList());
|
||||
map.put("2", Arrays.asList("two-A"));
|
||||
map.put("2", asList("two-A"));
|
||||
|
||||
List<String> list1 = new ArrayList<>();
|
||||
try (WriteContext wc = map.acquireUsingLocked("1", list1)) {
|
||||
list1.add("one");
|
||||
assertEquals(Arrays.asList("one"), list1);
|
||||
assertEquals(asList("one"), list1);
|
||||
}
|
||||
List<String> list2 = new ArrayList<>();
|
||||
try (ReadContext rc = map.getUsingLocked("1", list2)) {
|
||||
assertTrue(rc.present());
|
||||
assertEquals(Arrays.asList("one"), list2);
|
||||
assertEquals(asList("one"), list2);
|
||||
}
|
||||
|
||||
try (ReadContext rc = map.getUsingLocked("2", list2)) {
|
||||
assertTrue(rc.present());
|
||||
list2.add("two-B"); // this is not written as it only a read context
|
||||
assertEquals(Arrays.asList("two-A", "two-B"), list2);
|
||||
assertEquals(asList("two-A", "two-B"), list2);
|
||||
}
|
||||
|
||||
try (WriteContext wc = map.acquireUsingLocked("2", list1)) {
|
||||
list1.add("two-C");
|
||||
assertEquals(Arrays.asList("two-A", "two-C"), list1);
|
||||
assertEquals(asList("two-A", "two-C"), list1);
|
||||
}
|
||||
|
||||
try (ReadContext rc = map.getUsingLocked("2", list2)) {
|
||||
assertTrue(rc.present());
|
||||
assertEquals(Arrays.asList("two-A", "two-C"), list2);
|
||||
assertEquals(asList("two-A", "two-C"), list2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2107,25 +2107,25 @@ public class CHMUseCasesTest {
|
||||
|
||||
try (ChronicleMap<String, Set<String>> map = newInstance(builder)) {
|
||||
map.put("1", Collections.<String>emptySet());
|
||||
map.put("2", new LinkedHashSet<String>(Arrays.asList("one")));
|
||||
map.put("2", new LinkedHashSet<String>(asList("one")));
|
||||
|
||||
Set<String> list1 = new LinkedHashSet<>();
|
||||
try (WriteContext wc = map.acquireUsingLocked("1", list1)) {
|
||||
list1.add("two");
|
||||
assertEquals(new LinkedHashSet<String>(Arrays.asList("two")), list1);
|
||||
assertEquals(new LinkedHashSet<String>(asList("two")), list1);
|
||||
}
|
||||
Set<String> list2 = new LinkedHashSet<>();
|
||||
try (ReadContext rc = map.getUsingLocked("1", list2)) {
|
||||
assertTrue(rc.present());
|
||||
assertEquals(new LinkedHashSet<String>(Arrays.asList("two")), list2);
|
||||
assertEquals(new LinkedHashSet<String>(asList("two")), list2);
|
||||
}
|
||||
try (WriteContext wc = map.acquireUsingLocked("2", list1)) {
|
||||
list1.add("three");
|
||||
assertEquals(new LinkedHashSet<String>(Arrays.asList("one", "three")), list1);
|
||||
assertEquals(new LinkedHashSet<String>(asList("one", "three")), list1);
|
||||
}
|
||||
try (ReadContext rc = map.getUsingLocked("2", list2)) {
|
||||
assertTrue(rc.present());
|
||||
assertEquals(new LinkedHashSet<String>(Arrays.asList("one", "three")), list2);
|
||||
assertEquals(new LinkedHashSet<String>(asList("one", "three")), list2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ enum LongPairArrayReader implements BytesReader<LongPair[]> {
|
||||
|
||||
@Override
|
||||
public LongPair[] read(Bytes bytes, long size, LongPair[] toReuse) {
|
||||
if (size > Integer.MAX_VALUE * 16L)
|
||||
throw new IllegalStateException("LongPair[] size couldn't be " + (size / 16L));
|
||||
int resLen = (int) (size / 16L);
|
||||
LongPair[] res;
|
||||
if (toReuse != null) {
|
||||
|
||||
Reference in New Issue
Block a user