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

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


The following commit(s) were added to refs/heads/main by this push:
     new 49a8f4adbf Narrow table lock range for set tablet availability fate 
operation (#5949)
49a8f4adbf is described below

commit 49a8f4adbff81d9f1a70976d1066e0147cae797c
Author: Dom G. <[email protected]>
AuthorDate: Tue Jan 6 11:06:57 2026 -0500

    Narrow table lock range for set tablet availability fate operation (#5949)
    
    * Narrow the tablet availability FATE locks to a row range, reducing the 
locked area to only what is needed
---
 .../apache/accumulo/manager/tableOps/Utils.java    |  8 +++-
 .../manager/tableOps/availability/LockTable.java   | 46 +++++++++++++++++++++-
 2 files changed, 52 insertions(+), 2 deletions(-)

diff --git 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java
index cb8b774476..b791badf8b 100644
--- 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java
+++ 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java
@@ -86,7 +86,13 @@ public class Utils {
     }
   }
 
-  private static KeyExtent findContaining(Ample ample, TableId tableId, Text 
row) {
+  /**
+   * Finds the single tablet extent that contains the provided row.
+   *
+   * @throws NullPointerException if row is null
+   * @throws java.util.NoSuchElementException if no tablet contains the row
+   */
+  public static KeyExtent findContaining(Ample ample, TableId tableId, Text 
row) {
     Objects.requireNonNull(row);
     try (var tablets = ample.readTablets().forTable(tableId).overlapping(row, 
true, row)
         .fetch(TabletMetadata.ColumnType.PREV_ROW).build()) {
diff --git 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java
 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java
index b8ab0aac5a..7b5abfa3ad 100644
--- 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java
+++ 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java
@@ -21,17 +21,25 @@ package org.apache.accumulo.manager.tableOps.availability;
 import org.apache.accumulo.core.client.admin.TabletAvailability;
 import org.apache.accumulo.core.clientImpl.thrift.TableOperation;
 import org.apache.accumulo.core.data.NamespaceId;
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.data.RowRange;
 import org.apache.accumulo.core.data.TableId;
 import org.apache.accumulo.core.dataImpl.thrift.TRange;
 import org.apache.accumulo.core.fate.FateId;
 import org.apache.accumulo.core.fate.Repo;
 import org.apache.accumulo.core.fate.zookeeper.DistributedReadWriteLock;
+import org.apache.accumulo.core.fate.zookeeper.LockRange;
+import org.apache.accumulo.core.util.RowRangeUtil;
 import org.apache.accumulo.manager.tableOps.AbstractFateOperation;
 import org.apache.accumulo.manager.tableOps.FateEnv;
 import org.apache.accumulo.manager.tableOps.Utils;
+import org.apache.hadoop.io.Text;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class LockTable extends AbstractFateOperation {
   private static final long serialVersionUID = 1L;
+  private static final Logger LOG = LoggerFactory.getLogger(LockTable.class);
 
   private final TableId tableId;
   private final NamespaceId namespaceId;
@@ -48,10 +56,12 @@ public class LockTable extends AbstractFateOperation {
 
   @Override
   public long isReady(FateId fateId, FateEnv env) throws Exception {
+    LockRange lockRange = getLockRange(env);
     return Utils.reserveNamespace(env.getContext(), namespaceId, fateId,
         DistributedReadWriteLock.LockType.READ, true, 
TableOperation.SET_TABLET_AVAILABILITY)
         + Utils.reserveTable(env.getContext(), tableId, fateId,
-            DistributedReadWriteLock.LockType.WRITE, true, 
TableOperation.SET_TABLET_AVAILABILITY);
+            DistributedReadWriteLock.LockType.WRITE, true, 
TableOperation.SET_TABLET_AVAILABILITY,
+            lockRange);
   }
 
   @Override
@@ -66,4 +76,38 @@ public class LockTable extends AbstractFateOperation {
     Utils.unreserveTable(env.getContext(), tableId, fateId,
         DistributedReadWriteLock.LockType.WRITE);
   }
+
+  /**
+   * Get the LockRange for {@code this} object using its tRange field. 
Converts the key-range to a
+   * row-range which is needed for the LockRange. We do a safe conversion 
meaning potentially
+   * locking slightly more than is needed so we have at least what we need. If 
the key-range can't
+   * be converted to a RowRange, an infinite LockRange is returned.
+   */
+  private LockRange getLockRange(FateEnv env) {
+    if (tRange.infiniteStartKey && tRange.infiniteStopKey) {
+      return LockRange.infinite();
+    }
+    Range range = new Range(tRange);
+
+    try {
+      RowRange rowRange = RowRangeUtil.toRowRange(range);
+      Text startRow = rowRange.getLowerBound();
+      Text endRow = rowRange.getUpperBound();
+
+      Text lockStartRow = null;
+      if (startRow != null) {
+        if (rowRange.isLowerBoundInclusive()) {
+          lockStartRow =
+              Utils.findContaining(env.getContext().getAmple(), tableId, 
startRow).prevEndRow();
+        } else {
+          lockStartRow = startRow;
+        }
+      }
+
+      return LockRange.of(lockStartRow, endRow);
+    } catch (IllegalArgumentException | java.util.NoSuchElementException e) {
+      LOG.debug("Unable to convert {} to a RowRange, defaulting to infinite 
lock range", range, e);
+      return LockRange.infinite();
+    }
+  }
 }

Reply via email to