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 boolean hasCapability(String capability) {
|
|||||||
case StreamCapabilities.READAHEAD:
|
case StreamCapabilities.READAHEAD:
|
||||||
case StreamCapabilities.DROPBEHIND:
|
case StreamCapabilities.DROPBEHIND:
|
||||||
case StreamCapabilities.UNBUFFER:
|
case StreamCapabilities.UNBUFFER:
|
||||||
|
case StreamCapabilities.READBYTEBUFFER:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -59,6 +59,12 @@ public interface StreamCapabilities {
|
|||||||
*/
|
*/
|
||||||
String UNBUFFER = "in:unbuffer";
|
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.
|
* Capabilities that a stream can support and be queried for.
|
||||||
*/
|
*/
|
||||||
|
@ -1779,6 +1779,7 @@ public boolean hasCapability(String capability) {
|
|||||||
case StreamCapabilities.READAHEAD:
|
case StreamCapabilities.READAHEAD:
|
||||||
case StreamCapabilities.DROPBEHIND:
|
case StreamCapabilities.DROPBEHIND:
|
||||||
case StreamCapabilities.UNBUFFER:
|
case StreamCapabilities.UNBUFFER:
|
||||||
|
case StreamCapabilities.READBYTEBUFFER:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -1013,7 +1013,7 @@ static hdfsFile hdfsOpenFileImpl(hdfsFS fs, const char *path, int flags,
|
|||||||
return f{is|os};
|
return f{is|os};
|
||||||
*/
|
*/
|
||||||
int accmode = flags & O_ACCMODE;
|
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 jConfiguration = NULL, jPath = NULL, jFile = NULL;
|
||||||
jobject jFS = (jobject)fs;
|
jobject jFS = (jobject)fs;
|
||||||
jthrowable jthr;
|
jthrowable jthr;
|
||||||
@ -1171,16 +1171,22 @@ static hdfsFile hdfsOpenFileImpl(hdfsFS fs, const char *path, int flags,
|
|||||||
file->flags = 0;
|
file->flags = 0;
|
||||||
|
|
||||||
if ((flags & O_WRONLY) == 0) {
|
if ((flags & O_WRONLY) == 0) {
|
||||||
// Try a test read to see if we can do direct reads
|
// Check the StreamCapabilities of jFile to see if we can do direct reads
|
||||||
char buf;
|
jthr = newJavaStr(env, "in:readbytebuffer", &jCapabilityString);
|
||||||
if (readDirect(fs, file, &buf, 0) == 0) {
|
if (jthr) {
|
||||||
// Success - 0-byte read should return 0
|
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;
|
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;
|
ret = 0;
|
||||||
@ -1191,6 +1197,7 @@ done:
|
|||||||
destroyLocalReference(env, jConfiguration);
|
destroyLocalReference(env, jConfiguration);
|
||||||
destroyLocalReference(env, jPath);
|
destroyLocalReference(env, jPath);
|
||||||
destroyLocalReference(env, jFile);
|
destroyLocalReference(env, jFile);
|
||||||
|
destroyLocalReference(env, jCapabilityString);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (file) {
|
if (file) {
|
||||||
if (file->file) {
|
if (file->file) {
|
||||||
|
@ -503,7 +503,10 @@ TEST_F(HdfsExtTest, TestReadStats) {
|
|||||||
hdfsFileFreeReadStatistics(stats);
|
hdfsFileFreeReadStatistics(stats);
|
||||||
|
|
||||||
EXPECT_EQ(0, hdfsCloseFile(fs, file));
|
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
|
//Testing working directory
|
||||||
|
Loading…
Reference in New Issue
Block a user