update
This commit is contained in:
parent
ece5cdeb6e
commit
b55db89b5f
|
@ -3,17 +3,21 @@ package com.baeldung.uuid;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class UUIDLongGenerator {
|
/**
|
||||||
|
* Methods are called by reflection in the unit test
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class UUIDPositiveLongGenerator {
|
||||||
public long getLeastSignificantBits(){
|
public long getLeastSignificantBits(){
|
||||||
return UUID.randomUUID().getLeastSignificantBits();
|
return Math.abs(UUID.randomUUID().getLeastSignificantBits());
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getMostSignificantBits(){
|
public long getMostSignificantBits(){
|
||||||
return UUID.randomUUID().getMostSignificantBits();
|
return Math.abs(UUID.randomUUID().getMostSignificantBits());
|
||||||
}
|
}
|
||||||
|
|
||||||
public long gethashCode(){
|
public long gethashCode(){
|
||||||
return UUID.randomUUID().toString().hashCode();
|
return Math.abs(UUID.randomUUID().toString().hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public long combineByteBuffer(){
|
public long combineByteBuffer(){
|
||||||
|
@ -21,21 +25,21 @@ public class UUIDLongGenerator {
|
||||||
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
|
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
|
||||||
bb.putLong(uuid.getMostSignificantBits());
|
bb.putLong(uuid.getMostSignificantBits());
|
||||||
bb.putLong(uuid.getLeastSignificantBits());
|
bb.putLong(uuid.getLeastSignificantBits());
|
||||||
bb.rewind(); // Kembalikan posisi buffer ke awal
|
bb.rewind();
|
||||||
return bb.getLong();
|
return Math.abs(bb.getLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
public long combineBitwise(){
|
public long combineBitwise(){
|
||||||
UUID uniqueUUID;
|
UUID uniqueUUID;
|
||||||
uniqueUUID = UUID.randomUUID();
|
uniqueUUID = UUID.randomUUID();
|
||||||
return (uniqueUUID.getMostSignificantBits() << 32) | (uniqueUUID.getLeastSignificantBits() & 0xFFFFFFFFL);
|
return Math.abs((uniqueUUID.getMostSignificantBits() << 32) | (uniqueUUID.getLeastSignificantBits() & 0xFFFFFFFFL));
|
||||||
}
|
}
|
||||||
|
|
||||||
public long combineDirect(){
|
public long combineDirect(){
|
||||||
UUID uniqueUUID = UUID.randomUUID();
|
UUID uniqueUUID = UUID.randomUUID();
|
||||||
long mostSignificantBits = uniqueUUID.getMostSignificantBits();
|
long mostSignificantBits = uniqueUUID.getMostSignificantBits();
|
||||||
long leastSignificantBits = uniqueUUID.getLeastSignificantBits();
|
long leastSignificantBits = uniqueUUID.getLeastSignificantBits();
|
||||||
return mostSignificantBits ^ (leastSignificantBits >> 1);
|
return Math.abs(mostSignificantBits ^ (leastSignificantBits >> 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public long combinePermutation(){
|
public long combinePermutation(){
|
||||||
|
@ -53,6 +57,6 @@ public class UUIDLongGenerator {
|
||||||
for (byte b : uuidBytes) {
|
for (byte b : uuidBytes) {
|
||||||
result = (result << 8) | (b & 0xFF);
|
result = (result << 8) | (b & 0xFF);
|
||||||
}
|
}
|
||||||
return result;
|
return Math.abs(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,63 +0,0 @@
|
||||||
package com.baeldung.uuid;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.stream.IntStream;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
public class UUIDLongGeneratorUnitTest {
|
|
||||||
final static int n = 1000000;
|
|
||||||
UUIDLongGenerator uuidLongGenerator = new UUIDLongGenerator();
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void whenForeachGenerateLongValue_thenCollisionsCheck() {
|
|
||||||
printTableHeader();
|
|
||||||
for (Method method : uuidLongGenerator.getClass().getDeclaredMethods()) {
|
|
||||||
collisionAndNegativeCheck(method);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void printTableHeader() {
|
|
||||||
System.out.format("%-30s %-15s %-15s %-15s %-15s%n", "Approach", "collisions", "negatives", "collision", "negative");
|
|
||||||
System.out.format("%-30s %-15s %-15s %-15s %-15s%n", "(method name)", "count", "count", "probability", "probability");
|
|
||||||
System.out.println("--------------------------------------------------------------------------------------------");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void printOutput(String method, int collisionsCount, int negativeCount, double collisionsProbability, double negativeProbability) {
|
|
||||||
DecimalFormat decimalFormat = new DecimalFormat("#.#####");
|
|
||||||
System.out.format("%-30s %-15s %-15s %-15s %-15s%n", method, collisionsCount, negativeCount, decimalFormat.format(collisionsProbability), decimalFormat.format(negativeProbability));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void collisionAndNegativeCheck(Method method) {
|
|
||||||
Set<Long> uniqueValues = new HashSet<>();
|
|
||||||
AtomicInteger collisions = new AtomicInteger(0);
|
|
||||||
AtomicInteger negative = new AtomicInteger(0);
|
|
||||||
|
|
||||||
IntStream.range(0, n).forEach(i -> {
|
|
||||||
try {
|
|
||||||
long uniqueValue = (long) method.invoke(uuidLongGenerator);
|
|
||||||
if (!uniqueValues.add(uniqueValue)) {
|
|
||||||
collisions.incrementAndGet();
|
|
||||||
}
|
|
||||||
if (uniqueValue < 0) {
|
|
||||||
negative.incrementAndGet();
|
|
||||||
}
|
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
double collisionsProbability = (double) collisions.get() / n;
|
|
||||||
double negativeProbability = (double) negative.get() / n;
|
|
||||||
printOutput(method.getName(), collisions.get(), negative.get(), collisionsProbability, negativeProbability);
|
|
||||||
|
|
||||||
assertTrue(collisionsProbability <= 0.001); // threshold = 0.001
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.baeldung.uuid;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class UUIDPositiveLongGeneratorUnitTest {
|
||||||
|
private final static int n = 1000000;
|
||||||
|
private final UUIDPositiveLongGenerator uuidLongGenerator = new UUIDPositiveLongGenerator();
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(UUIDPositiveLongGeneratorUnitTest.class);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenForeachGenerateLongValue_thenCollisionsCheck() throws InvocationTargetException, IllegalAccessException {
|
||||||
|
printTableHeader();
|
||||||
|
for (Method method : uuidLongGenerator.getClass().getDeclaredMethods()) {
|
||||||
|
collisionAndNegativeCheck(method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void printTableHeader() {
|
||||||
|
logger.info(String.format("%-30s %-15s %-15s %-15s %-15s", "Approach", "collisions", "negatives", "collision", "negative"));
|
||||||
|
logger.info(String.format("%-30s %-15s %-15s %-15s %-15s", "(method name)", "count", "count", "probability", "probability"));
|
||||||
|
logger.info("--------------------------------------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printOutput(String method, int collisionsCount, int negativeCount, double collisionsProbability, double negativeProbability) {
|
||||||
|
DecimalFormat decimalFormat = new DecimalFormat("#.#####");
|
||||||
|
//logger.info(String.format("%-30s %-15s %-15s %-15s %-15s", method, collisionsCount, negativeCount, decimalFormat.format(collisionsProbability), decimalFormat.format(negativeProbability)));
|
||||||
|
logger.info("%-30s{} %-15s{} %-15s{} %-15s{} %-15s{}", method, collisionsCount, negativeCount, decimalFormat.format(collisionsProbability), decimalFormat.format(negativeProbability));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void collisionAndNegativeCheck(Method method) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
Set<Long> uniqueValues = new HashSet<>();
|
||||||
|
int collisions = 0;
|
||||||
|
int negative = 0;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
long uniqueValue = (long) method.invoke(uuidLongGenerator);
|
||||||
|
if (!uniqueValues.add(uniqueValue)) {
|
||||||
|
collisions++;
|
||||||
|
}
|
||||||
|
if (uniqueValue < 0) {
|
||||||
|
negative++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double collisionsProbability = (double) collisions / n;
|
||||||
|
double negativeProbability = (double) negative / n;
|
||||||
|
printOutput(method.getName(), collisions, negative, collisionsProbability, negativeProbability);
|
||||||
|
assertThat(collisionsProbability).isLessThan(0.001);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue