All Downloads are FREE. Search and download functionalities are using the official Maven repository.

skadistats.clarity.io.s1.SendTableFlattener Maven / Gradle / Ivy

package skadistats.clarity.io.s1;

import skadistats.clarity.model.s1.PropFlag;
import skadistats.clarity.model.s1.PropType;
import skadistats.clarity.processor.sendtables.DTClasses;

import java.util.*;

public class SendTableFlattener {

    private final DTClasses dtClasses;
    private final SendTable table;
    private final Set exclusions;
    private final List receiveProps;

    public SendTableFlattener(DTClasses dtClasses, SendTable table) {
        this.dtClasses = dtClasses;
        this.table = table;
        this.exclusions = new HashSet<>();
        this.receiveProps = new ArrayList<>(1024);
    }

    private SendTable sendTableForDtName(String dtName) {
        var dtClass = (S1DTClass) dtClasses.forDtName(dtName);
        return dtClass.getSendTable();
    }

    private void aggregateExclusions(SendTable table) {
        for (var sp : table.getSendProps()) {
            if ((sp.getFlags() & PropFlag.EXCLUDE) != 0) {
                exclusions.add(sp.getExcludeIdentifier());
            } else if (sp.getType() == PropType.DATATABLE) {
                aggregateExclusions(sendTableForDtName(sp.getDtName()));
            }
        }
    }

    private void gather(SendTable ancestor, List accumulator, StringBuilder nameBuf) {
        gatherCollapsible(ancestor, accumulator, nameBuf);
        var l = nameBuf.length();
        for (var sp : accumulator) {
            nameBuf.append(sp.getVarName());
            receiveProps.add(new ReceiveProp(sp, nameBuf.toString()));
            nameBuf.setLength(l);
        }
    }

    private void gatherCollapsible(SendTable ancestor, List accumulator, StringBuilder nameBuf) {
        for (var sp : ancestor.getSendProps()) {
            if (((PropFlag.EXCLUDE | PropFlag.INSIDE_ARRAY) & sp.getFlags()) != 0) {
                continue;
            }
            if (exclusions.contains(new SendTableExclusion(ancestor.getNetTableName(), sp.getVarName()))) {
                continue;
            }
            if (sp.getType() == PropType.DATATABLE) {
                if ((sp.getFlags() & PropFlag.COLLAPSIBLE) != 0) {
                    gatherCollapsible(sendTableForDtName(sp.getDtName()), accumulator, nameBuf);
                } else {
                    var l = nameBuf.length();
                    nameBuf.append(sp.getVarName());
                    nameBuf.append('.');
                    gather(sendTableForDtName(sp.getDtName()), new LinkedList<>(), nameBuf);
                    nameBuf.setLength(l);
                }
            } else {
                accumulator.add(sp);
            }
        }
    }

    private int[] computeIndexMapping() {
        var mapping =  new int[receiveProps.size()];
        for (var i = 0; i < mapping.length; i++) {
            mapping[i] = i;
        }

        Set priorities = new TreeSet<>();
        priorities.add(64);
        for (var rp : receiveProps) {
            priorities.add(rp.getSendProp().getPriority());
        }
        var hole = 0;

        for (var priority : priorities) {
            var cursor = hole;
            while (cursor < mapping.length) {
                var rp = receiveProps.get(mapping[cursor]);
                var sp = rp.getSendProp();
                var changesOften = (sp.getFlags() & PropFlag.CHANGES_OFTEN) != 0 && priority == 64;
                if (changesOften || sp.getPriority() == priority) {
                    var temp = mapping[cursor];
                    mapping[cursor] = mapping[hole];
                    mapping[hole] = temp;
                    hole++;
                }
                cursor++;
            }
        }
        return mapping;
    }

    public Result flatten() {
        aggregateExclusions(table);
        gather(table, new LinkedList<>(), new StringBuilder());
        var r = new Result();
        r.receiveProps = receiveProps.toArray(new ReceiveProp[] {});
        r.indexMapping = computeIndexMapping();
        return r;
    }

    public static class Result {
        public ReceiveProp[] receiveProps;
        public int[] indexMapping;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy