You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@bookkeeper.apache.org by GitBox <gi...@apache.org> on 2018/02/11 21:17:51 UTC
[GitHub] jvrao commented on a change in pull request #1141: Replace DoubleByteBuf with ByteBufList
jvrao commented on a change in pull request #1141: Replace DoubleByteBuf with ByteBufList
URL: https://github.com/apache/bookkeeper/pull/1141#discussion_r167450110
##########
File path: bookkeeper-server/src/main/java/org/apache/bookkeeper/util/ByteBufList.java
##########
@@ -0,0 +1,304 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.bookkeeper.util;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.PooledByteBufAllocator;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandler.Sharable;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelOutboundHandlerAdapter;
+import io.netty.channel.ChannelPromise;
+import io.netty.util.AbstractReferenceCounted;
+import io.netty.util.Recycler;
+import io.netty.util.Recycler.Handle;
+import io.netty.util.ReferenceCountUtil;
+import io.netty.util.ReferenceCounted;
+
+import java.util.ArrayList;
+
+/**
+ * ByteBufList is a holder of a sequence of {@link ByteBuf} objects.
+ *
+ * <p>This class doesn't trying to mimic the {@link ByteBuf}, but rather exposes itself just like a regular object which
+ * will need to be encoded on the channel. There are 2 utility encoders:
+ * <ul>
+ * <li>{@link #ENCODER}: regular encode that will write all the buffers in the {@link ByteBufList} on the channel</li>
+ * <li>{@link #ENCODER_WITH_SIZE}: similar to the previous one, but also prepend a 4 bytes size header, once, carrying
+ * the size of the readable bytes across all the buffers contained in the {@link ByteBufList}</li>
+ * </ul>
+ *
+ * <p>Example:
+ *
+ * <pre>
+ * bootstrap.handler(new ChannelInitializer<SocketChannel>() {
+ * public void initChannel(SocketChannel ch) throws Exception {
+ * ChannelPipeline pipeline = ch.pipeline();
+ * pipeline.addLast("bytebufList", ByteBufList.ENCODER);
+ * pipeline.addLast("mainhandler", MyHandler.class);
+ * }
+ * });
+ * </pre>
+ *
+ * <p>ByteBufList is pooling the instances and uses ref-counting to release them.
+ */
+public class ByteBufList extends AbstractReferenceCounted {
+ private final ArrayList<ByteBuf> buffers;
+ private final Handle<ByteBufList> recyclerHandle;
+
+ private static final int INITIAL_LIST_SIZE = 4;
+
+ private static final Recycler<ByteBufList> RECYCLER = new Recycler<ByteBufList>() {
+ @Override
+ protected ByteBufList newObject(Recycler.Handle<ByteBufList> handle) {
+ return new ByteBufList(handle);
+ }
+ };
+
+ private ByteBufList(Handle<ByteBufList> recyclerHandle) {
+ this.recyclerHandle = recyclerHandle;
+ this.buffers = new ArrayList<>(INITIAL_LIST_SIZE);
+ }
+
+ /**
+ * Get a new {@link ByteBufList} from the pool and assign 2 buffers to it.
+ *
+ * <p>The buffers b1 and b2 lifecycles are now managed by the ByteBufList: when the {@link ByteBufList} is
+ * deallocated, b1 and b2 will be released as well.
+ *
+ * @param b1
+ * first buffer
+ * @param b2
+ * second buffer
+ * @return a {@link ByteBufList} instance from the pool
+ */
+ public static ByteBufList get(ByteBuf b1, ByteBuf b2) {
+ ByteBufList buf = get();
+ buf.add(b1);
+ buf.add(b2);
+ return buf;
+ }
+
+ /**
+ * Get a new {@link ByteBufList} from the pool and assign 1 buffer to it.
+ *
+ * <p>The buffer b1 lifecycle is now managed by the ByteBufList: when the {@link ByteBufList} is
+ * deallocated, b1 will be released as well.
+ *
+ * @param b1
+ * first buffer
+ * @return a {@link ByteBufList} instance from the pool
+ */
+ public static ByteBufList get(ByteBuf b1) {
+ ByteBufList buf = get();
+ buf.add(b1);
+ return buf;
+ }
+
+ /**
+ * Get a new {@link ByteBufList} instance from the pool that is the clone of an already existing instance.
+ */
+ public static ByteBufList clone(ByteBufList other) {
+ ByteBufList buf = get();
+ for (int i = 0; i < other.buffers.size(); i++) {
+ // Create a duplicate of the buffer so that there is no interference from other threads
+ buf.add(other.buffers.get(i).retainedDuplicate());
+ }
+ return buf;
+ }
+
+ private static ByteBufList get() {
+ ByteBufList buf = RECYCLER.get();
+ buf.setRefCnt(1);
+ return buf;
+ }
+
+ /**
+ * Append a {@link ByteBuf} at the end of this {@link ByteBufList}.
+ */
+ public void add(ByteBuf buf) {
+ buffers.add(buf);
+ }
+
+ /**
+ * Prepend a {@link ByteBuf} at the end of this {@link ByteBufList}.
Review comment:
s/end of/head of
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
With regards,
Apache Git Services