Return-Path:
X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io
Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io
Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183])
by cust-asf2.ponee.io (Postfix) with ESMTP id 87D94200CF1
for ; Fri, 21 Jul 2017 00:07:20 +0200 (CEST)
Received: by cust-asf.ponee.io (Postfix)
id 864AD16C397; Thu, 20 Jul 2017 22:07:20 +0000 (UTC)
Delivered-To: archive-asf-public@cust-asf.ponee.io
Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
by cust-asf.ponee.io (Postfix) with SMTP id E491916C396
for ; Fri, 21 Jul 2017 00:07:17 +0200 (CEST)
Received: (qmail 54556 invoked by uid 500); 20 Jul 2017 22:07:16 -0000
Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm
Precedence: bulk
List-Help:
List-Unsubscribe:
List-Post:
List-Id:
Reply-To: dev@hbase.apache.org
Delivered-To: mailing list commits@hbase.apache.org
Received: (qmail 53683 invoked by uid 99); 20 Jul 2017 22:07:15 -0000
Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23)
by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 20 Jul 2017 22:07:15 +0000
Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33)
id C1661F327F; Thu, 20 Jul 2017 22:07:14 +0000 (UTC)
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
From: git-site-role@apache.org
To: commits@hbase.apache.org
Date: Thu, 20 Jul 2017 22:07:24 -0000
Message-Id:
In-Reply-To:
References:
X-Mailer: ASF-Git Admin Mailer
Subject: [11/19] hbase-site git commit: Published site at
82d554e3783372cc6b05489452c815b57c06f6cd.
archived-at: Thu, 20 Jul 2017 22:07:20 -0000
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9e6e3360/devapidocs/src-html/org/apache/hadoop/hbase/util/ByteBufferArray.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/util/ByteBufferArray.html b/devapidocs/src-html/org/apache/hadoop/hbase/util/ByteBufferArray.html
index 7a442f0..103cd9e 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/util/ByteBufferArray.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/util/ByteBufferArray.html
@@ -52,278 +52,285 @@
044 * reading/writing data from this large buffer with a position and offset045 */046@InterfaceAudience.Private
-047public final class ByteBufferArray {
+047public class ByteBufferArray {048 private static final Log LOG = LogFactory.getLog(ByteBufferArray.class);049050 public static final int DEFAULT_BUFFER_SIZE = 4 * 1024 * 1024;051 @VisibleForTesting052 ByteBuffer buffers[];053 private int bufferSize;
-054 private int bufferCount;
-055
-056 /**
-057 * We allocate a number of byte buffers as the capacity. In order not to out
-058 * of the array bounds for the last byte(see {@link ByteBufferArray#multiple}),
-059 * we will allocate one additional buffer with capacity 0;
-060 * @param capacity total size of the byte buffer array
-061 * @param directByteBuffer true if we allocate direct buffer
-062 * @param allocator the ByteBufferAllocator that will create the buffers
-063 * @throws IOException throws IOException if there is an exception thrown by the allocator
-064 */
-065 public ByteBufferArray(long capacity, boolean directByteBuffer, ByteBufferAllocator allocator)
-066 throws IOException {
-067 this.bufferSize = DEFAULT_BUFFER_SIZE;
-068 if (this.bufferSize > (capacity / 16))
-069 this.bufferSize = (int) roundUp(capacity / 16, 32768);
-070 this.bufferCount = (int) (roundUp(capacity, bufferSize) / bufferSize);
-071 LOG.info("Allocating buffers total=" + StringUtils.byteDesc(capacity)
-072 + ", sizePerBuffer=" + StringUtils.byteDesc(bufferSize) + ", count="
-073 + bufferCount + ", direct=" + directByteBuffer);
-074 buffers = new ByteBuffer[bufferCount + 1];
-075 createBuffers(directByteBuffer, allocator);
-076 }
-077
-078 private void createBuffers(boolean directByteBuffer, ByteBufferAllocator allocator)
-079 throws IOException {
-080 int threadCount = Runtime.getRuntime().availableProcessors();
-081 ExecutorService service = new ThreadPoolExecutor(threadCount, threadCount, 0L,
-082 TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
-083 int perThreadCount = Math.round((float) (bufferCount) / threadCount);
-084 int lastThreadCount = bufferCount - (perThreadCount * (threadCount - 1));
-085 Future<ByteBuffer[]>[] futures = new Future[threadCount];
-086 try {
-087 for (int i = 0; i < threadCount; i++) {
-088 // Last thread will have to deal with a different number of buffers
-089 int buffersToCreate = (i == threadCount - 1) ? lastThreadCount : perThreadCount;
-090 futures[i] = service.submit(
-091 new BufferCreatorCallable(bufferSize, directByteBuffer, buffersToCreate, allocator));
-092 }
-093 int bufferIndex = 0;
-094 for (Future<ByteBuffer[]> future : futures) {
-095 try {
-096 ByteBuffer[] buffers = future.get();
-097 for (ByteBuffer buffer : buffers) {
-098 this.buffers[bufferIndex++] = buffer;
-099 }
-100 } catch (InterruptedException | ExecutionException e) {
-101 LOG.error("Buffer creation interrupted", e);
-102 throw new IOException(e);
-103 }
-104 }
-105 } finally {
-106 service.shutdownNow();
-107 }
-108 // always create on heap empty dummy buffer at last
-109 this.buffers[bufferCount] = ByteBuffer.allocate(0);
-110 }
-111
-112 /**
-113 * A callable that creates buffers of the specified length either onheap/offheap using the
-114 * {@link ByteBufferAllocator}
-115 */
-116 private static class BufferCreatorCallable implements Callable<ByteBuffer[]> {
-117 private final int bufferCapacity;
-118 private final boolean directByteBuffer;
-119 private final int bufferCount;
-120 private final ByteBufferAllocator allocator;
-121
-122 BufferCreatorCallable(int bufferCapacity, boolean directByteBuffer, int bufferCount,
-123 ByteBufferAllocator allocator) {
-124 this.bufferCapacity = bufferCapacity;
-125 this.directByteBuffer = directByteBuffer;
-126 this.bufferCount = bufferCount;
-127 this.allocator = allocator;
-128 }
-129
-130 @Override
-131 public ByteBuffer[] call() throws Exception {
-132 ByteBuffer[] buffers = new ByteBuffer[this.bufferCount];
-133 for (int i = 0; i < this.bufferCount; i++) {
-134 buffers[i] = allocator.allocate(this.bufferCapacity, this.directByteBuffer);
-135 }
-136 return buffers;
-137 }
-138 }
-139
-140 private long roundUp(long n, long to) {
-141 return ((n + to - 1) / to) * to;
-142 }
-143
-144 /**
-145 * Transfers bytes from this buffer array into the given destination array
-146 * @param start start position in the ByteBufferArray
-147 * @param len The maximum number of bytes to be written to the given array
-148 * @param dstArray The array into which bytes are to be written
-149 * @return number of bytes read
-150 */
-151 public int getMultiple(long start, int len, byte[] dstArray) {
-152 return getMultiple(start, len, dstArray, 0);
-153 }
-154
-155 /**
-156 * Transfers bytes from this buffer array into the given destination array
-157 * @param start start offset of this buffer array
-158 * @param len The maximum number of bytes to be written to the given array
-159 * @param dstArray The array into which bytes are to be written
-160 * @param dstOffset The offset within the given array of the first byte to be
-161 * written
-162 * @return number of bytes read
-163 */
-164 public int getMultiple(long start, int len, byte[] dstArray, int dstOffset) {
-165 multiple(start, len, dstArray, dstOffset, GET_MULTIPLE_VISTOR);
-166 return len;
-167 }
-168
-169 private final static Visitor GET_MULTIPLE_VISTOR = new Visitor() {
-170 @Override
-171 public void visit(ByteBuffer bb, int pos, byte[] array, int arrayIdx, int len) {
-172 ByteBufferUtils.copyFromBufferToArray(array, bb, pos, arrayIdx, len);
-173 }
-174 };
+054 @VisibleForTesting
+055 int bufferCount;
+056
+057 /**
+058 * We allocate a number of byte buffers as the capacity. In order not to out
+059 * of the array bounds for the last byte(see {@link ByteBufferArray#multiple}),
+060 * we will allocate one additional buffer with capacity 0;
+061 * @param capacity total size of the byte buffer array
+062 * @param directByteBuffer true if we allocate direct buffer
+063 * @param allocator the ByteBufferAllocator that will create the buffers
+064 * @throws IOException throws IOException if there is an exception thrown by the allocator
+065 */
+066 public ByteBufferArray(long capacity, boolean directByteBuffer, ByteBufferAllocator allocator)
+067 throws IOException {
+068 this.bufferSize = DEFAULT_BUFFER_SIZE;
+069 if (this.bufferSize > (capacity / 16))
+070 this.bufferSize = (int) roundUp(capacity / 16, 32768);
+071 this.bufferCount = (int) (roundUp(capacity, bufferSize) / bufferSize);
+072 LOG.info("Allocating buffers total=" + StringUtils.byteDesc(capacity)
+073 + ", sizePerBuffer=" + StringUtils.byteDesc(bufferSize) + ", count="
+074 + bufferCount + ", direct=" + directByteBuffer);
+075 buffers = new ByteBuffer[bufferCount + 1];
+076 createBuffers(directByteBuffer, allocator);
+077 }
+078
+079 @VisibleForTesting
+080 void createBuffers(boolean directByteBuffer, ByteBufferAllocator allocator)
+081 throws IOException {
+082 int threadCount = getThreadCount();
+083 ExecutorService service = new ThreadPoolExecutor(threadCount, threadCount, 0L,
+084 TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
+085 int perThreadCount = (int)Math.floor((double) (bufferCount) / threadCount);
+086 int lastThreadCount = bufferCount - (perThreadCount * (threadCount - 1));
+087 Future<ByteBuffer[]>[] futures = new Future[threadCount];
+088 try {
+089 for (int i = 0; i < threadCount; i++) {
+090 // Last thread will have to deal with a different number of buffers
+091 int buffersToCreate = (i == threadCount - 1) ? lastThreadCount : perThreadCount;
+092 futures[i] = service.submit(
+093 new BufferCreatorCallable(bufferSize, directByteBuffer, buffersToCreate, allocator));
+094 }
+095 int bufferIndex = 0;
+096 for (Future<ByteBuffer[]> future : futures) {
+097 try {
+098 ByteBuffer[] buffers = future.get();
+099 for (ByteBuffer buffer : buffers) {
+100 this.buffers[bufferIndex++] = buffer;
+101 }
+102 } catch (InterruptedException | ExecutionException e) {
+103 LOG.error("Buffer creation interrupted", e);
+104 throw new IOException(e);
+105 }
+106 }
+107 } finally {
+108 service.shutdownNow();
+109 }
+110 // always create on heap empty dummy buffer at last
+111 this.buffers[bufferCount] = ByteBuffer.allocate(0);
+112 }
+113
+114 @VisibleForTesting
+115 int getThreadCount() {
+116 return Runtime.getRuntime().availableProcessors();
+117 }
+118
+119 /**
+120 * A callable that creates buffers of the specified length either onheap/offheap using the
+121 * {@link ByteBufferAllocator}
+122 */
+123 private static class BufferCreatorCallable implements Callable<ByteBuffer[]> {
+124 private final int bufferCapacity;
+125 private final boolean directByteBuffer;
+126 private final int bufferCount;
+127 private final ByteBufferAllocator allocator;
+128
+129 BufferCreatorCallable(int bufferCapacity, boolean directByteBuffer, int bufferCount,
+130 ByteBufferAllocator allocator) {
+131 this.bufferCapacity = bufferCapacity;
+132 this.directByteBuffer = directByteBuffer;
+133 this.bufferCount = bufferCount;
+134 this.allocator = allocator;
+135 }
+136
+137 @Override
+138 public ByteBuffer[] call() throws Exception {
+139 ByteBuffer[] buffers = new ByteBuffer[this.bufferCount];
+140 for (int i = 0; i < this.bufferCount; i++) {
+141 buffers[i] = allocator.allocate(this.bufferCapacity, this.directByteBuffer);
+142 }
+143 return buffers;
+144 }
+145 }
+146
+147 private long roundUp(long n, long to) {
+148 return ((n + to - 1) / to) * to;
+149 }
+150
+151 /**
+152 * Transfers bytes from this buffer array into the given destination array
+153 * @param start start position in the ByteBufferArray
+154 * @param len The maximum number of bytes to be written to the given array
+155 * @param dstArray The array into which bytes are to be written
+156 * @return number of bytes read
+157 */
+158 public int getMultiple(long start, int len, byte[] dstArray) {
+159 return getMultiple(start, len, dstArray, 0);
+160 }
+161
+162 /**
+163 * Transfers bytes from this buffer array into the given destination array
+164 * @param start start offset of this buffer array
+165 * @param len The maximum number of bytes to be written to the given array
+166 * @param dstArray The array into which bytes are to be written
+167 * @param dstOffset The offset within the given array of the first byte to be
+168 * written
+169 * @return number of bytes read
+170 */
+171 public int getMultiple(long start, int len, byte[] dstArray, int dstOffset) {
+172 multiple(start, len, dstArray, dstOffset, GET_MULTIPLE_VISTOR);
+173 return len;
+174 }175
-176 /**
-177 * Transfers bytes from the given source array into this buffer array
-178 * @param start start offset of this buffer array
-179 * @param len The maximum number of bytes to be read from the given array
-180 * @param srcArray The array from which bytes are to be read
-181 */
-182 public void putMultiple(long start, int len, byte[] srcArray) {
-183 putMultiple(start, len, srcArray, 0);
-184 }
-185
-186 /**
-187 * Transfers bytes from the given source array into this buffer array
-188 * @param start start offset of this buffer array
-189 * @param len The maximum number of bytes to be read from the given array
-190 * @param srcArray The array from which bytes are to be read
-191 * @param srcOffset The offset within the given array of the first byte to be
-192 * read
-193 */
-194 public void putMultiple(long start, int len, byte[] srcArray, int srcOffset) {
-195 multiple(start, len, srcArray, srcOffset, PUT_MULTIPLE_VISITOR);
-196 }
-197
-198 private final static Visitor PUT_MULTIPLE_VISITOR = new Visitor() {
-199 @Override
-200 public void visit(ByteBuffer bb, int pos, byte[] array, int arrayIdx, int len) {
-201 ByteBufferUtils.copyFromArrayToBuffer(bb, pos, array, arrayIdx, len);
-202 }
-203 };
+176 private final static Visitor GET_MULTIPLE_VISTOR = new Visitor() {
+177 @Override
+178 public void visit(ByteBuffer bb, int pos, byte[] array, int arrayIdx, int len) {
+179 ByteBufferUtils.copyFromBufferToArray(array, bb, pos, arrayIdx, len);
+180 }
+181 };
+182
+183 /**
+184 * Transfers bytes from the given source array into this buffer array
+185 * @param start start offset of this buffer array
+186 * @param len The maximum number of bytes to be read from the given array
+187 * @param srcArray The array from which bytes are to be read
+188 */
+189 public void putMultiple(long start, int len, byte[] srcArray) {
+190 putMultiple(start, len, srcArray, 0);
+191 }
+192
+193 /**
+194 * Transfers bytes from the given source array into this buffer array
+195 * @param start start offset of this buffer array
+196 * @param len The maximum number of bytes to be read from the given array
+197 * @param srcArray The array from which bytes are to be read
+198 * @param srcOffset The offset within the given array of the first byte to be
+199 * read
+200 */
+201 public void putMultiple(long start, int len, byte[] srcArray, int srcOffset) {
+202 multiple(start, len, srcArray, srcOffset, PUT_MULTIPLE_VISITOR);
+203 }204
-205 private interface Visitor {
-206 /**
-207 * Visit the given byte buffer, if it is a read action, we will transfer the
-208 * bytes from the buffer to the destination array, else if it is a write
-209 * action, we will transfer the bytes from the source array to the buffer
-210 * @param bb byte buffer
-211 * @param pos Start position in ByteBuffer
-212 * @param array a source or destination byte array
-213 * @param arrayOffset offset of the byte array
-214 * @param len read/write length
-215 */
-216 void visit(ByteBuffer bb, int pos, byte[] array, int arrayOffset, int len);
-217 }
-218
-219 /**
-220 * Access(read or write) this buffer array with a position and length as the
-221 * given array. Here we will only lock one buffer even if it may be need visit
-222 * several buffers. The consistency is guaranteed by the caller.
-223 * @param start start offset of this buffer array
-224 * @param len The maximum number of bytes to be accessed
-225 * @param array The array from/to which bytes are to be read/written
-226 * @param arrayOffset The offset within the given array of the first byte to
-227 * be read or written
-228 * @param visitor implement of how to visit the byte buffer
-229 */
-230 void multiple(long start, int len, byte[] array, int arrayOffset, Visitor visitor) {
-231 assert len >= 0;
-232 long end = start + len;
-233 int startBuffer = (int) (start / bufferSize), startOffset = (int) (start % bufferSize);
-234 int endBuffer = (int) (end / bufferSize), endOffset = (int) (end % bufferSize);
-235 assert array.length >= len + arrayOffset;
-236 assert startBuffer >= 0 && startBuffer < bufferCount;
-237 assert endBuffer >= 0 && endBuffer < bufferCount
-238 || (endBuffer == bufferCount && endOffset == 0);
-239 if (startBuffer >= buffers.length || startBuffer < 0) {
-240 String msg = "Failed multiple, start=" + start + ",startBuffer="
-241 + startBuffer + ",bufferSize=" + bufferSize;
-242 LOG.error(msg);
-243 throw new RuntimeException(msg);
-244 }
-245 int srcIndex = 0, cnt = -1;
-246 for (int i = startBuffer; i <= endBuffer; ++i) {
-247 ByteBuffer bb = buffers[i].duplicate();
-248 int pos = 0;
-249 if (i == startBuffer) {
-250 cnt = bufferSize - startOffset;
-251 if (cnt > len) cnt = len;
-252 pos = startOffset;
-253 } else if (i == endBuffer) {
-254 cnt = endOffset;
-255 } else {
-256 cnt = bufferSize;
-257 }
-258 visitor.visit(bb, pos, array, srcIndex + arrayOffset, cnt);
-259 srcIndex += cnt;
-260 }
-261 assert srcIndex == len;
-262 }
-263
-264 /**
-265 * Creates a ByteBuff from a given array of ByteBuffers from the given offset to the
-266 * length specified. For eg, if there are 4 buffers forming an array each with length 10 and
-267 * if we call asSubBuffer(5, 10) then we will create an MBB consisting of two BBs
-268 * and the first one be a BB from 'position' 5 to a 'length' 5 and the 2nd BB will be from
-269 * 'position' 0 to 'length' 5.
-270 * @param offset
-271 * @param len
-272 * @return a ByteBuff formed from the underlying ByteBuffers
-273 */
-274 public ByteBuff asSubByteBuff(long offset, int len) {
-275 assert len >= 0;
-276 long end = offset + len;
-277 int startBuffer = (int) (offset / bufferSize), startBufferOffset = (int) (offset % bufferSize);
-278 int endBuffer = (int) (end / bufferSize), endBufferOffset = (int) (end % bufferSize);
-279 // Last buffer in the array is a dummy one with 0 capacity. Avoid sending back that
-280 if (endBuffer == this.bufferCount) {
-281 endBuffer--;
-282 endBufferOffset = bufferSize;
-283 }
-284 assert startBuffer >= 0 && startBuffer < bufferCount;
-285 assert endBuffer >= 0 && endBuffer < bufferCount
-286 || (endBuffer == bufferCount && endBufferOffset == 0);
-287 if (startBuffer >= buffers.length || startBuffer < 0) {
-288 String msg = "Failed subArray, start=" + offset + ",startBuffer=" + startBuffer
-289 + ",bufferSize=" + bufferSize;
-290 LOG.error(msg);
-291 throw new RuntimeException(msg);
-292 }
-293 int srcIndex = 0, cnt = -1;
-294 ByteBuffer[] mbb = new ByteBuffer[endBuffer - startBuffer + 1];
-295 for (int i = startBuffer, j = 0; i <= endBuffer; ++i, j++) {
-296 ByteBuffer bb = buffers[i].duplicate();
-297 if (i == startBuffer) {
-298 cnt = bufferSize - startBufferOffset;
-299 if (cnt > len) cnt = len;
-300 bb.limit(startBufferOffset + cnt).position(startBufferOffset);
-301 } else if (i == endBuffer) {
-302 cnt = endBufferOffset;
-303 bb.position(0).limit(cnt);
-304 } else {
-305 cnt = bufferSize;
-306 bb.position(0).limit(cnt);
-307 }
-308 mbb[j] = bb.slice();
-309 srcIndex += cnt;
-310 }
-311 assert srcIndex == len;
-312 if (mbb.length > 1) {
-313 return new MultiByteBuff(mbb);
-314 } else {
-315 return new SingleByteBuff(mbb[0]);
-316 }
-317 }
-318}
+205 private final static Visitor PUT_MULTIPLE_VISITOR = new Visitor() {
+206 @Override
+207 public void visit(ByteBuffer bb, int pos, byte[] array, int arrayIdx, int len) {
+208 ByteBufferUtils.copyFromArrayToBuffer(bb, pos, array, arrayIdx, len);
+209 }
+210 };
+211
+212 private interface Visitor {
+213 /**
+214 * Visit the given byte buffer, if it is a read action, we will transfer the
+215 * bytes from the buffer to the destination array, else if it is a write
+216 * action, we will transfer the bytes from the source array to the buffer
+217 * @param bb byte buffer
+218 * @param pos Start position in ByteBuffer
+219 * @param array a source or destination byte array
+220 * @param arrayOffset offset of the byte array
+221 * @param len read/write length
+222 */
+223 void visit(ByteBuffer bb, int pos, byte[] array, int arrayOffset, int len);
+224 }
+225
+226 /**
+227 * Access(read or write) this buffer array with a position and length as the
+228 * given array. Here we will only lock one buffer even if it may be need visit
+229 * several buffers. The consistency is guaranteed by the caller.
+230 * @param start start offset of this buffer array
+231 * @param len The maximum number of bytes to be accessed
+232 * @param array The array from/to which bytes are to be read/written
+233 * @param arrayOffset The offset within the given array of the first byte to
+234 * be read or written
+235 * @param visitor implement of how to visit the byte buffer
+236 */
+237 void multiple(long start, int len, byte[] array, int arrayOffset, Visitor visitor) {
+238 assert len >= 0;
+239 long end = start + len;
+240 int startBuffer = (int) (start / bufferSize), startOffset = (int) (start % bufferSize);
+241 int endBuffer = (int) (end / bufferSize), endOffset = (int) (end % bufferSize);
+242 assert array.length >= len + arrayOffset;
+243 assert startBuffer >= 0 && startBuffer < bufferCount;
+244 assert endBuffer >= 0 && endBuffer < bufferCount
+245 || (endBuffer == bufferCount && endOffset == 0);
+246 if (startBuffer >= buffers.length || startBuffer < 0) {
+247 String msg = "Failed multiple, start=" + start + ",startBuffer="
+248 + startBuffer + ",bufferSize=" + bufferSize;
+249 LOG.error(msg);
+250 throw new RuntimeException(msg);
+251 }
+252 int srcIndex = 0, cnt = -1;
+253 for (int i = startBuffer; i <= endBuffer; ++i) {
+254 ByteBuffer bb = buffers[i].duplicate();
+255 int pos = 0;
+256 if (i == startBuffer) {
+257 cnt = bufferSize - startOffset;
+258 if (cnt > len) cnt = len;
+259 pos = startOffset;
+260 } else if (i == endBuffer) {
+261 cnt = endOffset;
+262 } else {
+263 cnt = bufferSize;
+264 }
+265 visitor.visit(bb, pos, array, srcIndex + arrayOffset, cnt);
+266 srcIndex += cnt;
+267 }
+268 assert srcIndex == len;
+269 }
+270
+271 /**
+272 * Creates a ByteBuff from a given array of ByteBuffers from the given offset to the
+273 * length specified. For eg, if there are 4 buffers forming an array each with length 10 and
+274 * if we call asSubBuffer(5, 10) then we will create an MBB consisting of two BBs
+275 * and the first one be a BB from 'position' 5 to a 'length' 5 and the 2nd BB will be from
+276 * 'position' 0 to 'length' 5.
+277 * @param offset
+278 * @param len
+279 * @return a ByteBuff formed from the underlying ByteBuffers
+280 */
+281 public ByteBuff asSubByteBuff(long offset, int len) {
+282 assert len >= 0;
+283 long end = offset + len;
+284 int startBuffer = (int) (offset / bufferSize), startBufferOffset = (int) (offset % bufferSize);
+285 int endBuffer = (int) (end / bufferSize), endBufferOffset = (int) (end % bufferSize);
+286 // Last buffer in the array is a dummy one with 0 capacity. Avoid sending back that
+287 if (endBuffer == this.bufferCount) {
+288 endBuffer--;
+289 endBufferOffset = bufferSize;
+290 }
+291 assert startBuffer >= 0 && startBuffer < bufferCount;
+292 assert endBuffer >= 0 && endBuffer < bufferCount
+293 || (endBuffer == bufferCount && endBufferOffset == 0);
+294 if (startBuffer >= buffers.length || startBuffer < 0) {
+295 String msg = "Failed subArray, start=" + offset + ",startBuffer=" + startBuffer
+296 + ",bufferSize=" + bufferSize;
+297 LOG.error(msg);
+298 throw new RuntimeException(msg);
+299 }
+300 int srcIndex = 0, cnt = -1;
+301 ByteBuffer[] mbb = new ByteBuffer[endBuffer - startBuffer + 1];
+302 for (int i = startBuffer, j = 0; i <= endBuffer; ++i, j++) {
+303 ByteBuffer bb = buffers[i].duplicate();
+304 if (i == startBuffer) {
+305 cnt = bufferSize - startBufferOffset;
+306 if (cnt > len) cnt = len;
+307 bb.limit(startBufferOffset + cnt).position(startBufferOffset);
+308 } else if (i == endBuffer) {
+309 cnt = endBufferOffset;
+310 bb.position(0).limit(cnt);
+311 } else {
+312 cnt = bufferSize;
+313 bb.position(0).limit(cnt);
+314 }
+315 mbb[j] = bb.slice();
+316 srcIndex += cnt;
+317 }
+318 assert srcIndex == len;
+319 if (mbb.length > 1) {
+320 return new MultiByteBuff(mbb);
+321 } else {
+322 return new SingleByteBuff(mbb[0]);
+323 }
+324 }
+325}
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9e6e3360/export_control.html
----------------------------------------------------------------------
diff --git a/export_control.html b/export_control.html
index 1c40eee..46d84d9 100644
--- a/export_control.html
+++ b/export_control.html
@@ -7,7 +7,7 @@
-
+
Apache HBase –
Export Control
@@ -336,7 +336,7 @@ for more details.