package example.memory;

import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.info.GraphLayout;
import org.openjdk.jol.vm.VM;
import org.openjdk.jol.vm.VirtualMachine;

public final class LayoutProbe {
    private static final class OrderLine {
        private long orderId;
        private int quantity;
        private boolean gift;
        private Object note;

        private OrderLine(long orderId, int quantity, boolean gift, Object note) {
            this.orderId = orderId;
            this.quantity = quantity;
            this.gift = gift;
            this.note = note;
        }
    }

    private LayoutProbe() {
    }

    public static void main(String[] args) {
        OrderLine line = new OrderLine(1001L, 3, true, new String(new char[] {'C', 'N', 'Y'}));
        ClassLayout shallow = ClassLayout.parseInstance(line);
        GraphLayout graph = GraphLayout.parseInstance(line);
        VirtualMachine vm = VM.current();

        System.out.println("--- class-layout ---");
        System.out.print(shallow.toPrintable());
        System.out.println("--- graph-footprint ---");
        System.out.print(graph.toFootprint());

        long shallowBytes = shallow.instanceSize();
        long graphBytes = graph.totalSize();
        boolean graphExceedsShallow = graphBytes > shallowBytes;
        if (!graphExceedsShallow) {
            throw new AssertionError("reachable graph must include objects outside the shallow instance");
        }

        System.out.println("layout-reference-bytes=" + vm.sizeOfField("oop"));
        System.out.println("layout-class-pointer-bytes=" + vm.classPointerSize());
        System.out.println("layout-object-header-bytes=" + vm.objectHeaderSize());
        System.out.println("layout-object-alignment-bytes=" + vm.objectAlignment());
        System.out.println("layout-shallow-bytes=" + shallowBytes);
        System.out.println("layout-graph-bytes=" + graphBytes);
        System.out.println("layout-internal-padding-bytes=" + shallow.getLossesInternal());
        System.out.println("layout-external-padding-bytes=" + shallow.getLossesExternal());
        System.out.println("layout-graph-exceeds-shallow=" + graphExceedsShallow);
        System.out.println("layout-payload-check="
                + (line.orderId == 1001L && line.quantity == 3 && line.gift && "CNY".equals(line.note)));
    }
}
