HDFS-14111. hdfsOpenFile on HDFS causes unnecessary IO from file offset 0. Contributed by Sahil Takiar.
Signed-off-by: Wei-Chiu Chuang <weichiu@apache.org>
This commit is contained in:
parent
6192c1fe3b
commit
618e009ac0
|
@ -740,6 +740,7 @@ public class CryptoInputStream extends FilterInputStream implements
|
|||
case StreamCapabilities.READAHEAD:
|
||||
case StreamCapabilities.DROPBEHIND:
|
||||
case StreamCapabilities.UNBUFFER:
|
||||
case StreamCapabilities.READBYTEBUFFER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -59,6 +59,12 @@ public interface StreamCapabilities {
|
|||
*/
|
||||
String UNBUFFER = "in:unbuffer";
|
||||
|
||||
/**
|
||||
* Stream read(ByteBuffer) capability implemented by
|
||||
* {@link ByteBufferReadable#read(java.nio.ByteBuffer)}.
|
||||
*/
|
||||
String READBYTEBUFFER = "in:readbytebuffer";
|
||||
|
||||
/**
|
||||
* Capabilities that a stream can support and be queried for.
|
||||
*/
|
||||
|
|
|
@ -1779,6 +1779,7 @@ public class DFSInputStream extends FSInputStream
|
|||
case StreamCapabilities.READAHEAD:
|
||||
case StreamCapabilities.DROPBEHIND:
|
||||
case StreamCapabilities.UNBUFFER:
|
||||
case StreamCapabilities.READBYTEBUFFER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -1013,7 +1013,7 @@ static hdfsFile hdfsOpenFileImpl(hdfsFS fs, const char *path, int flags,
|
|||
return f{is|os};
|
||||
*/
|
||||
int accmode = flags & O_ACCMODE;
|
||||
jstring jStrBufferSize = NULL, jStrReplication = NULL;
|
||||
jstring jStrBufferSize = NULL, jStrReplication = NULL, jCapabilityString = NULL;
|
||||
jobject jConfiguration = NULL, jPath = NULL, jFile = NULL;
|
||||
jobject jFS = (jobject)fs;
|
||||
jthrowable jthr;
|
||||
|
@ -1171,16 +1171,22 @@ static hdfsFile hdfsOpenFileImpl(hdfsFS fs, const char *path, int flags,
|
|||
file->flags = 0;
|
||||
|
||||
if ((flags & O_WRONLY) == 0) {
|
||||
// Try a test read to see if we can do direct reads
|
||||
char buf;
|
||||
if (readDirect(fs, file, &buf, 0) == 0) {
|
||||
// Success - 0-byte read should return 0
|
||||
// Check the StreamCapabilities of jFile to see if we can do direct reads
|
||||
jthr = newJavaStr(env, "in:readbytebuffer", &jCapabilityString);
|
||||
if (jthr) {
|
||||
ret = printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
|
||||
"hdfsOpenFile(%s): newJavaStr", path);
|
||||
goto done;
|
||||
}
|
||||
jthr = invokeMethod(env, &jVal, INSTANCE, jFile, HADOOP_ISTRM,
|
||||
"hasCapability", "(Ljava/lang/String;)Z", jCapabilityString);
|
||||
if (jthr) {
|
||||
ret = printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
|
||||
"hdfsOpenFile(%s): FSDataInputStream#hasCapability", path);
|
||||
goto done;
|
||||
}
|
||||
if (jVal.z) {
|
||||
file->flags |= HDFS_FILE_SUPPORTS_DIRECT_READ;
|
||||
} else if (errno != ENOTSUP) {
|
||||
// Unexpected error. Clear it, don't set the direct flag.
|
||||
fprintf(stderr,
|
||||
"hdfsOpenFile(%s): WARN: Unexpected error %d when testing "
|
||||
"for direct read compatibility\n", path, errno);
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
|
@ -1190,7 +1196,8 @@ done:
|
|||
destroyLocalReference(env, jStrReplication);
|
||||
destroyLocalReference(env, jConfiguration);
|
||||
destroyLocalReference(env, jPath);
|
||||
destroyLocalReference(env, jFile);
|
||||
destroyLocalReference(env, jFile);
|
||||
destroyLocalReference(env, jCapabilityString);
|
||||
if (ret) {
|
||||
if (file) {
|
||||
if (file->file) {
|
||||
|
|
|
@ -503,7 +503,10 @@ TEST_F(HdfsExtTest, TestReadStats) {
|
|||
hdfsFileFreeReadStatistics(stats);
|
||||
|
||||
EXPECT_EQ(0, hdfsCloseFile(fs, file));
|
||||
EXPECT_EQ(0, errno);
|
||||
// Since libhdfs is not guaranteed to set errno to 0 on successful
|
||||
// operations, we disable this check for now, see HDFS-14325 for a
|
||||
// long term solution to this problem
|
||||
// EXPECT_EQ(0, errno);
|
||||
}
|
||||
|
||||
//Testing working directory
|
||||
|
|
Loading…
Reference in New Issue