This is an automated email from the ASF dual-hosted git repository.

xiangfu0 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new ec52ed81f6f Intern the instance id in ServerInstance (#19583)
ec52ed81f6f is described below

commit ec52ed81f6f3a98adcc40d69dbea81a567b3ce8e
Author: Xiaotian (Jackie) Jiang <[email protected]>
AuthorDate: Wed Sep 16 17:53:48 2026 -0700

    Intern the instance id in ServerInstance (#19583)
    
    Co-authored-by: Claude Fable 5.1 <[email protected]>
---
 .../routing/manager/BaseBrokerRoutingManager.java     |  8 ++++----
 .../routing/manager/BrokerRoutingManagerTest.java     | 19 +++----------------
 .../apache/pinot/core/transport/ServerInstance.java   | 10 ++++++++--
 .../pinot/core/transport/ServerInstanceTest.java      | 12 ++++++++++++
 4 files changed, 27 insertions(+), 22 deletions(-)

diff --git 
a/pinot-broker/src/main/java/org/apache/pinot/broker/routing/manager/BaseBrokerRoutingManager.java
 
b/pinot-broker/src/main/java/org/apache/pinot/broker/routing/manager/BaseBrokerRoutingManager.java
index 4b50b852bed..25e5b784b7d 100644
--- 
a/pinot-broker/src/main/java/org/apache/pinot/broker/routing/manager/BaseBrokerRoutingManager.java
+++ 
b/pinot-broker/src/main/java/org/apache/pinot/broker/routing/manager/BaseBrokerRoutingManager.java
@@ -416,13 +416,13 @@ public abstract class BaseBrokerRoutingManager implements 
RoutingManager, Cluste
       String instanceId = instanceConfigZNRecord.getId();
       try {
         if (isEnabledServer(instanceConfigZNRecord)) {
-          // Join Jackson's JVM-interned IS/EV keys; a config-only Guava 
interner would use a separate pool.
-          instanceId = instanceId.intern();
-          enabledServers.add(instanceId);
-
           // Always refresh the server instance with the latest instance 
config in case it changes
           InstanceConfig instanceConfig = new 
InstanceConfig(instanceConfigZNRecord);
           ServerInstance serverInstance = new ServerInstance(instanceConfig);
+          // Key the maps by the interned instance id so that lookups with the 
Jackson-interned instance ids from IS/EV
+          // hit the identity fast path
+          instanceId = serverInstance.getInstanceId();
+          enabledServers.add(instanceId);
           if (_enabledServerInstanceMap.put(instanceId, serverInstance) == 
null) {
             newEnabledServers.add(instanceId);
 
diff --git 
a/pinot-broker/src/test/java/org/apache/pinot/broker/routing/manager/BrokerRoutingManagerTest.java
 
b/pinot-broker/src/test/java/org/apache/pinot/broker/routing/manager/BrokerRoutingManagerTest.java
index 5d7830ad04b..82668fd1ce1 100644
--- 
a/pinot-broker/src/test/java/org/apache/pinot/broker/routing/manager/BrokerRoutingManagerTest.java
+++ 
b/pinot-broker/src/test/java/org/apache/pinot/broker/routing/manager/BrokerRoutingManagerTest.java
@@ -77,21 +77,8 @@ import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotSame;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertSame;
-import static org.testng.Assert.assertTrue;
+import static org.mockito.Mockito.*;
+import static org.testng.Assert.*;
 
 
 public class BrokerRoutingManagerTest {
@@ -206,7 +193,7 @@ public class BrokerRoutingManagerTest {
       assertEquals(enabledServers.size(), 1);
       assertSame(enabledServers.keySet().iterator().next(), 
requiredInstanceId);
       ServerInstance server = enabledServers.get(requiredInstanceId);
-      assertEquals(server.getInstanceId(), SERVER_INSTANCE_ID);
+      assertSame(server.getInstanceId(), requiredInstanceId);
       assertEquals(server.getHostname(), SERVER_HOST);
       assertEquals(server.getPort(), SERVER_PORT);
       // An equal ID on a later config refresh must still replace the server's 
configuration.
diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/transport/ServerInstance.java 
b/pinot-core/src/main/java/org/apache/pinot/core/transport/ServerInstance.java
index 18b296d8adc..b0ca541bf16 100644
--- 
a/pinot-core/src/main/java/org/apache/pinot/core/transport/ServerInstance.java
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/transport/ServerInstance.java
@@ -59,8 +59,13 @@ public final class ServerInstance {
 
   /// By default (auto joined instances), server instance name is of format: 
`Server_<hostname>_<port>`, e.g.
   /// `Server_localhost_12345`, hostname is of format: `Server_<hostname>`, 
e.g. `Server_localhost`.
+  ///
+  /// The instance id is interned. The same id is repeated as a key across 
many long-lived routing structures, and
+  /// Jackson already interns it when decoding the map fields of `IdealState` 
/ `ExternalView`, so joining the JVM pool
+  /// lets all of them share one `String` and lets hash lookups hit the 
identity fast path. It also keeps the instances
+  /// rebuilt on every instance config refresh from each retaining a separate 
copy of the id.
   public ServerInstance(InstanceConfig instanceConfig) {
-    _instanceId = instanceConfig.getInstanceName();
+    _instanceId = instanceConfig.getInstanceName().intern();
     _hostname = extractHostnameFromConfig(instanceConfig);
     _port = extractPortFromConfig(instanceConfig);
     _grpcPort = 
instanceConfig.getRecord().getIntField(Helix.Instance.GRPC_PORT_KEY, 
INVALID_PORT);
@@ -113,7 +118,7 @@ public final class ServerInstance {
 
   @VisibleForTesting
   ServerInstance(String hostname, int port) {
-    _instanceId = Helix.PREFIX_OF_SERVER_INSTANCE + hostname + "_" + port;
+    _instanceId = (Helix.PREFIX_OF_SERVER_INSTANCE + hostname + "_" + 
port).intern();
     _hostname = hostname;
     _port = port;
     _grpcPort = INVALID_PORT;
@@ -124,6 +129,7 @@ public final class ServerInstance {
     _pool = FALLBACK_POOL_ID;
   }
 
+  /// Returns the interned instance id.
   public String getInstanceId() {
     return _instanceId;
   }
diff --git 
a/pinot-core/src/test/java/org/apache/pinot/core/transport/ServerInstanceTest.java
 
b/pinot-core/src/test/java/org/apache/pinot/core/transport/ServerInstanceTest.java
index dbd89f6b29a..e39c3905e89 100644
--- 
a/pinot-core/src/test/java/org/apache/pinot/core/transport/ServerInstanceTest.java
+++ 
b/pinot-core/src/test/java/org/apache/pinot/core/transport/ServerInstanceTest.java
@@ -24,6 +24,8 @@ import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.testng.annotations.Test;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertThrows;
 
 
@@ -34,6 +36,16 @@ public class ServerInstanceTest {
         .withNonnullFields("_instanceId").verify();
   }
 
+  @Test
+  public void testInstanceIdInterned() {
+    // Build the id at runtime so that the config holds a copy that is not 
already in the string pool
+    String instanceId = String.join("_", "Server", "myhost", "1234");
+    assertNotSame(instanceId, "Server_myhost_1234");
+    ServerInstance serverInstance = new ServerInstance(new InstanceConfig(new 
ZNRecord(instanceId)));
+    assertSame(serverInstance.getInstanceId(), "Server_myhost_1234");
+    assertSame(new ServerInstance("myhost", 1234).getInstanceId(), 
"Server_myhost_1234");
+  }
+
   @Test
   public void testExtractHostnameFromConfigWithServerPrefix() {
     InstanceConfig config = new InstanceConfig(new 
ZNRecord("Server_myhost_1234"));


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to