Skip to content

Commit

Permalink
add UT for CollectionFactory and IdSet
Browse files Browse the repository at this point in the history
Change-Id: I580df88f57302dfe474108a93108759e33e083e2
  • Loading branch information
zhoney committed Jun 8, 2021
1 parent d9b3300 commit 8b8be47
Show file tree
Hide file tree
Showing 7 changed files with 630 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ public <K, V> Map<K, V> newMap(int initialCapacity) {
return newMap(this.type, initialCapacity);
}

public <K, V> Map<K, V> newMap(Map<? extends K, ? extends V> map) {
return newMap(this.type, map);
}

public static <K, V> Map<K, V> newMap(CollectionType type) {
/*
* EC is faster 10%-20% than JCF, and it's more stable & less
Expand Down Expand Up @@ -207,6 +211,21 @@ public static <K, V> Map<K, V> newMap(CollectionType type,
}
}

public static <K, V> Map<K, V> newMap(CollectionType type,
Map<? extends K, ? extends V> map) {
switch (type) {
case EC:
return new UnifiedMap<>(map);
case JCF:
return new HashMap<>(map);
case FU:
return new Object2ObjectOpenHashMap<>(map);
default:
throw new AssertionError(
"Unsupported collection type: " + type);
}
}

public static <V> MutableIntObjectMap<V> newIntObjectMap() {
return new IntObjectHashMap<>();
}
Expand Down Expand Up @@ -235,11 +254,11 @@ public static <V> MutableIntObjectMap<V> newIntObjectMap(
return map;
}

public Set<Id> newIdSet() {
public IdSet newIdSet() {
return newIdSet(this.type);
}

public static Set<Id> newIdSet(CollectionType type) {
public static IdSet newIdSet(CollectionType type) {
return new IdSet(type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ public ConcurrentObjectIntMapping() {
}

@Watched
@SuppressWarnings("unchecked")
public synchronized int object2Code(Object object) {
return this.objectIntMapping.object2Code(object);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
import org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap;

import com.baidu.hugegraph.HugeException;
import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.perf.PerfUtil.Watched;

public class SingleThreadObjectIntMapping<V> implements ObjectIntMapping<V> {

private static final int MAGIC = 1 << 16;
private static final int MAX_OFFSET = 10;

private final IntObjectHashMap<V> int2IdMap;

Expand All @@ -41,8 +41,8 @@ public int object2Code(Object object) {
int code = object.hashCode();
// TODO: improve hash algorithm
for (int i = 1; i > 0; i <<= 1) {
for (int j = 0; j < 10; j++) {
Id existed = (Id) this.int2IdMap.get(code);
for (int j = 0; j < MAX_OFFSET; j++) {
V existed = this.int2IdMap.get(code);
if (existed == null) {
this.int2IdMap.put(code, (V) object);
return code;
Expand All @@ -51,12 +51,17 @@ public int object2Code(Object object) {
return code;
}
code = code + i + j;
/*
* If i < MAGIC, try (i * 2) to reduce conflicts, otherwise
* try (i + 1), (i + 2), ..., (i + 10) to try more times
* before try (i * 2).
*/
if (i < MAGIC) {
break;
}
}
}
throw new HugeException("Failed to get code for id: %s", object);
throw new HugeException("Failed to get code for object: %s", object);
}

@Watched
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@
import com.baidu.hugegraph.unit.serializer.StoreSerializerTest;
import com.baidu.hugegraph.unit.serializer.TableBackendEntryTest;
import com.baidu.hugegraph.unit.serializer.TextBackendEntryTest;
import com.baidu.hugegraph.unit.util.CollectionFactoryTest;
import com.baidu.hugegraph.unit.util.CompressUtilTest;
import com.baidu.hugegraph.unit.util.JsonUtilTest;
import com.baidu.hugegraph.unit.util.StringEncodingTest;
import com.baidu.hugegraph.unit.util.VersionTest;
import com.baidu.hugegraph.util.collection.IdSet;

@RunWith(Suite.class)
@Suite.SuiteClasses({
Expand Down Expand Up @@ -136,7 +136,8 @@
VersionTest.class,
JsonUtilTest.class,
StringEncodingTest.class,
CompressUtilTest.class
CompressUtilTest.class,
CollectionFactoryTest.class
})
public class UnitTestSuite {
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package com.baidu.hugegraph.unit.core;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
Expand Down Expand Up @@ -167,4 +168,161 @@ public void testIdSetWithMixedId() {
idSet.clear();
}
}

@Test
public void testIdSetContains() {
Random random = new Random();
Set<Long> numbers = new HashSet<>();
Set<UUID> uuids = new HashSet<>();
Set<String> strings = new HashSet<>();
long number = 0L;
UUID uuid = null;
String string = null;
for (CollectionType type : CollectionType.values()) {
idSet = new IdSet(type);
for (int i = 1; i < SIZE; i++) {
number = random.nextLong();
numbers.add(number);
idSet.add(IdGenerator.of(number));
}
for (int i = 0; i < SIZE; i++) {
uuid = UUID.randomUUID();
uuids.add(uuid);
idSet.add(IdGenerator.of(uuid));
}
for (int i = 0; i < SIZE; i++) {
string = RandomStringUtils.randomAlphanumeric(10);
strings.add(string);
idSet.add(IdGenerator.of(string));
}
Assert.assertEquals(numbers.size() + uuids.size() + strings.size(),
idSet.size());

LongHashSet numberIds = Whitebox.getInternalState(idSet,
"numberIds");
Assert.assertEquals(numbers.size(), numberIds.size());
Set<Id> nonNumberIds = Whitebox.getInternalState(idSet,
"nonNumberIds");
Assert.assertEquals(uuids.size() + strings.size(),
nonNumberIds.size());

Assert.assertTrue(idSet.contains(IdGenerator.of(number)));
Assert.assertTrue(idSet.contains(IdGenerator.of(uuid)));
Assert.assertTrue(idSet.contains(IdGenerator.of(string)));

numbers.clear();
uuids.clear();
strings.clear();
idSet.clear();
}
}

@Test
public void testIdSetIterator() {
Random random = new Random();
Set<Long> numbers = new HashSet<>();
Set<UUID> uuids = new HashSet<>();
Set<String> strings = new HashSet<>();
for (CollectionType type : CollectionType.values()) {
idSet = new IdSet(type);
for (int i = 1; i < SIZE; i++) {
long number = random.nextLong();
numbers.add(number);
idSet.add(IdGenerator.of(number));
}
for (int i = 0; i < SIZE; i++) {
UUID uuid = UUID.randomUUID();
uuids.add(uuid);
idSet.add(IdGenerator.of(uuid));
}
for (int i = 0; i < SIZE; i++) {
String string = RandomStringUtils.randomAlphanumeric(10);
strings.add(string);
idSet.add(IdGenerator.of(string));
}
Assert.assertEquals(numbers.size() + uuids.size() + strings.size(),
idSet.size());

LongHashSet numberIds = Whitebox.getInternalState(idSet,
"numberIds");
Assert.assertEquals(numbers.size(), numberIds.size());
Set<Id> nonNumberIds = Whitebox.getInternalState(idSet,
"nonNumberIds");
Assert.assertEquals(uuids.size() + strings.size(),
nonNumberIds.size());

Iterator<Id> iterator = idSet.iterator();
while (iterator.hasNext()) {
Id id = iterator.next();
if (id instanceof IdGenerator.LongId) {
Assert.assertTrue(numbers.contains(id.asLong()));
} else if (id instanceof IdGenerator.UuidId) {
Assert.assertTrue(id.uuid() &&
uuids.contains(id.asObject()));
} else {
Assert.assertTrue(id instanceof IdGenerator.StringId);
Assert.assertTrue(strings.contains(id.asString()));
}
}

numbers.clear();
uuids.clear();
strings.clear();
idSet.clear();
}
}

@Test
public void testIdSetRemove() {
Random random = new Random();
Set<Long> numbers = new HashSet<>();
Set<UUID> uuids = new HashSet<>();
Set<String> strings = new HashSet<>();
for (CollectionType type : CollectionType.values()) {
idSet = new IdSet(type);
for (int i = 1; i < SIZE; i++) {
long number = random.nextLong();
numbers.add(number);
idSet.add(IdGenerator.of(number));
}
for (int i = 0; i < SIZE; i++) {
UUID uuid = UUID.randomUUID();
uuids.add(uuid);
idSet.add(IdGenerator.of(uuid));
}
for (int i = 0; i < SIZE; i++) {
String string = RandomStringUtils.randomAlphanumeric(10);
strings.add(string);
idSet.add(IdGenerator.of(string));
}
Assert.assertEquals(numbers.size() + uuids.size() + strings.size(),
idSet.size());

LongHashSet numberIds = Whitebox.getInternalState(idSet,
"numberIds");
Assert.assertEquals(numbers.size(), numberIds.size());
Set<Id> nonNumberIds = Whitebox.getInternalState(idSet,
"nonNumberIds");
Assert.assertEquals(uuids.size() + strings.size(),
nonNumberIds.size());

for (long number : numbers) {
idSet.remove(IdGenerator.of(number));
}
Assert.assertEquals(nonNumberIds.size(), idSet.size());

for (UUID uuid : uuids) {
idSet.remove(IdGenerator.of(uuid));
}
for (String string : strings) {
idSet.remove(IdGenerator.of(string));
}
Assert.assertTrue(idSet.isEmpty());

numbers.clear();
uuids.clear();
strings.clear();
idSet.clear();
}
}
}
Loading

0 comments on commit 8b8be47

Please sign in to comment.