You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ms...@apache.org on 2026/03/24 20:23:36 UTC

(lucene) branch main updated: Remove lock in StringHelper, using atomic getAndUpdate instead (#15805)

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

msfroh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/lucene.git


The following commit(s) were added to refs/heads/main by this push:
     new 169b9ead1e6 Remove lock in StringHelper, using atomic getAndUpdate instead (#15805)
169b9ead1e6 is described below

commit 169b9ead1e6259138f58ea38681be18599df9365
Author: Michael Froh <ms...@apache.org>
AuthorDate: Tue Mar 24 13:23:29 2026 -0700

    Remove lock in StringHelper, using atomic getAndUpdate instead (#15805)
---
 .../core/src/java/org/apache/lucene/util/StringHelper.java | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/lucene/core/src/java/org/apache/lucene/util/StringHelper.java b/lucene/core/src/java/org/apache/lucene/util/StringHelper.java
index fc44fbfb9b4..715f3e13054 100644
--- a/lucene/core/src/java/org/apache/lucene/util/StringHelper.java
+++ b/lucene/core/src/java/org/apache/lucene/util/StringHelper.java
@@ -23,6 +23,7 @@ import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.HexFormat;
 import java.util.Properties;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Methods for manipulating strings.
@@ -361,11 +362,9 @@ public abstract class StringHelper {
   }
 
   // Holds 128 bit unsigned value:
-  @SuppressWarnings("NonFinalStaticField")
-  private static BigInteger nextId;
+  private static final AtomicReference<BigInteger> nextId;
 
   private static final BigInteger mask128;
-  private static final Object idLock = new Object();
 
   static {
     // 128 bit unsigned mask
@@ -436,7 +435,7 @@ public abstract class StringHelper {
     BigInteger unsignedX1 = BigInteger.valueOf(x1).and(mask64);
 
     // Concatentate bits of x0 and x1, as unsigned 128 bit integer:
-    nextId = unsignedX0.shiftLeft(64).or(unsignedX1);
+    nextId = new AtomicReference<>(unsignedX0.shiftLeft(64).or(unsignedX1));
   }
 
   /** length in bytes of an ID */
@@ -459,11 +458,8 @@ public abstract class StringHelper {
     //     what impact that has on the period, whereas the simple ++ (mod 2^128)
     //     we use here is guaranteed to have the full period.
 
-    byte[] bits;
-    synchronized (idLock) {
-      bits = nextId.toByteArray();
-      nextId = nextId.add(BigInteger.ONE).and(mask128);
-    }
+    BigInteger next = nextId.getAndUpdate(n -> n.add(BigInteger.ONE).and(mask128));
+    byte[] bits = next.toByteArray();
 
     // toByteArray() always returns a sign bit, so it may require an extra byte (always zero)
     if (bits.length > ID_LENGTH) {