Skip to content
This repository was archived by the owner on Dec 12, 2022. It is now read-only.

Commit 824d3e0

Browse files
authored
Merge pull request #37 from netty/bytebuffer-impl
Add a ByteBuffer based implementation of Buffer
2 parents 0272b1c + 66fbc44 commit 824d3e0

28 files changed

+1705
-113
lines changed

.github/workflows/ci-workflow.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
- uses: actions/checkout@v2
3434

3535
# Enable caching of Docker layers
36-
- uses: satackey/[email protected].8
36+
- uses: satackey/[email protected].11
3737
continue-on-error: true
3838
with:
3939
key: docker-cache-${{ steps.cache-key.outputs.key }}-{hash}

Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ WORKDIR /home/build
2929

3030
# Prepare our own build
3131
COPY pom.xml pom.xml
32-
RUN mvn dependency:go-offline surefire:test -ntp
32+
RUN mvn dependency:go-offline surefire:test checkstyle:check -ntp
3333

3434
# Copy over the project code and run our build
3535
COPY . .

pom.xml

+25-13
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,11 @@
6969
<properties>
7070
<javaModuleName>io.netty.incubator.buffer</javaModuleName>
7171
<netty.version>5.0.0.Final-SNAPSHOT</netty.version>
72-
<netty.build.version>28</netty.build.version>
72+
<netty.build.version>29</netty.build.version>
7373
<java.version>16</java.version>
7474
<junit.version>5.7.0</junit.version>
7575
<surefire.version>3.0.0-M5</surefire.version>
7676
<skipTests>false</skipTests>
77-
<argLine.java9.extras />
78-
<!-- Export some stuff which is used during our tests -->
79-
<argLine.java9>--illegal-access=deny ${argLine.java9.extras}</argLine.java9>
8077
<argLine.common>
8178
-server
8279
-dsa -da -ea:io.netty...
@@ -95,9 +92,21 @@
9592
</extension>
9693
</extensions>
9794
<plugins>
95+
<plugin>
96+
<groupId>org.apache.maven.plugins</groupId>
97+
<artifactId>maven-dependency-plugin</artifactId>
98+
<version>3.1.2</version>
99+
<executions>
100+
<execution>
101+
<goals>
102+
<goal>properties</goal>
103+
</goals>
104+
</execution>
105+
</executions>
106+
</plugin>
98107
<plugin>
99108
<artifactId>maven-compiler-plugin</artifactId>
100-
<version>3.8.0</version>
109+
<version>3.8.1</version>
101110
<configuration>
102111
<compilerVersion>${java.version}</compilerVersion>
103112
<fork>true</fork>
@@ -114,15 +123,18 @@
114123
<compilerArgs>
115124
<arg>--add-modules</arg>
116125
<arg>jdk.incubator.foreign</arg>
126+
127+
<!--
128+
These two are really only needed for test-compile, but the maven-compiler-plugin cannot express that
129+
-->
130+
<arg>--patch-module</arg>
131+
<arg>io.netty.buffer=${io.netty:netty-buffer:test-jar:tests}</arg>
117132
</compilerArgs>
118-
<excludes>
119-
<exclude>**/package-info.java</exclude>
120-
</excludes>
121133
</configuration>
122134
</plugin>
123135
<plugin>
124136
<artifactId>maven-checkstyle-plugin</artifactId>
125-
<version>3.1.0</version>
137+
<version>3.1.2</version>
126138
<executions>
127139
<execution>
128140
<id>check-style</id>
@@ -148,7 +160,7 @@
148160
<dependency>
149161
<groupId>com.puppycrawl.tools</groupId>
150162
<artifactId>checkstyle</artifactId>
151-
<version>8.29</version>
163+
<version>8.41</version>
152164
</dependency>
153165
<dependency>
154166
<groupId>io.netty</groupId>
@@ -164,8 +176,7 @@
164176
<includes>
165177
<include>**/*Test*.java</include>
166178
</includes>
167-
<runOrder>random</runOrder>
168-
<argLine>${argLine.common} ${argLine.printGC} ${argLine.java9} --add-modules jdk.incubator.foreign</argLine>
179+
<argLine>${argLine.common} ${argLine.printGC} --patch-module io.netty.buffer=${io.netty:netty-buffer:test-jar:tests} --add-modules jdk.incubator.foreign</argLine>
169180
<!-- Ensure the whole stacktrace is preserved when an exception is thrown. See https://issues.apache.org/jira/browse/SUREFIRE-1457 -->
170181
<trimStackTrace>false</trimStackTrace>
171182
</configuration>
@@ -235,7 +246,7 @@
235246
<plugin>
236247
<groupId>org.apache.felix</groupId>
237248
<artifactId>maven-bundle-plugin</artifactId>
238-
<version>2.5.4</version>
249+
<version>5.1.1</version>
239250
<executions>
240251
<execution>
241252
<id>generate-manifest</id>
@@ -399,6 +410,7 @@
399410
<artifactId>netty-buffer</artifactId>
400411
<version>${netty.version}</version>
401412
<type>test-jar</type>
413+
<classifier>tests</classifier>
402414
<scope>test</scope>
403415
</dependency>
404416
<dependency>

src/main/java/io/netty/buffer/api/Buffer.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -408,9 +408,7 @@ default Buffer reset() {
408408
*
409409
* @return A {@link ByteCursor} for iterating the readable bytes of this buffer.
410410
*/
411-
default ByteCursor openCursor() {
412-
return openCursor(readerOffset(), readableBytes());
413-
}
411+
ByteCursor openCursor();
414412

415413
/**
416414
* Open a cursor to iterate the given number bytes of this buffer, starting at the given offset.

src/main/java/io/netty/buffer/api/BufferAllocator.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package io.netty.buffer.api;
1717

18+
import io.netty.buffer.api.internal.Statics;
19+
1820
import java.nio.ByteOrder;
1921

2022
/**
@@ -75,18 +77,18 @@ default void close() {
7577
}
7678

7779
static BufferAllocator heap() {
78-
return new ManagedBufferAllocator(MemoryManager.getHeapMemoryManager(), Statics.CLEANER);
80+
return new ManagedBufferAllocator(MemoryManagers.getManagers().getHeapMemoryManager(), Statics.CLEANER);
7981
}
8082

8183
static BufferAllocator direct() {
82-
return new ManagedBufferAllocator(MemoryManager.getNativeMemoryManager(), Statics.CLEANER);
84+
return new ManagedBufferAllocator(MemoryManagers.getManagers().getNativeMemoryManager(), Statics.CLEANER);
8385
}
8486

8587
static BufferAllocator pooledHeap() {
86-
return new SizeClassedMemoryPool(MemoryManager.getHeapMemoryManager());
88+
return new SizeClassedMemoryPool(MemoryManagers.getManagers().getHeapMemoryManager());
8789
}
8890

8991
static BufferAllocator pooledDirect() {
90-
return new SizeClassedMemoryPool(MemoryManager.getNativeMemoryManager());
92+
return new SizeClassedMemoryPool(MemoryManagers.getManagers().getNativeMemoryManager());
9193
}
9294
}

src/main/java/io/netty/buffer/api/BufferHolder.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import java.lang.invoke.VarHandle;
1919
import java.util.Objects;
2020

21-
import static io.netty.buffer.api.Statics.findVarHandle;
21+
import static io.netty.buffer.api.internal.Statics.findVarHandle;
2222
import static java.lang.invoke.MethodHandles.lookup;
2323

2424
/**

src/main/java/io/netty/buffer/api/CleanerPooledDrop.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
import java.lang.ref.WeakReference;
2121
import java.util.concurrent.atomic.AtomicBoolean;
2222

23-
import static io.netty.buffer.api.Statics.CLEANER;
24-
import static io.netty.buffer.api.Statics.findVarHandle;
23+
import static io.netty.buffer.api.internal.Statics.CLEANER;
24+
import static io.netty.buffer.api.internal.Statics.findVarHandle;
2525
import static java.lang.invoke.MethodHandles.lookup;
2626

2727
class CleanerPooledDrop implements Drop<Buffer> {

src/main/java/io/netty/buffer/api/CompositeBuffer.java

+7
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,11 @@ public void copyInto(int srcPos, Buffer dest, int destPos, int length) {
396396
}
397397
}
398398

399+
@Override
400+
public ByteCursor openCursor() {
401+
return openCursor(readerOffset(), readableBytes());
402+
}
403+
399404
@Override
400405
public ByteCursor openCursor(int fromOffset, int length) {
401406
if (fromOffset < 0) {
@@ -1147,6 +1152,7 @@ protected Owned<CompositeBuffer> prepareSend() {
11471152
}
11481153
throw throwable;
11491154
}
1155+
boolean readOnly = this.readOnly;
11501156
makeInaccessible();
11511157
return new Owned<CompositeBuffer>() {
11521158
@Override
@@ -1167,6 +1173,7 @@ void makeInaccessible() {
11671173
capacity = 0;
11681174
roff = 0;
11691175
woff = 0;
1176+
readOnly = false;
11701177
closed = true;
11711178
}
11721179

src/main/java/io/netty/buffer/api/ManagedBufferAllocator.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import java.lang.ref.Cleaner;
1919

20-
import static io.netty.buffer.api.Statics.NO_OP_DROP;
20+
import static io.netty.buffer.api.internal.Statics.NO_OP_DROP;
2121

2222
class ManagedBufferAllocator implements BufferAllocator, AllocatorControl {
2323
private final MemoryManager manager;
@@ -44,6 +44,6 @@ public Object allocateUntethered(Buffer originator, int size) {
4444
@Override
4545
public void recoverMemory(Object memory) {
4646
// Free the recovered memory.
47-
manager.recoverMemory(memory, manager.drop()).close();
47+
manager.recoverMemory(this, memory, manager.drop()).close();
4848
}
4949
}

src/main/java/io/netty/buffer/api/MemoryManager.java

+3-11
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,11 @@
2121
import java.lang.ref.Cleaner;
2222

2323
public interface MemoryManager {
24-
static MemoryManager getHeapMemoryManager() {
25-
return new HeapMemorySegmentManager();
26-
}
27-
28-
static MemoryManager getNativeMemoryManager() {
29-
return new NativeMemorySegmentManager();
30-
}
31-
3224
boolean isNative();
33-
Buffer allocateConfined(AllocatorControl alloc, long size, Drop<Buffer> drop, Cleaner cleaner);
34-
Buffer allocateShared(AllocatorControl allo, long size, Drop<Buffer> drop, Cleaner cleaner);
25+
Buffer allocateConfined(AllocatorControl allocatorControl, long size, Drop<Buffer> drop, Cleaner cleaner);
26+
Buffer allocateShared(AllocatorControl allocatorControl, long size, Drop<Buffer> drop, Cleaner cleaner);
3527
Drop<Buffer> drop();
3628
Object unwrapRecoverableMemory(Buffer buf);
3729
int capacityOfRecoverableMemory(Object memory);
38-
Buffer recoverMemory(Object recoverableMemory, Drop<Buffer> drop);
30+
Buffer recoverMemory(AllocatorControl allocatorControl, Object recoverableMemory, Drop<Buffer> drop);
3931
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2021 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.buffer.api;
17+
18+
import java.util.ServiceLoader;
19+
import java.util.function.Supplier;
20+
import java.util.stream.Stream;
21+
22+
/**
23+
* The MemoryManagers interface is the handle through which {@link BufferAllocator buffer allocators} access the low
24+
* level memory management APIs.
25+
* <p>
26+
* This is hidden behind this interface in order to make allocation and pool agnostic and reusable across buffer and
27+
* memory implementations.
28+
*/
29+
public interface MemoryManagers {
30+
/**
31+
* Get the default, or currently configured, memory managers instance.
32+
* @return A MemoryManagers instance.
33+
*/
34+
static MemoryManagers getManagers() {
35+
return MemoryManagersOverride.getManagers();
36+
}
37+
38+
/**
39+
* Temporarily override the default configured memory managers instance.
40+
* <p>
41+
* Calls to {@link #getManagers()} from within the given supplier will get the given managers instance.
42+
*
43+
* @param managers Override the default configured managers instance with this instance.
44+
* @param supplier The supplier function to be called while the override is in place.
45+
* @param <T> The result type from the supplier.
46+
* @return The result from the supplier.
47+
*/
48+
static <T> T using(MemoryManagers managers, Supplier<T> supplier) {
49+
return MemoryManagersOverride.using(managers, supplier);
50+
}
51+
52+
/**
53+
* Get a lazy-loading stream of all available memory managers.
54+
*
55+
* @return A stream of providers of memory managers instances.
56+
*/
57+
static Stream<ServiceLoader.Provider<MemoryManagers>> getAllManagers() {
58+
var loader = ServiceLoader.load(MemoryManagers.class);
59+
return loader.stream();
60+
}
61+
62+
/**
63+
* Get a {@link MemoryManager} instance that is suitable for allocating on-heap {@link Buffer} instances.
64+
*
65+
* @return An on-heap {@link MemoryManager}.
66+
*/
67+
MemoryManager getHeapMemoryManager();
68+
69+
/**
70+
* Get a {@link MemoryManager} instance that is suitable for allocating off-heap {@link Buffer} instances.
71+
*
72+
* @return An off-heap {@link MemoryManager}.
73+
*/
74+
MemoryManager getNativeMemoryManager();
75+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2021 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.buffer.api;
17+
18+
import io.netty.buffer.api.memseg.SegmentMemoryManagers;
19+
20+
import java.util.Collections;
21+
import java.util.IdentityHashMap;
22+
import java.util.Map;
23+
import java.util.concurrent.atomic.AtomicInteger;
24+
import java.util.function.Supplier;
25+
26+
final class MemoryManagersOverride {
27+
private static final MemoryManagers DEFAULT = new SegmentMemoryManagers();
28+
private static final AtomicInteger OVERRIDES_AVAILABLE = new AtomicInteger();
29+
private static final Map<Thread, MemoryManagers> OVERRIDES = Collections.synchronizedMap(new IdentityHashMap<>());
30+
31+
private MemoryManagersOverride() {
32+
}
33+
34+
static MemoryManagers getManagers() {
35+
if (OVERRIDES_AVAILABLE.get() > 0) {
36+
return OVERRIDES.getOrDefault(Thread.currentThread(), DEFAULT);
37+
}
38+
return DEFAULT;
39+
}
40+
41+
static <T> T using(MemoryManagers managers, Supplier<T> supplier) {
42+
Thread thread = Thread.currentThread();
43+
OVERRIDES.put(thread, managers);
44+
OVERRIDES_AVAILABLE.incrementAndGet();
45+
try {
46+
return supplier.get();
47+
} finally {
48+
OVERRIDES_AVAILABLE.decrementAndGet();
49+
OVERRIDES.remove(thread);
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)