View Javadoc
1   /*
2    * Copyright 2025 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.channel.uring;
17  
18  import io.netty.buffer.ByteBuf;
19  import io.netty.buffer.ByteBufAllocator;
20  
21  import java.util.Objects;
22  import java.util.function.Consumer;
23  
24  /**
25   * Base class for {@link IoUringBufferRingAllocator} implementations which support large allocations.
26   */
27  public abstract class AbstractIoUringBufferRingAllocator implements IoUringBufferRingAllocator {
28      private final ByteBufAllocator allocator;
29      private final boolean largeAllocation;
30  
31      /**
32       * Creates new instance.
33       *
34       * @param allocator         the {@link ByteBufAllocator} to use for the allocations
35       * @param largeAllocation   {@code true} if we should do a large allocation for the whole buffer ring
36       *                          and then slice out the buffers or {@code false} if we should do one allocation
37       *                          per buffer.
38       */
39      protected AbstractIoUringBufferRingAllocator(ByteBufAllocator allocator, boolean largeAllocation) {
40          this.allocator = Objects.requireNonNull(allocator, "allocator");
41          this.largeAllocation = largeAllocation;
42      }
43  
44      @Override
45      public final void allocateBatch(Consumer<ByteBuf> consumer, int number) {
46          if (largeAllocation) {
47              int bufferSize = nextBufferSize();
48              ByteBuf buffer = allocator.directBuffer(nextBufferSize() * number);
49              try {
50                  for (int i = 0; i < number; i++) {
51                      consumer.accept(buffer
52                              .retainedSlice(i * bufferSize, bufferSize)
53                              .setIndex(0, 0)
54                      );
55                  }
56              } finally {
57                  buffer.release();
58              }
59          } else {
60              IoUringBufferRingAllocator.super.allocateBatch(consumer, number);
61          }
62      }
63  
64      @Override
65      public final ByteBuf allocate() {
66          return allocator.directBuffer(nextBufferSize());
67      }
68  
69      /**
70       * Does nothing by default, sub-classes might override this.
71       *
72       * @param attempted  the attempted bytes to read.
73       * @param actual     the number of bytes that could be read.
74       */
75      @Override
76      public void lastBytesRead(int attempted, int actual) {
77          // NOOP.
78      }
79  
80      /**
81       * Return the next buffer size of each {@link ByteBuf} that is put into the buffer ring.
82       *
83       * @return  the next size.
84       */
85      protected abstract int nextBufferSize();
86  }