|
@@ -224,27 +224,27 @@ public interface FsVolumeSpi
|
|
*/
|
|
*/
|
|
public static class ScanInfo implements Comparable<ScanInfo> {
|
|
public static class ScanInfo implements Comparable<ScanInfo> {
|
|
private final long blockId;
|
|
private final long blockId;
|
|
-
|
|
|
|
/**
|
|
/**
|
|
- * The block file path, relative to the volume's base directory.
|
|
|
|
- * If there was no block file found, this may be null. If 'vol'
|
|
|
|
- * is null, then this is the full path of the block file.
|
|
|
|
|
|
+ * The full path to the folder containing the block / meta files.
|
|
*/
|
|
*/
|
|
- private final String blockSuffix;
|
|
|
|
-
|
|
|
|
|
|
+ private final File basePath;
|
|
/**
|
|
/**
|
|
- * The suffix of the meta file path relative to the block file.
|
|
|
|
- * If blockSuffix is null, then this will be the entire path relative
|
|
|
|
- * to the volume base directory, or an absolute path if vol is also
|
|
|
|
- * null.
|
|
|
|
|
|
+ * The block file name, with no path
|
|
*/
|
|
*/
|
|
- private final String metaSuffix;
|
|
|
|
|
|
+ private final String blockFile;
|
|
|
|
+ /**
|
|
|
|
+ * Holds the meta file name, with no path, only if blockFile is null.
|
|
|
|
+ * If blockFile is not null, the meta file will be named identically to
|
|
|
|
+ * the blockFile, but with a suffix like "_1234.meta". If the blockFile
|
|
|
|
+ * is present, we store only the meta file suffix.
|
|
|
|
+ */
|
|
|
|
+ private final String metaFile;
|
|
|
|
|
|
private final FsVolumeSpi volume;
|
|
private final FsVolumeSpi volume;
|
|
|
|
|
|
private final FileRegion fileRegion;
|
|
private final FileRegion fileRegion;
|
|
/**
|
|
/**
|
|
- * Get the file's length in async block scan
|
|
|
|
|
|
+ * Get the file's length in async block scan.
|
|
*/
|
|
*/
|
|
private final long blockLength;
|
|
private final long blockLength;
|
|
|
|
|
|
@@ -254,35 +254,19 @@ public interface FsVolumeSpi
|
|
private final static String QUOTED_FILE_SEPARATOR =
|
|
private final static String QUOTED_FILE_SEPARATOR =
|
|
Matcher.quoteReplacement(File.separator);
|
|
Matcher.quoteReplacement(File.separator);
|
|
|
|
|
|
- /**
|
|
|
|
- * Get the most condensed version of the path.
|
|
|
|
- *
|
|
|
|
- * For example, the condensed version of /foo//bar is /foo/bar
|
|
|
|
- * Unlike {@link File#getCanonicalPath()}, this will never perform I/O
|
|
|
|
- * on the filesystem.
|
|
|
|
- *
|
|
|
|
- * @param path the path to condense
|
|
|
|
- * @return the condensed path
|
|
|
|
- */
|
|
|
|
- private static String getCondensedPath(String path) {
|
|
|
|
- return CONDENSED_PATH_REGEX.matcher(path).
|
|
|
|
- replaceAll(QUOTED_FILE_SEPARATOR);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Get a path suffix.
|
|
* Get a path suffix.
|
|
*
|
|
*
|
|
- * @param f The file to get the suffix for.
|
|
|
|
|
|
+ * @param f The string to get the suffix for.
|
|
* @param prefix The prefix we're stripping off.
|
|
* @param prefix The prefix we're stripping off.
|
|
*
|
|
*
|
|
- * @return A suffix such that prefix + suffix = path to f
|
|
|
|
|
|
+ * @return A suffix such that prefix + suffix = f
|
|
*/
|
|
*/
|
|
- private static String getSuffix(File f, String prefix) {
|
|
|
|
- String fullPath = getCondensedPath(f.getAbsolutePath());
|
|
|
|
- if (fullPath.startsWith(prefix)) {
|
|
|
|
- return fullPath.substring(prefix.length());
|
|
|
|
|
|
+ private static String getSuffix(String f, String prefix) {
|
|
|
|
+ if (f.startsWith(prefix)) {
|
|
|
|
+ return f.substring(prefix.length());
|
|
}
|
|
}
|
|
- throw new RuntimeException(prefix + " is not a prefix of " + fullPath);
|
|
|
|
|
|
+ throw new RuntimeException(prefix + " is not a prefix of " + f);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -290,27 +274,27 @@ public interface FsVolumeSpi
|
|
* the block data and meta-data files.
|
|
* the block data and meta-data files.
|
|
*
|
|
*
|
|
* @param blockId the block ID
|
|
* @param blockId the block ID
|
|
- * @param blockFile the path to the block data file
|
|
|
|
- * @param metaFile the path to the block meta-data file
|
|
|
|
|
|
+ * @param basePath The full path to the directory the block is stored in
|
|
|
|
+ * @param blockFile The block filename, with no path
|
|
|
|
+ * @param metaFile The meta filename, with no path. If blockFile is not null
|
|
|
|
+ * then the metaFile and blockFile should have the same
|
|
|
|
+ * prefix, with the meta file having a suffix like
|
|
|
|
+ * "_1234.meta". To save memory, if the blockFile is present
|
|
|
|
+ * we store only the meta file suffix in the object
|
|
* @param vol the volume that contains the block
|
|
* @param vol the volume that contains the block
|
|
*/
|
|
*/
|
|
- public ScanInfo(long blockId, File blockFile, File metaFile,
|
|
|
|
- FsVolumeSpi vol) {
|
|
|
|
|
|
+ public ScanInfo(long blockId, File basePath, String blockFile,
|
|
|
|
+ String metaFile, FsVolumeSpi vol) {
|
|
this.blockId = blockId;
|
|
this.blockId = blockId;
|
|
- String condensedVolPath =
|
|
|
|
- (vol == null || vol.getBaseURI() == null) ? null :
|
|
|
|
- getCondensedPath(new File(vol.getBaseURI()).getAbsolutePath());
|
|
|
|
- this.blockSuffix = blockFile == null ? null :
|
|
|
|
- getSuffix(blockFile, condensedVolPath);
|
|
|
|
- this.blockLength = (blockFile != null) ? blockFile.length() : 0;
|
|
|
|
- if (metaFile == null) {
|
|
|
|
- this.metaSuffix = null;
|
|
|
|
- } else if (blockFile == null) {
|
|
|
|
- this.metaSuffix = getSuffix(metaFile, condensedVolPath);
|
|
|
|
|
|
+ this.basePath = basePath;
|
|
|
|
+ this.blockFile = blockFile;
|
|
|
|
+ if (blockFile != null && metaFile != null) {
|
|
|
|
+ this.metaFile = getSuffix(metaFile, blockFile);
|
|
} else {
|
|
} else {
|
|
- this.metaSuffix = getSuffix(metaFile,
|
|
|
|
- condensedVolPath + blockSuffix);
|
|
|
|
|
|
+ this.metaFile = metaFile;
|
|
}
|
|
}
|
|
|
|
+ this.blockLength = (blockFile != null) ?
|
|
|
|
+ new File(basePath, blockFile).length() : 0;
|
|
this.volume = vol;
|
|
this.volume = vol;
|
|
this.fileRegion = null;
|
|
this.fileRegion = null;
|
|
}
|
|
}
|
|
@@ -330,8 +314,9 @@ public interface FsVolumeSpi
|
|
this.blockLength = length;
|
|
this.blockLength = length;
|
|
this.volume = vol;
|
|
this.volume = vol;
|
|
this.fileRegion = fileRegion;
|
|
this.fileRegion = fileRegion;
|
|
- this.blockSuffix = null;
|
|
|
|
- this.metaSuffix = null;
|
|
|
|
|
|
+ this.basePath = null;
|
|
|
|
+ this.blockFile = null;
|
|
|
|
+ this.metaFile = null;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -340,8 +325,8 @@ public interface FsVolumeSpi
|
|
* @return the block data file
|
|
* @return the block data file
|
|
*/
|
|
*/
|
|
public File getBlockFile() {
|
|
public File getBlockFile() {
|
|
- return (blockSuffix == null) ? null :
|
|
|
|
- new File(new File(volume.getBaseURI()).getAbsolutePath(), blockSuffix);
|
|
|
|
|
|
+ return (blockFile == null) ? null :
|
|
|
|
+ new File(basePath.getAbsolutePath(), blockFile);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -360,15 +345,10 @@ public interface FsVolumeSpi
|
|
* @return the block meta data file
|
|
* @return the block meta data file
|
|
*/
|
|
*/
|
|
public File getMetaFile() {
|
|
public File getMetaFile() {
|
|
- if (metaSuffix == null) {
|
|
|
|
|
|
+ if (metaFile == null) {
|
|
return null;
|
|
return null;
|
|
- } else if (blockSuffix == null) {
|
|
|
|
- return new File(new File(volume.getBaseURI()).getAbsolutePath(),
|
|
|
|
- metaSuffix);
|
|
|
|
- } else {
|
|
|
|
- return new File(new File(volume.getBaseURI()).getAbsolutePath(),
|
|
|
|
- blockSuffix + metaSuffix);
|
|
|
|
}
|
|
}
|
|
|
|
+ return new File(basePath.getAbsolutePath(), fullMetaFile());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -417,14 +397,24 @@ public interface FsVolumeSpi
|
|
}
|
|
}
|
|
|
|
|
|
public long getGenStamp() {
|
|
public long getGenStamp() {
|
|
- return metaSuffix != null ? Block.getGenerationStamp(
|
|
|
|
- getMetaFile().getName()) :
|
|
|
|
- HdfsConstants.GRANDFATHER_GENERATION_STAMP;
|
|
|
|
|
|
+ return metaFile != null ? Block.getGenerationStamp(fullMetaFile())
|
|
|
|
+ : HdfsConstants.GRANDFATHER_GENERATION_STAMP;
|
|
}
|
|
}
|
|
|
|
|
|
public FileRegion getFileRegion() {
|
|
public FileRegion getFileRegion() {
|
|
return fileRegion;
|
|
return fileRegion;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ private String fullMetaFile() {
|
|
|
|
+ if (metaFile == null) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ if (blockFile == null) {
|
|
|
|
+ return metaFile;
|
|
|
|
+ } else {
|
|
|
|
+ return blockFile + metaFile;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|