From 2cc3ed7c9a4993b001971a3c960c415a8cf3a684 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Thu, 19 Mar 2026 10:24:23 +0200
Subject: [PATCH 01/45] remove buffer*
---
.../channel/buffer/BufferContainer.java | 69 ------
.../channel/buffer/BufferContainerImpl.java | 87 --------
.../channel/buffer/BufferContainerStub.java | 73 -------
.../net_01/channel/buffer/BufferLease.java | 89 --------
.../channel/buffer/BufferLeaseImpl.java | 136 ------------
.../channel/buffer/BufferLeasePool.java | 203 ------------------
.../channel/buffer/BufferLeaseStub.java | 93 --------
.../context/buffer/BufferLeasePoolTest.java | 119 ----------
8 files changed, 869 deletions(-)
delete mode 100644 src/main/java/com/teragrep/net_01/channel/buffer/BufferContainer.java
delete mode 100644 src/main/java/com/teragrep/net_01/channel/buffer/BufferContainerImpl.java
delete mode 100644 src/main/java/com/teragrep/net_01/channel/buffer/BufferContainerStub.java
delete mode 100644 src/main/java/com/teragrep/net_01/channel/buffer/BufferLease.java
delete mode 100644 src/main/java/com/teragrep/net_01/channel/buffer/BufferLeaseImpl.java
delete mode 100644 src/main/java/com/teragrep/net_01/channel/buffer/BufferLeasePool.java
delete mode 100644 src/main/java/com/teragrep/net_01/channel/buffer/BufferLeaseStub.java
delete mode 100644 src/test/java/com/teragrep/net_01/channel/context/buffer/BufferLeasePoolTest.java
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/BufferContainer.java b/src/main/java/com/teragrep/net_01/channel/buffer/BufferContainer.java
deleted file mode 100644
index 8865e89..0000000
--- a/src/main/java/com/teragrep/net_01/channel/buffer/BufferContainer.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Java Zero Copy Networking Library net_01
- * Copyright (C) 2024 Suomen Kanuuna Oy
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *
- *
- * Additional permission under GNU Affero General Public License version 3
- * section 7
- *
- * If you modify this Program, or any covered work, by linking or combining it
- * with other code, such other code is not for that reason alone subject to any
- * of the requirements of the GNU Affero GPL version 3 as long as this Program
- * is the same Program as licensed from Suomen Kanuuna Oy without any additional
- * modifications.
- *
- * Supplemented terms under GNU Affero General Public License version 3
- * section 7
- *
- * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
- * versions must be marked as "Modified version of" The Program.
- *
- * Names of the licensors and authors may not be used for publicity purposes.
- *
- * No rights are granted for use of trade names, trademarks, or service marks
- * which are in The Program if any.
- *
- * Licensee must indemnify licensors and authors for any liability that these
- * contractual assumptions impose on licensors and authors.
- *
- * To the extent this program is licensed as part of the Commercial versions of
- * Teragrep, the applicable Commercial License may apply to this file if you as
- * a licensee so wish it.
- */
-package com.teragrep.net_01.channel.buffer;
-
-import java.nio.ByteBuffer;
-
-/**
- * BufferContainer is a decorator for {@link ByteBuffer} with an id.
- */
-public interface BufferContainer {
-
- /**
- * @return id of the buffer
- */
- long id();
-
- /**
- * @return encapsulated {@link ByteBuffer}.
- */
- ByteBuffer buffer();
-
- /**
- * @return is this a stub implementation.
- */
- boolean isStub();
-}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/BufferContainerImpl.java b/src/main/java/com/teragrep/net_01/channel/buffer/BufferContainerImpl.java
deleted file mode 100644
index 6ac9924..0000000
--- a/src/main/java/com/teragrep/net_01/channel/buffer/BufferContainerImpl.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Java Zero Copy Networking Library net_01
- * Copyright (C) 2024 Suomen Kanuuna Oy
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *
- *
- * Additional permission under GNU Affero General Public License version 3
- * section 7
- *
- * If you modify this Program, or any covered work, by linking or combining it
- * with other code, such other code is not for that reason alone subject to any
- * of the requirements of the GNU Affero GPL version 3 as long as this Program
- * is the same Program as licensed from Suomen Kanuuna Oy without any additional
- * modifications.
- *
- * Supplemented terms under GNU Affero General Public License version 3
- * section 7
- *
- * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
- * versions must be marked as "Modified version of" The Program.
- *
- * Names of the licensors and authors may not be used for publicity purposes.
- *
- * No rights are granted for use of trade names, trademarks, or service marks
- * which are in The Program if any.
- *
- * Licensee must indemnify licensors and authors for any liability that these
- * contractual assumptions impose on licensors and authors.
- *
- * To the extent this program is licensed as part of the Commercial versions of
- * Teragrep, the applicable Commercial License may apply to this file if you as
- * a licensee so wish it.
- */
-package com.teragrep.net_01.channel.buffer;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.nio.ByteBuffer;
-
-/**
- * Decorator for {@link ByteBuffer} with a synchronized access for it.
- */
-final class BufferContainerImpl implements BufferContainer {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(BufferContainerImpl.class);
- private final long id;
- private final ByteBuffer buffer;
-
- BufferContainerImpl(long id, ByteBuffer buffer) {
- this.id = id;
- this.buffer = buffer;
- }
-
- @Override
- public long id() {
- return id;
- }
-
- @Override
- public synchronized ByteBuffer buffer() {
- return buffer;
- }
-
- @Override
- public String toString() {
- return "BufferContainer{" + "buffer=" + buffer + ", id=" + id + '}';
- }
-
- @Override
- public boolean isStub() {
- LOGGER.debug("id <{}>", id);
- return false;
- }
-}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/BufferContainerStub.java b/src/main/java/com/teragrep/net_01/channel/buffer/BufferContainerStub.java
deleted file mode 100644
index 1171305..0000000
--- a/src/main/java/com/teragrep/net_01/channel/buffer/BufferContainerStub.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Java Zero Copy Networking Library net_01
- * Copyright (C) 2024 Suomen Kanuuna Oy
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *
- *
- * Additional permission under GNU Affero General Public License version 3
- * section 7
- *
- * If you modify this Program, or any covered work, by linking or combining it
- * with other code, such other code is not for that reason alone subject to any
- * of the requirements of the GNU Affero GPL version 3 as long as this Program
- * is the same Program as licensed from Suomen Kanuuna Oy without any additional
- * modifications.
- *
- * Supplemented terms under GNU Affero General Public License version 3
- * section 7
- *
- * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
- * versions must be marked as "Modified version of" The Program.
- *
- * Names of the licensors and authors may not be used for publicity purposes.
- *
- * No rights are granted for use of trade names, trademarks, or service marks
- * which are in The Program if any.
- *
- * Licensee must indemnify licensors and authors for any liability that these
- * contractual assumptions impose on licensors and authors.
- *
- * To the extent this program is licensed as part of the Commercial versions of
- * Teragrep, the applicable Commercial License may apply to this file if you as
- * a licensee so wish it.
- */
-package com.teragrep.net_01.channel.buffer;
-
-import java.nio.ByteBuffer;
-
-/**
- * Stub implementation of the {@link BufferContainer}.
- */
-final class BufferContainerStub implements BufferContainer {
-
- BufferContainerStub() {
-
- }
-
- @Override
- public long id() {
- throw new IllegalStateException("BufferContainerStub does not have an id!");
- }
-
- @Override
- public ByteBuffer buffer() {
- throw new IllegalStateException("BufferContainerStub does not allow access to the buffer!");
- }
-
- @Override
- public boolean isStub() {
- return true;
- }
-}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/BufferLease.java b/src/main/java/com/teragrep/net_01/channel/buffer/BufferLease.java
deleted file mode 100644
index 152a65e..0000000
--- a/src/main/java/com/teragrep/net_01/channel/buffer/BufferLease.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Java Zero Copy Networking Library net_01
- * Copyright (C) 2024 Suomen Kanuuna Oy
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *
- *
- * Additional permission under GNU Affero General Public License version 3
- * section 7
- *
- * If you modify this Program, or any covered work, by linking or combining it
- * with other code, such other code is not for that reason alone subject to any
- * of the requirements of the GNU Affero GPL version 3 as long as this Program
- * is the same Program as licensed from Suomen Kanuuna Oy without any additional
- * modifications.
- *
- * Supplemented terms under GNU Affero General Public License version 3
- * section 7
- *
- * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
- * versions must be marked as "Modified version of" The Program.
- *
- * Names of the licensors and authors may not be used for publicity purposes.
- *
- * No rights are granted for use of trade names, trademarks, or service marks
- * which are in The Program if any.
- *
- * Licensee must indemnify licensors and authors for any liability that these
- * contractual assumptions impose on licensors and authors.
- *
- * To the extent this program is licensed as part of the Commercial versions of
- * Teragrep, the applicable Commercial License may apply to this file if you as
- * a licensee so wish it.
- */
-package com.teragrep.net_01.channel.buffer;
-
-import java.nio.ByteBuffer;
-
-/**
- * BufferLease is a decorator for {@link BufferContainer} with reference counter
- */
-public interface BufferLease {
-
- /**
- * @return identity of the decorated {@link BufferContainer}.
- */
- long id();
-
- /**
- * @return current reference count.
- */
- long refs();
-
- /**
- * @return encapsulated buffer of the {@link BufferContainer}.
- */
- ByteBuffer buffer();
-
- /**
- * Add reference, throws {@link IllegalStateException} if lease has expired.
- */
- void addRef() throws IllegalStateException;
-
- /**
- * Remove reference, throws {@link IllegalStateException} if lease has expired.
- */
- void removeRef() throws IllegalStateException;
-
- /**
- * @return status of the lease, {@code true} indicates that the lease has expired.
- */
- boolean isTerminated();
-
- /**
- * @return is this a stub implementation.
- */
- boolean isStub();
-}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/BufferLeaseImpl.java b/src/main/java/com/teragrep/net_01/channel/buffer/BufferLeaseImpl.java
deleted file mode 100644
index c7001b9..0000000
--- a/src/main/java/com/teragrep/net_01/channel/buffer/BufferLeaseImpl.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Java Zero Copy Networking Library net_01
- * Copyright (C) 2024 Suomen Kanuuna Oy
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *
- *
- * Additional permission under GNU Affero General Public License version 3
- * section 7
- *
- * If you modify this Program, or any covered work, by linking or combining it
- * with other code, such other code is not for that reason alone subject to any
- * of the requirements of the GNU Affero GPL version 3 as long as this Program
- * is the same Program as licensed from Suomen Kanuuna Oy without any additional
- * modifications.
- *
- * Supplemented terms under GNU Affero General Public License version 3
- * section 7
- *
- * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
- * versions must be marked as "Modified version of" The Program.
- *
- * Names of the licensors and authors may not be used for publicity purposes.
- *
- * No rights are granted for use of trade names, trademarks, or service marks
- * which are in The Program if any.
- *
- * Licensee must indemnify licensors and authors for any liability that these
- * contractual assumptions impose on licensors and authors.
- *
- * To the extent this program is licensed as part of the Commercial versions of
- * Teragrep, the applicable Commercial License may apply to this file if you as
- * a licensee so wish it.
- */
-package com.teragrep.net_01.channel.buffer;
-
-import java.nio.ByteBuffer;
-import java.util.concurrent.Phaser;
-
-/**
- * Decorator for {@link BufferContainer} that automatically clears (frees) the encapsulated {@link ByteBuffer} and
- * returns the {@link BufferContainer} to {@link BufferLeasePool} when reference count hits zero. Starts with one
- * initial reference. Internally uses a {@link Phaser} to track reference count in a non-blocking way.
- */
-final class BufferLeaseImpl implements BufferLease {
-
- private final BufferContainer bufferContainer;
- private final Phaser phaser;
- private final BufferLeasePool bufferLeasePool;
-
- BufferLeaseImpl(BufferContainer bc, BufferLeasePool bufferLeasePool) {
- this.bufferContainer = bc;
- this.bufferLeasePool = bufferLeasePool;
-
- // initial registered parties set to 1
- this.phaser = new ClearingPhaser(1);
- }
-
- @Override
- public long id() {
- return bufferContainer.id();
- }
-
- @Override
- public long refs() {
- // initial number of registered parties is 1
- return phaser.getRegisteredParties();
- }
-
- @Override
- public ByteBuffer buffer() {
- if (phaser.isTerminated()) {
- throw new IllegalStateException(
- "Cannot return wrapped ByteBuffer, BufferLease phaser was already terminated!"
- );
- }
- return bufferContainer.buffer();
- }
-
- @Override
- public void addRef() {
- if (phaser.register() < 0) {
- throw new IllegalStateException("Cannot add reference, BufferLease phaser was already terminated!");
- }
- }
-
- @Override
- public void removeRef() {
- if (phaser.arriveAndDeregister() < 0) {
- throw new IllegalStateException("Cannot remove reference, BufferLease phaser was already terminated!");
- }
- }
-
- @Override
- public boolean isTerminated() {
- return phaser.isTerminated();
- }
-
- @Override
- public boolean isStub() {
- return bufferContainer.isStub();
- }
-
- /**
- * Phaser that clears the buffer on termination (registeredParties=0)
- */
- private class ClearingPhaser extends Phaser {
-
- public ClearingPhaser(int i) {
- super(i);
- }
-
- @Override
- protected boolean onAdvance(int phase, int registeredParties) {
- boolean rv = false;
- if (registeredParties == 0) {
- buffer().clear();
- bufferLeasePool.internalOffer(bufferContainer);
- rv = true;
- }
- return rv;
- }
- }
-
-}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/BufferLeasePool.java b/src/main/java/com/teragrep/net_01/channel/buffer/BufferLeasePool.java
deleted file mode 100644
index db1c66c..0000000
--- a/src/main/java/com/teragrep/net_01/channel/buffer/BufferLeasePool.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Java Zero Copy Networking Library net_01
- * Copyright (C) 2024 Suomen Kanuuna Oy
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *
- *
- * Additional permission under GNU Affero General Public License version 3
- * section 7
- *
- * If you modify this Program, or any covered work, by linking or combining it
- * with other code, such other code is not for that reason alone subject to any
- * of the requirements of the GNU Affero GPL version 3 as long as this Program
- * is the same Program as licensed from Suomen Kanuuna Oy without any additional
- * modifications.
- *
- * Supplemented terms under GNU Affero General Public License version 3
- * section 7
- *
- * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
- * versions must be marked as "Modified version of" The Program.
- *
- * Names of the licensors and authors may not be used for publicity purposes.
- *
- * No rights are granted for use of trade names, trademarks, or service marks
- * which are in The Program if any.
- *
- * Licensee must indemnify licensors and authors for any liability that these
- * contractual assumptions impose on licensors and authors.
- *
- * To the extent this program is licensed as part of the Commercial versions of
- * Teragrep, the applicable Commercial License may apply to this file if you as
- * a licensee so wish it.
- */
-package com.teragrep.net_01.channel.buffer;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.nio.ByteBuffer;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.function.Supplier;
-
-/**
- * Non-blocking pool for {@link BufferContainer} objects. All objects in the pool are {@link ByteBuffer#clear()}ed
- * before returning to the pool by {@link BufferLease}.
- */
-public final class BufferLeasePool {
- // TODO create tests
-
- private static final Logger LOGGER = LoggerFactory.getLogger(BufferLeasePool.class);
-
- private final Supplier byteBufferSupplier;
-
- private final ConcurrentLinkedQueue queue;
-
- private final BufferLease bufferLeaseStub;
- private final BufferContainer bufferContainerStub;
- private final AtomicBoolean close;
-
- private final int segmentSize;
-
- private final AtomicLong bufferId;
-
- private final Lock lock;
-
- // TODO check locking pattern, addRef in BufferLease can escape offer's check and cause dirty in pool?
- public BufferLeasePool() {
- this.segmentSize = 4096;
- this.byteBufferSupplier = () -> ByteBuffer.allocateDirect(segmentSize); // TODO configurable extents
- this.queue = new ConcurrentLinkedQueue<>();
- this.bufferLeaseStub = new BufferLeaseStub();
- this.bufferContainerStub = new BufferContainerStub();
- this.close = new AtomicBoolean();
- this.bufferId = new AtomicLong();
- this.lock = new ReentrantLock();
- }
-
- private BufferLease take() {
- // get or create
- BufferContainer bufferContainer = queue.poll();
- BufferLease bufferLease;
- if (bufferContainer == null) {
- // if queue is empty or stub object, create a new BufferContainer and BufferLease.
- bufferLease = new BufferLeaseImpl(
- new BufferContainerImpl(bufferId.incrementAndGet(), byteBufferSupplier.get()),
- this
- );
- }
- else {
- // otherwise, wrap bufferContainer with phaser decorator (bufferLease)
- bufferLease = new BufferLeaseImpl(bufferContainer, this);
- }
-
- if (LOGGER.isDebugEnabled()) {
- LOGGER
- .debug(
- "returning bufferLease id <{}> with refs <{}> at buffer position <{}>", bufferLease.id(),
- bufferLease.refs(), bufferLease.buffer().position()
- );
- }
-
- if (bufferLease.buffer().position() != 0) {
- throw new IllegalStateException("Dirty buffer in pool, terminating!");
- }
-
- return bufferLease;
-
- }
-
- /**
- * @param size minimum size of the {@link BufferLease}s requested.
- * @return list of {@link BufferLease}s meeting or exceeding the size requested.
- */
- public List take(long size) {
- if (close.get()) {
- return Collections.singletonList(bufferLeaseStub);
- }
-
- LOGGER.debug("requesting take with size <{}>", size);
- long currentSize = 0;
- List bufferLeases = new LinkedList<>();
- while (currentSize < size) {
- BufferLease bufferLease = take();
- bufferLeases.add(bufferLease);
- currentSize = currentSize + bufferLease.buffer().capacity();
-
- }
- return bufferLeases;
-
- }
-
- /**
- * return {@link BufferContainer} into the pool.
- *
- * @param bufferContainer {@link BufferContainer} from {@link BufferLease} which has been
- * {@link ByteBuffer#clear()}ed.
- */
- void internalOffer(BufferContainer bufferContainer) {
- // Add buffer back to pool if it is not a stub object
- if (!bufferContainer.isStub()) {
- queue.add(bufferContainer);
- }
-
- if (close.get()) {
- LOGGER.debug("closing in offer");
- while (!queue.isEmpty()) {
- if (lock.tryLock()) {
- queue.clear();
- lock.unlock();
- }
- else {
- break;
- }
- }
- }
- if (LOGGER.isDebugEnabled()) {
- long queueSegments = queue.size();
- long queueBytes = queueSegments * segmentSize;
- LOGGER.debug("offer complete, queueSegments <{}>, queueBytes <{}>", queueSegments, queueBytes);
- }
- }
-
- /**
- * Closes the {@link BufferLeasePool}, deallocating currently residing {@link BufferContainer}s and future ones when
- * returned.
- */
- public void close() {
- LOGGER.debug("close called");
- close.set(true);
-
- // close all that are in the pool right now
- internalOffer(bufferContainerStub);
-
- }
-
- /**
- * Estimate the pool size, due to non-blocking nature of the pool, this is only an estimate.
- *
- * @return estimate of the pool size, counting only the residing buffers.
- */
- public int estimatedSize() {
- return queue.size();
- }
-}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/BufferLeaseStub.java b/src/main/java/com/teragrep/net_01/channel/buffer/BufferLeaseStub.java
deleted file mode 100644
index ad85f04..0000000
--- a/src/main/java/com/teragrep/net_01/channel/buffer/BufferLeaseStub.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Java Zero Copy Networking Library net_01
- * Copyright (C) 2024 Suomen Kanuuna Oy
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *
- *
- * Additional permission under GNU Affero General Public License version 3
- * section 7
- *
- * If you modify this Program, or any covered work, by linking or combining it
- * with other code, such other code is not for that reason alone subject to any
- * of the requirements of the GNU Affero GPL version 3 as long as this Program
- * is the same Program as licensed from Suomen Kanuuna Oy without any additional
- * modifications.
- *
- * Supplemented terms under GNU Affero General Public License version 3
- * section 7
- *
- * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
- * versions must be marked as "Modified version of" The Program.
- *
- * Names of the licensors and authors may not be used for publicity purposes.
- *
- * No rights are granted for use of trade names, trademarks, or service marks
- * which are in The Program if any.
- *
- * Licensee must indemnify licensors and authors for any liability that these
- * contractual assumptions impose on licensors and authors.
- *
- * To the extent this program is licensed as part of the Commercial versions of
- * Teragrep, the applicable Commercial License may apply to this file if you as
- * a licensee so wish it.
- */
-package com.teragrep.net_01.channel.buffer;
-
-import java.nio.ByteBuffer;
-
-/**
- * Stub implementation of the {@link BufferLease}
- */
-final class BufferLeaseStub implements BufferLease {
-
- BufferLeaseStub() {
-
- }
-
- @Override
- public long id() {
- throw new IllegalStateException("BufferLeaseStub does not have an id!");
- }
-
- @Override
- public long refs() {
- throw new IllegalStateException("BufferLeaseStub does not have refs!");
- }
-
- @Override
- public ByteBuffer buffer() {
- throw new IllegalStateException("BufferLeaseStub does not have a buffer!");
- }
-
- @Override
- public void addRef() {
- throw new IllegalStateException("BufferLeaseStub does not allow adding refs!");
- }
-
- @Override
- public void removeRef() {
- throw new IllegalStateException("BufferLeaseStub does not allow removing refs!");
- }
-
- @Override
- public boolean isTerminated() {
- throw new IllegalStateException("BufferLeaseStub does not have ref count!");
- }
-
- @Override
- public boolean isStub() {
- return true;
- }
-}
diff --git a/src/test/java/com/teragrep/net_01/channel/context/buffer/BufferLeasePoolTest.java b/src/test/java/com/teragrep/net_01/channel/context/buffer/BufferLeasePoolTest.java
deleted file mode 100644
index 5dbaea3..0000000
--- a/src/test/java/com/teragrep/net_01/channel/context/buffer/BufferLeasePoolTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Java Zero Copy Networking Library net_01
- * Copyright (C) 2024 Suomen Kanuuna Oy
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *
- *
- * Additional permission under GNU Affero General Public License version 3
- * section 7
- *
- * If you modify this Program, or any covered work, by linking or combining it
- * with other code, such other code is not for that reason alone subject to any
- * of the requirements of the GNU Affero GPL version 3 as long as this Program
- * is the same Program as licensed from Suomen Kanuuna Oy without any additional
- * modifications.
- *
- * Supplemented terms under GNU Affero General Public License version 3
- * section 7
- *
- * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
- * versions must be marked as "Modified version of" The Program.
- *
- * Names of the licensors and authors may not be used for publicity purposes.
- *
- * No rights are granted for use of trade names, trademarks, or service marks
- * which are in The Program if any.
- *
- * Licensee must indemnify licensors and authors for any liability that these
- * contractual assumptions impose on licensors and authors.
- *
- * To the extent this program is licensed as part of the Commercial versions of
- * Teragrep, the applicable Commercial License may apply to this file if you as
- * a licensee so wish it.
- */
-package com.teragrep.net_01.channel.context.buffer;
-
-import com.teragrep.net_01.channel.buffer.BufferLease;
-import com.teragrep.net_01.channel.buffer.BufferLeasePool;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-public class BufferLeasePoolTest {
-
- @Test
- public void testPool() {
- BufferLeasePool bufferLeasePool = new BufferLeasePool();
- List leases = bufferLeasePool.take(1);
-
- Assertions.assertEquals(1, leases.size());
-
- Assertions.assertEquals(0, bufferLeasePool.estimatedSize()); // none in the pool
-
- BufferLease lease = leases.get(0);
-
- Assertions.assertFalse(lease.isStub());
-
- Assertions.assertFalse(lease.isTerminated()); // initially 1 refs
-
- Assertions.assertEquals(1, lease.refs()); // check initial 1 ref
-
- lease.addRef();
-
- Assertions.assertEquals(2, lease.refs());
-
- lease.buffer().put((byte) 'x');
-
- Assertions.assertEquals(1, lease.buffer().position());
-
- lease.buffer().flip();
-
- Assertions.assertEquals(0, lease.buffer().position());
-
- Assertions.assertEquals(1, lease.buffer().limit());
-
- Assertions.assertEquals((byte) 'x', lease.buffer().get());
-
- Assertions.assertEquals(1, lease.buffer().position());
-
- Assertions.assertEquals(2, lease.refs());
-
- lease.removeRef();
-
- Assertions.assertFalse(lease.isTerminated()); // initial ref must be still in place
-
- Assertions.assertEquals(1, lease.refs()); // initial ref must be still in
-
- ByteBuffer buffer = lease.buffer(); // get a hold of a reference
-
- lease.removeRef(); // removes initial ref
-
- Assertions.assertEquals(1, bufferLeasePool.estimatedSize()); // the one offered must be there
-
- Assertions.assertTrue(lease.isTerminated()); // no refs
-
- Assertions.assertThrows(IllegalStateException.class, lease::buffer);
-
- Assertions.assertEquals(buffer.capacity(), buffer.limit());
-
- Assertions.assertEquals(0, buffer.position());
-
- bufferLeasePool.close();
-
- Assertions.assertEquals(0, bufferLeasePool.estimatedSize());
- }
-}
From d9b62d76aad81f0e25edf7b1b947dc8566279f7a Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Thu, 19 Mar 2026 10:24:42 +0200
Subject: [PATCH 02/45] replace with buf_01 usages
---
.../buffer/writable/WriteableLeaseful.java | 18 ++++--
.../net_01/channel/context/Clock.java | 6 +-
.../context/EstablishedContextImpl.java | 14 +++--
.../net_01/channel/context/IngressImpl.java | 59 ++++++++-----------
.../net_01/channel/socket/EncryptionInfo.java | 7 +--
.../channel/socket/EncryptionInfoStub.java | 2 +-
.../channel/socket/EncryptionInfoTLS.java | 4 +-
7 files changed, 55 insertions(+), 55 deletions(-)
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java
index 9c79a4c..bc8c201 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java
@@ -45,10 +45,13 @@
*/
package com.teragrep.net_01.channel.buffer.writable;
-import com.teragrep.net_01.channel.buffer.BufferLease;
+import com.teragrep.buf_01.buffer.lease.OpenableLease;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.lang.foreign.MemorySegment;
import java.nio.ByteBuffer;
import java.util.List;
@@ -57,9 +60,9 @@ public final class WriteableLeaseful implements Writeable {
private static final Logger LOGGER = LoggerFactory.getLogger(WriteableLeaseful.class);
private final Writeable writeable;
- private final List leases;
+ private final List> leases;
- public WriteableLeaseful(Writeable writeable, List leases) {
+ public WriteableLeaseful(Writeable writeable, List> leases) {
this.writeable = writeable;
this.leases = leases;
}
@@ -83,11 +86,16 @@ public boolean isStub() {
public void close() {
writeable.close();
// TODO subleases for fragments
- for (BufferLease bufferLease : leases) {
+ for (OpenableLease bufferLease : leases) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("releasing id <{}> with refs <{}>", bufferLease.id(), bufferLease.refs());
}
- bufferLease.removeRef();
+ // FIXME: bufferLease.removeRef();
+ try {
+ bufferLease.close();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
}
diff --git a/src/main/java/com/teragrep/net_01/channel/context/Clock.java b/src/main/java/com/teragrep/net_01/channel/context/Clock.java
index 36f86a6..76d1ca8 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/Clock.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/Clock.java
@@ -45,7 +45,9 @@
*/
package com.teragrep.net_01.channel.context;
-import com.teragrep.net_01.channel.buffer.BufferLease;
+import com.teragrep.buf_01.buffer.lease.Lease;
+
+import java.lang.foreign.MemorySegment;
public interface Clock extends AutoCloseable {
@@ -53,5 +55,5 @@ public interface Clock extends AutoCloseable {
* @param bufferLease to be consumed by the Clock. Clock or it's subsequent actions must close all BufferLease's it
* receives otherwise encapsulated buffers are not reusable and memory allocator consumes time.
*/
- void advance(BufferLease bufferLease);
+ void advance(Lease bufferLease);
}
diff --git a/src/main/java/com/teragrep/net_01/channel/context/EstablishedContextImpl.java b/src/main/java/com/teragrep/net_01/channel/context/EstablishedContextImpl.java
index 80202d7..fc18e1c 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/EstablishedContextImpl.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/EstablishedContextImpl.java
@@ -45,12 +45,16 @@
*/
package com.teragrep.net_01.channel.context;
+import com.teragrep.buf_01.buffer.lease.MemorySegmentLeaseStub;
+import com.teragrep.buf_01.buffer.pool.OpeningPool;
+import com.teragrep.buf_01.buffer.supply.ArenaMemorySegmentLeaseSupplier;
import com.teragrep.net_01.channel.socket.Socket;
-import com.teragrep.net_01.channel.buffer.BufferLeasePool;
+import com.teragrep.poj_01.pool.UnboundPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
+import java.lang.foreign.Arena;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.SelectionKey;
import java.nio.channels.spi.AbstractSelectableChannel;
@@ -71,7 +75,7 @@ final class EstablishedContextImpl implements EstablishedContext {
private final Socket socket;
private final InterestOps interestOps;
- private final BufferLeasePool bufferLeasePool;
+ private final OpeningPool memorySegmentLeasePool;
private final Ingress ingress;
private final Egress egress;
@@ -80,8 +84,8 @@ final class EstablishedContextImpl implements EstablishedContext {
this.executorService = executorService;
this.socket = socket;
- this.bufferLeasePool = new BufferLeasePool();
- this.ingress = new IngressImpl(this, this.bufferLeasePool);
+ this.memorySegmentLeasePool = new OpeningPool(new UnboundPool<>(new ArenaMemorySegmentLeaseSupplier(Arena.ofShared(), 4096), new MemorySegmentLeaseStub()));
+ this.ingress = new IngressImpl(this, this.memorySegmentLeasePool);
this.egress = new EgressImpl(this);
}
@@ -111,7 +115,7 @@ public void close() {
LOGGER.warn("IOException <{}> in close", ioe.getMessage());
}
- bufferLeasePool.close();
+ memorySegmentLeasePool.close();
}
@Override
diff --git a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
index 534c913..4feb360 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
@@ -45,14 +45,17 @@
*/
package com.teragrep.net_01.channel.context;
-import com.teragrep.net_01.channel.buffer.BufferLease;
-import com.teragrep.net_01.channel.buffer.BufferLeasePool;
+import com.teragrep.buf_01.buffer.lease.OpenableLease;
+import com.teragrep.buf_01.buffer.pool.LeaseMultiGet;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.poj_01.pool.Pool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tlschannel.NeedsReadException;
import tlschannel.NeedsWriteException;
import java.io.IOException;
+import java.lang.foreign.MemorySegment;
import java.nio.ByteBuffer;
import java.nio.channels.CancelledKeyException;
import java.util.LinkedList;
@@ -68,18 +71,18 @@ final class IngressImpl implements Ingress {
private static final Logger LOGGER = LoggerFactory.getLogger(IngressImpl.class);
private final EstablishedContextImpl establishedContext;
- private final BufferLeasePool bufferLeasePool;
+ private final Pool> memorySegmentLeasePool;
- private final LinkedList activeBuffers;
+ private final LinkedList activeBuffers;
private final Lock lock;
// tls
public final AtomicBoolean needWrite;
private final List interestedClocks;
- IngressImpl(EstablishedContextImpl establishedContext, BufferLeasePool bufferLeasePool) {
+ IngressImpl(EstablishedContextImpl establishedContext, Pool> memorySegmentLeasePool) {
this.establishedContext = establishedContext;
- this.bufferLeasePool = bufferLeasePool;
+ this.memorySegmentLeasePool = memorySegmentLeasePool;
this.activeBuffers = new LinkedList<>();
this.lock = new ReentrantLock();
@@ -109,8 +112,7 @@ public void run() {
boolean continueReading = true;
while (!activeBuffers.isEmpty()) {
// IMPORTANT: current tls implementation will skip bytes if BufferLeases are not fully consumed.
- BufferLease bufferLease = activeBuffers.removeFirst();
- bufferLease.addRef();
+ TrackedMemorySegmentLease bufferLease = activeBuffers.removeFirst();
LOGGER
.debug(
"submitting buffer <{}> from activeBuffers <{}> to relpFrame", bufferLease,
@@ -120,12 +122,6 @@ public void run() {
if (!interestedClocks.isEmpty()) {
for (Clock clock : interestedClocks) {
clock.advance(bufferLease);
-
- if (bufferLease.buffer().hasRemaining()) {
- // shared buffer between clocks, ready for another
- bufferLease.addRef();
- }
-
}
}
@@ -134,19 +130,19 @@ public void run() {
}
LOGGER.debug("clock returned continueReading <{}>", continueReading);
- if (bufferLease.buffer().hasRemaining()) {
+
+ if (bufferLease.hasNext()) {
// return back as it has some remaining
LOGGER.debug("pushBack bufferLease id <{}>", bufferLease.id());
activeBuffers.push(bufferLease);
if (LOGGER.isDebugEnabled()) {
LOGGER
.debug(
- "buffer.buffer <{}>, buffer.buffer().hasRemaining() <{}> returned it to activeBuffers <{}>",
- bufferLease.buffer(), bufferLease.buffer().hasRemaining(), activeBuffers
+ "buffer.leasedObject <{}>, buffer.hasNext <{}> returned it to activeBuffers <{}>",
+ bufferLease.leasedObject(), bufferLease.hasNext(), activeBuffers
);
}
}
- bufferLease.removeRef();
if (!continueReading) {
break;
}
@@ -230,41 +226,32 @@ else if (readBytes < 0) {
}
private long readData() throws IOException {
- long readBytes = 0;
+ long readBytes;
- List bufferLeases = bufferLeasePool.take(4);
+ List> bufferLeases = new LeaseMultiGet(memorySegmentLeasePool).get(4);
List byteBufferList = new LinkedList<>();
- for (BufferLease bufferLease : bufferLeases) {
+ for (OpenableLease bufferLease : bufferLeases) {
if (bufferLease.isStub()) {
continue;
}
- byteBufferList.add(bufferLease.buffer());
+ byteBufferList.add(bufferLease.leasedObject().asByteBuffer());
}
ByteBuffer[] byteBufferArray = byteBufferList.toArray(new ByteBuffer[0]);
readBytes = establishedContext.socket().read(byteBufferArray);
+ // TODO: Figure out a way to see which buffers were written into.
+ // Right now, buffers that are not written into are pushed into activeBuffers.
- activateBuffers(bufferLeases);
+ for (final OpenableLease bufferLease : bufferLeases) {
+ activeBuffers.push(new TrackedMemorySegmentLease(bufferLease));
+ }
LOGGER.debug("establishedContext.read got <{}> bytes from socket", readBytes);
return readBytes;
}
- private void activateBuffers(List bufferLeases) {
- for (BufferLease bufferLease : bufferLeases) {
- if (bufferLease.buffer().position() != 0) {
- bufferLease.buffer().flip();
- activeBuffers.add(bufferLease);
- }
- else {
- // unused buffer, releasing back to pool
- bufferLease.removeRef();
- }
- }
- }
-
public AtomicBoolean needWrite() {
return needWrite;
}
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfo.java b/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfo.java
index 52561e9..ad0621a 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfo.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfo.java
@@ -47,7 +47,6 @@
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
-import javax.security.cert.X509Certificate;
import java.security.Principal;
import java.security.cert.Certificate;
@@ -86,11 +85,11 @@ public interface EncryptionInfo {
/**
* throws IllegalStateException if isEncrypted returns false
- *
- * @return see {@link SSLSession#getPeerCertificateChain()}
+ *
+ * @return see {@link SSLSession#getPeerCertificates()}
* @throws SSLPeerUnverifiedException
*/
- X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException;
+ Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException;
/**
* throws IllegalStateException if isEncrypted returns false
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoStub.java b/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoStub.java
index d7d32cf..9e059d4 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoStub.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoStub.java
@@ -80,7 +80,7 @@ public Principal getLocalPrincipal() {
}
@Override
- public X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException {
+ public Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException {
throw new IllegalStateException("not encrypted");
}
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoTLS.java b/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoTLS.java
index 0e7c791..1517e07 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoTLS.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoTLS.java
@@ -81,8 +81,8 @@ public Principal getLocalPrincipal() {
}
@Override
- public X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException {
- return tlsChannel.getSslEngine().getSession().getPeerCertificateChain();
+ public Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException {
+ return tlsChannel.getSslEngine().getSession().getPeerCertificates();
}
@Override
From 23c699ed4b08844d371cd596cd54f4e3c84a8d06 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Thu, 19 Mar 2026 10:24:54 +0200
Subject: [PATCH 03/45] introduce TrackedMemorySegmentLease
---
.../buffer/TrackedMemorySegmentLease.java | 76 +++++++++++++++++++
.../buffer/TrackedMemorySegmentLeaseTest.java | 36 +++++++++
2 files changed, 112 insertions(+)
create mode 100644 src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
create mode 100644 src/test/java/com/teragrep/net_01/channel/context/buffer/TrackedMemorySegmentLeaseTest.java
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
new file mode 100644
index 0000000..b66d9fb
--- /dev/null
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
@@ -0,0 +1,76 @@
+package com.teragrep.net_01.channel.buffer;
+
+import com.teragrep.buf_01.buffer.lease.Lease;
+
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.ValueLayout;
+import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class TrackedMemorySegmentLease implements Lease, Iterator {
+ private final Lease origin;
+ private final AtomicLong currentOffset;
+
+ public TrackedMemorySegmentLease(final Lease origin) {
+ this(origin, new AtomicLong(0L));
+ }
+
+ public TrackedMemorySegmentLease(final Lease origin, final AtomicLong currentOffset) {
+ this.origin = origin;
+ this.currentOffset = currentOffset;
+ }
+
+ @Override
+ public long id() {
+ return origin.id();
+ }
+
+ @Override
+ public long refs() {
+ return origin.refs();
+ }
+
+ @Override
+ public MemorySegment leasedObject() {
+ return origin.leasedObject();
+ }
+
+ @Override
+ public boolean hasZeroRefs() {
+ return origin.hasZeroRefs();
+ }
+
+ @Override
+ public Lease sliceAt(final long offset) {
+ return origin.sliceAt(offset);
+ }
+
+ @Override
+ public boolean isStub() {
+ return origin.isStub();
+ }
+
+ @Override
+ public void close() throws Exception {
+ origin.close();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return currentOffset.get() < origin.leasedObject().byteSize();
+ }
+
+ @Override
+ public Byte next() {
+ if (!hasNext()) {
+ throw new IndexOutOfBoundsException("Reached end of segment, cannot provide next byte");
+ }
+ final long nextIndex = currentOffset.getAndIncrement();
+
+ return origin.leasedObject().get(ValueLayout.JAVA_BYTE, nextIndex);
+ }
+
+ public long position() {
+ return currentOffset.get();
+ }
+}
diff --git a/src/test/java/com/teragrep/net_01/channel/context/buffer/TrackedMemorySegmentLeaseTest.java b/src/test/java/com/teragrep/net_01/channel/context/buffer/TrackedMemorySegmentLeaseTest.java
new file mode 100644
index 0000000..5aa6c73
--- /dev/null
+++ b/src/test/java/com/teragrep/net_01/channel/context/buffer/TrackedMemorySegmentLeaseTest.java
@@ -0,0 +1,36 @@
+package com.teragrep.net_01.channel.context.buffer;
+
+import com.teragrep.buf_01.buffer.lease.MemorySegmentLeaseStub;
+import com.teragrep.buf_01.buffer.pool.OpeningPool;
+import com.teragrep.buf_01.buffer.supply.ArenaMemorySegmentLeaseSupplier;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.poj_01.pool.UnboundPool;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.lang.foreign.Arena;
+
+public final class TrackedMemorySegmentLeaseTest
+{
+ @Test
+ void testProgressing() {
+ final OpeningPool pool = new OpeningPool(new UnboundPool<>(new ArenaMemorySegmentLeaseSupplier(Arena.ofShared(), 5), new MemorySegmentLeaseStub()));
+ final TrackedMemorySegmentLease trackedLease = new TrackedMemorySegmentLease(pool.get());
+
+ Assertions.assertEquals(0L, trackedLease.position());
+
+ int loops = 0;
+ for (int i = 0; i < 5; i++) {
+ Assertions.assertEquals(i, trackedLease.position());
+ Assertions.assertTrue(trackedLease.hasNext());
+ Assertions.assertEquals((byte)0, trackedLease.next());
+ loops++;
+ }
+ Assertions.assertEquals(5, loops);
+
+ Assertions.assertFalse(trackedLease.hasNext());
+ Assertions.assertThrows(IndexOutOfBoundsException.class, trackedLease::next);
+ Assertions.assertEquals(5L, trackedLease.position());
+ }
+}
+
From dca39ce6dc711ec278a6c4a0dfb3ebe596f98954 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Thu, 19 Mar 2026 10:39:34 +0200
Subject: [PATCH 04/45] pom.xml: JDK25 & poj_01, buf_01 dependencies
---
pom.xml | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/pom.xml b/pom.xml
index 8aae18c..8af5ea9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,17 +29,29 @@
-SNAPSHOT
- 1.8
+ 251.10.25.10.2
- 1.8
- 1.8
+ 25
+ 25UTF-8UTF-80.0.1
+ 1.0.0
+ 3.0.0
+
+ com.teragrep
+ buf_01
+ ${teragrep.buf_01.version}
+
+
+ com.teragrep
+ poj_01
+ ${teragrep.poj_01.version}
+ org.slf4j
@@ -104,7 +116,7 @@
3.2.5
- 1.8
+ 25
@@ -253,7 +265,7 @@
jar
- 8
+ 25
From 20cdb0bffdd9769f28a8aefd6abdfcc6969d9e30 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Fri, 27 Mar 2026 10:46:41 +0200
Subject: [PATCH 05/45] serverTest & ingressimpl in progress
---
.../net_01/channel/context/Clock.java | 3 +-
.../net_01/channel/context/IngressImpl.java | 37 +++++++---
.../net_01/channel/context/ListenContext.java | 1 +
.../teragrep/net_01/eventloop/EventLoop.java | 11 ++-
.../teragrep/net_01/server/ServerFactory.java | 4 +-
.../channel/context/ClockFactoryFake.java | 18 +++++
.../net_01/channel/context/ClockFake.java | 41 +++++++++++
.../net_01/channel/server/ServerTest.java | 73 +++++++++++++++++++
8 files changed, 172 insertions(+), 16 deletions(-)
create mode 100644 src/test/java/com/teragrep/net_01/channel/context/ClockFactoryFake.java
create mode 100644 src/test/java/com/teragrep/net_01/channel/context/ClockFake.java
create mode 100644 src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
diff --git a/src/main/java/com/teragrep/net_01/channel/context/Clock.java b/src/main/java/com/teragrep/net_01/channel/context/Clock.java
index 76d1ca8..710c97a 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/Clock.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/Clock.java
@@ -46,6 +46,7 @@
package com.teragrep.net_01.channel.context;
import com.teragrep.buf_01.buffer.lease.Lease;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
import java.lang.foreign.MemorySegment;
@@ -55,5 +56,5 @@ public interface Clock extends AutoCloseable {
* @param bufferLease to be consumed by the Clock. Clock or it's subsequent actions must close all BufferLease's it
* receives otherwise encapsulated buffers are not reusable and memory allocator consumes time.
*/
- void advance(Lease bufferLease);
+ void advance(TrackedMemorySegmentLease bufferLease);
}
diff --git a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
index 4feb360..3dc7a03 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
@@ -45,6 +45,7 @@
*/
package com.teragrep.net_01.channel.context;
+import com.teragrep.buf_01.buffer.lease.MemorySegmentLease;
import com.teragrep.buf_01.buffer.lease.OpenableLease;
import com.teragrep.buf_01.buffer.pool.LeaseMultiGet;
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
@@ -58,9 +59,12 @@
import java.lang.foreign.MemorySegment;
import java.nio.ByteBuffer;
import java.nio.channels.CancelledKeyException;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -73,7 +77,7 @@ final class IngressImpl implements Ingress {
private final EstablishedContextImpl establishedContext;
private final Pool> memorySegmentLeasePool;
- private final LinkedList activeBuffers;
+ private final List activeBuffers;
private final Lock lock;
// tls
public final AtomicBoolean needWrite;
@@ -84,11 +88,11 @@ final class IngressImpl implements Ingress {
this.establishedContext = establishedContext;
this.memorySegmentLeasePool = memorySegmentLeasePool;
- this.activeBuffers = new LinkedList<>();
+ this.activeBuffers = Collections.synchronizedList(new LinkedList<>());
this.lock = new ReentrantLock();
this.needWrite = new AtomicBoolean();
- this.interestedClocks = new LinkedList<>();
+ this.interestedClocks = Collections.synchronizedList(new LinkedList<>());
}
@Override
@@ -106,10 +110,12 @@ public void run() {
long readBytes = readData();
if (!isDataAvailable(readBytes)) {
+ System.out.println("No data available");
break;
}
boolean continueReading = true;
+ System.out.println("activeBuffers.isEmpty=" + activeBuffers.isEmpty());
while (!activeBuffers.isEmpty()) {
// IMPORTANT: current tls implementation will skip bytes if BufferLeases are not fully consumed.
TrackedMemorySegmentLease bufferLease = activeBuffers.removeFirst();
@@ -133,8 +139,9 @@ public void run() {
if (bufferLease.hasNext()) {
// return back as it has some remaining
+ System.out.println("something remaining");
LOGGER.debug("pushBack bufferLease id <{}>", bufferLease.id());
- activeBuffers.push(bufferLease);
+ activeBuffers.add(bufferLease);
if (LOGGER.isDebugEnabled()) {
LOGGER
.debug(
@@ -240,12 +247,24 @@ private long readData() throws IOException {
ByteBuffer[] byteBufferArray = byteBufferList.toArray(new ByteBuffer[0]);
readBytes = establishedContext.socket().read(byteBufferArray);
- // TODO: Figure out a way to see which buffers were written into.
- // Right now, buffers that are not written into are pushed into activeBuffers.
+ System.out.println("readBytes = " + readBytes);
+ long bytesLeft = readBytes;
+ boolean allRead = false;
+ for (final OpenableLease bufferLease : bufferLeases) {
+ final long byteSize = bufferLease.leasedObject().byteSize();
- for (final OpenableLease bufferLease : bufferLeases) {
- activeBuffers.push(new TrackedMemorySegmentLease(bufferLease));
- }
+ if (!allRead) {
+ activeBuffers.add(new TrackedMemorySegmentLease(bufferLease, new AtomicLong(Math.min(bytesLeft, byteSize))));
+ }
+
+ bytesLeft -= byteSize;
+
+ if (bytesLeft <= 0) {
+ allRead = true;
+ }
+ }
+
+ System.out.println("buffers.size=" + activeBuffers.size());
LOGGER.debug("establishedContext.read got <{}> bytes from socket", readBytes);
diff --git a/src/main/java/com/teragrep/net_01/channel/context/ListenContext.java b/src/main/java/com/teragrep/net_01/channel/context/ListenContext.java
index 50c020e..6a018cb 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/ListenContext.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/ListenContext.java
@@ -85,6 +85,7 @@ public final class ListenContext implements Context {
@Override
public void handleEvent(SelectionKey selectionKey) {
+ System.out.println("handling event: " + selectionKey);
try {
if (selectionKey.isAcceptable()) {
// create the client socket for a newly received connection
diff --git a/src/main/java/com/teragrep/net_01/eventloop/EventLoop.java b/src/main/java/com/teragrep/net_01/eventloop/EventLoop.java
index 988cb3d..1f58e6b 100644
--- a/src/main/java/com/teragrep/net_01/eventloop/EventLoop.java
+++ b/src/main/java/com/teragrep/net_01/eventloop/EventLoop.java
@@ -87,11 +87,13 @@ public final class EventLoop implements AutoCloseable, Runnable {
* @param context to register
*/
public void register(Context context) {
+ LOGGER.info("EventLoop.Register: {}", context);
pendingContextRegistrations.add(context);
wakeup();
}
private void registerPendingRegistrations() {
+ LOGGER.info("register pending regs");
while (true) {
Context context = pendingContextRegistrations.poll();
if (context != null) {
@@ -120,10 +122,10 @@ public void poll() throws IOException {
registerPendingRegistrations();
- LOGGER.debug("readyKeys <{}>", readyKeys);
+ LOGGER.info("readyKeys <{}>", readyKeys);
Set selectionKeys = selector.selectedKeys();
- LOGGER.debug("selectionKeys <{}> ", selectionKeys);
+ LOGGER.info("selectionKeys <{}> ", selectionKeys);
for (SelectionKey selectionKey : selectionKeys) {
try {
if (LOGGER.isDebugEnabled()) {
@@ -193,8 +195,9 @@ public void wakeup() {
@Override
public void run() {
try {
- LOGGER.debug("Started");
+ LOGGER.info("Started");
while (!stop.get()) {
+ System.out.println("polling " + Thread.currentThread().getName());
poll();
}
}
@@ -204,7 +207,7 @@ public void run() {
finally {
close();
}
- LOGGER.debug("Stopped");
+ LOGGER.info("Stopped");
}
public void stop() {
diff --git a/src/main/java/com/teragrep/net_01/server/ServerFactory.java b/src/main/java/com/teragrep/net_01/server/ServerFactory.java
index 74e7672..5f5cabb 100644
--- a/src/main/java/com/teragrep/net_01/server/ServerFactory.java
+++ b/src/main/java/com/teragrep/net_01/server/ServerFactory.java
@@ -98,9 +98,9 @@ public Server create(int port) throws IOException {
);
ListenContext listenContext = listenContextFactory.open(new InetSocketAddress(port));
- LOGGER.debug("registering to eventLoop <{}>", eventLoop);
+ LOGGER.info("registering to eventLoop <{}>", eventLoop);
eventLoop.register(listenContext);
- LOGGER.debug("registered to eventLoop <{}>", eventLoop);
+ LOGGER.info("registered to eventLoop <{}>", eventLoop);
return new Server(listenContext);
}
}
diff --git a/src/test/java/com/teragrep/net_01/channel/context/ClockFactoryFake.java b/src/test/java/com/teragrep/net_01/channel/context/ClockFactoryFake.java
new file mode 100644
index 0000000..cdd6426
--- /dev/null
+++ b/src/test/java/com/teragrep/net_01/channel/context/ClockFactoryFake.java
@@ -0,0 +1,18 @@
+package com.teragrep.net_01.channel.context;
+
+import java.util.List;
+import java.util.function.Consumer;
+
+public final class ClockFactoryFake implements ClockFactory{
+
+ private final Consumer> messageConsumer;
+
+ public ClockFactoryFake(Consumer> messageConsumer){
+ this.messageConsumer = messageConsumer;
+ }
+
+ @Override
+ public Clock create(final EstablishedContext establishedContext) {
+ return new ClockFake(establishedContext, messageConsumer);
+ }
+}
diff --git a/src/test/java/com/teragrep/net_01/channel/context/ClockFake.java b/src/test/java/com/teragrep/net_01/channel/context/ClockFake.java
new file mode 100644
index 0000000..bbcc884
--- /dev/null
+++ b/src/test/java/com/teragrep/net_01/channel/context/ClockFake.java
@@ -0,0 +1,41 @@
+package com.teragrep.net_01.channel.context;
+
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+
+import java.lang.foreign.ValueLayout;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+public final class ClockFake implements Clock {
+ private final EstablishedContext ctx;
+ private final Consumer> messageConsumer;
+
+ public ClockFake(final EstablishedContext ctx, final Consumer> messageConsumer) {
+ this.ctx = ctx;
+ this.messageConsumer = messageConsumer;
+ }
+
+ @Override
+ public void advance(TrackedMemorySegmentLease lease) {
+ System.out.println("advancing clock @" + Thread.currentThread().getName());
+ System.out.println("pos=" + lease.position());
+
+ System.out.println(lease.leasedObject().get(ValueLayout.JAVA_BYTE, 0));
+
+ final List bytes = new ArrayList<>();
+ while (lease.hasNext()) {
+ final byte b = lease.next();
+ if (b != 0){
+ bytes.add(b);
+ }
+ }
+
+ messageConsumer.accept(bytes);
+ }
+
+ @Override
+ public void close() throws Exception {
+ // no-op
+ }
+}
diff --git a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
new file mode 100644
index 0000000..8bd7332
--- /dev/null
+++ b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
@@ -0,0 +1,73 @@
+package com.teragrep.net_01.channel.server;
+
+import com.teragrep.net_01.channel.context.ClockFactory;
+import com.teragrep.net_01.channel.context.ClockFactoryFake;
+import com.teragrep.net_01.channel.socket.PlainFactory;
+import com.teragrep.net_01.channel.socket.Socket;
+import com.teragrep.net_01.channel.socket.SocketFactory;
+import com.teragrep.net_01.eventloop.EventLoop;
+import com.teragrep.net_01.eventloop.EventLoopFactory;
+import com.teragrep.net_01.server.Server;
+import com.teragrep.net_01.server.ServerFactory;
+import org.junit.jupiter.api.*;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Executors;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+public final class ServerTest {
+ private Server server;
+ private final List> messages = new ArrayList<>();
+ @BeforeAll
+ void beforeAll() {
+ final EventLoopFactory eventLoopFactory = new EventLoopFactory();
+ final SocketFactory socketFactory = new PlainFactory();
+ final ClockFactory clockFactory = new ClockFactoryFake(messages::add);
+
+ final EventLoop el = Assertions.assertDoesNotThrow(eventLoopFactory::create);
+
+ // eventLoopThread must run, otherwise nothing will be processed
+ final Thread elT = new Thread(el);
+ elT.start();
+
+ final ServerFactory serverFactory = new ServerFactory(el,
+ Executors.newSingleThreadExecutor(), socketFactory, clockFactory);
+
+ this.server = Assertions.assertDoesNotThrow(() -> serverFactory.create(9090));
+ }
+
+ @AfterAll
+ void afterAll() {
+ Assertions.assertDoesNotThrow(this.server::close);
+ }
+
+ @BeforeEach
+ void beforeEach() {
+ messages.clear();
+ }
+
+ @Test
+ void test() throws Exception{
+ final java.net.Socket clientSocket = Assertions.assertDoesNotThrow(() -> new java.net.Socket("localhost", 9090));
+
+ final PrintWriter out = new PrintWriter(Assertions.assertDoesNotThrow(clientSocket::getOutputStream), true);
+ final BufferedReader in = new BufferedReader(new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream)));
+
+ out.println("aaaa");
+ out.flush();
+
+ Thread.sleep(500);
+
+ Assertions.assertEquals(1, messages.size());
+ Assertions.assertEquals(List.of((byte) 'a'), messages.getFirst());
+
+ Assertions.assertDoesNotThrow(in::close);
+ Assertions.assertDoesNotThrow(out::close);
+ Assertions.assertDoesNotThrow(clientSocket::close);
+ }
+}
From fc10bd4582b66e9a2732bc6dd6348690f7631d50 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Fri, 27 Mar 2026 12:08:26 +0200
Subject: [PATCH 06/45] finally working serverTest
---
.../java/com/teragrep/net_01/channel/context/IngressImpl.java | 3 ++-
.../java/com/teragrep/net_01/channel/context/ClockFake.java | 2 --
.../java/com/teragrep/net_01/channel/server/ServerTest.java | 4 ++--
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
index 3dc7a03..481e3b0 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
@@ -254,7 +254,8 @@ private long readData() throws IOException {
final long byteSize = bufferLease.leasedObject().byteSize();
if (!allRead) {
- activeBuffers.add(new TrackedMemorySegmentLease(bufferLease, new AtomicLong(Math.min(bytesLeft, byteSize))));
+ // same as ByteBuffer.flip()
+ activeBuffers.add(new TrackedMemorySegmentLease(bufferLease));
}
bytesLeft -= byteSize;
diff --git a/src/test/java/com/teragrep/net_01/channel/context/ClockFake.java b/src/test/java/com/teragrep/net_01/channel/context/ClockFake.java
index bbcc884..43ffa61 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/ClockFake.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/ClockFake.java
@@ -21,8 +21,6 @@ public void advance(TrackedMemorySegmentLease lease) {
System.out.println("advancing clock @" + Thread.currentThread().getName());
System.out.println("pos=" + lease.position());
- System.out.println(lease.leasedObject().get(ValueLayout.JAVA_BYTE, 0));
-
final List bytes = new ArrayList<>();
while (lease.hasNext()) {
final byte b = lease.next();
diff --git a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
index 8bd7332..929da9e 100644
--- a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
@@ -18,6 +18,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicLong;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public final class ServerTest {
@@ -58,12 +59,11 @@ void test() throws Exception{
final PrintWriter out = new PrintWriter(Assertions.assertDoesNotThrow(clientSocket::getOutputStream), true);
final BufferedReader in = new BufferedReader(new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream)));
- out.println("aaaa");
+ out.print("a");
out.flush();
Thread.sleep(500);
- Assertions.assertEquals(1, messages.size());
Assertions.assertEquals(List.of((byte) 'a'), messages.getFirst());
Assertions.assertDoesNotThrow(in::close);
From 684adfa78e1c125b7f8a0e491509f686da266173 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Fri, 27 Mar 2026 12:41:01 +0200
Subject: [PATCH 07/45] replace thread.sleep with countDownLatch in ServerTest.
---
.../net_01/channel/server/ServerTest.java | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
index 929da9e..9397ab2 100644
--- a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
@@ -15,20 +15,24 @@
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
-import java.util.concurrent.atomic.AtomicLong;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public final class ServerTest {
private Server server;
+ private CountDownLatch countDownLatch;
private final List> messages = new ArrayList<>();
+
@BeforeAll
void beforeAll() {
final EventLoopFactory eventLoopFactory = new EventLoopFactory();
final SocketFactory socketFactory = new PlainFactory();
- final ClockFactory clockFactory = new ClockFactoryFake(messages::add);
+ final ClockFactory clockFactory = new ClockFactoryFake((msg -> {
+ messages.add(msg);
+ countDownLatch.countDown();
+ }));
final EventLoop el = Assertions.assertDoesNotThrow(eventLoopFactory::create);
@@ -53,7 +57,8 @@ void beforeEach() {
}
@Test
- void test() throws Exception{
+ void testReceivingOneMessage() {
+ this.countDownLatch = new CountDownLatch(1);
final java.net.Socket clientSocket = Assertions.assertDoesNotThrow(() -> new java.net.Socket("localhost", 9090));
final PrintWriter out = new PrintWriter(Assertions.assertDoesNotThrow(clientSocket::getOutputStream), true);
@@ -62,7 +67,7 @@ void test() throws Exception{
out.print("a");
out.flush();
- Thread.sleep(500);
+ Assertions.assertDoesNotThrow(() -> countDownLatch.await());
Assertions.assertEquals(List.of((byte) 'a'), messages.getFirst());
From ae3b4792bf9fe46c3171d23c4613802fe254dfe7 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Fri, 27 Mar 2026 13:20:33 +0200
Subject: [PATCH 08/45] test one and three chars
---
.../net_01/channel/server/ServerTest.java | 26 ++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
index 9397ab2..3bdb0ff 100644
--- a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
@@ -57,7 +57,7 @@ void beforeEach() {
}
@Test
- void testReceivingOneMessage() {
+ void testReceivingOneChar() {
this.countDownLatch = new CountDownLatch(1);
final java.net.Socket clientSocket = Assertions.assertDoesNotThrow(() -> new java.net.Socket("localhost", 9090));
@@ -75,4 +75,28 @@ void testReceivingOneMessage() {
Assertions.assertDoesNotThrow(out::close);
Assertions.assertDoesNotThrow(clientSocket::close);
}
+
+ @Test
+ void testReceivingThreeChars() {
+ this.countDownLatch = new CountDownLatch(1);
+ final java.net.Socket clientSocket = Assertions.assertDoesNotThrow(() -> new java.net.Socket("localhost", 9090));
+
+ final PrintWriter out = new PrintWriter(Assertions.assertDoesNotThrow(clientSocket::getOutputStream), true);
+ final BufferedReader in = new BufferedReader(new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream)));
+
+ out.print("a");
+ out.flush();
+ out.print("b");
+ out.flush();
+ out.print("c");
+ out.flush();
+
+ Assertions.assertDoesNotThrow(() -> countDownLatch.await());
+
+ Assertions.assertEquals(List.of((byte) 'a', (byte) 'b', (byte) 'c'), messages.getFirst());
+
+ Assertions.assertDoesNotThrow(in::close);
+ Assertions.assertDoesNotThrow(out::close);
+ Assertions.assertDoesNotThrow(clientSocket::close);
+ }
}
From e1d32584e861e57cbb9cc4bd8c021448c1d8ce87 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Fri, 27 Mar 2026 13:29:33 +0200
Subject: [PATCH 09/45] Change ServerTest beforeEach to afterEach as it makes
more sense.
---
.../java/com/teragrep/net_01/channel/server/ServerTest.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
index 3bdb0ff..464acfd 100644
--- a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
@@ -51,8 +51,8 @@ void afterAll() {
Assertions.assertDoesNotThrow(this.server::close);
}
- @BeforeEach
- void beforeEach() {
+ @AfterEach
+ void afterEach() {
messages.clear();
}
From ac78167c964d9bd077b75c9f819565b39d0abf46 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Fri, 27 Mar 2026 15:02:24 +0200
Subject: [PATCH 10/45] add SocketTest
---
.../net_01/channel/socket/SocketTest.java | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
create mode 100644 src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
diff --git a/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java b/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
new file mode 100644
index 0000000..81da7bb
--- /dev/null
+++ b/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
@@ -0,0 +1,31 @@
+package com.teragrep.net_01.channel.socket;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import java.net.InetSocketAddress;
+import java.nio.channels.ServerSocketChannel;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+public final class SocketTest {
+
+ @Test
+ void testPlainSocketConnection() {
+ Assertions.assertDoesNotThrow(() -> {
+ // Create ServerSocketChannel and bind it to port=9090
+ ServerSocketChannel socketCh = ServerSocketChannel.open();
+ socketCh.bind(new InetSocketAddress(9090));
+
+ // Init client
+ java.net.Socket clientSocket = new java.net.Socket("localhost", 9090);
+
+ // Init PlainSocket
+ Socket socket = new PlainSocket(socketCh.accept());
+
+ clientSocket.close();
+ socketCh.close();
+ socket.close();
+ });
+ }
+}
From a568e33d53f6130a178e555b2e47866474224a2d Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Fri, 27 Mar 2026 15:51:02 +0200
Subject: [PATCH 11/45] add SocketTest read/write test
---
.../net_01/channel/socket/SocketTest.java | 89 +++++++++++++++++++
1 file changed, 89 insertions(+)
diff --git a/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java b/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
index 81da7bb..0efb952 100644
--- a/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
@@ -4,8 +4,13 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
+import java.nio.charset.StandardCharsets;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public final class SocketTest {
@@ -28,4 +33,88 @@ void testPlainSocketConnection() {
socket.close();
});
}
+
+ @Test
+ void testPlainSocketWrite() {
+ Assertions.assertDoesNotThrow(() -> {
+ // Create ServerSocketChannel and bind it to port=9090
+ ServerSocketChannel socketCh = ServerSocketChannel.open();
+ socketCh.bind(new InetSocketAddress(9090));
+
+ // Init client
+ java.net.Socket clientSocket = new java.net.Socket("localhost", 9090);
+ final BufferedReader in = new BufferedReader(new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream)));
+
+ // Init PlainSocket
+ Socket socket = new PlainSocket(socketCh.accept());
+
+ socket.write(stringToBuffer("helloWorld\n"));
+
+ final String readLine = in.readLine();
+
+ Assertions.assertEquals("helloWorld", readLine);
+
+ clientSocket.close();
+ socketCh.close();
+ socket.close();
+ });
+ }
+
+ @Test
+ void testPlainSocketRead() {
+ Assertions.assertDoesNotThrow(() -> {
+ // Create ServerSocketChannel and bind it to port=9090
+ ServerSocketChannel socketCh = ServerSocketChannel.open();
+ socketCh.bind(new InetSocketAddress(9090));
+
+ // Init client
+ java.net.Socket clientSocket = new java.net.Socket("localhost", 9090);
+ final PrintWriter out = new PrintWriter(Assertions.assertDoesNotThrow(clientSocket::getOutputStream), true);
+
+ // Init PlainSocket
+ Socket socket = new PlainSocket(socketCh.accept());
+
+ out.println("worldHello");
+
+ ByteBuffer[] bufs = emptyBuffers(1, 10);
+ socket.read(bufs);
+
+ Assertions.assertEquals("worldHello", bufferToString(bufs));
+
+ clientSocket.close();
+ socketCh.close();
+ socket.close();
+ });
+ }
+
+ private String bufferToString(final ByteBuffer[] bufs) {
+ final StringBuilder stringBuilder = new StringBuilder();
+ for (final ByteBuffer buf : bufs) {
+ buf.flip();
+ while (buf.hasRemaining()) {
+ stringBuilder.append((char) buf.get());
+ }
+ buf.flip();
+ }
+ return stringBuilder.toString();
+ }
+
+ private ByteBuffer[] stringToBuffer(final String str) {
+ final ByteBuffer[] arr = new ByteBuffer[1];
+
+ final byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
+ arr[0] = ByteBuffer.wrap(bytes);
+
+ return arr;
+ }
+
+ private ByteBuffer[] emptyBuffers(int n, int bytesEach) {
+ final ByteBuffer[] arr = new ByteBuffer[n];
+
+ for (int i = 0; i < n; i++) {
+ arr[i] = ByteBuffer.allocate(bytesEach);
+ }
+
+ return arr;
+ }
}
From 05338dea984225fa7cbec50f015ac3932e1e9b82 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Fri, 27 Mar 2026 15:56:14 +0200
Subject: [PATCH 12/45] socketTest variables to final
---
.../teragrep/net_01/channel/socket/SocketTest.java | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java b/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
index 0efb952..5371825 100644
--- a/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
@@ -19,14 +19,14 @@ public final class SocketTest {
void testPlainSocketConnection() {
Assertions.assertDoesNotThrow(() -> {
// Create ServerSocketChannel and bind it to port=9090
- ServerSocketChannel socketCh = ServerSocketChannel.open();
+ final ServerSocketChannel socketCh = ServerSocketChannel.open();
socketCh.bind(new InetSocketAddress(9090));
// Init client
- java.net.Socket clientSocket = new java.net.Socket("localhost", 9090);
+ final java.net.Socket clientSocket = new java.net.Socket("localhost", 9090);
// Init PlainSocket
- Socket socket = new PlainSocket(socketCh.accept());
+ final Socket socket = new PlainSocket(socketCh.accept());
clientSocket.close();
socketCh.close();
@@ -38,15 +38,15 @@ void testPlainSocketConnection() {
void testPlainSocketWrite() {
Assertions.assertDoesNotThrow(() -> {
// Create ServerSocketChannel and bind it to port=9090
- ServerSocketChannel socketCh = ServerSocketChannel.open();
+ final ServerSocketChannel socketCh = ServerSocketChannel.open();
socketCh.bind(new InetSocketAddress(9090));
// Init client
- java.net.Socket clientSocket = new java.net.Socket("localhost", 9090);
+ final java.net.Socket clientSocket = new java.net.Socket("localhost", 9090);
final BufferedReader in = new BufferedReader(new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream)));
// Init PlainSocket
- Socket socket = new PlainSocket(socketCh.accept());
+ final Socket socket = new PlainSocket(socketCh.accept());
socket.write(stringToBuffer("helloWorld\n"));
From 381ad14e76e2b8f26c08f49f7dd2a749c99da02e Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Mon, 30 Mar 2026 10:51:45 +0300
Subject: [PATCH 13/45] add limit type functionality to
TrackedMemorySegmentLease and IngressImpl.
---
.../buffer/TrackedMemorySegmentLease.java | 22 +++++++++++++++++--
.../net_01/channel/context/IngressImpl.java | 14 ++++++++++--
2 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
index b66d9fb..6ab14b2 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
@@ -10,14 +10,20 @@
public class TrackedMemorySegmentLease implements Lease, Iterator {
private final Lease origin;
private final AtomicLong currentOffset;
+ private final AtomicLong limit;
public TrackedMemorySegmentLease(final Lease origin) {
this(origin, new AtomicLong(0L));
}
public TrackedMemorySegmentLease(final Lease origin, final AtomicLong currentOffset) {
+ this(origin, currentOffset, new AtomicLong(-1L));
+ }
+
+ public TrackedMemorySegmentLease(final Lease origin, final AtomicLong currentOffset, final AtomicLong limit) {
this.origin = origin;
this.currentOffset = currentOffset;
+ this.limit = limit;
}
@Override
@@ -57,13 +63,21 @@ public void close() throws Exception {
@Override
public boolean hasNext() {
- return currentOffset.get() < origin.leasedObject().byteSize();
+ final boolean rv;
+ if (limit.get() == -1) {
+ // limit not set, ignore
+ rv = currentOffset.get() < origin.leasedObject().byteSize();
+ }
+ else {
+ rv = currentOffset.get() < Math.min(limit.get(), origin.leasedObject().byteSize());
+ }
+ return rv;
}
@Override
public Byte next() {
if (!hasNext()) {
- throw new IndexOutOfBoundsException("Reached end of segment, cannot provide next byte");
+ throw new IndexOutOfBoundsException("Reached end of segment or limit, cannot provide next byte");
}
final long nextIndex = currentOffset.getAndIncrement();
@@ -73,4 +87,8 @@ public Byte next() {
public long position() {
return currentOffset.get();
}
+
+ public long limit() {
+ return limit.get();
+ }
}
diff --git a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
index 481e3b0..2786965 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
@@ -253,9 +253,19 @@ private long readData() throws IOException {
for (final OpenableLease bufferLease : bufferLeases) {
final long byteSize = bufferLease.leasedObject().byteSize();
- if (!allRead) {
+ if (!allRead && readBytes > 0) {
// same as ByteBuffer.flip()
- activeBuffers.add(new TrackedMemorySegmentLease(bufferLease));
+ final long diff = bytesLeft - byteSize;
+ if (diff < 0) {
+ // mem.segment bigger than bytes left.
+ // set limit to read amount.
+ final long limit = byteSize - Math.abs(diff);
+ activeBuffers.add(new TrackedMemorySegmentLease(bufferLease, new AtomicLong(0L), new AtomicLong(limit)));
+ }
+ else {
+ //else: full mem.segment used, no need to set limit.
+ activeBuffers.add(new TrackedMemorySegmentLease(bufferLease));
+ }
}
bytesLeft -= byteSize;
From 0eee7c705b1cab945f787dc4f5a46f8e81b345e7 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Mon, 30 Mar 2026 12:57:49 +0300
Subject: [PATCH 14/45] remove unnecessary code from
ServerTest.testReceivingOneChar
---
src/test/java/com/teragrep/net_01/channel/server/ServerTest.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
index 464acfd..26132ca 100644
--- a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
@@ -3,7 +3,6 @@
import com.teragrep.net_01.channel.context.ClockFactory;
import com.teragrep.net_01.channel.context.ClockFactoryFake;
import com.teragrep.net_01.channel.socket.PlainFactory;
-import com.teragrep.net_01.channel.socket.Socket;
import com.teragrep.net_01.channel.socket.SocketFactory;
import com.teragrep.net_01.eventloop.EventLoop;
import com.teragrep.net_01.eventloop.EventLoopFactory;
From 7fe62ca47eca266e50d0efc79c64c13f33a9e558 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Mon, 30 Mar 2026 13:23:29 +0300
Subject: [PATCH 15/45] rename Clock fakes to ConsumingClock, cleanup
---
.../{ClockFake.java => ConsumingClock.java} | 13 ++-----
...ryFake.java => ConsumingClockFactory.java} | 6 ++--
.../net_01/channel/server/ServerTest.java | 34 +++++++++++++++++--
3 files changed, 38 insertions(+), 15 deletions(-)
rename src/test/java/com/teragrep/net_01/channel/context/{ClockFake.java => ConsumingClock.java} (61%)
rename src/test/java/com/teragrep/net_01/channel/context/{ClockFactoryFake.java => ConsumingClockFactory.java} (59%)
diff --git a/src/test/java/com/teragrep/net_01/channel/context/ClockFake.java b/src/test/java/com/teragrep/net_01/channel/context/ConsumingClock.java
similarity index 61%
rename from src/test/java/com/teragrep/net_01/channel/context/ClockFake.java
rename to src/test/java/com/teragrep/net_01/channel/context/ConsumingClock.java
index 43ffa61..1bec299 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/ClockFake.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/ConsumingClock.java
@@ -2,31 +2,24 @@
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
-import java.lang.foreign.ValueLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
-public final class ClockFake implements Clock {
+public final class ConsumingClock implements Clock {
private final EstablishedContext ctx;
private final Consumer> messageConsumer;
- public ClockFake(final EstablishedContext ctx, final Consumer> messageConsumer) {
+ public ConsumingClock(final EstablishedContext ctx, final Consumer> messageConsumer) {
this.ctx = ctx;
this.messageConsumer = messageConsumer;
}
@Override
public void advance(TrackedMemorySegmentLease lease) {
- System.out.println("advancing clock @" + Thread.currentThread().getName());
- System.out.println("pos=" + lease.position());
-
final List bytes = new ArrayList<>();
while (lease.hasNext()) {
- final byte b = lease.next();
- if (b != 0){
- bytes.add(b);
- }
+ bytes.add(lease.next());
}
messageConsumer.accept(bytes);
diff --git a/src/test/java/com/teragrep/net_01/channel/context/ClockFactoryFake.java b/src/test/java/com/teragrep/net_01/channel/context/ConsumingClockFactory.java
similarity index 59%
rename from src/test/java/com/teragrep/net_01/channel/context/ClockFactoryFake.java
rename to src/test/java/com/teragrep/net_01/channel/context/ConsumingClockFactory.java
index cdd6426..0f6ae32 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/ClockFactoryFake.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/ConsumingClockFactory.java
@@ -3,16 +3,16 @@
import java.util.List;
import java.util.function.Consumer;
-public final class ClockFactoryFake implements ClockFactory{
+public final class ConsumingClockFactory implements ClockFactory {
private final Consumer> messageConsumer;
- public ClockFactoryFake(Consumer> messageConsumer){
+ public ConsumingClockFactory(Consumer> messageConsumer){
this.messageConsumer = messageConsumer;
}
@Override
public Clock create(final EstablishedContext establishedContext) {
- return new ClockFake(establishedContext, messageConsumer);
+ return new ConsumingClock(establishedContext, messageConsumer);
}
}
diff --git a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
index 26132ca..1f720fb 100644
--- a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
@@ -1,7 +1,7 @@
package com.teragrep.net_01.channel.server;
import com.teragrep.net_01.channel.context.ClockFactory;
-import com.teragrep.net_01.channel.context.ClockFactoryFake;
+import com.teragrep.net_01.channel.context.ConsumingClockFactory;
import com.teragrep.net_01.channel.socket.PlainFactory;
import com.teragrep.net_01.channel.socket.SocketFactory;
import com.teragrep.net_01.eventloop.EventLoop;
@@ -28,7 +28,7 @@ public final class ServerTest {
void beforeAll() {
final EventLoopFactory eventLoopFactory = new EventLoopFactory();
final SocketFactory socketFactory = new PlainFactory();
- final ClockFactory clockFactory = new ClockFactoryFake((msg -> {
+ final ClockFactory clockFactory = new ConsumingClockFactory((msg -> {
messages.add(msg);
countDownLatch.countDown();
}));
@@ -94,6 +94,36 @@ void testReceivingThreeChars() {
Assertions.assertEquals(List.of((byte) 'a', (byte) 'b', (byte) 'c'), messages.getFirst());
+ Assertions.assertDoesNotThrow(in::close);
+ Assertions.assertDoesNotThrow(out::close);
+ Assertions.assertDoesNotThrow(clientSocket::close);
+ }
+
+ @Test
+ void testSending() {
+ this.countDownLatch = new CountDownLatch(1);
+ final java.net.Socket clientSocket = Assertions.assertDoesNotThrow(() -> new java.net.Socket("localhost", 9090));
+
+ final PrintWriter out = new PrintWriter(Assertions.assertDoesNotThrow(clientSocket::getOutputStream), true);
+ final BufferedReader in = new BufferedReader(new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream)));
+
+ out.print("a");
+ out.flush();
+ out.print("b");
+ out.flush();
+ out.print("c");
+ out.flush();
+
+ Assertions.assertDoesNotThrow(() -> countDownLatch.await());
+
+ Assertions.assertEquals(List.of((byte) 'a', (byte) 'b', (byte) 'c'), messages.getFirst());
+
+ String x;
+ while ((x = Assertions.assertDoesNotThrow(in::readLine)) != null){
+ System.out.println("resp: " + x);
+ }
+
+
Assertions.assertDoesNotThrow(in::close);
Assertions.assertDoesNotThrow(out::close);
Assertions.assertDoesNotThrow(clientSocket::close);
From eb9e351de6f63fe116278a28aa0215bee7b95f41 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Mon, 30 Mar 2026 15:22:23 +0300
Subject: [PATCH 16/45] ServerReceivingTest added, along with
SendingClock&Factory
---
.../net_01/channel/context/SendingClock.java | 34 +++++++++
.../channel/context/SendingClockFactory.java | 16 +++++
.../channel/context/StringWriteable.java | 45 ++++++++++++
...rverTest.java => ServerReceivingTest.java} | 32 +--------
.../channel/server/ServerSendingTest.java | 70 +++++++++++++++++++
5 files changed, 166 insertions(+), 31 deletions(-)
create mode 100644 src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
create mode 100644 src/test/java/com/teragrep/net_01/channel/context/SendingClockFactory.java
create mode 100644 src/test/java/com/teragrep/net_01/channel/context/StringWriteable.java
rename src/test/java/com/teragrep/net_01/channel/server/{ServerTest.java => ServerReceivingTest.java} (76%)
create mode 100644 src/test/java/com/teragrep/net_01/channel/server/ServerSendingTest.java
diff --git a/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java b/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
new file mode 100644
index 0000000..a010dba
--- /dev/null
+++ b/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
@@ -0,0 +1,34 @@
+package com.teragrep.net_01.channel.context;
+
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+
+import java.util.function.Consumer;
+
+public final class SendingClock implements Clock {
+ private final EstablishedContext ctx;
+ private final Consumer consumer;
+
+ public SendingClock(final EstablishedContext ctx, final Consumer consumer) {
+ this.ctx = ctx;
+ this.consumer = consumer;
+ }
+
+ @Override
+ public void advance(final TrackedMemorySegmentLease bufferLease) {
+ final StringBuilder stringBuilder = new StringBuilder();
+ while (bufferLease.hasNext()) {
+ stringBuilder.append((char)bufferLease.next().byteValue());
+ }
+
+ final String str = stringBuilder.toString();
+
+ ctx.egress().accept(new StringWriteable(str));
+
+ consumer.accept(str);
+ }
+
+ @Override
+ public void close() throws Exception {
+ // no-op
+ }
+}
diff --git a/src/test/java/com/teragrep/net_01/channel/context/SendingClockFactory.java b/src/test/java/com/teragrep/net_01/channel/context/SendingClockFactory.java
new file mode 100644
index 0000000..0ab630e
--- /dev/null
+++ b/src/test/java/com/teragrep/net_01/channel/context/SendingClockFactory.java
@@ -0,0 +1,16 @@
+package com.teragrep.net_01.channel.context;
+
+import java.util.function.Consumer;
+
+public final class SendingClockFactory implements ClockFactory {
+ private final Consumer consumer;
+
+ public SendingClockFactory(final Consumer consumer) {
+ this.consumer = consumer;
+ }
+
+ @Override
+ public Clock create(final EstablishedContext establishedContext) {
+ return new SendingClock(establishedContext, consumer);
+ }
+}
diff --git a/src/test/java/com/teragrep/net_01/channel/context/StringWriteable.java b/src/test/java/com/teragrep/net_01/channel/context/StringWriteable.java
new file mode 100644
index 0000000..92cebcf
--- /dev/null
+++ b/src/test/java/com/teragrep/net_01/channel/context/StringWriteable.java
@@ -0,0 +1,45 @@
+package com.teragrep.net_01.channel.context;
+
+import com.teragrep.net_01.channel.buffer.writable.Writeable;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+
+public final class StringWriteable implements Writeable {
+ private final ByteBuffer[] buffers;
+
+ public StringWriteable(final String str) {
+ this(new ByteBuffer[]{ByteBuffer.wrap(str.getBytes(StandardCharsets.UTF_8))});
+ }
+
+ public StringWriteable(final ByteBuffer[] buffers) {
+ this.buffers = buffers;
+ }
+
+ @Override
+ public void close() {
+ // no-op
+ }
+
+ @Override
+ public ByteBuffer[] buffers() {
+ return buffers;
+ }
+
+ @Override
+ public boolean hasRemaining() {
+ boolean rv = false;
+ for (final ByteBuffer buffer : buffers) {
+ if (buffer.hasRemaining()) {
+ rv = true;
+ break;
+ }
+ }
+ return rv;
+ }
+
+ @Override
+ public boolean isStub() {
+ return false;
+ }
+}
diff --git a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java b/src/test/java/com/teragrep/net_01/channel/server/ServerReceivingTest.java
similarity index 76%
rename from src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
rename to src/test/java/com/teragrep/net_01/channel/server/ServerReceivingTest.java
index 1f720fb..be305d3 100644
--- a/src/test/java/com/teragrep/net_01/channel/server/ServerTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/server/ServerReceivingTest.java
@@ -19,7 +19,7 @@
import java.util.concurrent.Executors;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-public final class ServerTest {
+public final class ServerReceivingTest {
private Server server;
private CountDownLatch countDownLatch;
private final List> messages = new ArrayList<>();
@@ -94,36 +94,6 @@ void testReceivingThreeChars() {
Assertions.assertEquals(List.of((byte) 'a', (byte) 'b', (byte) 'c'), messages.getFirst());
- Assertions.assertDoesNotThrow(in::close);
- Assertions.assertDoesNotThrow(out::close);
- Assertions.assertDoesNotThrow(clientSocket::close);
- }
-
- @Test
- void testSending() {
- this.countDownLatch = new CountDownLatch(1);
- final java.net.Socket clientSocket = Assertions.assertDoesNotThrow(() -> new java.net.Socket("localhost", 9090));
-
- final PrintWriter out = new PrintWriter(Assertions.assertDoesNotThrow(clientSocket::getOutputStream), true);
- final BufferedReader in = new BufferedReader(new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream)));
-
- out.print("a");
- out.flush();
- out.print("b");
- out.flush();
- out.print("c");
- out.flush();
-
- Assertions.assertDoesNotThrow(() -> countDownLatch.await());
-
- Assertions.assertEquals(List.of((byte) 'a', (byte) 'b', (byte) 'c'), messages.getFirst());
-
- String x;
- while ((x = Assertions.assertDoesNotThrow(in::readLine)) != null){
- System.out.println("resp: " + x);
- }
-
-
Assertions.assertDoesNotThrow(in::close);
Assertions.assertDoesNotThrow(out::close);
Assertions.assertDoesNotThrow(clientSocket::close);
diff --git a/src/test/java/com/teragrep/net_01/channel/server/ServerSendingTest.java b/src/test/java/com/teragrep/net_01/channel/server/ServerSendingTest.java
new file mode 100644
index 0000000..2ad96ba
--- /dev/null
+++ b/src/test/java/com/teragrep/net_01/channel/server/ServerSendingTest.java
@@ -0,0 +1,70 @@
+package com.teragrep.net_01.channel.server;
+
+import com.teragrep.net_01.channel.context.ClockFactory;
+import com.teragrep.net_01.channel.context.ConsumingClockFactory;
+import com.teragrep.net_01.channel.context.SendingClockFactory;
+import com.teragrep.net_01.channel.socket.PlainFactory;
+import com.teragrep.net_01.channel.socket.SocketFactory;
+import com.teragrep.net_01.eventloop.EventLoop;
+import com.teragrep.net_01.eventloop.EventLoopFactory;
+import com.teragrep.net_01.server.Server;
+import com.teragrep.net_01.server.ServerFactory;
+import org.junit.jupiter.api.*;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+public final class ServerSendingTest {
+ private Server server;
+ private CountDownLatch countDownLatch;
+ @BeforeAll
+ void beforeAll() {
+ final EventLoopFactory eventLoopFactory = new EventLoopFactory();
+ final SocketFactory socketFactory = new PlainFactory();
+ final ClockFactory clockFactory = new SendingClockFactory((msgStr) -> countDownLatch.countDown());
+
+ final EventLoop el = Assertions.assertDoesNotThrow(eventLoopFactory::create);
+
+ // eventLoopThread must run, otherwise nothing will be processed
+ final Thread elT = new Thread(el);
+ elT.start();
+
+ final ServerFactory serverFactory = new ServerFactory(el,
+ Executors.newSingleThreadExecutor(), socketFactory, clockFactory);
+
+ this.server = Assertions.assertDoesNotThrow(() -> serverFactory.create(9090));
+ }
+
+ @AfterAll
+ void afterAll() {
+ Assertions.assertDoesNotThrow(this.server::close);
+ }
+
+ @Test
+ void testSending() {
+ this.countDownLatch = new CountDownLatch(1);
+ final java.net.Socket clientSocket = Assertions.assertDoesNotThrow(() -> new java.net.Socket("localhost", 9090));
+
+ final PrintWriter out = new PrintWriter(Assertions.assertDoesNotThrow(clientSocket::getOutputStream), true);
+ final BufferedReader in = new BufferedReader(new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream)));
+ final String request = "Hello world! This is some input";
+ out.println(request);
+ out.flush();
+
+ Assertions.assertDoesNotThrow(() -> countDownLatch.await());
+
+ final String resp = Assertions.assertDoesNotThrow(in::readLine);
+
+ // SendingClock replies with the request
+ Assertions.assertEquals(request, resp);
+ Assertions.assertDoesNotThrow(in::close);
+ Assertions.assertDoesNotThrow(out::close);
+ Assertions.assertDoesNotThrow(clientSocket::close);
+ }
+}
From 65b9d8e12412f505347ec49ccc1dc9fa57eed60c Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Tue, 7 Apr 2026 11:48:54 +0300
Subject: [PATCH 17/45] IOResult stuff / SocketTest fix
---
.../buffer/TrackedMemorySegmentLease.java | 9 ++
.../channel/buffer/writable/Writeable.java | 6 +-
.../buffer/writable/WriteableAccess.java | 6 +-
.../buffer/writable/WriteableClosure.java | 6 +-
.../writable/WriteableInvalidation.java | 17 ++-
.../buffer/writable/WriteableLeaseful.java | 7 +-
.../buffer/writable/WriteableStub.java | 6 +-
.../channel/buffer/writable/Writeables.java | 15 +--
.../net_01/channel/context/EgressImpl.java | 15 ++-
.../net_01/channel/context/IngressImpl.java | 40 ++-----
.../net_01/channel/socket/IOResult.java | 10 ++
.../net_01/channel/socket/PlainSocket.java | 105 +++++++++++++++++-
.../net_01/channel/socket/ReadResult.java | 25 +++++
.../net_01/channel/socket/Socket.java | 7 +-
.../net_01/channel/socket/TLSSocket.java | 12 +-
.../net_01/channel/socket/WrittenResult.java | 25 +++++
.../net_01/channel/LeaseToString.java | 35 ++++++
.../net_01/channel/context/SendingClock.java | 8 +-
.../channel/context/SendingClockFactory.java | 8 +-
.../channel/context/StringWriteable.java | 26 +++--
.../channel/server/ServerSendingTest.java | 10 +-
.../net_01/channel/socket/SocketFake.java | 12 +-
.../net_01/channel/socket/SocketTest.java | 93 ++++++++++++----
23 files changed, 388 insertions(+), 115 deletions(-)
create mode 100644 src/main/java/com/teragrep/net_01/channel/socket/IOResult.java
create mode 100644 src/main/java/com/teragrep/net_01/channel/socket/ReadResult.java
create mode 100644 src/main/java/com/teragrep/net_01/channel/socket/WrittenResult.java
create mode 100644 src/test/java/com/teragrep/net_01/channel/LeaseToString.java
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
index 6ab14b2..5022d03 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
@@ -91,4 +91,13 @@ public long position() {
public long limit() {
return limit.get();
}
+
+ public long limit(int index) {
+ if (index < 0 || index > leasedObject().byteSize()) {
+ throw new IndexOutOfBoundsException("Out of bounds");
+ }
+
+ limit.set(index);
+ return limit.get();
+ }
}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeable.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeable.java
index 2fefc6f..2298cbf 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeable.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeable.java
@@ -45,15 +45,17 @@
*/
package com.teragrep.net_01.channel.buffer.writable;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+
import java.io.Closeable;
-import java.nio.ByteBuffer;
+import java.util.List;
public interface Writeable extends Closeable {
@Override
void close();
- ByteBuffer[] buffers();
+ List memorySegmentLeases();
boolean hasRemaining();
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableAccess.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableAccess.java
index c78778a..8a47e8c 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableAccess.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableAccess.java
@@ -45,10 +45,12 @@
*/
package com.teragrep.net_01.channel.buffer.writable;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
import com.teragrep.net_01.channel.buffer.access.Access;
import com.teragrep.net_01.channel.buffer.access.Lease;
import java.nio.ByteBuffer;
+import java.util.List;
public final class WriteableAccess implements Writeable {
@@ -61,10 +63,10 @@ public WriteableAccess(Writeable writeable, Access access) {
}
@Override
- public ByteBuffer[] buffers() {
+ public List memorySegmentLeases() {
// FIXME just not right
try (Lease ignored = access.get()) {
- return writeable.buffers();
+ return writeable.memorySegmentLeases();
}
}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableClosure.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableClosure.java
index 1e2e88e..1d4e748 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableClosure.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableClosure.java
@@ -45,11 +45,13 @@
*/
package com.teragrep.net_01.channel.buffer.writable;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
import com.teragrep.net_01.channel.context.EstablishedContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
+import java.util.List;
/**
* Closes a connection at close()
@@ -81,8 +83,8 @@ public void close() {
}
@Override
- public ByteBuffer[] buffers() {
- return writeable.buffers();
+ public List memorySegmentLeases() {
+ return writeable.memorySegmentLeases();
}
@Override
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableInvalidation.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableInvalidation.java
index fddb2dd..5148931 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableInvalidation.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableInvalidation.java
@@ -45,11 +45,14 @@
*/
package com.teragrep.net_01.channel.buffer.writable;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+
import java.nio.ByteBuffer;
+import java.util.List;
/**
* Decoration of {@link Writeable} Invalidates a writable so that {@link ByteBuffer}s returned from
- * {@link Writeable#buffers()} have position and limit set to zero. Because ByteBuffer can not be Decorated directly
+ * {@link Writeable#memorySegmentLeases()} have position and limit set to zero. Because ByteBuffer can not be Decorated directly
* this is only viable alternative to best-effort invalidate access to it.
*/
public final class WriteableInvalidation implements Writeable {
@@ -62,15 +65,19 @@ public WriteableInvalidation(Writeable writeable) {
@Override
public void close() {
- for (ByteBuffer byteBuffer : buffers()) {
- byteBuffer.limit(0);
+ for (final TrackedMemorySegmentLease lease : memorySegmentLeases()) {
+ try {
+ lease.close();
+ } catch (final Exception e) {
+ throw new RuntimeException("Error occurred whilst closing lease", e);
+ }
}
writeable.close();
}
@Override
- public ByteBuffer[] buffers() {
- return writeable.buffers();
+ public List memorySegmentLeases() {
+ return writeable.memorySegmentLeases();
}
@Override
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java
index bc8c201..16dc518 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java
@@ -46,11 +46,10 @@
package com.teragrep.net_01.channel.buffer.writable;
import com.teragrep.buf_01.buffer.lease.OpenableLease;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.IOException;
-import java.io.UncheckedIOException;
import java.lang.foreign.MemorySegment;
import java.nio.ByteBuffer;
import java.util.List;
@@ -68,8 +67,8 @@ public WriteableLeaseful(Writeable writeable, List>
}
@Override
- public ByteBuffer[] buffers() {
- return writeable.buffers();
+ public List memorySegmentLeases() {
+ return writeable.memorySegmentLeases();
}
@Override
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableStub.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableStub.java
index 341afef..ff96133 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableStub.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableStub.java
@@ -45,12 +45,14 @@
*/
package com.teragrep.net_01.channel.buffer.writable;
-import java.nio.ByteBuffer;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+
+import java.util.List;
public final class WriteableStub implements Writeable {
@Override
- public ByteBuffer[] buffers() {
+ public List memorySegmentLeases() {
throw new UnsupportedOperationException("WriteableStub does not allow this method");
}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeables.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeables.java
index c67c751..3664520 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeables.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeables.java
@@ -45,7 +45,11 @@
*/
package com.teragrep.net_01.channel.buffer.writable;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+
import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
public final class Writeables implements Writeable {
@@ -56,10 +60,10 @@ public Writeables(Writeable ... writeables) {
}
@Override
- public ByteBuffer[] buffers() {
+ public List memorySegmentLeases() {
long totalBuffers = 0;
for (Writeable writeable : writeables) {
- totalBuffers = totalBuffers + writeable.buffers().length;
+ totalBuffers = totalBuffers + writeable.memorySegmentLeases().size();
}
if (totalBuffers > Integer.MAX_VALUE) {
@@ -68,12 +72,9 @@ public ByteBuffer[] buffers() {
);
}
- ByteBuffer[] bufferArray = new ByteBuffer[(int) totalBuffers];
- int written = 0;
+ List bufferArray = new ArrayList<>((int) totalBuffers);
for (final Writeable writeable : writeables) {
- int bufferLength = writeable.buffers().length;
- System.arraycopy(writeable.buffers(), 0, bufferArray, written, bufferLength);
- written += bufferLength;
+ bufferArray.addAll(writeable.memorySegmentLeases());
}
return bufferArray;
diff --git a/src/main/java/com/teragrep/net_01/channel/context/EgressImpl.java b/src/main/java/com/teragrep/net_01/channel/context/EgressImpl.java
index 536e48f..c53acd4 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/EgressImpl.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/EgressImpl.java
@@ -45,8 +45,11 @@
*/
package com.teragrep.net_01.channel.context;
+import com.teragrep.buf_01.buffer.lease.OpenableLease;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
import com.teragrep.net_01.channel.buffer.writable.Writeable;
import com.teragrep.net_01.channel.buffer.writable.WriteableStub;
+import com.teragrep.net_01.channel.socket.WrittenResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tlschannel.NeedsReadException;
@@ -54,13 +57,16 @@
import java.io.IOException;
+import java.lang.foreign.MemorySegment;
import java.nio.ByteBuffer;
import java.nio.channels.CancelledKeyException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -169,17 +175,17 @@ private void transmit(final List toWriteList) throws IOException {
Iterator toWriteIterator = toWriteList.iterator();
while (toWriteIterator.hasNext()) {
Writeable w = toWriteIterator.next();
- numberOfBuffers += w.buffers().length;
+ numberOfBuffers += w.memorySegmentLeases().size();
}
- ByteBuffer[] writeBuffers = new ByteBuffer[numberOfBuffers];
+ TrackedMemorySegmentLease[] writeBuffers = new TrackedMemorySegmentLease[numberOfBuffers];
int writeBuffersIndex = 0;
Iterator toWriteIterator2 = toWriteList.iterator();
while (toWriteIterator2.hasNext()) {
Writeable w = toWriteIterator2.next();
- for (ByteBuffer buffer : w.buffers()) {
+ for (TrackedMemorySegmentLease buffer : w.memorySegmentLeases()) {
writeBuffers[writeBuffersIndex] = buffer;
writeBuffersIndex++;
}
@@ -188,7 +194,8 @@ private void transmit(final List toWriteList) throws IOException {
writeInProgressList.add(w);
}
- establishedContext.socket().write(writeBuffers);
+
+ final WrittenResult result = establishedContext.socket().write(writeBuffers);
// remove written ones
Iterator writeableIterator = writeInProgressList.iterator();
diff --git a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
index 2786965..f108859 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
@@ -49,6 +49,7 @@
import com.teragrep.buf_01.buffer.lease.OpenableLease;
import com.teragrep.buf_01.buffer.pool.LeaseMultiGet;
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.net_01.channel.socket.ReadResult;
import com.teragrep.poj_01.pool.Pool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -237,49 +238,22 @@ private long readData() throws IOException {
List> bufferLeases = new LeaseMultiGet(memorySegmentLeasePool).get(4);
- List byteBufferList = new LinkedList<>();
+ List trackedMemorySegmentLeases = new LinkedList<>();
for (OpenableLease bufferLease : bufferLeases) {
if (bufferLease.isStub()) {
continue;
}
- byteBufferList.add(bufferLease.leasedObject().asByteBuffer());
+ trackedMemorySegmentLeases.add(new TrackedMemorySegmentLease(bufferLease));
}
- ByteBuffer[] byteBufferArray = byteBufferList.toArray(new ByteBuffer[0]);
- readBytes = establishedContext.socket().read(byteBufferArray);
- System.out.println("readBytes = " + readBytes);
- long bytesLeft = readBytes;
- boolean allRead = false;
- for (final OpenableLease bufferLease : bufferLeases) {
- final long byteSize = bufferLease.leasedObject().byteSize();
-
- if (!allRead && readBytes > 0) {
- // same as ByteBuffer.flip()
- final long diff = bytesLeft - byteSize;
- if (diff < 0) {
- // mem.segment bigger than bytes left.
- // set limit to read amount.
- final long limit = byteSize - Math.abs(diff);
- activeBuffers.add(new TrackedMemorySegmentLease(bufferLease, new AtomicLong(0L), new AtomicLong(limit)));
- }
- else {
- //else: full mem.segment used, no need to set limit.
- activeBuffers.add(new TrackedMemorySegmentLease(bufferLease));
- }
- }
-
- bytesLeft -= byteSize;
-
- if (bytesLeft <= 0) {
- allRead = true;
- }
- }
+ final ReadResult result = establishedContext.socket().read(trackedMemorySegmentLeases);
+ activeBuffers.addAll(result.leases());
System.out.println("buffers.size=" + activeBuffers.size());
- LOGGER.debug("establishedContext.read got <{}> bytes from socket", readBytes);
+ LOGGER.debug("establishedContext.read got <{}> bytes from socket", result.bytes());
- return readBytes;
+ return result.bytes();
}
public AtomicBoolean needWrite() {
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/IOResult.java b/src/main/java/com/teragrep/net_01/channel/socket/IOResult.java
new file mode 100644
index 0000000..65326f8
--- /dev/null
+++ b/src/main/java/com/teragrep/net_01/channel/socket/IOResult.java
@@ -0,0 +1,10 @@
+package com.teragrep.net_01.channel.socket;
+
+import com.teragrep.buf_01.buffer.lease.Lease;
+
+import java.util.List;
+
+public interface IOResult> {
+ public abstract long bytes();
+ public abstract List leases();
+}
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/PlainSocket.java b/src/main/java/com/teragrep/net_01/channel/socket/PlainSocket.java
index 519ab3f..8d48704 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/PlainSocket.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/PlainSocket.java
@@ -45,9 +45,18 @@
*/
package com.teragrep.net_01.channel.socket;
+import com.teragrep.buf_01.buffer.lease.OpenableLease;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+
import java.io.IOException;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.ValueLayout;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
final class PlainSocket implements Socket {
@@ -61,13 +70,101 @@ final class PlainSocket implements Socket {
}
@Override
- public long read(ByteBuffer[] dsts) throws IOException {
- return socketChannel.read(dsts);
+ public ReadResult read(List srcs) throws IOException {
+ final List rv = new ArrayList<>(srcs.size());
+ final List byteBuffers = new ArrayList<>(srcs.size());
+ srcs.forEach(src -> {
+ byteBuffers.add(src.leasedObject().asByteBuffer());
+ });
+
+ final long readBytes = socketChannel.read(byteBuffers.toArray(new ByteBuffer[0]));
+
+ long bytesLeft = readBytes;
+ boolean allRead = false;
+ for (final TrackedMemorySegmentLease bufferLease : srcs) {
+ final long byteSize = bufferLease.leasedObject().byteSize();
+
+ if (!allRead && readBytes > 0) {
+ // same as ByteBuffer.flip()
+ final long diff = bytesLeft - byteSize;
+ if (diff < 0) {
+ // mem.segment bigger than bytes left.
+ // set limit to read amount.
+ final long limit = byteSize - Math.abs(diff);
+ rv.add(new TrackedMemorySegmentLease(bufferLease, new AtomicLong(0L), new AtomicLong(limit)));
+ }
+ else {
+ //else: full mem.segment used, no need to set limit.
+ rv.add(new TrackedMemorySegmentLease(bufferLease));
+ }
+ }
+
+ bytesLeft -= byteSize;
+
+ if (bytesLeft <= 0) {
+ allRead = true;
+ }
+ }
+
+ //rv.forEach(l -> {
+ System.out.println("Lease:");
+ /*for (long i = 0 ; i < l.leasedObject().byteSize(); i++) {
+ System.out.printf("%s", (char)l.leasedObject().get(ValueLayout.JAVA_BYTE, i));
+ }*/
+
+ /* while (l.hasNext()) {
+ System.out.printf("%s", (char)l.next().byteValue());
+ }
+
+ System.out.println();*/
+ //});
+ return new ReadResult(readBytes, rv);
}
@Override
- public long write(ByteBuffer[] dsts) throws IOException {
- return socketChannel.write(dsts);
+ public WrittenResult write(List leases) throws IOException {
+ final List buffersToWrite = new ArrayList<>(leases.size());
+ final List rv = new ArrayList<>(leases.size());
+
+ for (final TrackedMemorySegmentLease lease : leases) {
+ buffersToWrite.add(lease.leasedObject().asByteBuffer());
+ }
+
+ final long bytesWritten = socketChannel.write(buffersToWrite.toArray(new ByteBuffer[0]));
+ System.out.println("wrote bytes: " + bytesWritten);
+
+ long bytesLeft = bytesWritten;
+ boolean allWritten = false;
+ for (final TrackedMemorySegmentLease bufferLease : leases) {
+ final long byteSize = bufferLease.leasedObject().byteSize();
+
+ if (!allWritten && bytesWritten > 0) {
+ // same as ByteBuffer.flip()
+ final long diff = bytesLeft - byteSize;
+ if (diff < 0) {
+ // mem.segment bigger than bytes left.
+ // set limit to written amount.
+ final long limit = byteSize - Math.abs(diff);
+ rv.add(new TrackedMemorySegmentLease(bufferLease, new AtomicLong(0L), new AtomicLong(limit)));
+ }
+ else {
+ //else: full mem.segment used, no need to set limit.
+ rv.add(new TrackedMemorySegmentLease(bufferLease));
+ }
+ }
+
+ bytesLeft -= byteSize;
+
+ if (bytesLeft <= 0) {
+ allWritten = true;
+ }
+ }
+
+ rv.forEach(l -> {
+ System.out.println(Arrays.toString(l.leasedObject().toArray(ValueLayout.JAVA_BYTE)));
+ });
+
+ return new WrittenResult(bytesWritten, rv);
}
@Override
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/ReadResult.java b/src/main/java/com/teragrep/net_01/channel/socket/ReadResult.java
new file mode 100644
index 0000000..1907a5b
--- /dev/null
+++ b/src/main/java/com/teragrep/net_01/channel/socket/ReadResult.java
@@ -0,0 +1,25 @@
+package com.teragrep.net_01.channel.socket;
+
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+
+import java.util.List;
+
+public final class ReadResult implements IOResult {
+ private final long bytesRead;
+ private final List leases;
+
+ public ReadResult(final long bytesRead, final List leases) {
+ this.bytesRead = bytesRead;
+ this.leases = leases;
+ }
+
+ @Override
+ public long bytes() {
+ return bytesRead;
+ }
+
+ @Override
+ public List leases() {
+ return leases;
+ }
+}
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/Socket.java b/src/main/java/com/teragrep/net_01/channel/socket/Socket.java
index 67cada1..2b2bd66 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/Socket.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/Socket.java
@@ -45,9 +45,12 @@
*/
package com.teragrep.net_01.channel.socket;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
+import java.util.List;
/**
* {@link Socket} provides network connectivity methods
@@ -61,7 +64,7 @@ public interface Socket {
* @return amount of bytes read
* @throws IOException if read fails
*/
- long read(ByteBuffer[] dsts) throws IOException;
+ ReadResult read(List srcs) throws IOException;
/**
* Write data through a network connection.
@@ -70,7 +73,7 @@ public interface Socket {
* @return amount of bytes written
* @throws IOException if write fails
*/
- long write(ByteBuffer[] dsts) throws IOException;
+ WrittenResult write(List dsts) throws IOException;
/**
* Provides information about a network connection
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/TLSSocket.java b/src/main/java/com/teragrep/net_01/channel/socket/TLSSocket.java
index dc07b94..c42f9b2 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/TLSSocket.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/TLSSocket.java
@@ -45,11 +45,13 @@
*/
package com.teragrep.net_01.channel.socket;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
import tlschannel.TlsChannel;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
+import java.util.List;
final class TLSSocket implements Socket {
@@ -65,13 +67,15 @@ final class TLSSocket implements Socket {
}
@Override
- public long read(ByteBuffer[] dsts) throws IOException {
- return tlsChannel.read(dsts);
+ public ReadResult read(List dsts) throws IOException {
+ throw new UnsupportedOperationException();
+ //return tlsChannel.read(dsts);
}
@Override
- public long write(ByteBuffer[] dsts) throws IOException {
- return tlsChannel.write(dsts);
+ public WrittenResult write(List dsts) throws IOException {
+ throw new UnsupportedOperationException();
+ //return tlsChannel.write(dsts);
}
@Override
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/WrittenResult.java b/src/main/java/com/teragrep/net_01/channel/socket/WrittenResult.java
new file mode 100644
index 0000000..0f4946b
--- /dev/null
+++ b/src/main/java/com/teragrep/net_01/channel/socket/WrittenResult.java
@@ -0,0 +1,25 @@
+package com.teragrep.net_01.channel.socket;
+
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+
+import java.util.List;
+
+public class WrittenResult implements IOResult {
+ private final long bytesWritten;
+ private final List leases;
+
+ public WrittenResult(final long bytesWritten, final List leases) {
+ this.bytesWritten = bytesWritten;
+ this.leases = leases;
+ }
+
+ @Override
+ public long bytes() {
+ return bytesWritten;
+ }
+
+ @Override
+ public List leases() {
+ return leases;
+ }
+}
diff --git a/src/test/java/com/teragrep/net_01/channel/LeaseToString.java b/src/test/java/com/teragrep/net_01/channel/LeaseToString.java
new file mode 100644
index 0000000..d5df829
--- /dev/null
+++ b/src/test/java/com/teragrep/net_01/channel/LeaseToString.java
@@ -0,0 +1,35 @@
+package com.teragrep.net_01.channel;
+
+import com.teragrep.buf_01.buffer.lease.MemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.OpenableLease;
+import com.teragrep.buf_01.buffer.pool.LeaseMultiGet;
+import com.teragrep.buf_01.buffer.pool.OpeningPool;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.net_01.channel.buffer.writable.Writeable;
+import com.teragrep.net_01.channel.context.StringWriteable;
+
+import java.lang.foreign.MemorySegment;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+public final class LeaseToString {
+
+ private final String origin;
+ private final OpeningPool pool;
+ public LeaseToString(final String origin, OpeningPool pool) {
+ this.origin = origin;
+ this.pool = pool;
+ }
+
+ public Writeable toWriteable() {
+ byte[] bytes = origin.getBytes(StandardCharsets.UTF_8);
+ List> leases = new LeaseMultiGet(pool).get(bytes.length);
+ List trackedLeases = new ArrayList<>(leases.size());
+ for (OpenableLease lease : leases) {
+ trackedLeases.add(new TrackedMemorySegmentLease(lease));
+ }
+
+ return new StringWriteable(trackedLeases);
+ }
+}
diff --git a/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java b/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
index a010dba..3572f6e 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
@@ -1,5 +1,7 @@
package com.teragrep.net_01.channel.context;
+import com.teragrep.buf_01.buffer.pool.OpeningPool;
+import com.teragrep.net_01.channel.LeaseToString;
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
import java.util.function.Consumer;
@@ -7,10 +9,12 @@
public final class SendingClock implements Clock {
private final EstablishedContext ctx;
private final Consumer consumer;
+ private final OpeningPool pool;
- public SendingClock(final EstablishedContext ctx, final Consumer consumer) {
+ public SendingClock(final EstablishedContext ctx, final Consumer consumer, final OpeningPool pool) {
this.ctx = ctx;
this.consumer = consumer;
+ this.pool = pool;
}
@Override
@@ -22,7 +26,7 @@ public void advance(final TrackedMemorySegmentLease bufferLease) {
final String str = stringBuilder.toString();
- ctx.egress().accept(new StringWriteable(str));
+ ctx.egress().accept(new LeaseToString(str, pool).toWriteable());
consumer.accept(str);
}
diff --git a/src/test/java/com/teragrep/net_01/channel/context/SendingClockFactory.java b/src/test/java/com/teragrep/net_01/channel/context/SendingClockFactory.java
index 0ab630e..1d9e295 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/SendingClockFactory.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/SendingClockFactory.java
@@ -1,16 +1,20 @@
package com.teragrep.net_01.channel.context;
+import com.teragrep.buf_01.buffer.pool.OpeningPool;
+
import java.util.function.Consumer;
public final class SendingClockFactory implements ClockFactory {
private final Consumer consumer;
+ private final OpeningPool pool;
- public SendingClockFactory(final Consumer consumer) {
+ public SendingClockFactory(final Consumer consumer, final OpeningPool pool) {
this.consumer = consumer;
+ this.pool = pool;
}
@Override
public Clock create(final EstablishedContext establishedContext) {
- return new SendingClock(establishedContext, consumer);
+ return new SendingClock(establishedContext, consumer, pool);
}
}
diff --git a/src/test/java/com/teragrep/net_01/channel/context/StringWriteable.java b/src/test/java/com/teragrep/net_01/channel/context/StringWriteable.java
index 92cebcf..588b03c 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/StringWriteable.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/StringWriteable.java
@@ -1,36 +1,38 @@
package com.teragrep.net_01.channel.context;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
import com.teragrep.net_01.channel.buffer.writable.Writeable;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
+import java.util.List;
public final class StringWriteable implements Writeable {
- private final ByteBuffer[] buffers;
+ private final List buffers;
- public StringWriteable(final String str) {
- this(new ByteBuffer[]{ByteBuffer.wrap(str.getBytes(StandardCharsets.UTF_8))});
- }
-
- public StringWriteable(final ByteBuffer[] buffers) {
+ public StringWriteable(final List buffers) {
this.buffers = buffers;
}
@Override
public void close() {
- // no-op
+ for (TrackedMemorySegmentLease buf : buffers) {
+ try {
+ buf.close();
+ } catch (final Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
}
@Override
- public ByteBuffer[] buffers() {
+ public List memorySegmentLeases() {
return buffers;
}
@Override
public boolean hasRemaining() {
boolean rv = false;
- for (final ByteBuffer buffer : buffers) {
- if (buffer.hasRemaining()) {
+ for (final TrackedMemorySegmentLease buffer : buffers) {
+ if (buffer.hasNext()) {
rv = true;
break;
}
diff --git a/src/test/java/com/teragrep/net_01/channel/server/ServerSendingTest.java b/src/test/java/com/teragrep/net_01/channel/server/ServerSendingTest.java
index 2ad96ba..d42676f 100644
--- a/src/test/java/com/teragrep/net_01/channel/server/ServerSendingTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/server/ServerSendingTest.java
@@ -1,5 +1,8 @@
package com.teragrep.net_01.channel.server;
+import com.teragrep.buf_01.buffer.lease.MemorySegmentLeaseStub;
+import com.teragrep.buf_01.buffer.pool.OpeningPool;
+import com.teragrep.buf_01.buffer.supply.ArenaMemorySegmentLeaseSupplier;
import com.teragrep.net_01.channel.context.ClockFactory;
import com.teragrep.net_01.channel.context.ConsumingClockFactory;
import com.teragrep.net_01.channel.context.SendingClockFactory;
@@ -9,11 +12,13 @@
import com.teragrep.net_01.eventloop.EventLoopFactory;
import com.teragrep.net_01.server.Server;
import com.teragrep.net_01.server.ServerFactory;
+import com.teragrep.poj_01.pool.UnboundPool;
import org.junit.jupiter.api.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
+import java.lang.foreign.Arena;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@@ -23,11 +28,13 @@
public final class ServerSendingTest {
private Server server;
private CountDownLatch countDownLatch;
+ private OpeningPool pool;
@BeforeAll
void beforeAll() {
final EventLoopFactory eventLoopFactory = new EventLoopFactory();
final SocketFactory socketFactory = new PlainFactory();
- final ClockFactory clockFactory = new SendingClockFactory((msgStr) -> countDownLatch.countDown());
+ this.pool = new OpeningPool(new UnboundPool<>(new ArenaMemorySegmentLeaseSupplier(Arena.ofShared(), 128), new MemorySegmentLeaseStub()));
+ final ClockFactory clockFactory = new SendingClockFactory((msgStr) -> countDownLatch.countDown(), pool);
final EventLoop el = Assertions.assertDoesNotThrow(eventLoopFactory::create);
@@ -44,6 +51,7 @@ void beforeAll() {
@AfterAll
void afterAll() {
Assertions.assertDoesNotThrow(this.server::close);
+ Assertions.assertDoesNotThrow(this.pool::close);
}
@Test
diff --git a/src/test/java/com/teragrep/net_01/channel/socket/SocketFake.java b/src/test/java/com/teragrep/net_01/channel/socket/SocketFake.java
index 0263769..b5ba826 100644
--- a/src/test/java/com/teragrep/net_01/channel/socket/SocketFake.java
+++ b/src/test/java/com/teragrep/net_01/channel/socket/SocketFake.java
@@ -45,8 +45,12 @@
*/
package com.teragrep.net_01.channel.socket;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
+import java.util.Collections;
+import java.util.List;
public class SocketFake implements Socket {
@@ -57,13 +61,13 @@ public SocketFake() {
}
@Override
- public long read(ByteBuffer[] dsts) {
- return 0;
+ public ReadResult read(List dsts) {
+ return new ReadResult(0, Collections.emptyList());
}
@Override
- public long write(ByteBuffer[] dsts) {
- return 0;
+ public WrittenResult write(List dsts) {
+ return new WrittenResult(0, Collections.emptyList());
}
@Override
diff --git a/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java b/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
index 5371825..c66b113 100644
--- a/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
@@ -1,19 +1,42 @@
package com.teragrep.net_01.channel.socket;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
+import com.teragrep.buf_01.buffer.lease.MemorySegmentLeaseStub;
+import com.teragrep.buf_01.buffer.lease.OpenableLease;
+import com.teragrep.buf_01.buffer.pool.LeaseMultiGet;
+import com.teragrep.buf_01.buffer.pool.OpeningPool;
+import com.teragrep.buf_01.buffer.supply.ArenaMemorySegmentLeaseSupplier;
+import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.poj_01.pool.UnboundPool;
+import org.junit.jupiter.api.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
+import java.lang.foreign.Arena;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.ValueLayout;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public final class SocketTest {
+ private OpeningPool pool;
+
+ @BeforeAll
+ void beforeAll() {
+ this.pool = new OpeningPool(new UnboundPool<>(new ArenaMemorySegmentLeaseSupplier(Arena.ofShared(), 128), new MemorySegmentLeaseStub()));
+ }
+
+ @AfterAll
+ void afterAll() {
+ this.pool.close();
+ }
@Test
void testPlainSocketConnection() {
@@ -76,10 +99,10 @@ void testPlainSocketRead() {
out.println("worldHello");
- ByteBuffer[] bufs = emptyBuffers(1, 10);
- socket.read(bufs);
+ List bufs = emptyBuffers(10);
+ ReadResult res = socket.read(bufs);
- Assertions.assertEquals("worldHello", bufferToString(bufs));
+ Assertions.assertEquals("worldHello\n", bufferToString(res.leases()));
clientSocket.close();
socketCh.close();
@@ -87,34 +110,58 @@ void testPlainSocketRead() {
});
}
- private String bufferToString(final ByteBuffer[] bufs) {
+ private String bufferToString(final List leases) {
final StringBuilder stringBuilder = new StringBuilder();
- for (final ByteBuffer buf : bufs) {
- buf.flip();
- while (buf.hasRemaining()) {
- stringBuilder.append((char) buf.get());
+ for (final TrackedMemorySegmentLease buf : leases) {
+ while (buf.hasNext()) {
+ stringBuilder.append((char) buf.next().byteValue());
}
- buf.flip();
}
return stringBuilder.toString();
}
- private ByteBuffer[] stringToBuffer(final String str) {
- final ByteBuffer[] arr = new ByteBuffer[1];
-
+ private List stringToBuffer(final String str) {
final byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
- arr[0] = ByteBuffer.wrap(bytes);
+ final List leases = emptyBuffers(bytes.length);
+
+ Iterator it = leases.iterator();
+ TrackedMemorySegmentLease currentLease = it.next();
+ int currentIndex = 0;
+ long size = currentLease.leasedObject().byteSize();
+ for (int i = 0; i < bytes.length; i++) {
+ System.out.println("i: " + i + " " + bytes[i]);
+ if (currentIndex < size) {
+ currentLease.leasedObject().set(ValueLayout.JAVA_BYTE, currentIndex, bytes[i]);
+ currentIndex++;
+ }
+ else {
+ if (!it.hasNext()) {
+ throw new IllegalStateException();
+ }
+ currentLease = it.next();
+ currentIndex = 0;
+ size = currentLease.leasedObject().byteSize();
+ currentLease.leasedObject().set(ValueLayout.JAVA_BYTE, currentIndex, bytes[i]);
+ }
+ }
+
+
+ System.out.println("stringToBuffer");
+ leases.forEach(l -> {
+ System.out.println(Arrays.toString(l.leasedObject().toArray(ValueLayout.JAVA_BYTE)));
+ });
- return arr;
+ return leases;
}
- private ByteBuffer[] emptyBuffers(int n, int bytesEach) {
- final ByteBuffer[] arr = new ByteBuffer[n];
+ private List emptyBuffers(int bytes) {
+ final List> leases = new LeaseMultiGet(pool).get(bytes);
+ final List rv = new ArrayList<>(leases.size());
- for (int i = 0; i < n; i++) {
- arr[i] = ByteBuffer.allocate(bytesEach);
- }
+ leases.forEach(lease -> {
+ rv.add(new TrackedMemorySegmentLease(lease));
+ });
- return arr;
+ return rv;
}
}
From 39a719af4e219e88af3bd135cb9a48559797a1ad Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Tue, 7 Apr 2026 13:40:53 +0300
Subject: [PATCH 18/45] fix LeaseToString not writing bytes to lease. fix name
to StringToLease
---
...{LeaseToString.java => StringToLease.java} | 21 ++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
rename src/test/java/com/teragrep/net_01/channel/{LeaseToString.java => StringToLease.java} (55%)
diff --git a/src/test/java/com/teragrep/net_01/channel/LeaseToString.java b/src/test/java/com/teragrep/net_01/channel/StringToLease.java
similarity index 55%
rename from src/test/java/com/teragrep/net_01/channel/LeaseToString.java
rename to src/test/java/com/teragrep/net_01/channel/StringToLease.java
index d5df829..327d4d3 100644
--- a/src/test/java/com/teragrep/net_01/channel/LeaseToString.java
+++ b/src/test/java/com/teragrep/net_01/channel/StringToLease.java
@@ -1,6 +1,5 @@
package com.teragrep.net_01.channel;
-import com.teragrep.buf_01.buffer.lease.MemorySegmentLease;
import com.teragrep.buf_01.buffer.lease.OpenableLease;
import com.teragrep.buf_01.buffer.pool.LeaseMultiGet;
import com.teragrep.buf_01.buffer.pool.OpeningPool;
@@ -13,23 +12,31 @@
import java.util.ArrayList;
import java.util.List;
-public final class LeaseToString {
+public final class StringToLease {
private final String origin;
private final OpeningPool pool;
- public LeaseToString(final String origin, OpeningPool pool) {
+ public StringToLease(final String origin, OpeningPool pool) {
this.origin = origin;
this.pool = pool;
}
public Writeable toWriteable() {
- byte[] bytes = origin.getBytes(StandardCharsets.UTF_8);
- List> leases = new LeaseMultiGet(pool).get(bytes.length);
- List trackedLeases = new ArrayList<>(leases.size());
- for (OpenableLease lease : leases) {
+ final byte[] bytes = origin.getBytes(StandardCharsets.UTF_8);
+ final List> leases = new LeaseMultiGet(pool).get(bytes.length);
+ final List trackedLeases = new ArrayList<>(leases.size());
+ for (final OpenableLease lease : leases) {
trackedLeases.add(new TrackedMemorySegmentLease(lease));
}
+ int i = 0;
+ for (final TrackedMemorySegmentLease trackedLease : trackedLeases) {
+ while (trackedLease.hasNext() && i < bytes.length) {
+ trackedLease.write(bytes[i]);
+ i++;
+ }
+ }
+
return new StringWriteable(trackedLeases);
}
}
From 40b56f8a5672f3b47317118a75e1e67e73cab508 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Tue, 7 Apr 2026 13:57:56 +0300
Subject: [PATCH 19/45] SendingClock cleanup
---
.../teragrep/net_01/channel/context/SendingClock.java | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java b/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
index 3572f6e..d3ee693 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
@@ -1,8 +1,9 @@
package com.teragrep.net_01.channel.context;
import com.teragrep.buf_01.buffer.pool.OpeningPool;
-import com.teragrep.net_01.channel.LeaseToString;
+import com.teragrep.net_01.channel.StringToLease;
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.net_01.channel.buffer.writable.Writeable;
import java.util.function.Consumer;
@@ -21,12 +22,14 @@ public SendingClock(final EstablishedContext ctx, final Consumer consume
public void advance(final TrackedMemorySegmentLease bufferLease) {
final StringBuilder stringBuilder = new StringBuilder();
while (bufferLease.hasNext()) {
- stringBuilder.append((char)bufferLease.next().byteValue());
+ final char c = (char) bufferLease.next().byteValue();
+ stringBuilder.append(c);
}
final String str = stringBuilder.toString();
- ctx.egress().accept(new LeaseToString(str, pool).toWriteable());
+ final Writeable w = new StringToLease(str, pool).toWriteable();
+ ctx.egress().accept(w);
consumer.accept(str);
}
From 3161d55595e7715247aae8a85b6a4cea7245bba1 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Wed, 8 Apr 2026 13:37:07 +0300
Subject: [PATCH 20/45] fix `EgressImpl.transmit()` method; PlainSocket now
modifies pre-existing TrackedMemorySegmentLeases; add writing and changing
position/limit to TrackedMemorySegmentLease; spotless applied
---
pom.xml | 2 +-
.../buffer/TrackedMemorySegmentLease.java | 70 ++++++++++++++++++-
.../buffer/writable/WriteableAccess.java | 1 -
.../buffer/writable/WriteableClosure.java | 1 -
.../writable/WriteableInvalidation.java | 7 +-
.../buffer/writable/WriteableLeaseful.java | 4 +-
.../channel/buffer/writable/Writeables.java | 1 -
.../net_01/channel/context/Clock.java | 3 -
.../net_01/channel/context/EgressImpl.java | 30 ++------
.../context/EstablishedContextImpl.java | 4 +-
.../net_01/channel/context/IngressImpl.java | 4 --
.../channel/socket/EncryptionInfoStub.java | 1 -
.../channel/socket/EncryptionInfoTLS.java | 1 -
.../net_01/channel/socket/IOResult.java | 47 +++++++++++++
.../net_01/channel/socket/PlainSocket.java | 36 +++++-----
.../net_01/channel/socket/ReadResult.java | 46 ++++++++++++
.../net_01/channel/socket/TLSSocket.java | 1 -
.../net_01/channel/socket/WrittenResult.java | 46 ++++++++++++
.../net_01/channel/StringToLease.java | 46 ++++++++++++
.../channel/context/ConsumingClock.java | 46 ++++++++++++
.../context/ConsumingClockFactory.java | 47 ++++++++++++-
.../net_01/channel/context/SendingClock.java | 46 ++++++++++++
.../channel/context/SendingClockFactory.java | 46 ++++++++++++
.../channel/context/StringWriteable.java | 49 ++++++++++++-
.../buffer/TrackedMemorySegmentLeaseTest.java | 56 +++++++++++++--
.../channel/server/ServerReceivingTest.java | 68 ++++++++++++++++--
.../channel/server/ServerSendingTest.java | 69 +++++++++++++++---
.../net_01/channel/socket/SocketFake.java | 1 -
.../net_01/channel/socket/SocketTest.java | 56 +++++++++++++--
29 files changed, 743 insertions(+), 92 deletions(-)
diff --git a/pom.xml b/pom.xml
index 8af5ea9..bcc8ad4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,9 +37,9 @@
UTF-8UTF-80.0.1
+ 1.0.03.0.0
-
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
index 5022d03..15baba8 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
@@ -1,3 +1,48 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel.buffer;
import com.teragrep.buf_01.buffer.lease.Lease;
@@ -8,6 +53,7 @@
import java.util.concurrent.atomic.AtomicLong;
public class TrackedMemorySegmentLease implements Lease, Iterator {
+
private final Lease origin;
private final AtomicLong currentOffset;
private final AtomicLong limit;
@@ -20,7 +66,11 @@ public TrackedMemorySegmentLease(final Lease origin, final Atomic
this(origin, currentOffset, new AtomicLong(-1L));
}
- public TrackedMemorySegmentLease(final Lease origin, final AtomicLong currentOffset, final AtomicLong limit) {
+ public TrackedMemorySegmentLease(
+ final Lease origin,
+ final AtomicLong currentOffset,
+ final AtomicLong limit
+ ) {
this.origin = origin;
this.currentOffset = currentOffset;
this.limit = limit;
@@ -84,14 +134,32 @@ public Byte next() {
return origin.leasedObject().get(ValueLayout.JAVA_BYTE, nextIndex);
}
+ public void write(final byte b) {
+ if (!hasNext()) {
+ throw new IndexOutOfBoundsException("Reached end of segment or limit, cannot write to next byte");
+ }
+
+ final long nextIndex = currentOffset.getAndIncrement();
+
+ origin.leasedObject().set(ValueLayout.JAVA_BYTE, nextIndex, b);
+ }
+
public long position() {
return currentOffset.get();
}
+ public void position(long pos) {
+ currentOffset.set(pos);
+ }
+
public long limit() {
return limit.get();
}
+ public void limit(long newLimit) {
+ limit.set(newLimit);
+ }
+
public long limit(int index) {
if (index < 0 || index > leasedObject().byteSize()) {
throw new IndexOutOfBoundsException("Out of bounds");
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableAccess.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableAccess.java
index 8a47e8c..e0b0fde 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableAccess.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableAccess.java
@@ -49,7 +49,6 @@
import com.teragrep.net_01.channel.buffer.access.Access;
import com.teragrep.net_01.channel.buffer.access.Lease;
-import java.nio.ByteBuffer;
import java.util.List;
public final class WriteableAccess implements Writeable {
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableClosure.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableClosure.java
index 1d4e748..6b3c4d7 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableClosure.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableClosure.java
@@ -50,7 +50,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.nio.ByteBuffer;
import java.util.List;
/**
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableInvalidation.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableInvalidation.java
index 5148931..082b674 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableInvalidation.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableInvalidation.java
@@ -52,8 +52,8 @@
/**
* Decoration of {@link Writeable} Invalidates a writable so that {@link ByteBuffer}s returned from
- * {@link Writeable#memorySegmentLeases()} have position and limit set to zero. Because ByteBuffer can not be Decorated directly
- * this is only viable alternative to best-effort invalidate access to it.
+ * {@link Writeable#memorySegmentLeases()} have position and limit set to zero. Because ByteBuffer can not be Decorated
+ * directly this is only viable alternative to best-effort invalidate access to it.
*/
public final class WriteableInvalidation implements Writeable {
@@ -68,7 +68,8 @@ public void close() {
for (final TrackedMemorySegmentLease lease : memorySegmentLeases()) {
try {
lease.close();
- } catch (final Exception e) {
+ }
+ catch (final Exception e) {
throw new RuntimeException("Error occurred whilst closing lease", e);
}
}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java
index 16dc518..36748a2 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java
@@ -51,7 +51,6 @@
import org.slf4j.LoggerFactory;
import java.lang.foreign.MemorySegment;
-import java.nio.ByteBuffer;
import java.util.List;
public final class WriteableLeaseful implements Writeable {
@@ -92,7 +91,8 @@ public void close() {
// FIXME: bufferLease.removeRef();
try {
bufferLease.close();
- } catch (Exception e) {
+ }
+ catch (Exception e) {
throw new RuntimeException(e);
}
}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeables.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeables.java
index 3664520..8df719b 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeables.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeables.java
@@ -47,7 +47,6 @@
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
-import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/main/java/com/teragrep/net_01/channel/context/Clock.java b/src/main/java/com/teragrep/net_01/channel/context/Clock.java
index 710c97a..d1bfca0 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/Clock.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/Clock.java
@@ -45,11 +45,8 @@
*/
package com.teragrep.net_01.channel.context;
-import com.teragrep.buf_01.buffer.lease.Lease;
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
-import java.lang.foreign.MemorySegment;
-
public interface Clock extends AutoCloseable {
/**
diff --git a/src/main/java/com/teragrep/net_01/channel/context/EgressImpl.java b/src/main/java/com/teragrep/net_01/channel/context/EgressImpl.java
index c53acd4..b121545 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/EgressImpl.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/EgressImpl.java
@@ -45,7 +45,6 @@
*/
package com.teragrep.net_01.channel.context;
-import com.teragrep.buf_01.buffer.lease.OpenableLease;
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
import com.teragrep.net_01.channel.buffer.writable.Writeable;
import com.teragrep.net_01.channel.buffer.writable.WriteableStub;
@@ -57,16 +56,12 @@
import java.io.IOException;
-import java.lang.foreign.MemorySegment;
-import java.nio.ByteBuffer;
import java.nio.channels.CancelledKeyException;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -170,33 +165,18 @@ public void accept(Writeable writeable) {
private void transmit(final List toWriteList) throws IOException {
try {
+ final List writeBuffers = new ArrayList<>();
- int numberOfBuffers = 0;
- Iterator toWriteIterator = toWriteList.iterator();
- while (toWriteIterator.hasNext()) {
- Writeable w = toWriteIterator.next();
- numberOfBuffers += w.memorySegmentLeases().size();
- }
-
- TrackedMemorySegmentLease[] writeBuffers = new TrackedMemorySegmentLease[numberOfBuffers];
- int writeBuffersIndex = 0;
-
- Iterator toWriteIterator2 = toWriteList.iterator();
- while (toWriteIterator2.hasNext()) {
- Writeable w = toWriteIterator2.next();
-
- for (TrackedMemorySegmentLease buffer : w.memorySegmentLeases()) {
- writeBuffers[writeBuffersIndex] = buffer;
- writeBuffersIndex++;
- }
-
- toWriteIterator2.remove();
+ for (final Writeable w : toWriteList) {
+ writeBuffers.addAll(w.memorySegmentLeases());
writeInProgressList.add(w);
}
+ LOGGER.info("Writing to socket");
final WrittenResult result = establishedContext.socket().write(writeBuffers);
+ LOGGER.info("Transmit <{}> byte(s) to socket", result.bytes());
// remove written ones
Iterator writeableIterator = writeInProgressList.iterator();
while (writeableIterator.hasNext()) {
diff --git a/src/main/java/com/teragrep/net_01/channel/context/EstablishedContextImpl.java b/src/main/java/com/teragrep/net_01/channel/context/EstablishedContextImpl.java
index fc18e1c..a26c0e0 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/EstablishedContextImpl.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/EstablishedContextImpl.java
@@ -84,7 +84,9 @@ final class EstablishedContextImpl implements EstablishedContext {
this.executorService = executorService;
this.socket = socket;
- this.memorySegmentLeasePool = new OpeningPool(new UnboundPool<>(new ArenaMemorySegmentLeaseSupplier(Arena.ofShared(), 4096), new MemorySegmentLeaseStub()));
+ this.memorySegmentLeasePool = new OpeningPool(
+ new UnboundPool<>(new ArenaMemorySegmentLeaseSupplier(Arena.ofShared(), 4096), new MemorySegmentLeaseStub())
+ );
this.ingress = new IngressImpl(this, this.memorySegmentLeasePool);
this.egress = new EgressImpl(this);
diff --git a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
index f108859..de13a10 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
@@ -45,7 +45,6 @@
*/
package com.teragrep.net_01.channel.context;
-import com.teragrep.buf_01.buffer.lease.MemorySegmentLease;
import com.teragrep.buf_01.buffer.lease.OpenableLease;
import com.teragrep.buf_01.buffer.pool.LeaseMultiGet;
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
@@ -58,14 +57,11 @@
import java.io.IOException;
import java.lang.foreign.MemorySegment;
-import java.nio.ByteBuffer;
import java.nio.channels.CancelledKeyException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoStub.java b/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoStub.java
index 9e059d4..208994a 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoStub.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoStub.java
@@ -46,7 +46,6 @@
package com.teragrep.net_01.channel.socket;
import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.security.cert.X509Certificate;
import java.security.Principal;
import java.security.cert.Certificate;
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoTLS.java b/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoTLS.java
index 1517e07..bb08bd2 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoTLS.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/EncryptionInfoTLS.java
@@ -48,7 +48,6 @@
import tlschannel.TlsChannel;
import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.security.cert.X509Certificate;
import java.security.Principal;
import java.security.cert.Certificate;
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/IOResult.java b/src/main/java/com/teragrep/net_01/channel/socket/IOResult.java
index 65326f8..247247d 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/IOResult.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/IOResult.java
@@ -1,3 +1,48 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel.socket;
import com.teragrep.buf_01.buffer.lease.Lease;
@@ -5,6 +50,8 @@
import java.util.List;
public interface IOResult> {
+
public abstract long bytes();
+
public abstract List leases();
}
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/PlainSocket.java b/src/main/java/com/teragrep/net_01/channel/socket/PlainSocket.java
index 8d48704..5c6a364 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/PlainSocket.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/PlainSocket.java
@@ -45,16 +45,12 @@
*/
package com.teragrep.net_01.channel.socket;
-import com.teragrep.buf_01.buffer.lease.OpenableLease;
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
import java.io.IOException;
-import java.lang.foreign.MemorySegment;
-import java.lang.foreign.ValueLayout;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
@@ -107,16 +103,16 @@ public ReadResult read(List srcs) throws IOException
}
//rv.forEach(l -> {
- System.out.println("Lease:");
- /*for (long i = 0 ; i < l.leasedObject().byteSize(); i++) {
- System.out.printf("%s", (char)l.leasedObject().get(ValueLayout.JAVA_BYTE, i));
- }*/
-
- /* while (l.hasNext()) {
- System.out.printf("%s", (char)l.next().byteValue());
- }
-
- System.out.println();*/
+ System.out.println("Lease:");
+ /*for (long i = 0 ; i < l.leasedObject().byteSize(); i++) {
+ System.out.printf("%s", (char)l.leasedObject().get(ValueLayout.JAVA_BYTE, i));
+ }*/
+
+ /* while (l.hasNext()) {
+ System.out.printf("%s", (char)l.next().byteValue());
+ }
+
+ System.out.println();*/
//});
return new ReadResult(readBytes, rv);
}
@@ -145,11 +141,15 @@ public WrittenResult write(List leases) throws IOExce
// mem.segment bigger than bytes left.
// set limit to written amount.
final long limit = byteSize - Math.abs(diff);
- rv.add(new TrackedMemorySegmentLease(bufferLease, new AtomicLong(0L), new AtomicLong(limit)));
+ //rv.add(new TrackedMemorySegmentLease(bufferLease, new AtomicLong(0L), new AtomicLong(limit)));
+ bufferLease.position(0L);
+ bufferLease.limit(limit);
+ rv.add(bufferLease);
}
else {
//else: full mem.segment used, no need to set limit.
- rv.add(new TrackedMemorySegmentLease(bufferLease));
+ //rv.add(new TrackedMemorySegmentLease(bufferLease));
+ rv.add(bufferLease);
}
}
@@ -160,10 +160,6 @@ public WrittenResult write(List leases) throws IOExce
}
}
- rv.forEach(l -> {
- System.out.println(Arrays.toString(l.leasedObject().toArray(ValueLayout.JAVA_BYTE)));
- });
-
return new WrittenResult(bytesWritten, rv);
}
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/ReadResult.java b/src/main/java/com/teragrep/net_01/channel/socket/ReadResult.java
index 1907a5b..fc54de4 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/ReadResult.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/ReadResult.java
@@ -1,3 +1,48 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel.socket;
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
@@ -5,6 +50,7 @@
import java.util.List;
public final class ReadResult implements IOResult {
+
private final long bytesRead;
private final List leases;
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/TLSSocket.java b/src/main/java/com/teragrep/net_01/channel/socket/TLSSocket.java
index c42f9b2..f5e0274 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/TLSSocket.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/TLSSocket.java
@@ -49,7 +49,6 @@
import tlschannel.TlsChannel;
import java.io.IOException;
-import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.List;
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/WrittenResult.java b/src/main/java/com/teragrep/net_01/channel/socket/WrittenResult.java
index 0f4946b..585bad0 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/WrittenResult.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/WrittenResult.java
@@ -1,3 +1,48 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel.socket;
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
@@ -5,6 +50,7 @@
import java.util.List;
public class WrittenResult implements IOResult {
+
private final long bytesWritten;
private final List leases;
diff --git a/src/test/java/com/teragrep/net_01/channel/StringToLease.java b/src/test/java/com/teragrep/net_01/channel/StringToLease.java
index 327d4d3..b36003f 100644
--- a/src/test/java/com/teragrep/net_01/channel/StringToLease.java
+++ b/src/test/java/com/teragrep/net_01/channel/StringToLease.java
@@ -1,3 +1,48 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel;
import com.teragrep.buf_01.buffer.lease.OpenableLease;
@@ -16,6 +61,7 @@ public final class StringToLease {
private final String origin;
private final OpeningPool pool;
+
public StringToLease(final String origin, OpeningPool pool) {
this.origin = origin;
this.pool = pool;
diff --git a/src/test/java/com/teragrep/net_01/channel/context/ConsumingClock.java b/src/test/java/com/teragrep/net_01/channel/context/ConsumingClock.java
index 1bec299..e89300d 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/ConsumingClock.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/ConsumingClock.java
@@ -1,3 +1,48 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel.context;
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
@@ -7,6 +52,7 @@
import java.util.function.Consumer;
public final class ConsumingClock implements Clock {
+
private final EstablishedContext ctx;
private final Consumer> messageConsumer;
diff --git a/src/test/java/com/teragrep/net_01/channel/context/ConsumingClockFactory.java b/src/test/java/com/teragrep/net_01/channel/context/ConsumingClockFactory.java
index 0f6ae32..359c022 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/ConsumingClockFactory.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/ConsumingClockFactory.java
@@ -1,3 +1,48 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel.context;
import java.util.List;
@@ -7,7 +52,7 @@ public final class ConsumingClockFactory implements ClockFactory {
private final Consumer> messageConsumer;
- public ConsumingClockFactory(Consumer> messageConsumer){
+ public ConsumingClockFactory(Consumer> messageConsumer) {
this.messageConsumer = messageConsumer;
}
diff --git a/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java b/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
index d3ee693..8e7bf35 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
@@ -1,3 +1,48 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel.context;
import com.teragrep.buf_01.buffer.pool.OpeningPool;
@@ -8,6 +53,7 @@
import java.util.function.Consumer;
public final class SendingClock implements Clock {
+
private final EstablishedContext ctx;
private final Consumer consumer;
private final OpeningPool pool;
diff --git a/src/test/java/com/teragrep/net_01/channel/context/SendingClockFactory.java b/src/test/java/com/teragrep/net_01/channel/context/SendingClockFactory.java
index 1d9e295..e39c26e 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/SendingClockFactory.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/SendingClockFactory.java
@@ -1,3 +1,48 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel.context;
import com.teragrep.buf_01.buffer.pool.OpeningPool;
@@ -5,6 +50,7 @@
import java.util.function.Consumer;
public final class SendingClockFactory implements ClockFactory {
+
private final Consumer consumer;
private final OpeningPool pool;
diff --git a/src/test/java/com/teragrep/net_01/channel/context/StringWriteable.java b/src/test/java/com/teragrep/net_01/channel/context/StringWriteable.java
index 588b03c..4474de8 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/StringWriteable.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/StringWriteable.java
@@ -1,3 +1,48 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel.context;
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
@@ -6,6 +51,7 @@
import java.util.List;
public final class StringWriteable implements Writeable {
+
private final List buffers;
public StringWriteable(final List buffers) {
@@ -17,7 +63,8 @@ public void close() {
for (TrackedMemorySegmentLease buf : buffers) {
try {
buf.close();
- } catch (final Exception e) {
+ }
+ catch (final Exception e) {
throw new RuntimeException(e);
}
}
diff --git a/src/test/java/com/teragrep/net_01/channel/context/buffer/TrackedMemorySegmentLeaseTest.java b/src/test/java/com/teragrep/net_01/channel/context/buffer/TrackedMemorySegmentLeaseTest.java
index 5aa6c73..099ee4f 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/buffer/TrackedMemorySegmentLeaseTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/buffer/TrackedMemorySegmentLeaseTest.java
@@ -1,3 +1,48 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel.context.buffer;
import com.teragrep.buf_01.buffer.lease.MemorySegmentLeaseStub;
@@ -10,11 +55,13 @@
import java.lang.foreign.Arena;
-public final class TrackedMemorySegmentLeaseTest
-{
+public final class TrackedMemorySegmentLeaseTest {
+
@Test
void testProgressing() {
- final OpeningPool pool = new OpeningPool(new UnboundPool<>(new ArenaMemorySegmentLeaseSupplier(Arena.ofShared(), 5), new MemorySegmentLeaseStub()));
+ final OpeningPool pool = new OpeningPool(
+ new UnboundPool<>(new ArenaMemorySegmentLeaseSupplier(Arena.ofShared(), 5), new MemorySegmentLeaseStub())
+ );
final TrackedMemorySegmentLease trackedLease = new TrackedMemorySegmentLease(pool.get());
Assertions.assertEquals(0L, trackedLease.position());
@@ -23,7 +70,7 @@ void testProgressing() {
for (int i = 0; i < 5; i++) {
Assertions.assertEquals(i, trackedLease.position());
Assertions.assertTrue(trackedLease.hasNext());
- Assertions.assertEquals((byte)0, trackedLease.next());
+ Assertions.assertEquals((byte) 0, trackedLease.next());
loops++;
}
Assertions.assertEquals(5, loops);
@@ -33,4 +80,3 @@ void testProgressing() {
Assertions.assertEquals(5L, trackedLease.position());
}
}
-
diff --git a/src/test/java/com/teragrep/net_01/channel/server/ServerReceivingTest.java b/src/test/java/com/teragrep/net_01/channel/server/ServerReceivingTest.java
index be305d3..4c2aa3a 100644
--- a/src/test/java/com/teragrep/net_01/channel/server/ServerReceivingTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/server/ServerReceivingTest.java
@@ -1,3 +1,48 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel.server;
import com.teragrep.net_01.channel.context.ClockFactory;
@@ -20,6 +65,7 @@
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public final class ServerReceivingTest {
+
private Server server;
private CountDownLatch countDownLatch;
private final List> messages = new ArrayList<>();
@@ -39,8 +85,12 @@ void beforeAll() {
final Thread elT = new Thread(el);
elT.start();
- final ServerFactory serverFactory = new ServerFactory(el,
- Executors.newSingleThreadExecutor(), socketFactory, clockFactory);
+ final ServerFactory serverFactory = new ServerFactory(
+ el,
+ Executors.newSingleThreadExecutor(),
+ socketFactory,
+ clockFactory
+ );
this.server = Assertions.assertDoesNotThrow(() -> serverFactory.create(9090));
}
@@ -58,10 +108,13 @@ void afterEach() {
@Test
void testReceivingOneChar() {
this.countDownLatch = new CountDownLatch(1);
- final java.net.Socket clientSocket = Assertions.assertDoesNotThrow(() -> new java.net.Socket("localhost", 9090));
+ final java.net.Socket clientSocket = Assertions
+ .assertDoesNotThrow(() -> new java.net.Socket("localhost", 9090));
final PrintWriter out = new PrintWriter(Assertions.assertDoesNotThrow(clientSocket::getOutputStream), true);
- final BufferedReader in = new BufferedReader(new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream)));
+ final BufferedReader in = new BufferedReader(
+ new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream))
+ );
out.print("a");
out.flush();
@@ -78,10 +131,13 @@ void testReceivingOneChar() {
@Test
void testReceivingThreeChars() {
this.countDownLatch = new CountDownLatch(1);
- final java.net.Socket clientSocket = Assertions.assertDoesNotThrow(() -> new java.net.Socket("localhost", 9090));
+ final java.net.Socket clientSocket = Assertions
+ .assertDoesNotThrow(() -> new java.net.Socket("localhost", 9090));
final PrintWriter out = new PrintWriter(Assertions.assertDoesNotThrow(clientSocket::getOutputStream), true);
- final BufferedReader in = new BufferedReader(new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream)));
+ final BufferedReader in = new BufferedReader(
+ new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream))
+ );
out.print("a");
out.flush();
diff --git a/src/test/java/com/teragrep/net_01/channel/server/ServerSendingTest.java b/src/test/java/com/teragrep/net_01/channel/server/ServerSendingTest.java
index d42676f..e0e6466 100644
--- a/src/test/java/com/teragrep/net_01/channel/server/ServerSendingTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/server/ServerSendingTest.java
@@ -1,10 +1,54 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel.server;
import com.teragrep.buf_01.buffer.lease.MemorySegmentLeaseStub;
import com.teragrep.buf_01.buffer.pool.OpeningPool;
import com.teragrep.buf_01.buffer.supply.ArenaMemorySegmentLeaseSupplier;
import com.teragrep.net_01.channel.context.ClockFactory;
-import com.teragrep.net_01.channel.context.ConsumingClockFactory;
import com.teragrep.net_01.channel.context.SendingClockFactory;
import com.teragrep.net_01.channel.socket.PlainFactory;
import com.teragrep.net_01.channel.socket.SocketFactory;
@@ -19,21 +63,23 @@
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.foreign.Arena;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public final class ServerSendingTest {
+
private Server server;
private CountDownLatch countDownLatch;
private OpeningPool pool;
+
@BeforeAll
void beforeAll() {
final EventLoopFactory eventLoopFactory = new EventLoopFactory();
final SocketFactory socketFactory = new PlainFactory();
- this.pool = new OpeningPool(new UnboundPool<>(new ArenaMemorySegmentLeaseSupplier(Arena.ofShared(), 128), new MemorySegmentLeaseStub()));
+ this.pool = new OpeningPool(
+ new UnboundPool<>(new ArenaMemorySegmentLeaseSupplier(Arena.ofShared(), 128), new MemorySegmentLeaseStub())
+ );
final ClockFactory clockFactory = new SendingClockFactory((msgStr) -> countDownLatch.countDown(), pool);
final EventLoop el = Assertions.assertDoesNotThrow(eventLoopFactory::create);
@@ -42,8 +88,12 @@ void beforeAll() {
final Thread elT = new Thread(el);
elT.start();
- final ServerFactory serverFactory = new ServerFactory(el,
- Executors.newSingleThreadExecutor(), socketFactory, clockFactory);
+ final ServerFactory serverFactory = new ServerFactory(
+ el,
+ Executors.newSingleThreadExecutor(),
+ socketFactory,
+ clockFactory
+ );
this.server = Assertions.assertDoesNotThrow(() -> serverFactory.create(9090));
}
@@ -57,10 +107,13 @@ void afterAll() {
@Test
void testSending() {
this.countDownLatch = new CountDownLatch(1);
- final java.net.Socket clientSocket = Assertions.assertDoesNotThrow(() -> new java.net.Socket("localhost", 9090));
+ final java.net.Socket clientSocket = Assertions
+ .assertDoesNotThrow(() -> new java.net.Socket("localhost", 9090));
final PrintWriter out = new PrintWriter(Assertions.assertDoesNotThrow(clientSocket::getOutputStream), true);
- final BufferedReader in = new BufferedReader(new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream)));
+ final BufferedReader in = new BufferedReader(
+ new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream))
+ );
final String request = "Hello world! This is some input";
out.println(request);
out.flush();
diff --git a/src/test/java/com/teragrep/net_01/channel/socket/SocketFake.java b/src/test/java/com/teragrep/net_01/channel/socket/SocketFake.java
index b5ba826..fd56c69 100644
--- a/src/test/java/com/teragrep/net_01/channel/socket/SocketFake.java
+++ b/src/test/java/com/teragrep/net_01/channel/socket/SocketFake.java
@@ -47,7 +47,6 @@
import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
-import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Collections;
import java.util.List;
diff --git a/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java b/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
index c66b113..d98ee7f 100644
--- a/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
@@ -1,3 +1,48 @@
+/*
+ * Java Zero Copy Networking Library net_01
+ * Copyright (C) 2024 Suomen Kanuuna Oy
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ *
+ * Additional permission under GNU Affero General Public License version 3
+ * section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with other code, such other code is not for that reason alone subject to any
+ * of the requirements of the GNU Affero GPL version 3 as long as this Program
+ * is the same Program as licensed from Suomen Kanuuna Oy without any additional
+ * modifications.
+ *
+ * Supplemented terms under GNU Affero General Public License version 3
+ * section 7
+ *
+ * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
+ * versions must be marked as "Modified version of" The Program.
+ *
+ * Names of the licensors and authors may not be used for publicity purposes.
+ *
+ * No rights are granted for use of trade names, trademarks, or service marks
+ * which are in The Program if any.
+ *
+ * Licensee must indemnify licensors and authors for any liability that these
+ * contractual assumptions impose on licensors and authors.
+ *
+ * To the extent this program is licensed as part of the Commercial versions of
+ * Teragrep, the applicable Commercial License may apply to this file if you as
+ * a licensee so wish it.
+ */
package com.teragrep.net_01.channel.socket;
import com.teragrep.buf_01.buffer.lease.MemorySegmentLeaseStub;
@@ -16,7 +61,6 @@
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@@ -26,11 +70,14 @@
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public final class SocketTest {
+
private OpeningPool pool;
@BeforeAll
void beforeAll() {
- this.pool = new OpeningPool(new UnboundPool<>(new ArenaMemorySegmentLeaseSupplier(Arena.ofShared(), 128), new MemorySegmentLeaseStub()));
+ this.pool = new OpeningPool(
+ new UnboundPool<>(new ArenaMemorySegmentLeaseSupplier(Arena.ofShared(), 128), new MemorySegmentLeaseStub())
+ );
}
@AfterAll
@@ -66,7 +113,9 @@ void testPlainSocketWrite() {
// Init client
final java.net.Socket clientSocket = new java.net.Socket("localhost", 9090);
- final BufferedReader in = new BufferedReader(new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream)));
+ final BufferedReader in = new BufferedReader(
+ new InputStreamReader(Assertions.assertDoesNotThrow(clientSocket::getInputStream))
+ );
// Init PlainSocket
final Socket socket = new PlainSocket(socketCh.accept());
@@ -145,7 +194,6 @@ private List stringToBuffer(final String str) {
}
}
-
System.out.println("stringToBuffer");
leases.forEach(l -> {
System.out.println(Arrays.toString(l.leasedObject().toArray(ValueLayout.JAVA_BYTE)));
From 7ea558ec34724ad37266f668f8360179236ed380 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Wed, 8 Apr 2026 14:22:37 +0300
Subject: [PATCH 21/45] change method names to better ones in
TrackedMemorySegmentLease
---
.../buffer/TrackedMemorySegmentLease.java | 18 +++++++-----------
.../buffer/TrackedMemorySegmentLeaseTest.java | 6 +++---
2 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
index 15baba8..10ae381 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
@@ -144,28 +144,24 @@ public void write(final byte b) {
origin.leasedObject().set(ValueLayout.JAVA_BYTE, nextIndex, b);
}
- public long position() {
+ public long currentPosition() {
return currentOffset.get();
}
- public void position(long pos) {
- currentOffset.set(pos);
+ public void position(final long newPosition) {
+ currentOffset.set(newPosition);
}
- public long limit() {
+ public long currentLimit() {
return limit.get();
}
- public void limit(long newLimit) {
- limit.set(newLimit);
- }
-
- public long limit(int index) {
- if (index < 0 || index > leasedObject().byteSize()) {
+ public long limit(final long newLimit) {
+ if (newLimit < 0 || newLimit > leasedObject().byteSize()) {
throw new IndexOutOfBoundsException("Out of bounds");
}
- limit.set(index);
+ limit.set(newLimit);
return limit.get();
}
}
diff --git a/src/test/java/com/teragrep/net_01/channel/context/buffer/TrackedMemorySegmentLeaseTest.java b/src/test/java/com/teragrep/net_01/channel/context/buffer/TrackedMemorySegmentLeaseTest.java
index 099ee4f..e08776c 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/buffer/TrackedMemorySegmentLeaseTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/buffer/TrackedMemorySegmentLeaseTest.java
@@ -64,11 +64,11 @@ void testProgressing() {
);
final TrackedMemorySegmentLease trackedLease = new TrackedMemorySegmentLease(pool.get());
- Assertions.assertEquals(0L, trackedLease.position());
+ Assertions.assertEquals(0L, trackedLease.currentPosition());
int loops = 0;
for (int i = 0; i < 5; i++) {
- Assertions.assertEquals(i, trackedLease.position());
+ Assertions.assertEquals(i, trackedLease.currentPosition());
Assertions.assertTrue(trackedLease.hasNext());
Assertions.assertEquals((byte) 0, trackedLease.next());
loops++;
@@ -77,6 +77,6 @@ void testProgressing() {
Assertions.assertFalse(trackedLease.hasNext());
Assertions.assertThrows(IndexOutOfBoundsException.class, trackedLease::next);
- Assertions.assertEquals(5L, trackedLease.position());
+ Assertions.assertEquals(5L, trackedLease.currentPosition());
}
}
From bb88473a754454098d35836edf897cf8b6ddfc69 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Wed, 8 Apr 2026 14:23:07 +0300
Subject: [PATCH 22/45] remove return value from limit method in
TrackedMemorySegmentLease
---
.../net_01/channel/buffer/TrackedMemorySegmentLease.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
index 10ae381..8cf3754 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
@@ -156,12 +156,11 @@ public long currentLimit() {
return limit.get();
}
- public long limit(final long newLimit) {
+ public void limit(final long newLimit) {
if (newLimit < 0 || newLimit > leasedObject().byteSize()) {
throw new IndexOutOfBoundsException("Out of bounds");
}
limit.set(newLimit);
- return limit.get();
}
}
From 6c6541124085ad65b242f4c47c1206afb8936a40 Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Wed, 8 Apr 2026 14:26:55 +0300
Subject: [PATCH 23/45] add checks for Out of bounds in
TrackedMemorySegmentLease
---
.../channel/buffer/TrackedMemorySegmentLease.java | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
index 8cf3754..1171a94 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
@@ -149,6 +149,13 @@ public long currentPosition() {
}
public void position(final long newPosition) {
+ final long segmentByteSize = leasedObject().byteSize();
+ if (newPosition < 0 || newPosition > segmentByteSize) {
+ throw new IndexOutOfBoundsException(
+ "New position was out of bounds; expected value between 0 and " + segmentByteSize + "; was "
+ + newPosition
+ );
+ }
currentOffset.set(newPosition);
}
@@ -157,8 +164,12 @@ public long currentLimit() {
}
public void limit(final long newLimit) {
- if (newLimit < 0 || newLimit > leasedObject().byteSize()) {
- throw new IndexOutOfBoundsException("Out of bounds");
+ final long segmentByteSize = leasedObject().byteSize();
+ if (newLimit < -1 || newLimit > segmentByteSize) {
+ throw new IndexOutOfBoundsException(
+ "New limit was out of bounds; expected value between -1 and " + segmentByteSize + "; was "
+ + newLimit
+ );
}
limit.set(newLimit);
From 1107873593173f2ce494d3c1165314e0a1cdcf0d Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Fri, 10 Apr 2026 15:13:55 +0300
Subject: [PATCH 24/45] remove boxed Byte from TrackedMemorySegmentLease
---
.../net_01/channel/buffer/TrackedMemorySegmentLease.java | 7 ++-----
.../com/teragrep/net_01/channel/context/SendingClock.java | 2 +-
.../com/teragrep/net_01/channel/socket/SocketTest.java | 2 +-
3 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
index 1171a94..a3e52cf 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
@@ -49,10 +49,9 @@
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
-import java.util.Iterator;
import java.util.concurrent.atomic.AtomicLong;
-public class TrackedMemorySegmentLease implements Lease, Iterator {
+public class TrackedMemorySegmentLease implements Lease {
private final Lease origin;
private final AtomicLong currentOffset;
@@ -111,7 +110,6 @@ public void close() throws Exception {
origin.close();
}
- @Override
public boolean hasNext() {
final boolean rv;
if (limit.get() == -1) {
@@ -124,8 +122,7 @@ public boolean hasNext() {
return rv;
}
- @Override
- public Byte next() {
+ public byte next() {
if (!hasNext()) {
throw new IndexOutOfBoundsException("Reached end of segment or limit, cannot provide next byte");
}
diff --git a/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java b/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
index 8e7bf35..f1018f1 100644
--- a/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
+++ b/src/test/java/com/teragrep/net_01/channel/context/SendingClock.java
@@ -68,7 +68,7 @@ public SendingClock(final EstablishedContext ctx, final Consumer consume
public void advance(final TrackedMemorySegmentLease bufferLease) {
final StringBuilder stringBuilder = new StringBuilder();
while (bufferLease.hasNext()) {
- final char c = (char) bufferLease.next().byteValue();
+ final char c = (char) bufferLease.next();
stringBuilder.append(c);
}
diff --git a/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java b/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
index d98ee7f..10db124 100644
--- a/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
+++ b/src/test/java/com/teragrep/net_01/channel/socket/SocketTest.java
@@ -163,7 +163,7 @@ private String bufferToString(final List leases) {
final StringBuilder stringBuilder = new StringBuilder();
for (final TrackedMemorySegmentLease buf : leases) {
while (buf.hasNext()) {
- stringBuilder.append((char) buf.next().byteValue());
+ stringBuilder.append((char) buf.next());
}
}
return stringBuilder.toString();
From 35d58794e298757b6f24e33bcabc6ba387cbb2de Mon Sep 17 00:00:00 2001
From: eemhu <125959687+eemhu@users.noreply.github.com>
Date: Tue, 21 Apr 2026 09:24:18 +0300
Subject: [PATCH 25/45] change to use buf_01 version of
TrackedMemorySegmentLease
---
.../buffer/TrackedMemorySegmentLease.java | 174 ------------------
.../channel/buffer/writable/Writeable.java | 5 +-
.../buffer/writable/WriteableAccess.java | 6 +-
.../buffer/writable/WriteableClosure.java | 6 +-
.../writable/WriteableInvalidation.java | 7 +-
.../buffer/writable/WriteableLeaseful.java | 5 +-
.../buffer/writable/WriteableStub.java | 5 +-
.../channel/buffer/writable/Writeables.java | 8 +-
.../net_01/channel/context/Clock.java | 6 +-
.../net_01/channel/context/EgressImpl.java | 5 +-
.../net_01/channel/context/IngressImpl.java | 9 +-
.../net_01/channel/socket/PlainSocket.java | 20 +-
.../net_01/channel/socket/ReadResult.java | 11 +-
.../net_01/channel/socket/Socket.java | 11 +-
.../net_01/channel/socket/TLSSocket.java | 7 +-
.../net_01/channel/socket/WrittenResult.java | 11 +-
.../net_01/channel/StringToLease.java | 7 +-
.../channel/context/ConsumingClock.java | 5 +-
.../net_01/channel/context/SendingClock.java | 5 +-
.../channel/context/StringWriteable.java | 13 +-
.../buffer/TrackedMemorySegmentLeaseTest.java | 6 +-
.../net_01/channel/socket/SocketFake.java | 7 +-
.../net_01/channel/socket/SocketTest.java | 21 ++-
23 files changed, 107 insertions(+), 253 deletions(-)
delete mode 100644 src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java b/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
deleted file mode 100644
index a3e52cf..0000000
--- a/src/main/java/com/teragrep/net_01/channel/buffer/TrackedMemorySegmentLease.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Java Zero Copy Networking Library net_01
- * Copyright (C) 2024 Suomen Kanuuna Oy
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *
- *
- * Additional permission under GNU Affero General Public License version 3
- * section 7
- *
- * If you modify this Program, or any covered work, by linking or combining it
- * with other code, such other code is not for that reason alone subject to any
- * of the requirements of the GNU Affero GPL version 3 as long as this Program
- * is the same Program as licensed from Suomen Kanuuna Oy without any additional
- * modifications.
- *
- * Supplemented terms under GNU Affero General Public License version 3
- * section 7
- *
- * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
- * versions must be marked as "Modified version of" The Program.
- *
- * Names of the licensors and authors may not be used for publicity purposes.
- *
- * No rights are granted for use of trade names, trademarks, or service marks
- * which are in The Program if any.
- *
- * Licensee must indemnify licensors and authors for any liability that these
- * contractual assumptions impose on licensors and authors.
- *
- * To the extent this program is licensed as part of the Commercial versions of
- * Teragrep, the applicable Commercial License may apply to this file if you as
- * a licensee so wish it.
- */
-package com.teragrep.net_01.channel.buffer;
-
-import com.teragrep.buf_01.buffer.lease.Lease;
-
-import java.lang.foreign.MemorySegment;
-import java.lang.foreign.ValueLayout;
-import java.util.concurrent.atomic.AtomicLong;
-
-public class TrackedMemorySegmentLease implements Lease {
-
- private final Lease origin;
- private final AtomicLong currentOffset;
- private final AtomicLong limit;
-
- public TrackedMemorySegmentLease(final Lease origin) {
- this(origin, new AtomicLong(0L));
- }
-
- public TrackedMemorySegmentLease(final Lease origin, final AtomicLong currentOffset) {
- this(origin, currentOffset, new AtomicLong(-1L));
- }
-
- public TrackedMemorySegmentLease(
- final Lease origin,
- final AtomicLong currentOffset,
- final AtomicLong limit
- ) {
- this.origin = origin;
- this.currentOffset = currentOffset;
- this.limit = limit;
- }
-
- @Override
- public long id() {
- return origin.id();
- }
-
- @Override
- public long refs() {
- return origin.refs();
- }
-
- @Override
- public MemorySegment leasedObject() {
- return origin.leasedObject();
- }
-
- @Override
- public boolean hasZeroRefs() {
- return origin.hasZeroRefs();
- }
-
- @Override
- public Lease sliceAt(final long offset) {
- return origin.sliceAt(offset);
- }
-
- @Override
- public boolean isStub() {
- return origin.isStub();
- }
-
- @Override
- public void close() throws Exception {
- origin.close();
- }
-
- public boolean hasNext() {
- final boolean rv;
- if (limit.get() == -1) {
- // limit not set, ignore
- rv = currentOffset.get() < origin.leasedObject().byteSize();
- }
- else {
- rv = currentOffset.get() < Math.min(limit.get(), origin.leasedObject().byteSize());
- }
- return rv;
- }
-
- public byte next() {
- if (!hasNext()) {
- throw new IndexOutOfBoundsException("Reached end of segment or limit, cannot provide next byte");
- }
- final long nextIndex = currentOffset.getAndIncrement();
-
- return origin.leasedObject().get(ValueLayout.JAVA_BYTE, nextIndex);
- }
-
- public void write(final byte b) {
- if (!hasNext()) {
- throw new IndexOutOfBoundsException("Reached end of segment or limit, cannot write to next byte");
- }
-
- final long nextIndex = currentOffset.getAndIncrement();
-
- origin.leasedObject().set(ValueLayout.JAVA_BYTE, nextIndex, b);
- }
-
- public long currentPosition() {
- return currentOffset.get();
- }
-
- public void position(final long newPosition) {
- final long segmentByteSize = leasedObject().byteSize();
- if (newPosition < 0 || newPosition > segmentByteSize) {
- throw new IndexOutOfBoundsException(
- "New position was out of bounds; expected value between 0 and " + segmentByteSize + "; was "
- + newPosition
- );
- }
- currentOffset.set(newPosition);
- }
-
- public long currentLimit() {
- return limit.get();
- }
-
- public void limit(final long newLimit) {
- final long segmentByteSize = leasedObject().byteSize();
- if (newLimit < -1 || newLimit > segmentByteSize) {
- throw new IndexOutOfBoundsException(
- "New limit was out of bounds; expected value between -1 and " + segmentByteSize + "; was "
- + newLimit
- );
- }
-
- limit.set(newLimit);
- }
-}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeable.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeable.java
index 2298cbf..2018032 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeable.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeable.java
@@ -45,9 +45,10 @@
*/
package com.teragrep.net_01.channel.buffer.writable;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
import java.io.Closeable;
+import java.lang.foreign.MemorySegment;
import java.util.List;
public interface Writeable extends Closeable {
@@ -55,7 +56,7 @@ public interface Writeable extends Closeable {
@Override
void close();
- List memorySegmentLeases();
+ List> memorySegmentLeases();
boolean hasRemaining();
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableAccess.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableAccess.java
index e0b0fde..78cb506 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableAccess.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableAccess.java
@@ -45,10 +45,12 @@
*/
package com.teragrep.net_01.channel.buffer.writable;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
+import com.teragrep.buf_01.buffer.lease.TrackedMemorySegmentLease;
import com.teragrep.net_01.channel.buffer.access.Access;
import com.teragrep.net_01.channel.buffer.access.Lease;
+import java.lang.foreign.MemorySegment;
import java.util.List;
public final class WriteableAccess implements Writeable {
@@ -62,7 +64,7 @@ public WriteableAccess(Writeable writeable, Access access) {
}
@Override
- public List memorySegmentLeases() {
+ public List> memorySegmentLeases() {
// FIXME just not right
try (Lease ignored = access.get()) {
return writeable.memorySegmentLeases();
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableClosure.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableClosure.java
index 6b3c4d7..22f4895 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableClosure.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableClosure.java
@@ -45,11 +45,13 @@
*/
package com.teragrep.net_01.channel.buffer.writable;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
+import com.teragrep.buf_01.buffer.lease.TrackedMemorySegmentLease;
import com.teragrep.net_01.channel.context.EstablishedContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.lang.foreign.MemorySegment;
import java.util.List;
/**
@@ -82,7 +84,7 @@ public void close() {
}
@Override
- public List memorySegmentLeases() {
+ public List> memorySegmentLeases() {
return writeable.memorySegmentLeases();
}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableInvalidation.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableInvalidation.java
index 082b674..ec9c4b7 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableInvalidation.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableInvalidation.java
@@ -45,8 +45,9 @@
*/
package com.teragrep.net_01.channel.buffer.writable;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
+import java.lang.foreign.MemorySegment;
import java.nio.ByteBuffer;
import java.util.List;
@@ -65,7 +66,7 @@ public WriteableInvalidation(Writeable writeable) {
@Override
public void close() {
- for (final TrackedMemorySegmentLease lease : memorySegmentLeases()) {
+ for (final TrackedLease lease : memorySegmentLeases()) {
try {
lease.close();
}
@@ -77,7 +78,7 @@ public void close() {
}
@Override
- public List memorySegmentLeases() {
+ public List> memorySegmentLeases() {
return writeable.memorySegmentLeases();
}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java
index 36748a2..dd23d98 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableLeaseful.java
@@ -46,7 +46,8 @@
package com.teragrep.net_01.channel.buffer.writable;
import com.teragrep.buf_01.buffer.lease.OpenableLease;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
+import com.teragrep.buf_01.buffer.lease.TrackedMemorySegmentLease;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -66,7 +67,7 @@ public WriteableLeaseful(Writeable writeable, List>
}
@Override
- public List memorySegmentLeases() {
+ public List> memorySegmentLeases() {
return writeable.memorySegmentLeases();
}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableStub.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableStub.java
index ff96133..d37daf8 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableStub.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/WriteableStub.java
@@ -45,14 +45,15 @@
*/
package com.teragrep.net_01.channel.buffer.writable;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
+import java.lang.foreign.MemorySegment;
import java.util.List;
public final class WriteableStub implements Writeable {
@Override
- public List memorySegmentLeases() {
+ public List> memorySegmentLeases() {
throw new UnsupportedOperationException("WriteableStub does not allow this method");
}
diff --git a/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeables.java b/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeables.java
index 8df719b..fdb46c4 100644
--- a/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeables.java
+++ b/src/main/java/com/teragrep/net_01/channel/buffer/writable/Writeables.java
@@ -45,8 +45,10 @@
*/
package com.teragrep.net_01.channel.buffer.writable;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
+import com.teragrep.buf_01.buffer.lease.TrackedMemorySegmentLease;
+import java.lang.foreign.MemorySegment;
import java.util.ArrayList;
import java.util.List;
@@ -59,7 +61,7 @@ public Writeables(Writeable ... writeables) {
}
@Override
- public List memorySegmentLeases() {
+ public List> memorySegmentLeases() {
long totalBuffers = 0;
for (Writeable writeable : writeables) {
totalBuffers = totalBuffers + writeable.memorySegmentLeases().size();
@@ -71,7 +73,7 @@ public List memorySegmentLeases() {
);
}
- List bufferArray = new ArrayList<>((int) totalBuffers);
+ List> bufferArray = new ArrayList<>((int) totalBuffers);
for (final Writeable writeable : writeables) {
bufferArray.addAll(writeable.memorySegmentLeases());
}
diff --git a/src/main/java/com/teragrep/net_01/channel/context/Clock.java b/src/main/java/com/teragrep/net_01/channel/context/Clock.java
index d1bfca0..ad2861d 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/Clock.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/Clock.java
@@ -45,7 +45,9 @@
*/
package com.teragrep.net_01.channel.context;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
+
+import java.lang.foreign.MemorySegment;
public interface Clock extends AutoCloseable {
@@ -53,5 +55,5 @@ public interface Clock extends AutoCloseable {
* @param bufferLease to be consumed by the Clock. Clock or it's subsequent actions must close all BufferLease's it
* receives otherwise encapsulated buffers are not reusable and memory allocator consumes time.
*/
- void advance(TrackedMemorySegmentLease bufferLease);
+ void advance(TrackedLease bufferLease);
}
diff --git a/src/main/java/com/teragrep/net_01/channel/context/EgressImpl.java b/src/main/java/com/teragrep/net_01/channel/context/EgressImpl.java
index b121545..5d35488 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/EgressImpl.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/EgressImpl.java
@@ -45,7 +45,7 @@
*/
package com.teragrep.net_01.channel.context;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
import com.teragrep.net_01.channel.buffer.writable.Writeable;
import com.teragrep.net_01.channel.buffer.writable.WriteableStub;
import com.teragrep.net_01.channel.socket.WrittenResult;
@@ -56,6 +56,7 @@
import java.io.IOException;
+import java.lang.foreign.MemorySegment;
import java.nio.channels.CancelledKeyException;
import java.util.ArrayList;
import java.util.Iterator;
@@ -165,7 +166,7 @@ public void accept(Writeable writeable) {
private void transmit(final List toWriteList) throws IOException {
try {
- final List writeBuffers = new ArrayList<>();
+ final List> writeBuffers = new ArrayList<>();
for (final Writeable w : toWriteList) {
writeBuffers.addAll(w.memorySegmentLeases());
diff --git a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
index de13a10..159fd12 100644
--- a/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
+++ b/src/main/java/com/teragrep/net_01/channel/context/IngressImpl.java
@@ -46,8 +46,9 @@
package com.teragrep.net_01.channel.context;
import com.teragrep.buf_01.buffer.lease.OpenableLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
+import com.teragrep.buf_01.buffer.lease.TrackedMemorySegmentLease;
import com.teragrep.buf_01.buffer.pool.LeaseMultiGet;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
import com.teragrep.net_01.channel.socket.ReadResult;
import com.teragrep.poj_01.pool.Pool;
import org.slf4j.Logger;
@@ -74,7 +75,7 @@ final class IngressImpl implements Ingress {
private final EstablishedContextImpl establishedContext;
private final Pool> memorySegmentLeasePool;
- private final List activeBuffers;
+ private final List> activeBuffers;
private final Lock lock;
// tls
public final AtomicBoolean needWrite;
@@ -115,7 +116,7 @@ public void run() {
System.out.println("activeBuffers.isEmpty=" + activeBuffers.isEmpty());
while (!activeBuffers.isEmpty()) {
// IMPORTANT: current tls implementation will skip bytes if BufferLeases are not fully consumed.
- TrackedMemorySegmentLease bufferLease = activeBuffers.removeFirst();
+ TrackedLease bufferLease = activeBuffers.removeFirst();
LOGGER
.debug(
"submitting buffer <{}> from activeBuffers <{}> to relpFrame", bufferLease,
@@ -234,7 +235,7 @@ private long readData() throws IOException {
List> bufferLeases = new LeaseMultiGet(memorySegmentLeasePool).get(4);
- List trackedMemorySegmentLeases = new LinkedList<>();
+ List> trackedMemorySegmentLeases = new LinkedList<>();
for (OpenableLease bufferLease : bufferLeases) {
if (bufferLease.isStub()) {
continue;
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/PlainSocket.java b/src/main/java/com/teragrep/net_01/channel/socket/PlainSocket.java
index 5c6a364..f902317 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/PlainSocket.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/PlainSocket.java
@@ -45,9 +45,11 @@
*/
package com.teragrep.net_01.channel.socket;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
+import com.teragrep.buf_01.buffer.lease.TrackedMemorySegmentLease;
import java.io.IOException;
+import java.lang.foreign.MemorySegment;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
@@ -66,8 +68,8 @@ final class PlainSocket implements Socket {
}
@Override
- public ReadResult read(List srcs) throws IOException {
- final List rv = new ArrayList<>(srcs.size());
+ public ReadResult read(List> srcs) throws IOException {
+ final List> rv = new ArrayList<>(srcs.size());
final List byteBuffers = new ArrayList<>(srcs.size());
srcs.forEach(src -> {
byteBuffers.add(src.leasedObject().asByteBuffer());
@@ -77,7 +79,7 @@ public ReadResult read(List srcs) throws IOException
long bytesLeft = readBytes;
boolean allRead = false;
- for (final TrackedMemorySegmentLease bufferLease : srcs) {
+ for (final TrackedLease bufferLease : srcs) {
final long byteSize = bufferLease.leasedObject().byteSize();
if (!allRead && readBytes > 0) {
@@ -87,7 +89,7 @@ public ReadResult read(List srcs) throws IOException
// mem.segment bigger than bytes left.
// set limit to read amount.
final long limit = byteSize - Math.abs(diff);
- rv.add(new TrackedMemorySegmentLease(bufferLease, new AtomicLong(0L), new AtomicLong(limit)));
+ rv.add(new TrackedMemorySegmentLease(bufferLease, 0L, limit));
}
else {
//else: full mem.segment used, no need to set limit.
@@ -118,11 +120,11 @@ public ReadResult read(List srcs) throws IOException
}
@Override
- public WrittenResult write(List leases) throws IOException {
+ public WrittenResult write(List> leases) throws IOException {
final List buffersToWrite = new ArrayList<>(leases.size());
- final List rv = new ArrayList<>(leases.size());
+ final List> rv = new ArrayList<>(leases.size());
- for (final TrackedMemorySegmentLease lease : leases) {
+ for (final TrackedLease lease : leases) {
buffersToWrite.add(lease.leasedObject().asByteBuffer());
}
@@ -131,7 +133,7 @@ public WrittenResult write(List leases) throws IOExce
long bytesLeft = bytesWritten;
boolean allWritten = false;
- for (final TrackedMemorySegmentLease bufferLease : leases) {
+ for (final TrackedLease bufferLease : leases) {
final long byteSize = bufferLease.leasedObject().byteSize();
if (!allWritten && bytesWritten > 0) {
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/ReadResult.java b/src/main/java/com/teragrep/net_01/channel/socket/ReadResult.java
index fc54de4..c5a10ed 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/ReadResult.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/ReadResult.java
@@ -45,16 +45,17 @@
*/
package com.teragrep.net_01.channel.socket;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
+import java.lang.foreign.MemorySegment;
import java.util.List;
-public final class ReadResult implements IOResult {
+public final class ReadResult implements IOResult> {
private final long bytesRead;
- private final List leases;
+ private final List> leases;
- public ReadResult(final long bytesRead, final List leases) {
+ public ReadResult(final long bytesRead, final List> leases) {
this.bytesRead = bytesRead;
this.leases = leases;
}
@@ -65,7 +66,7 @@ public long bytes() {
}
@Override
- public List leases() {
+ public List> leases() {
return leases;
}
}
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/Socket.java b/src/main/java/com/teragrep/net_01/channel/socket/Socket.java
index 2b2bd66..8faebe8 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/Socket.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/Socket.java
@@ -45,9 +45,10 @@
*/
package com.teragrep.net_01.channel.socket;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
import java.io.IOException;
+import java.lang.foreign.MemorySegment;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.List;
@@ -60,20 +61,20 @@ public interface Socket {
/**
* Read data from a network connection.
*
- * @param dsts {@link ByteBuffer}s which are read to from the connection
+ * @param srcs {@link TrackedLease}s which are read to from the connection
* @return amount of bytes read
* @throws IOException if read fails
*/
- ReadResult read(List srcs) throws IOException;
+ ReadResult read(List> srcs) throws IOException;
/**
* Write data through a network connection.
*
- * @param dsts {@link ByteBuffer}s which are written to the connection
+ * @param dsts {@link TrackedLease}s which are written to the connection
* @return amount of bytes written
* @throws IOException if write fails
*/
- WrittenResult write(List dsts) throws IOException;
+ WrittenResult write(List> dsts) throws IOException;
/**
* Provides information about a network connection
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/TLSSocket.java b/src/main/java/com/teragrep/net_01/channel/socket/TLSSocket.java
index f5e0274..07a4b03 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/TLSSocket.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/TLSSocket.java
@@ -45,10 +45,11 @@
*/
package com.teragrep.net_01.channel.socket;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
import tlschannel.TlsChannel;
import java.io.IOException;
+import java.lang.foreign.MemorySegment;
import java.nio.channels.SocketChannel;
import java.util.List;
@@ -66,13 +67,13 @@ final class TLSSocket implements Socket {
}
@Override
- public ReadResult read(List dsts) throws IOException {
+ public ReadResult read(List> dsts) throws IOException {
throw new UnsupportedOperationException();
//return tlsChannel.read(dsts);
}
@Override
- public WrittenResult write(List dsts) throws IOException {
+ public WrittenResult write(List> dsts) throws IOException {
throw new UnsupportedOperationException();
//return tlsChannel.write(dsts);
}
diff --git a/src/main/java/com/teragrep/net_01/channel/socket/WrittenResult.java b/src/main/java/com/teragrep/net_01/channel/socket/WrittenResult.java
index 585bad0..e198f4f 100644
--- a/src/main/java/com/teragrep/net_01/channel/socket/WrittenResult.java
+++ b/src/main/java/com/teragrep/net_01/channel/socket/WrittenResult.java
@@ -45,16 +45,17 @@
*/
package com.teragrep.net_01.channel.socket;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
+import java.lang.foreign.MemorySegment;
import java.util.List;
-public class WrittenResult implements IOResult {
+public class WrittenResult implements IOResult> {
private final long bytesWritten;
- private final List leases;
+ private final List> leases;
- public WrittenResult(final long bytesWritten, final List leases) {
+ public WrittenResult(final long bytesWritten, final List> leases) {
this.bytesWritten = bytesWritten;
this.leases = leases;
}
@@ -65,7 +66,7 @@ public long bytes() {
}
@Override
- public List leases() {
+ public List> leases() {
return leases;
}
}
diff --git a/src/test/java/com/teragrep/net_01/channel/StringToLease.java b/src/test/java/com/teragrep/net_01/channel/StringToLease.java
index b36003f..ad4f272 100644
--- a/src/test/java/com/teragrep/net_01/channel/StringToLease.java
+++ b/src/test/java/com/teragrep/net_01/channel/StringToLease.java
@@ -46,9 +46,10 @@
package com.teragrep.net_01.channel;
import com.teragrep.buf_01.buffer.lease.OpenableLease;
+import com.teragrep.buf_01.buffer.lease.TrackedLease;
+import com.teragrep.buf_01.buffer.lease.TrackedMemorySegmentLease;
import com.teragrep.buf_01.buffer.pool.LeaseMultiGet;
import com.teragrep.buf_01.buffer.pool.OpeningPool;
-import com.teragrep.net_01.channel.buffer.TrackedMemorySegmentLease;
import com.teragrep.net_01.channel.buffer.writable.Writeable;
import com.teragrep.net_01.channel.context.StringWriteable;
@@ -70,13 +71,13 @@ public StringToLease(final String origin, OpeningPool pool) {
public Writeable toWriteable() {
final byte[] bytes = origin.getBytes(StandardCharsets.UTF_8);
final List> leases = new LeaseMultiGet(pool).get(bytes.length);
- final List trackedLeases = new ArrayList<>(leases.size());
+ final List> trackedLeases = new ArrayList<>(leases.size());
for (final OpenableLease lease : leases) {
trackedLeases.add(new TrackedMemorySegmentLease(lease));
}
int i = 0;
- for (final TrackedMemorySegmentLease trackedLease : trackedLeases) {
+ for (final TrackedLease