import java.util.ArrayDeque;
import java.util.Deque;
import java.util.List;

/**
 * Kalkulator sekaligus simulasi performa concurrency berbasis angka tetap:
 * hukum Amdahl, model kontensi lock, rumus ukuran thread pool, model memori
 * platform vs virtual thread, dan simulasi penjadwalan round-robin
 * berpenghitung langkah. Seluruh keluaran deterministik.
 */
public class SkalaConcurrency {

    public static void main(String[] args) {
        // ---- 1. Hukum Amdahl: speedup maksimum ----
        System.out.println("== 1. Hukum Amdahl: speedup maksimum ==");
        System.out.printf("%10s %6s %6s %6s %6s %6s%n",
            "p paralel", "N=1", "N=2", "N=4", "N=8", "N=16");
        for (double p : new double[] {0.50, 0.90, 0.95, 0.99}) {
            System.out.printf("%10.2f", p);
            for (int n : new int[] {1, 2, 4, 8, 16}) {
                double speedup = 1.0 / ((1.0 - p) + p / n);
                System.out.printf(" %6.2f", speedup);
            }
            System.out.println();
        }
        System.out.println();

        // ---- 2. Kontensi lock: bagian kritis memaksa antrean ----
        System.out.println("== 2. Model kontensi lock (8 core, tugas 100 unit) ==");
        System.out.printf("%12s %12s %12s%n", "unit kritis", "speedup", "efisiensi");
        for (int c : new int[] {5, 10, 20}) {
            int n = 8;
            int w = 100;
            double waktu = (double) (n * c + (w - c)); // antrean serial + sisa paralel
            double speedup = (double) (n * w) / waktu;
            System.out.printf("%12d %12.2f %11.0f%%%n", c, speedup, 100.0 * speedup / n);
        }
        System.out.println();

        // ---- 3. Ukuran thread pool menurut rasio tunggu/hitung ----
        System.out.println("== 3. Rumus pool: thread = core x (1 + W/C), 8 core ==");
        System.out.printf("%12s %12s%n", "W/C", "thread");
        for (double rasio : new double[] {0.5, 1, 2, 8}) {
            int thread = (int) Math.round(8 * (1 + rasio));
            System.out.printf("%12.1f %12d%n", rasio, thread);
        }
        System.out.println();

        // ---- 4. Jejak memori platform vs virtual (model) ----
        System.out.println("== 4. Model memori untuk 10.000 thread ==");
        System.out.println("platform : 10.000 x 1 MB stack = 10 GB ruang alamat dipesan");
        System.out.println("virtual  : 10.000 x ~2 KB      = sekitar 20 MB di heap");
        System.out.println();

        // ---- 5. Simulasi penjadwalan virtual thread round-robin ----
        System.out.println("== 5. Simulasi penjadwalan (12 tugas x 8 langkah, 4 carrier) ==");
        Deque<Integer> antrean = new ArrayDeque<>(List.of(
            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12));
        int[] langkahPerCarrier = new int[4];
        int totalLangkah = 0;
        while (!antrean.isEmpty()) {
            for (int carrier = 0; carrier < 4 && !antrean.isEmpty(); carrier++) {
                int tugas = antrean.poll();
                for (int langkah = 0; langkah < 8; langkah++) {
                    langkahPerCarrier[carrier]++;
                    totalLangkah++;
                }
            }
        }
        for (int carrier = 0; carrier < 4; carrier++) {
            System.out.println("carrier-" + carrier + " : " + langkahPerCarrier[carrier] + " langkah");
        }
        System.out.println("total " + totalLangkah + " langkah, seimbang, tanpa langkah menganggur");
        System.out.println();
        System.out.println("Kesimpulan: tambah thread hanya menolong beban I/O;");
        System.out.println("bagian serial dan bagian kritis menutup ruang speedup.");
    }
}
