/*
 * Copyright 2016-2022 chronicle.software
 *
 *       https://chronicle.software
 *
 * Licensed under Contract only
 */

package net.openhft.chronicle.wire.channel;

import net.openhft.chronicle.bytes.Bytes;
import net.openhft.chronicle.bytes.MethodReader;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.wire.DocumentContext;
import net.openhft.chronicle.wire.WireOut;
import net.openhft.chronicle.wire.channel.echo.DummyData;
import net.openhft.chronicle.wire.channel.echo.EchoHandler;

import java.util.concurrent.atomic.AtomicLong;

public class PerfThroughputMain {
    static final int RUN_TIME = Integer.getInteger("runTime", 5);
    static final String URL = System.getProperty("url", "tcp://:1248");
    static final boolean METHOD_RW = Jvm.getBoolean("method.rw");

    public static void main(String[] args) {
        try (ChronicleContext context = ChronicleContext.newContext(URL)) {
            EchoHandler echoHandler = new EchoHandler();
            final ChronicleChannelSupplier supplier = context.newChannelSupplier(echoHandler);
            ChronicleChannel channel = supplier.get();

            doTest("unbuffered", channel);

            echoHandler.buffered(true);
            ChronicleChannel channel2 = supplier.buffered(true).get();

            doTest("buffered", channel2);
        }
    }

    private static void doTest(String desc, ChronicleChannel channel) {
        DummyData data = new DummyData();
        for (int size = 32 << 10; size >= 8; size /= 2) {
            data.data(new byte[size - Long.BYTES]);
            long start = System.currentTimeMillis();
            long end = start + RUN_TIME * 1000L;
            final Echoing echoing = channel.methodWriter(Echoing.class);
            long count = 0;
            AtomicLong unread = new AtomicLong(0);
            int window = (128 << 20) / size;
            if (METHOD_RW) {
                MethodReader reader = channel.methodReader((Echoing) d -> {
                    unread.getAndDecrement();
                });
                do {
                    echoing.echo(data);
                    unread.getAndIncrement();
                    count++;
                    do {
                        reader.readOne();
                    } while (unread.get() > window);
                } while (System.currentTimeMillis() < end);

                do {
                    reader.readOne();
                } while (unread.get() > 0);

            } else {
                InternalChronicleChannel icc = (InternalChronicleChannel) channel;
                do {
                    final Bytes<?> bytes = icc.acquireProducer().bytes();
                    bytes.writeInt(size);
                    for(int i=0;i<size;i+=8)
                        bytes.writeLong(0L);
                    icc.releaseProducer();

                    unread.getAndIncrement();
                    count++;
                    do {
                        try (DocumentContext dc = channel.readingDocument()){
                            if (dc.isPresent())
                                unread.getAndDecrement();
                        }
                    } while (unread.get() > window);
                } while (System.currentTimeMillis() < end);

                do {
                    try (DocumentContext dc = channel.readingDocument()){
                        if (dc.isPresent())
                            unread.getAndDecrement();
                    }
                } while (unread.get() > 0);
            }
            long time = System.currentTimeMillis() - start;
            long totalBytes = size * count;
            long MBps = totalBytes / time / (1_000_000 / 1_000);
            long rate = count * 1000 / time;
            System.out.println("desc: " + desc + ", size: " + size + ", MBps: " + MBps+", mps: "+rate);
        }
    }
}

@@ -347,51 +347,8 @@
 xt;%0A
-import net.openhft.chronicle.wire.WireOut;%0A
 impo
@@ -401,16 +401,16 @@
 myData;%0A
+
 import n
@@ -548,74 +548,8 @@
 n %7B%0A
-    static final int RUN_TIME = Integer.getInteger(%22runTime%22, 5);%0A
     
@@ -616,16 +616,82 @@
 1248%22);%0A
+    static final int RUN_TIME = Integer.getInteger(%22runTime%22, 5);%0A
     stat
@@ -745,24 +745,24 @@
 thod.rw%22);%0A%0A
-
     public s
@@ -790,24 +790,167 @@
 g%5B%5D args) %7B%0A
+        System.out.println(%22-Durl=%22 + URL + %22 %22 +%0A                %22-DrunTime=%22 + RUN_TIME + %22 %22 +%0A                %22-Dmethod.rw=%22 + METHOD_RW);%0A
         try 
@@ -2819,27 +2819,36 @@
  for
+ 
 (int i
-=0;i%3C
+ = 0; i %3C 
 size;
-i
+ i 
 +=
+ 
 8)%0A 
@@ -3103,32 +3103,33 @@
 adingDocument())
+ 
 %7B%0A              
@@ -3453,16 +3453,17 @@
 ument())
+ 
 %7B%0A      
@@ -3934,17 +3934,19 @@
 %22 + MBps
-+
+ + 
 %22, mps: 
@@ -3946,17 +3946,19 @@
 , mps: %22
-+
+ + 
 rate);%0A 

Add a single channel throughput test