HDFS-9133. ExternalBlockReader and ReplicaAccessor need to return -1 on read when at EOF. (Colin Patrick McCabe via Lei (Eddy) Xu)

(cherry picked from commit 67b0e967f0)
This commit is contained in:
Lei Xu 2015-09-25 16:01:41 -07:00
parent 1a2870f6ff
commit 82d4c05b2d
4 changed files with 30 additions and 8 deletions

View File

@ -45,6 +45,9 @@ public final class ExternalBlockReader implements BlockReader {
@Override @Override
public int read(byte[] buf, int off, int len) throws IOException { public int read(byte[] buf, int off, int len) throws IOException {
int nread = accessor.read(pos, buf, off, len); int nread = accessor.read(pos, buf, off, len);
if (nread < 0) {
return nread;
}
pos += nread; pos += nread;
return nread; return nread;
} }
@ -52,6 +55,9 @@ public final class ExternalBlockReader implements BlockReader {
@Override @Override
public int read(ByteBuffer buf) throws IOException { public int read(ByteBuffer buf) throws IOException {
int nread = accessor.read(pos, buf); int nread = accessor.read(pos, buf);
if (nread < 0) {
return nread;
}
pos += nread; pos += nread;
return nread; return nread;
} }

View File

@ -40,8 +40,9 @@ public abstract class ReplicaAccessor {
* *
* @return The number of bytes read. If the read extends past the end * @return The number of bytes read. If the read extends past the end
* of the replica, a short read count will be returned. We * of the replica, a short read count will be returned. We
* will never return a negative number. We will never * will should return -1 if EOF is reached and no bytes
* return a short read count unless EOF is reached. * can be returned. We will never return a short read
* count unless EOF is reached.
*/ */
public abstract int read(long pos, byte[] buf, int off, int len) public abstract int read(long pos, byte[] buf, int off, int len)
throws IOException; throws IOException;
@ -58,8 +59,9 @@ public abstract class ReplicaAccessor {
* *
* @return The number of bytes read. If the read extends past the end * @return The number of bytes read. If the read extends past the end
* of the replica, a short read count will be returned. We * of the replica, a short read count will be returned. We
* will never return a negative number. We will never return * should return -1 if EOF is reached and no bytes can be
* a short read count unless EOF is reached. * returned. We will never return a short read count unless
* EOF is reached.
*/ */
public abstract int read(long pos, ByteBuffer buf) throws IOException; public abstract int read(long pos, ByteBuffer buf) throws IOException;

View File

@ -623,6 +623,9 @@ Release 2.8.0 - UNRELEASED
HDFS-9132. Pass genstamp to ReplicaAccessorBuilder. (Colin Patrick McCabe via HDFS-9132. Pass genstamp to ReplicaAccessorBuilder. (Colin Patrick McCabe via
Lei (Eddy) Xu) Lei (Eddy) Xu)
HDFS-9133. ExternalBlockReader and ReplicaAccessor need to return -1 on read
when at EOF. (Colin Patrick McCabe via Lei (Eddy) Xu)
OPTIMIZATIONS OPTIMIZATIONS
HDFS-8026. Trace FSOutputSummer#writeChecksumChunks rather than HDFS-8026. Trace FSOutputSummer#writeChecksumChunks rather than

View File

@ -190,8 +190,8 @@ public class TestExternalBlockReader {
"than 0 at " + pos); "than 0 at " + pos);
return 0; return 0;
} }
int i = 0, nread = 0; int i = 0, nread = 0, ipos;
for (int ipos = (int)pos; for (ipos = (int)pos;
(ipos < contents.length) && (nread < len); (ipos < contents.length) && (nread < len);
ipos++) { ipos++) {
buf[i++] = contents[ipos]; buf[i++] = contents[ipos];
@ -199,6 +199,9 @@ public class TestExternalBlockReader {
totalRead++; totalRead++;
LOG.info("ipos = " + ipos + ", contents.length = " + contents.length + ", nread = " + nread + ", len = " + len); LOG.info("ipos = " + ipos + ", contents.length = " + contents.length + ", nread = " + nread + ", len = " + len);
} }
if ((nread == 0) && (ipos >= contents.length)) {
return -1;
}
return nread; return nread;
} }
@ -211,8 +214,8 @@ public class TestExternalBlockReader {
"than 0 at " + pos); "than 0 at " + pos);
return 0; return 0;
} }
int i = 0, nread = 0; int i = 0, nread = 0, ipos;
for (int ipos = (int)pos; for (ipos = (int)pos;
ipos < contents.length; ipos++) { ipos < contents.length; ipos++) {
try { try {
buf.put(contents[ipos]); buf.put(contents[ipos]);
@ -222,6 +225,9 @@ public class TestExternalBlockReader {
nread++; nread++;
totalRead++; totalRead++;
} }
if ((nread == 0) && (ipos >= contents.length)) {
return -1;
}
return nread; return nread;
} }
@ -304,6 +310,11 @@ public class TestExternalBlockReader {
Assert.assertEquals(1024L, accessor.totalRead); Assert.assertEquals(1024L, accessor.totalRead);
Assert.assertEquals("", accessor.getError()); Assert.assertEquals("", accessor.getError());
Assert.assertEquals(1, accessor.numCloses); Assert.assertEquals(1, accessor.numCloses);
byte[] tempBuf = new byte[5];
Assert.assertEquals(-1, accessor.read(TEST_LENGTH,
tempBuf, 0, 0));
Assert.assertEquals(-1, accessor.read(TEST_LENGTH,
tempBuf, 0, tempBuf.length));
accessors.remove(uuid); accessors.remove(uuid);
} finally { } finally {
dfs.close(); dfs.close();