/** * 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.io; import java.io.DataOutput; import java.io.DataInput; import java.io.IOException; import org.apache.hadoop.fs.CreateOptions; import org.apache.hadoop.io.nativeio.NativeIO; /** * This class manages a bitset which is used to pass common options for * Read/Write block headers. This bitset should be used whenever we need to add * an extra field in the Read/Write block headers. */ public class DataTransferHeaderOptions extends CreateOptions{ // a bitmask of various options. // First long // 1. the value of first three bits denote the type of FADVISE(0-5). See // NativeIO.java to know what each individual value corresponds to. // 2. Bit 4 denotes overwrite, if true and a file exists, will overwrite that file. // 3. Bit 5 denotes profiling enabled. // 4. Bits 6-7 denote the class of service for ioprio_set // 5. Bits 8-10 denote the priority for ioprio_set // 6. Bits 11-13 denote bits for sync_file_range // 7. Bit 14 denotes Force Sync. // Second long // The threshold in milliseconds for logging profile data for slow write // packets. protected long[] options = new long[2]; private static final long fadviseMask = 0x07; private static final int FADVISE_OFFSET = 0; private static final int IOPRIO_OFFSET = 0; private static final int IOPRIO_CLASS_SHIFT = 5; private static final int IOPRIO_DATA_SHIFT = 7; private static final long ioprioClassMask = (0x03 << IOPRIO_CLASS_SHIFT); private static final long ioprioDataMask = (0x07 << IOPRIO_DATA_SHIFT); private static final long enableProfileMask = 0x10; private static final int ENABLE_PROFILE_OFFSET = 0; public void setIfProfileEnabled(boolean profileEnabled) { if (profileEnabled) { options[ENABLE_PROFILE_OFFSET] |= enableProfileMask; } else { options[ENABLE_PROFILE_OFFSET] &= ~enableProfileMask; } } public boolean ifProfileEnabled() { return (options[ENABLE_PROFILE_OFFSET] & enableProfileMask) != 0; } public boolean isIoprioDisabled() { return (getIoprioClass() == 0 && getIoprioData() == 0); } public int getIoprioClass() { return (int) ((options[IOPRIO_OFFSET] & ioprioClassMask) >>> IOPRIO_CLASS_SHIFT); } public int getIoprioData() { return (int) ((options[IOPRIO_OFFSET] & ioprioDataMask) >>> IOPRIO_DATA_SHIFT); } public void setIoprio(int classOfService, int data) { NativeIO.validateIoprioSet(classOfService, data); options[IOPRIO_OFFSET] = options[IOPRIO_OFFSET] & ~ioprioClassMask | (classOfService << IOPRIO_CLASS_SHIFT); options[IOPRIO_OFFSET] = options[IOPRIO_OFFSET] & ~ioprioDataMask | (data << IOPRIO_DATA_SHIFT); } public int getFadvise() { return (int) (options[FADVISE_OFFSET] & (fadviseMask)); } public void setFadvise(int advise) { NativeIO.validatePosixFadvise(advise); options[FADVISE_OFFSET] = options[FADVISE_OFFSET] & ~fadviseMask | advise; } public void write(DataOutput out) throws IOException { int size = (options == null) ? 0 : options.length; out.writeInt(size); for (long option : options) { out.writeLong(option); } } public void readFields(DataInput in) throws IOException { int size = in.readInt(); options = (size > options.length) ? new long[size] : options; for (int i = 0; i < size; i++) { options[i] = in.readLong(); } } /** * Gets specific bits of a specific number. * @param value The number to get bits from * @param start Index of the rightmost bit we want. 0-based. * @param len How many bits we want. * @return The result. */ protected static long getBits(long value, int start, int len){ return ( (value >>> start) & ((1L<<len)-1) ); } /** * Sets specific bits of a specific number. * @param num The number to set bits. * @param start Index of the rightmost bit we want to set. 0-based. * @param len How many bits we want to set. * @param value The value we want to set to. * @return The number after changing specific bits. */ protected static long setBits(long num, int start, int len, long value){ // Get rid of illegal bits of value: value = value & ((1L<<len)-1); long val_mask = value << start; long zero_mask = ~( ((1L << len) -1) << start ); return ( num & zero_mask ) | val_mask; } public DataTransferHeaderOptions getValue(){ return this; } }