org.apache.hadoop.fs.Options Maven / Gradle / Ivy
The newest version!
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.fs;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.util.DataChecksum;
import org.apache.hadoop.util.Progressable;
/**
* This class contains options related to file system operations.
*/
@InterfaceAudience.Public
@InterfaceStability.Evolving
public final class Options {
/**
* Class to support the varargs for create() options.
*
*/
public static class CreateOpts {
private CreateOpts() { };
public static BlockSize blockSize(long bs) {
return new BlockSize(bs);
}
public static BufferSize bufferSize(int bs) {
return new BufferSize(bs);
}
public static ReplicationFactor repFac(short rf) {
return new ReplicationFactor(rf);
}
public static BytesPerChecksum bytesPerChecksum(short crc) {
return new BytesPerChecksum(crc);
}
public static ChecksumParam checksumParam(
ChecksumOpt csumOpt) {
return new ChecksumParam(csumOpt);
}
public static Progress progress(Progressable prog) {
return new Progress(prog);
}
public static Perms perms(FsPermission perm) {
return new Perms(perm);
}
public static CreateParent createParent() {
return new CreateParent(true);
}
public static CreateParent donotCreateParent() {
return new CreateParent(false);
}
public static class BlockSize extends CreateOpts {
private final long blockSize;
protected BlockSize(long bs) {
if (bs <= 0) {
throw new IllegalArgumentException(
"Block size must be greater than 0");
}
blockSize = bs;
}
public long getValue() { return blockSize; }
}
public static class ReplicationFactor extends CreateOpts {
private final short replication;
protected ReplicationFactor(short rf) {
if (rf <= 0) {
throw new IllegalArgumentException(
"Replication must be greater than 0");
}
replication = rf;
}
public short getValue() { return replication; }
}
public static class BufferSize extends CreateOpts {
private final int bufferSize;
protected BufferSize(int bs) {
if (bs <= 0) {
throw new IllegalArgumentException(
"Buffer size must be greater than 0");
}
bufferSize = bs;
}
public int getValue() { return bufferSize; }
}
/** This is not needed if ChecksumParam is specified. **/
public static class BytesPerChecksum extends CreateOpts {
private final int bytesPerChecksum;
protected BytesPerChecksum(short bpc) {
if (bpc <= 0) {
throw new IllegalArgumentException(
"Bytes per checksum must be greater than 0");
}
bytesPerChecksum = bpc;
}
public int getValue() { return bytesPerChecksum; }
}
public static class ChecksumParam extends CreateOpts {
private final ChecksumOpt checksumOpt;
protected ChecksumParam(ChecksumOpt csumOpt) {
checksumOpt = csumOpt;
}
public ChecksumOpt getValue() { return checksumOpt; }
}
public static class Perms extends CreateOpts {
private final FsPermission permissions;
protected Perms(FsPermission perm) {
if(perm == null) {
throw new IllegalArgumentException("Permissions must not be null");
}
permissions = perm;
}
public FsPermission getValue() { return permissions; }
}
public static class Progress extends CreateOpts {
private final Progressable progress;
protected Progress(Progressable prog) {
if(prog == null) {
throw new IllegalArgumentException("Progress must not be null");
}
progress = prog;
}
public Progressable getValue() { return progress; }
}
public static class CreateParent extends CreateOpts {
private final boolean createParent;
protected CreateParent(boolean createPar) {
createParent = createPar;}
public boolean getValue() { return createParent; }
}
/**
* Get an option of desired type
* @param clazz is the desired class of the opt
* @param opts - not null - at least one opt must be passed
* @return an opt from one of the opts of type theClass.
* returns null if there isn't any
*/
static T getOpt(Class clazz, CreateOpts... opts) {
if (opts == null) {
throw new IllegalArgumentException("Null opt");
}
T result = null;
for (int i = 0; i < opts.length; ++i) {
if (opts[i].getClass() == clazz) {
if (result != null) {
throw new IllegalArgumentException("multiple opts varargs: " + clazz);
}
@SuppressWarnings("unchecked")
T t = (T)opts[i];
result = t;
}
}
return result;
}
/**
* set an option
* @param newValue the option to be set
* @param opts - the option is set into this array of opts
* @return updated CreateOpts[] == opts + newValue
*/
static CreateOpts[] setOpt(final T newValue,
final CreateOpts... opts) {
final Class> clazz = newValue.getClass();
boolean alreadyInOpts = false;
if (opts != null) {
for (int i = 0; i < opts.length; ++i) {
if (opts[i].getClass() == clazz) {
if (alreadyInOpts) {
throw new IllegalArgumentException("multiple opts varargs: " + clazz);
}
alreadyInOpts = true;
opts[i] = newValue;
}
}
}
CreateOpts[] resultOpt = opts;
if (!alreadyInOpts) { // no newValue in opt
final int oldLength = opts == null? 0: opts.length;
CreateOpts[] newOpts = new CreateOpts[oldLength + 1];
if (oldLength > 0) {
System.arraycopy(opts, 0, newOpts, 0, oldLength);
}
newOpts[oldLength] = newValue;
resultOpt = newOpts;
}
return resultOpt;
}
}
/**
* Enum to support the varargs for rename() options
*/
public enum Rename {
NONE((byte) 0), // No options
OVERWRITE((byte) 1), // Overwrite the rename destination
TO_TRASH ((byte) 2); // Rename to trash
private final byte code;
private Rename(byte code) {
this.code = code;
}
public static Rename valueOf(byte code) {
return code < 0 || code >= values().length ? null : values()[code];
}
public byte value() {
return code;
}
}
/**
* This is used in FileSystem and FileContext to specify checksum options.
*/
public static class ChecksumOpt {
private final DataChecksum.Type checksumType;
private final int bytesPerChecksum;
/**
* Create a uninitialized one
*/
public ChecksumOpt() {
this(DataChecksum.Type.DEFAULT, -1);
}
/**
* Normal ctor
* @param type checksum type
* @param size bytes per checksum
*/
public ChecksumOpt(DataChecksum.Type type, int size) {
checksumType = type;
bytesPerChecksum = size;
}
public int getBytesPerChecksum() {
return bytesPerChecksum;
}
public DataChecksum.Type getChecksumType() {
return checksumType;
}
@Override
public String toString() {
return checksumType + ":" + bytesPerChecksum;
}
/**
* Create a ChecksumOpts that disables checksum.
*
* @return ChecksumOpt.
*/
public static ChecksumOpt createDisabled() {
return new ChecksumOpt(DataChecksum.Type.NULL, -1);
}
/**
* A helper method for processing user input and default value to
* create a combined checksum option. This is a bit complicated because
* bytesPerChecksum is kept for backward compatibility.
*
* @param defaultOpt Default checksum option
* @param userOpt User-specified checksum option. Ignored if null.
* @param userBytesPerChecksum User-specified bytesPerChecksum
* Ignored if {@literal <} 0.
* @return ChecksumOpt.
*/
public static ChecksumOpt processChecksumOpt(ChecksumOpt defaultOpt,
ChecksumOpt userOpt, int userBytesPerChecksum) {
final boolean useDefaultType;
final DataChecksum.Type type;
if (userOpt != null
&& userOpt.getChecksumType() != DataChecksum.Type.DEFAULT) {
useDefaultType = false;
type = userOpt.getChecksumType();
} else {
useDefaultType = true;
type = defaultOpt.getChecksumType();
}
// bytesPerChecksum - order of preference
// user specified value in bytesPerChecksum
// user specified value in checksumOpt
// default.
if (userBytesPerChecksum > 0) {
return new ChecksumOpt(type, userBytesPerChecksum);
} else if (userOpt != null && userOpt.getBytesPerChecksum() > 0) {
return !useDefaultType? userOpt
: new ChecksumOpt(type, userOpt.getBytesPerChecksum());
} else {
return useDefaultType? defaultOpt
: new ChecksumOpt(type, defaultOpt.getBytesPerChecksum());
}
}
/**
* A helper method for processing user input and default value to
* create a combined checksum option.
*
* @param defaultOpt Default checksum option
* @param userOpt User-specified checksum option
*
* @return ChecksumOpt.
*/
public static ChecksumOpt processChecksumOpt(ChecksumOpt defaultOpt,
ChecksumOpt userOpt) {
return processChecksumOpt(defaultOpt, userOpt, -1);
}
}
/**
* Options for creating {@link PathHandle} references.
*/
public static class HandleOpt {
protected HandleOpt() {
}
/**
* Utility function for mapping {@link FileSystem#getPathHandle} to a
* fixed set of handle options.
* @param fs Target filesystem
* @param opt Options to bind in partially evaluated function
* @return Function reference with options fixed
*/
public static Function resolve(
FileSystem fs, HandleOpt... opt) {
return resolve(fs::getPathHandle, opt);
}
/**
* Utility function for partial evaluation of {@link FileStatus}
* instances to a fixed set of handle options.
* @param fsr Function reference
* @param opt Options to associate with {@link FileStatus} instances to
* produce {@link PathHandle} instances.
* @return Function reference with options fixed
*/
public static Function resolve(
BiFunction fsr,
HandleOpt... opt) {
return (stat) -> fsr.apply(stat, opt);
}
/**
* Handle is valid iff the referent is neither moved nor changed.
* Equivalent to changed(false), moved(false).
* @return Options requiring that the content and location of the entity
* be unchanged between calls.
*/
public static HandleOpt[] exact() {
return new HandleOpt[] {changed(false), moved(false) };
}
/**
* Handle is valid iff the content of the referent is the same.
* Equivalent to changed(false), moved(true).
* @return Options requiring that the content of the entity is unchanged,
* but it may be at a different location.
*/
public static HandleOpt[] content() {
return new HandleOpt[] {changed(false), moved(true) };
}
/**
* Handle is valid iff the referent is unmoved in the namespace.
* Equivalent to changed(true), moved(false).
* @return Options requiring that the referent exist in the same location,
* but its content may have changed.
*/
public static HandleOpt[] path() {
return new HandleOpt[] {changed(true), moved(false) };
}
/**
* Handle is valid iff the referent exists in the namespace.
* Equivalent to changed(true), moved(true).
* @return Options requiring that the implementation resolve a reference
* to this entity regardless of changes to content or location.
*/
public static HandleOpt[] reference() {
return new HandleOpt[] {changed(true), moved(true) };
}
/**
* @param allow If true, resolve references to this entity even if it has
* been modified.
* @return Handle option encoding parameter.
*/
public static Data changed(boolean allow) {
return new Data(allow);
}
/**
* @param allow If true, resolve references to this entity anywhere in
* the namespace.
* @return Handle option encoding parameter.
*/
public static Location moved(boolean allow) {
return new Location(allow);
}
/**
* Utility method to extract a HandleOpt from the set provided.
* @param c Target class
* @param opt List of options
* @param Type constraint for exact match
* @throws IllegalArgumentException If more than one matching type is found.
* @return An option assignable from the specified type or null if either
* opt is null or a suitable match is not found.
*/
public static Optional getOpt(
Class c, HandleOpt... opt) {
if (null == opt) {
return Optional.empty();
}
T ret = null;
for (HandleOpt o : opt) {
if (c.isAssignableFrom(o.getClass())) {
if (ret != null) {
throw new IllegalArgumentException("Duplicate option "
+ c.getSimpleName());
}
@SuppressWarnings("unchecked")
T tmp = (T) o;
ret = tmp;
}
}
return Optional.ofNullable(ret);
}
/**
* Option storing standard constraints on data.
*/
public static class Data extends HandleOpt {
private final boolean allowChanged;
Data(boolean allowChanged) {
this.allowChanged = allowChanged;
}
/**
* Tracks whether any changes to file content are permitted.
* @return True if content changes are allowed, false otherwise.
*/
public boolean allowChange() {
return allowChanged;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("data(allowChange=")
.append(allowChanged).append(")");
return sb.toString();
}
}
/**
* Option storing standard constraints on location.
*/
public static class Location extends HandleOpt {
private final boolean allowChanged;
Location(boolean allowChanged) {
this.allowChanged = allowChanged;
}
/**
* Tracks whether any changes to file location are permitted.
* @return True if relocation in the namespace is allowed, false
* otherwise.
*/
public boolean allowChange() {
return allowChanged;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("loc(allowChange=")
.append(allowChanged).append(")");
return sb.toString();
}
}
}
/**
* Enum for indicating what mode to use when combining chunk and block
* checksums to define an aggregate FileChecksum. This should be considered
* a client-side runtime option rather than a persistent property of any
* stored metadata, which is why this is not part of ChecksumOpt, which
* deals with properties of files at rest.
*/
public enum ChecksumCombineMode {
MD5MD5CRC, // MD5 of block checksums, which are MD5 over chunk CRCs
COMPOSITE_CRC // Block/chunk-independent composite CRC
}
/**
* The standard {@code openFile()} options.
*/
@InterfaceAudience.Public
@InterfaceStability.Evolving
public static final class OpenFileOptions {
private OpenFileOptions() {
}
/**
* Prefix for all standard filesystem options: {@value}.
*/
private static final String FILESYSTEM_OPTION = "fs.option.";
/**
* Prefix for all openFile options: {@value}.
*/
public static final String FS_OPTION_OPENFILE =
FILESYSTEM_OPTION + "openfile.";
/**
* OpenFile option for file length: {@value}.
*/
public static final String FS_OPTION_OPENFILE_LENGTH =
FS_OPTION_OPENFILE + "length";
/**
* OpenFile option for split start: {@value}.
*/
public static final String FS_OPTION_OPENFILE_SPLIT_START =
FS_OPTION_OPENFILE + "split.start";
/**
* OpenFile option for split end: {@value}.
*/
public static final String FS_OPTION_OPENFILE_SPLIT_END =
FS_OPTION_OPENFILE + "split.end";
/**
* OpenFile option for buffer size: {@value}.
*/
public static final String FS_OPTION_OPENFILE_BUFFER_SIZE =
FS_OPTION_OPENFILE + "buffer.size";
/**
* OpenFile footer cache flag: {@value}.
*/
public static final String FS_OPTION_OPENFILE_FOOTER_CACHE =
FS_OPTION_OPENFILE + "footer.cache";
/**
* OpenFile option for read policies: {@value}.
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY =
FS_OPTION_OPENFILE + "read.policy";
/**
* Set of standard options which openFile implementations
* MUST recognize, even if they ignore the actual values.
*/
public static final Set FS_OPTION_OPENFILE_STANDARD_OPTIONS =
Collections.unmodifiableSet(Stream.of(
FS_OPTION_OPENFILE_BUFFER_SIZE,
FS_OPTION_OPENFILE_FOOTER_CACHE,
FS_OPTION_OPENFILE_READ_POLICY,
FS_OPTION_OPENFILE_LENGTH,
FS_OPTION_OPENFILE_SPLIT_START,
FS_OPTION_OPENFILE_SPLIT_END)
.collect(Collectors.toSet()));
/**
* Read policy for adaptive IO: {@value}.
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY_ADAPTIVE =
"adaptive";
/**
* We are an avro file: {@value}.
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY_AVRO = "avro";
/**
* This is a columnar file format.
* Do whatever is needed to optimize for it: {@value}.
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY_COLUMNAR =
"columnar";
/**
* This is a CSV file of plain or UTF-8 text
* to be read sequentially.
* Do whatever is needed to optimize for it: {@value}.
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY_CSV =
"csv";
/**
* Read policy {@value} -whatever the implementation does by default.
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY_DEFAULT =
"default";
/**
* This is a table file for Apache HBase.
* Do whatever is needed to optimize for it: {@value}.
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY_HBASE =
"hbase";
/**
* This is a JSON file of UTF-8 text, including a
* JSON line file where each line is a JSON entity.
* Do whatever is needed to optimize for it: {@value}.
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY_JSON =
"json";
/**
* This is an ORC file.
* Do whatever is needed to optimize for it: {@value}.
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY_ORC =
"orc";
/**
* This is a parquet file with a v1/v3 footer: {@value}.
* Do whatever is needed to optimize for it, such as footer
* prefetch and cache,
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY_PARQUET =
"parquet";
/**
* Read policy for random IO: {@value}.
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY_RANDOM =
"random";
/**
* Read policy for sequential IO: {@value}.
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY_SEQUENTIAL =
"sequential";
/**
* Vectored IO API to be used: {@value}.
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY_VECTOR =
"vector";
/**
* Whole file to be read, end-to-end: {@value}.
*/
public static final String FS_OPTION_OPENFILE_READ_POLICY_WHOLE_FILE =
"whole-file";
/**
* All the current read policies as a set.
*/
public static final Set FS_OPTION_OPENFILE_READ_POLICIES =
Collections.unmodifiableSet(Stream.of(
FS_OPTION_OPENFILE_READ_POLICY_ADAPTIVE,
FS_OPTION_OPENFILE_READ_POLICY_AVRO,
FS_OPTION_OPENFILE_READ_POLICY_COLUMNAR,
FS_OPTION_OPENFILE_READ_POLICY_CSV,
FS_OPTION_OPENFILE_READ_POLICY_DEFAULT,
FS_OPTION_OPENFILE_READ_POLICY_JSON,
FS_OPTION_OPENFILE_READ_POLICY_ORC,
FS_OPTION_OPENFILE_READ_POLICY_PARQUET,
FS_OPTION_OPENFILE_READ_POLICY_RANDOM,
FS_OPTION_OPENFILE_READ_POLICY_SEQUENTIAL,
FS_OPTION_OPENFILE_READ_POLICY_VECTOR,
FS_OPTION_OPENFILE_READ_POLICY_WHOLE_FILE)
.collect(Collectors.toSet()));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy