2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org
.apache
.hadoop
.hbase
.io
;
20 import java
.io
.IOException
;
21 import java
.io
.OutputStream
;
22 import java
.nio
.ByteBuffer
;
23 import java
.util
.Objects
;
25 import org
.apache
.hadoop
.hbase
.io
.util
.StreamUtils
;
26 import org
.apache
.hadoop
.hbase
.util
.ByteBufferUtils
;
27 import org
.apache
.yetus
.audience
.InterfaceAudience
;
30 * When deal with OutputStream which is not ByteBufferWriter type, wrap it with this class. We will
31 * have to write offheap ByteBuffer (DBB) data into the OS. This class is having a temp byte array
32 * to which we can copy the DBB data for writing to the OS.
34 * This is used while writing Cell data to WAL. In case of AsyncWAL, the OS created there is
35 * ByteBufferWriter. But in case of FSHLog, the OS passed by DFS client, is not of type
36 * ByteBufferWriter. We will need this temp solution until DFS client supports writing ByteBuffer
37 * directly to the OS it creates.
39 * Note: This class is not thread safe.
41 @InterfaceAudience.Private
42 public class ByteBufferWriterOutputStream
extends OutputStream
43 implements ByteBufferWriter
{
45 private static final int DEFAULT_BUFFER_SIZE
= 4096;
47 private final OutputStream os
;
48 private final int bufSize
;
51 public ByteBufferWriterOutputStream(OutputStream os
) {
52 this(os
, DEFAULT_BUFFER_SIZE
);
55 public ByteBufferWriterOutputStream(OutputStream os
, int size
) {
62 * Writes len bytes from the specified ByteBuffer starting at offset off to this OutputStream. If
63 * off is negative or larger than the ByteBuffer then an ArrayIndexOutOfBoundsException is thrown.
64 * If len is greater than the length of the ByteBuffer, then an ArrayIndexOutOfBoundsException is
65 * thrown. This method does not change the position of the ByteBuffer.
66 * @param b the ByteBuffer
67 * @param off the start offset in the data
68 * @param len the number of bytes to write
69 * @throws IOException if an I/O error occurs. In particular, an IOException is thrown if the
70 * output stream is closed.
71 * @throws NullPointerException if {@code b} is {@code null}
74 public void write(ByteBuffer b
, int off
, int len
) throws IOException
{
75 Objects
.requireNonNull(b
);
77 // Lazily load in the event that this version of 'write' is not invoked
78 if (this.buf
== null) {
79 this.buf
= new byte[this.bufSize
];
82 while (totalCopied
< len
) {
83 int bytesToCopy
= Math
.min((len
- totalCopied
), this.bufSize
);
84 ByteBufferUtils
.copyFromBufferToArray(this.buf
, b
, off
+ totalCopied
, 0,
86 this.os
.write(this.buf
, 0, bytesToCopy
);
87 totalCopied
+= bytesToCopy
;
92 public void writeInt(int i
) throws IOException
{
93 StreamUtils
.writeInt(this.os
, i
);
97 public void write(int b
) throws IOException
{
102 public void write(byte[] b
, int off
, int len
) throws IOException
{
103 this.os
.write(b
, off
, len
);
107 public void flush() throws IOException
{
112 public void close() throws IOException
{