Rev 567 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (c) 2009, Chris Miller
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* 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
* General Public License for more details.
*/
package uk.me.parabola.splitter.tools;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.junit.Test;
/**
*
*/
public class CustomCollectionsTest
{
//@Test(expectedExceptions = IllegalArgumentException.class)
//public void testInit() {
// new IntObjMap<String>(123, 0.5f);
//}
@Test
public void testLong2IntMap
() {
testMap
(new Long2IntClosedMap
("test",
10000, -
1));
}
private static void testMap
(Long2IntClosedMapFunction map
) {
int val
;
for (int i =
1; i
< 1000; i++
) {
int j = map.
add((long) i
* 10, i
);
assertEquals
(i -
1, j
);
assertEquals
(i, map.
size());
}
for (int i =
1; i
< 1000; i++
) {
int pos = map.
getKeyPos(i
* 10);
assertEquals
(pos +
1, i
);
}
for (int i =
1; i
< 1000; i++
) {
val = map.
getRandom(i
* 10);
assertEquals
(val, i
);
}
try {
map.
switchToSeqAccess(null);
} catch (IOException e
) {
// TODO Auto-generated catch block
e.
printStackTrace();
}
try{
val = map.
getRandom(5);
} catch (IllegalArgumentException e
){
assertEquals
("random access on sequential-only map requested", e.
getMessage());
}
val = map.
getSeq(5);
assertEquals
(-
1, val
);
val = map.
getSeq(10);
assertEquals
(1, val
);
val = map.
getSeq(19);
assertEquals
(-
1, val
);
val = map.
getSeq(30);
assertEquals
(3, val
);
map.
finish();
}
private static void testVals
(SparseLong2IntMap map,
long idOffset,
List<Integer> vals
) {
map.
clear();
map.
put(1, -
12000);
long key =
128;
for (int val : vals
) {
map.
put(idOffset + key++, val
);
}
map.
put(1,
0); // trigger saving of chunk
key =
128;
for (int val : vals
) {
assertEquals
("values " + vals.
toString(), val, map.
get(idOffset + key++
));
}
map.
clear();
}
@Test
public void testSparseLong2IntMap
() {
ByteBuffer buf =
ByteBuffer.
allocate(4);
for (int i =
0; i
< 32; i++
) {
int val =
1 << i
;
do {
for (int j =
1; j
<=
4; j++
) {
int bytesToUse = j
;
if (bytesToUse ==
1 && val
>=
Byte.
MIN_VALUE && val
<=
Byte.
MAX_VALUE
|| bytesToUse ==
2 && val
>=
Short.
MIN_VALUE && val
<=
Short.
MAX_VALUE
|| bytesToUse ==
3 && val
>= -0x800000
&& val
<= 0x7fffff
) {
buf.
clear();
SparseLong2IntMap.
putVal(buf, val, bytesToUse
);
buf.
flip();
assertEquals
(SparseLong2IntMap.
getVal(buf, bytesToUse
), val
);
}
}
val = ~val
;
} while (val
< 0);
}
testMap
(0L
);
testMap
(-10000L
);
testMap
(1L
<< 35);
testMap
(-1L
<< 35);
}
private static int UNASSIGNED =
Integer.
MIN_VALUE;
private static void testMap
(long idOffset
) {
SparseLong2IntMap map =
new SparseLong2IntMap
("test");
map.
defaultReturnValue(UNASSIGNED
);
// special patterns
testVals
(map, idOffset,
Arrays.
asList(1,
2,
1,
1,
1,
2,
1,
1,
2,
1,
1,
2));
testVals
(map, idOffset,
Arrays.
asList(1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2));
testVals
(map, idOffset,
Arrays.
asList(66560,
7936,
7936,
6144));
testVals
(map, idOffset,
Arrays.
asList(Integer.
MIN_VALUE +
1,
1234));
testVals
(map, idOffset,
Arrays.
asList(1)); // single value chunk with 1 byte value
testVals
(map, idOffset,
Arrays.
asList(1000)); // single value chunk with 2 byte value
testVals
(map, idOffset,
Arrays.
asList(33000)); // single value chunk with 3 byte value
testVals
(map, idOffset,
Arrays.
asList(1<<25)); // single value chunk with 4 byte value
testVals
(map, idOffset,
Arrays.
asList(856,
856,
844,
844,
646,
646,
646,
646,
646,
646));
testVals
(map, idOffset,
Arrays.
asList(260,
31,
31,
24));
testVals
(map, idOffset,
Arrays.
asList(137,
110,
114,
128,
309,
114));
testVals
(map, idOffset,
Arrays.
asList(254,
12,
12,
12,
12));
testVals
(map, idOffset,
Arrays.
asList(254,
254,
12,
12));
testVals
(map, idOffset,
Arrays.
asList(254,
12,
13));
testVals
(map, idOffset,
Arrays.
asList(1000,
800,
700,
820));
testVals
(map, idOffset,
Arrays.
asList(1000,
1000,
700));
testVals
(map, idOffset,
Arrays.
asList(-
32519,
255, -
32519));
testVals
(map, idOffset,
Arrays.
asList(-
1,
1,
200,
1));
testVals
(map, idOffset,
Arrays.
asList(Integer.
MIN_VALUE +
1,
Integer.
MIN_VALUE +
1,
1234));
testVals
(map, idOffset,
Arrays.
asList(Integer.
MIN_VALUE +
1,
1234,
Integer.
MIN_VALUE +
1));
for (int i =
1; i
< 1000; i++
) {
int j = map.
put(idOffset + i, i
);
assertEquals
(UNASSIGNED, j
);
assertEquals
(i, map.
size());
}
for (int i =
1; i
< 1000; i++
) {
boolean b = map.
containsKey(idOffset + i
);
assertEquals
(true, b
);
}
for (int i =
1; i
< 1000; i++
) {
assertEquals
(i, map.
get(idOffset + i
));
}
// random read access
for (int i =
1; i
< 1000; i++
) {
int key =
(int) Math.
max(1,
(Math.
random() * 1000));
assertEquals
(key, map.
get(idOffset + key
));
}
for (int i =
1000; i
< 2000; i++
) {
assertEquals
(UNASSIGNED, map.
get(idOffset + i
));
}
for (int i =
1000; i
< 2000; i++
) {
boolean b = map.
containsKey(idOffset + i
);
assertEquals
(false, b
);
}
for (int i =
1000; i
< 1200; i++
) {
int j = map.
put(idOffset + i,
333);
assertEquals
(UNASSIGNED, j
);
assertEquals
(i, map.
size());
}
// random read access 2
assertEquals
(333, map.
get(idOffset +
1010));
for (int i =
1; i
< 1000; i++
) {
int key =
1000 +
(int) (Math.
random() * 200);
assertEquals
(333, map.
get(idOffset + key
));
}
for (int i = -
2000; i
< -
1000; i++
) {
assertEquals
(UNASSIGNED, map.
get(idOffset + i
));
}
for (int i = -
2000; i
< -
1000; i++
) {
boolean b = map.
containsKey(idOffset + i
);
assertEquals
(false, b
);
}
long mapSize = map.
size();
// seq. update existing records
for (int i =
1; i
< 1000; i++
) {
int j = map.
put(idOffset + i, i+
333);
assertEquals
(i, j
);
assertEquals
(mapSize, map.
size());
}
// random read access 3, update existing entries
for (int i =
1; i
< 1000; i++
) {
int j = map.
put(idOffset + i, i+
555);
assertEquals
(true, j == i+
333 | j == i+
555);
assertEquals
(mapSize, map.
size());
}
assertEquals
(UNASSIGNED, map.
get(idOffset +
123456));
map.
put(idOffset +
123456,
999);
assertEquals
(999, map.
get(idOffset +
123456));
map.
put(idOffset +
123456,
888);
assertEquals
(888, map.
get(idOffset +
123456));
assertEquals
(UNASSIGNED, map.
get(idOffset -
123456));
map.
put(idOffset -
123456,
999);
assertEquals
(999, map.
get(idOffset -
123456));
map.
put(idOffset -
123456,
888);
assertEquals
(888, map.
get(idOffset -
123456));
map.
put(idOffset +
3008,
888);
map.
put(idOffset +
3009,
888);
map.
put(idOffset +
3010,
876);
map.
put(idOffset +
3011,
876);
map.
put(idOffset +
3012,
678);
map.
put(idOffset +
3013,
678);
map.
put(idOffset +
3014,
678);
map.
put(idOffset +
3015,
678);
map.
put(idOffset +
3016,
678);
map.
put(idOffset +
3017,
678);
map.
put(idOffset +
4000,
888);
map.
put(idOffset +
4001,
888);
map.
put(idOffset +
4002,
876);
map.
put(idOffset +
4003,
876);
// update the first one
map.
put(idOffset +
3008,
889);
// update the 2nd one
map.
put(idOffset +
4000,
889);
// add a very different key
map.
put(idOffset +
5000,
889);
map.
put(idOffset +
5001,
222);
assertEquals
(889, map.
get(idOffset +
3008));
assertEquals
(888, map.
get(idOffset +
3009));
assertEquals
(876, map.
get(idOffset +
3010));
assertEquals
(876, map.
get(idOffset +
3011));
assertEquals
(678, map.
get(idOffset +
3012));
assertEquals
(678, map.
get(idOffset +
3013));
assertEquals
(678, map.
get(idOffset +
3014));
assertEquals
(889, map.
get(idOffset +
4000));
assertEquals
(888, map.
get(idOffset +
4001));
assertEquals
(876, map.
get(idOffset +
4002));
assertEquals
(876, map.
get(idOffset +
4003));
assertEquals
(889, map.
get(idOffset +
5000));
assertEquals
(222, map.
get(idOffset +
5001));
map.
clear();
// special pattern 1
assertEquals
(UNASSIGNED, map.
put(idOffset +
1,
0));
assertEquals
(UNASSIGNED, map.
put(idOffset +
65, -
1));
assertEquals
(UNASSIGNED, map.
get(idOffset +
999));
assertEquals
(0, map.
get(idOffset +
1));
assertEquals
(-
1, map.
get(idOffset +
65));
map.
clear();
map.
put(idOffset +
1,
22);
map.
put(idOffset +
5,
22);
map.
put(idOffset +
100,
44);
assertEquals
(22, map.
put(idOffset +
5,
33));
map.
clear();
// larger values
for (int i =
100_000
; i
< 110_000
; i++
) {
map.
put(idOffset + i, i
);
}
for (int i =
100_000
; i
< 110_000
; i++
) {
assertEquals
(i, map.
get(idOffset + i
));
}
map.
clear();
Random random =
new Random(101);
Map<Long,
Integer> ref =
new HashMap<>();
// special cases long chunks (all 64 values used and random
for (int i =
0; i
< 3; i++
) {
for (int j =
0; j
< 1000; j++
) {
int val = random.
nextInt(Integer.
MAX_VALUE);
map.
put(idOffset + j, val
);
ref.
put(idOffset + j, val
);
}
}
// map.stats(0);
ref.
entrySet().
forEach(e -
> {
long id = e.
getKey();
int val = map.
get(id
);
assertEquals
("id=" + id,
(int) e.
getValue(), val
);
});
ref.
clear();
map.
clear();
for (int i =
0; i
< 10_000
; i++
) {
long id =
Math.
round((1L
<< 29) * random.
nextDouble());
int val =
(-
1 * (1 << 20) +
(int) Math.
round((1 << 20) * random.
nextDouble()));
map.
put(idOffset + id, val
);
ref.
put(idOffset + id, val
);
}
// map.stats(0);
ref.
entrySet().
forEach(e -
> {
long id = e.
getKey();
int val = map.
get(id
);
assertEquals
("id=" + id,
(int) e.
getValue(), val
);
});
// simulate split where all nodes fall into same tile
map.
clear();
for (int i =
0; i
< 1 << 27; i+=
64) {
map.
put(idOffset + i,
12);
}
assertEquals
("id=" + idOffset+
2048,
12, map.
get(idOffset +
2048));
assertEquals
("id=" + idOffset+
2048*1024,
12, map.
get(idOffset +
2048*1024));
assertEquals
("id=" + idOffset+
2048*1024 +
1, UNASSIGNED, map.
get(idOffset +
2048*1024+
1));
return;
}
}