MINOR: small optimization for DirectoryId.random

DirectoryId.random doesn't need to instantiate the first 100 IDs to check if an ID is one of them.

Reviewers: Ismael Juma <ismael@juma.me.uk>, Justine Olshan <jolshan@confluent.io>, Proven Provenzano <93720617+pprovenzano@users.noreply.github.com>
This commit is contained in:
Colin P. McCabe 2023-10-30 16:36:31 -07:00
parent 4d8efa94cb
commit a672a19e80
2 changed files with 29 additions and 29 deletions

View File

@ -18,12 +18,9 @@ package org.apache.kafka.common;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
public class DirectoryId { public class DirectoryId {
@ -47,30 +44,31 @@ public class DirectoryId {
public static final Uuid MIGRATING = new Uuid(0L, 2L); public static final Uuid MIGRATING = new Uuid(0L, 2L);
/** /**
* The set of reserved UUIDs that will never be returned by the random method. * Static factory to generate a directory ID.
*
* This will not generate a reserved UUID (first 100), or one whose string representation
* starts with a dash ("-")
*/ */
public static final Set<Uuid> RESERVED; public static Uuid random() {
while (true) {
static { // Uuid.randomUuid does not generate Uuids whose string representation starts with a
HashSet<Uuid> reserved = new HashSet<>(); // dash.
// The first 100 Uuids are reserved for future use. Uuid uuid = Uuid.randomUuid();
for (long i = 0L; i < 100L; i++) { if (!DirectoryId.reserved(uuid)) {
reserved.add(new Uuid(0L, i)); return uuid;
}
} }
RESERVED = Collections.unmodifiableSet(reserved);
} }
/** /**
* Static factory to generate a directory ID. * Check if a directory ID is part of the first 100 reserved IDs.
* *
* This will not generate a reserved UUID (first 100), or one whose string representation starts with a dash ("-") * @param uuid the directory ID to check.
* @return true only if the directory ID is reserved.
*/ */
public static Uuid random() { public static boolean reserved(Uuid uuid) {
Uuid uuid = Uuid.randomUuid(); return (uuid.getMostSignificantBits() == 0 &&
while (RESERVED.contains(uuid) || uuid.toString().startsWith("-")) { uuid.getLeastSignificantBits() < 100);
uuid = Uuid.randomUuid();
}
return uuid;
} }
/** /**

View File

@ -28,17 +28,19 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
public class DirectoryIdTest { public class DirectoryIdTest {
@Test
void testUnassignedIsReserved() {
assertTrue(DirectoryId.reserved(DirectoryId.UNASSIGNED));
}
@Test @Test
void testReserved() { void testLostIsReserved() {
Set<Long> seen = new HashSet<>(100); assertTrue(DirectoryId.reserved(DirectoryId.LOST));
for (Uuid reservedId : DirectoryId.RESERVED) {
assertEquals(0L, reservedId.getMostSignificantBits(), "Unexpected reserved msb value");
long lsb = reservedId.getLeastSignificantBits();
assertTrue(lsb >= 0 && lsb < 100L, "Unexpected reserved lsb value");
assertTrue(seen.add(lsb), "Duplicate reserved value");
} }
assertEquals(100, DirectoryId.RESERVED.size());
@Test
void testMigratingIsReserved() {
assertTrue(DirectoryId.reserved(DirectoryId.MIGRATING));
} }
@Test @Test