You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by la...@apache.org on 2012/12/13 20:34:27 UTC
svn commit: r1421440 -
/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java
Author: larsh
Date: Thu Dec 13 19:34:26 2012
New Revision: 1421440
URL: http://svn.apache.org/viewvc?rev=1421440&view=rev
Log:
HBASE-7336 HFileBlock.readAtOffset does not work well with multiple threads
Modified:
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java?rev=1421440&r1=1421439&r2=1421440&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java Thu Dec 13 19:34:26 2012
@@ -28,6 +28,8 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.fs.FSDataInputStream;
@@ -1143,6 +1145,8 @@ public class HFileBlock implements Cache
/** The path (if any) where this data is coming from */
protected Path path;
+ private final Lock streamLock = new ReentrantLock();
+
/** The default buffer size for our buffered streams */
public static final int DEFAULT_BUFFER_SIZE = 1 << 20;
@@ -1217,23 +1221,9 @@ public class HFileBlock implements Cache
"-byte array at offset " + destOffset);
}
- if (pread) {
- // Positional read. Better for random reads.
- int extraSize = peekIntoNextBlock ? hdrSize : 0;
-
- int ret = istream.read(fileOffset, dest, destOffset, size + extraSize);
- if (ret < size) {
- throw new IOException("Positional read of " + size + " bytes " +
- "failed at offset " + fileOffset + " (returned " + ret + ")");
- }
-
- if (ret == size || ret < size + extraSize) {
- // Could not read the next block's header, or did not try.
- return -1;
- }
- } else {
+ if (!pread && streamLock.tryLock()) {
// Seek + read. Better for scanning.
- synchronized (istream) {
+ try {
istream.seek(fileOffset);
long realOffset = istream.getPos();
@@ -1251,6 +1241,22 @@ public class HFileBlock implements Cache
// Try to read the next block header.
if (!readWithExtra(istream, dest, destOffset, size, hdrSize))
return -1;
+ } finally {
+ streamLock.unlock();
+ }
+ } else {
+ // Positional read. Better for random reads; or when the streamLock is already locked.
+ int extraSize = peekIntoNextBlock ? hdrSize : 0;
+
+ int ret = istream.read(fileOffset, dest, destOffset, size + extraSize);
+ if (ret < size) {
+ throw new IOException("Positional read of " + size + " bytes " +
+ "failed at offset " + fileOffset + " (returned " + ret + ")");
+ }
+
+ if (ret == size || ret < size + extraSize) {
+ // Could not read the next block's header, or did not try.
+ return -1;
}
}