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

cshannon pushed a commit to branch no-chop-merge
in repository https://gitbox.apache.org/repos/asf/accumulo.git

commit 7fbb262b77a7dcee86af169db27e90cbd28a6742
Merge: 04b614c35f 0214c6f99f
Author: Christopher L. Shannon (cshannon) <christopher.l.shan...@gmail.com>
AuthorDate: Fri Jun 23 09:19:30 2023 -0400

    Merge branch 'main' into no-chop-merge

 .../core/clientImpl/bulk/BulkSerialize.java        |   3 +-
 .../apache/accumulo/core/lock/ServiceLockData.java |  11 +-
 .../accumulo/core/metadata/AbstractTabletFile.java |   7 -
 .../core/metadata/ReferencedTabletFile.java        | 156 ++++++++++++++++-----
 .../accumulo/core/metadata/StoredTabletFile.java   |  18 +--
 .../accumulo/core/metadata/TabletDirectory.java    |  65 ---------
 .../core/metadata/UnreferencedTabletFile.java      |  10 +-
 .../accumulo/core/metadata/ValidationUtil.java     |   1 +
 .../schema/ExternalCompactionFinalState.java       |   8 +-
 .../schema/ExternalCompactionMetadata.java         |   9 +-
 .../core/metadata/schema/RootTabletMetadata.java   |   8 +-
 .../spi/compaction/DefaultCompactionPlanner.java   |   6 +-
 .../spi/scan/ConfigurableScanServerSelector.java   |   7 +-
 .../apache/accumulo/core/util/ComparablePair.java  |   6 +-
 .../{ComparablePair.java => GsonSingleton.java}    |  30 ++--
 .../java/org/apache/accumulo/core/util/Pair.java   |   4 +-
 .../metadata/schema/ReferencedTabletFileTest.java  |   6 +-
 pom.xml                                            |   2 +-
 .../accumulo/server/metadata/RootGcCandidates.java |   8 +-
 .../accumulo/manager/tableOps/TraceRepo.java       |   5 +-
 .../util/logging/AccumuloMonitorAppender.java      |   6 +-
 .../accumulo/test/CountNameNodeOpsBulkIT.java      |   5 +-
 22 files changed, 201 insertions(+), 180 deletions(-)

diff --cc 
core/src/main/java/org/apache/accumulo/core/metadata/AbstractTabletFile.java
index c6d1ded80d,146c2b2467..51b8f6166f
--- 
a/core/src/main/java/org/apache/accumulo/core/metadata/AbstractTabletFile.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/metadata/AbstractTabletFile.java
@@@ -32,21 -31,12 +32,14 @@@ import org.apache.hadoop.fs.Path
  public abstract class AbstractTabletFile<T extends AbstractTabletFile<T>>
      implements TabletFile, Comparable<T> {
  
-   private final String fileName; // C0004.rf
    protected final Path path;
 +  protected final Range range;
  
 -  protected AbstractTabletFile(Path path) {
 +  protected AbstractTabletFile(Path path, Range range) {
      this.path = Objects.requireNonNull(path);
-     this.fileName = path.getName();
 +    this.range = Objects.requireNonNull(range);
    }
  
-   @Override
-   public String getFileName() {
-     return fileName;
-   }
- 
    @Override
    public Path getPath() {
      return path;
diff --cc 
core/src/main/java/org/apache/accumulo/core/metadata/ReferencedTabletFile.java
index b1cefc5f45,ff1bfe7e3a..3edfd1d41f
--- 
a/core/src/main/java/org/apache/accumulo/core/metadata/ReferencedTabletFile.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/metadata/ReferencedTabletFile.java
@@@ -20,11 -20,11 +20,13 @@@ package org.apache.accumulo.core.metada
  
  import static org.apache.accumulo.core.Constants.HDFS_TABLES_DIR;
  
+ import java.net.URI;
 +import java.util.Comparator;
  import java.util.Objects;
  
 +import org.apache.accumulo.core.data.Range;
  import org.apache.accumulo.core.data.TableId;
+ import org.apache.commons.lang3.StringUtils;
  import org.apache.hadoop.fs.Path;
  import org.apache.hadoop.io.Text;
  import org.slf4j.Logger;
@@@ -43,48 -43,122 +45,130 @@@ import com.google.common.base.Precondit
   * in Upgrader9to10.upgradeRelativePaths()
   */
  public class ReferencedTabletFile extends 
AbstractTabletFile<ReferencedTabletFile> {
-   // parts of an absolute URI, like 
"hdfs://1.2.3.4/accumulo/tables/2a/t-0003/C0004.rf"
-   private final TabletDirectory tabletDir; // 
hdfs://1.2.3.4/accumulo/tables/2a/t-0003
-   private final String normalizedPath;
+ 
+   public static class FileParts {
+ 
+     // parts of an absolute URI, like 
"hdfs://1.2.3.4/accumulo/tables/2a/t-0003/C0004.rf"
+     // volume: hdfs://1.2.3.4/accumulo
+     // tableId: 2a
+     // tabletDir: t-0003
+     // fileName: C0004.rf
+     // normalizedPath: hdfs://1.2.3.4/accumulo/tables/2a/t-0003/C0004.rf
+     private final String volume;
+     private final TableId tableId;
+     private final String tabletDir;
+     private final String fileName;
+     private final String normalizedPath;
+ 
+     public FileParts(String volume, TableId tableId, String tabletDir, String 
fileName,
+         String normalizedPath) {
+       this.volume = volume;
+       this.tableId = tableId;
+       this.tabletDir = tabletDir;
+       this.fileName = fileName;
+       this.normalizedPath = normalizedPath;
+     }
+ 
+     public String getVolume() {
+       return volume;
+     }
+ 
+     public TableId getTableId() {
+       return tableId;
+     }
+ 
+     public String getTabletDir() {
+       return tabletDir;
+     }
+ 
+     public String getFileName() {
+       return fileName;
+     }
+ 
+     public String getNormalizedPath() {
+       return normalizedPath;
+     }
+ 
+   }
+ 
+   private static String constructErrorMsg(Path filePath) {
+     return "Missing or invalid part of tablet file metadata entry: " + 
filePath;
+   }
+ 
+   public static FileParts parsePath(Path filePath) {
+     // File name construct: <volume>/<tablePath>/<tableId>/<tablet>/<file>
+     // Example: 
hdfs://namenode:9020/accumulo/tables/1/default_tablet/F00001.rf
+     final URI uri = filePath.toUri();
+ 
+     // validate that this is a fully qualified uri
+     Preconditions.checkArgument(uri.getScheme() != null, 
constructErrorMsg(filePath));
+ 
+     final String path = uri.getPath(); // ex: 
/accumulo/tables/1/default_tablet/F00001.rf
+     final String[] parts = path.split("/");
+     final int numParts = parts.length; // should contain tables, 1, 
default_tablet, F00001.rf
+ 
+     if (numParts < 4) {
+       throw new IllegalArgumentException(constructErrorMsg(filePath));
+     }
+ 
+     final String fileName = parts[numParts - 1];
+     final String tabletDirectory = parts[numParts - 2];
+     final TableId tableId = TableId.of(parts[numParts - 3]);
+     final String tablesPath = parts[numParts - 4];
+ 
+     // determine where file path starts, the rest is the volume
+     final String computedFilePath =
+         HDFS_TABLES_DIR + "/" + tableId.canonical() + "/" + tabletDirectory + 
"/" + fileName;
+     final String uriString = uri.toString();
+     int idx = uriString.lastIndexOf(computedFilePath);
+ 
+     if (idx == -1) {
+       throw new IllegalArgumentException(constructErrorMsg(filePath));
+     }
+ 
+     // The volume is the beginning portion of the uri up to the start
+     // of the file path.
+     final String volume = uriString.substring(0, idx);
+ 
+     if (StringUtils.isBlank(fileName) || StringUtils.isBlank(tabletDirectory)
+         || StringUtils.isBlank(tablesPath) || StringUtils.isBlank(volume)) {
+       throw new IllegalArgumentException(constructErrorMsg(filePath));
+     }
+     ValidationUtil.validateFileName(fileName);
+     Preconditions.checkArgument(tablesPath.equals(HDFS_TABLES_DIR_NAME),
+         "tables directory name is not " + HDFS_TABLES_DIR_NAME + ", is " + 
tablesPath);
+ 
+     final String normalizedPath = volume + computedFilePath;
+ 
+     if (!normalizedPath.equals(uriString)) {
+       throw new RuntimeException("Error parsing file path, " + normalizedPath 
+ " != " + uriString);
+     }
+ 
+     return new FileParts(volume, tableId, tabletDirectory, fileName, 
normalizedPath);
+ 
+   }
+ 
+   private final FileParts parts;
  
    private static final Logger log = 
LoggerFactory.getLogger(ReferencedTabletFile.class);
+   private static final String HDFS_TABLES_DIR_NAME = 
HDFS_TABLES_DIR.substring(1);
  
 +  private static final Comparator<ReferencedTabletFile> comparator =
 +      Comparator.comparing(ReferencedTabletFile::getNormalizedPathStr)
 +          .thenComparing(ReferencedTabletFile::getRange);
 +
 +  public ReferencedTabletFile(Path metaPath) {
 +    this(metaPath, new Range());
 +  }
 +
    /**
     * Construct new tablet file using a Path. Used in the case where we had to 
use Path object to
     * qualify an absolute path or create a new file.
     */
 -  public ReferencedTabletFile(Path metaPath) {
 -    super(Objects.requireNonNull(metaPath));
 +  public ReferencedTabletFile(Path metaPath, Range range) {
 +    super(Objects.requireNonNull(metaPath), range);
-     String errorMsg = "Missing or invalid part of tablet file metadata entry: 
" + metaPath;
      log.trace("Parsing TabletFile from {}", metaPath);
- 
-     // Validate characters in file name
-     ValidationUtil.validateFileName(path.getName());
- 
-     // use Path object to step backwards from the filename through all the 
parts
-     Path tabletDirPath = Objects.requireNonNull(metaPath.getParent(), 
errorMsg);
- 
-     Path tableIdPath = Objects.requireNonNull(tabletDirPath.getParent(), 
errorMsg);
-     var id = tableIdPath.getName();
- 
-     Path tablePath = Objects.requireNonNull(tableIdPath.getParent(), 
errorMsg);
-     String tpString = "/" + tablePath.getName();
-     Preconditions.checkArgument(tpString.equals(HDFS_TABLES_DIR), errorMsg);
- 
-     Path volumePath = Objects.requireNonNull(tablePath.getParent(), errorMsg);
-     Preconditions.checkArgument(volumePath.toUri().getScheme() != null, 
errorMsg);
-     var volume = volumePath.toString();
- 
-     this.tabletDir = new TabletDirectory(volume, TableId.of(id), 
tabletDirPath.getName());
-     this.normalizedPath = tabletDir.getNormalizedPath() + "/" + getFileName();
+     parts = parsePath(metaPath);
    }
  
    public String getVolume() {
@@@ -141,14 -220,14 +230,15 @@@
    public boolean equals(Object obj) {
      if (obj instanceof ReferencedTabletFile) {
        ReferencedTabletFile that = (ReferencedTabletFile) obj;
-       return normalizedPath.equals(that.normalizedPath) && 
range.equals(that.range);
 -      return parts.getNormalizedPath().equals(that.parts.getNormalizedPath());
++      return parts.getNormalizedPath().equals(that.parts.getNormalizedPath())
++          && range.equals(that.range);
      }
      return false;
    }
  
    @Override
    public int hashCode() {
-     return Objects.hash(normalizedPath, range);
 -    return parts.getNormalizedPath().hashCode();
++    return Objects.hash(parts.getNormalizedPath(), range);
    }
  
    @Override
diff --cc 
core/src/main/java/org/apache/accumulo/core/metadata/StoredTabletFile.java
index 68f84e5a5b,3bf5e701d5..feb3fd03e9
--- a/core/src/main/java/org/apache/accumulo/core/metadata/StoredTabletFile.java
+++ b/core/src/main/java/org/apache/accumulo/core/metadata/StoredTabletFile.java
@@@ -19,9 -19,7 +19,8 @@@
  package org.apache.accumulo.core.metadata;
  
  import java.util.Objects;
- import java.util.function.Supplier;
  
 +import org.apache.accumulo.core.data.Range;
  import org.apache.accumulo.core.data.TableId;
  import org.apache.hadoop.fs.Path;
  import org.apache.hadoop.io.Text;
@@@ -48,11 -44,9 +45,11 @@@ public class StoredTabletFile extends A
     * the entry can be deleted.
     */
    public StoredTabletFile(String metadataEntry) {
 -    super(new Path(metadataEntry));
 +    // TODO: Future version of metadataEntry will contains the path
 +    // and the range so we will need to parse the string here
 +    super(new Path(metadataEntry), new Range());
      this.metadataEntry = metadataEntry;
-     this.referencedTabletFile = Suppliers.memoize(() -> 
ReferencedTabletFile.of(getPath()));
+     this.referencedTabletFile = ReferencedTabletFile.of(getPath());
    }
  
    /**
diff --cc 
core/src/main/java/org/apache/accumulo/core/metadata/UnreferencedTabletFile.java
index 4b39023fc1,4f6b16a946..3d5c1d40f8
--- 
a/core/src/main/java/org/apache/accumulo/core/metadata/UnreferencedTabletFile.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/metadata/UnreferencedTabletFile.java
@@@ -41,13 -40,17 +41,21 @@@ import org.apache.hadoop.fs.Path
   */
  public class UnreferencedTabletFile extends 
AbstractTabletFile<UnreferencedTabletFile> {
  
+   private final String fileName; // C0004.rf
+ 
    public UnreferencedTabletFile(FileSystem fs, Path path) {
 -    
super(Objects.requireNonNull(fs).makeQualified(Objects.requireNonNull(path)));
 +    this(fs, path, new Range());
 +  }
 +
 +  public UnreferencedTabletFile(FileSystem fs, Path path, Range range) {
 +    
super(Objects.requireNonNull(fs).makeQualified(Objects.requireNonNull(path)), 
range);
-     ValidationUtil.validateFileName(path.getName());
+     this.fileName = path.getName();
+     ValidationUtil.validateFileName(fileName);
+   }
+ 
+   @Override
+   public String getFileName() {
+     return fileName;
    }
  
    @Override

Reply via email to