package _VisualDVM.ProjectData.SapforData.Arrays; import Common.Utils.Utils_; import Common.Database.Objects.DBObject; import Common.Utils.Index; import _VisualDVM.Global; import _VisualDVM.ProjectData.DBArray.DBArray; import _VisualDVM.ProjectData.Files.DBProjectFile; import _VisualDVM.ProjectData.SapforData.Arrays.Distribution.Dimension; import _VisualDVM.ProjectData.SapforData.Arrays.Templates.TemplateDimension; import _VisualDVM.ProjectData.SapforData.Arrays.Templates.TemplateDimensionState; import _VisualDVM.ProjectData.SapforData.Arrays.Templates.TemplateLink; import _VisualDVM.ProjectData.SapforData.Regions.ParallelRegion; import _VisualDVM.ProjectData.SapforData.Regions.UI.ArrayAlignmentBar; import _VisualDVM.Passes.PassCode; import javafx.util.Pair; import javax.swing.*; import java.math.BigInteger; import java.util.LinkedHashMap; import java.util.Vector; import java.util.stream.Collectors; public class ProjectArray extends DBObject { //---------------------------------------------------------------------- public static final String[] alignNames = {"i", "j", "k", "l", "m", "n", "q", "r", "s", "t", "u", "w", "x", "y", "z"}; //- public static String filterName = ""; public static String filterLocation = ""; public static String filterLocationName = ""; public static String filterFile = ""; public static String filterRegion = "*"; public String UniqKey; public ArrayState State; //----------------------------- public long id; public String name; public String shortName; public int dimSize; public int typeSize; public ArrayLocation location; public String locName; //только для шаблонов. для ФИЛЬТРА управления распределением измерений. public Vector dimensions = new Vector<>(); public int isTemplFlag; public int isLoopArrayFlag; //---------------------------- public BigInteger address; //---------------------------- public ParallelRegion parent_region = null; //родительяская область распараллеливания. //связи-> public LinkedHashMap links = new LinkedHashMap<>(); //------> public ProjectArray align_template = null; //ссылка на шаблон на который идет выравнивание. public String spaces_shift = ""; //смещение из пробелов //ИЗМЕНЕНИЕ РАСПРЕДЕЛЕНИЯ //------------------------------------------------------------------------------------------------------> //текущие public LinkedHashMap ac_current = new LinkedHashMap<>(); //кандидаты на замену. public LinkedHashMap ac_new = new LinkedHashMap<>(); //https://stackoverflow.com/questions/4941372/how-to-insert-image-into-jtable-cell public ArrayAlignmentBar bar = null; //------------------------------------------------------------------------------------------------------> // public Vector regIDs = new Vector<>(); Vector> sizes = new Vector<>(); Vector deprecateToDist = new Vector<>(); Vector mappedDims = new Vector<>(); LinkedHashMap templateInfo = new LinkedHashMap<>(); Vector declPlaces = new Vector<>(); Vector regions = new Vector<>(); public ProjectArray(String[] infoF, Index idx, BigInteger address_in) { id = Integer.parseInt(infoF[idx.Inc()]); name = infoF[idx.Inc()]; shortName = infoF[idx.Inc()]; dimSize = Integer.parseInt(infoF[idx.Inc()]); typeSize = Integer.parseInt(infoF[idx.Inc()]); address = address_in; State = ArrayState.fromInt(Integer.parseInt(infoF[idx.Inc()])); location = ArrayLocation.fromInt(Integer.parseInt(infoF[idx.Inc()])); locName = infoF[idx.Inc()]; int sizes_size = Integer.parseInt(infoF[idx.Inc()]); for (int i = 0; i < sizes_size; ++i) { int first = Integer.parseInt(infoF[idx.Inc()]); int second = Integer.parseInt(infoF[idx.Inc()]); sizes.add(new Pair<>(first, second)); } sizes_size = Integer.parseInt(infoF[idx.Inc()]); for (int i = 0; i < sizes_size; ++i) deprecateToDist.add(Integer.parseInt(infoF[idx.Inc()])); sizes_size = Integer.parseInt(infoF[idx.Inc()]); for (int i = 0; i < sizes_size; ++i) mappedDims.add(Integer.parseInt(infoF[idx.Inc()])); int templateInfo_size = Integer.parseInt(infoF[idx.Inc()]); for (int i = 0; i < templateInfo_size; ++i) { BigInteger key = new BigInteger(infoF[idx.Inc()]); TemplateLink templateLink = new TemplateLink(infoF, idx); templateInfo.put(key, templateLink); } String[] localSplited = infoF[idx.Inc()].split("\\|"); isTemplFlag = Integer.parseInt(localSplited[0]); isLoopArrayFlag = Integer.parseInt(localSplited[1]); int numDeclPlaces = Integer.parseInt(localSplited[2]); int idxPl = 3; for (int i = 0; i < numDeclPlaces; ++i, idxPl += 2) { String declFile = Utils_.toW(localSplited[idxPl]); DBProjectFile file = Global.mainModule.getProject().db.files.Data.get(declFile); int declLine = Integer.parseInt(localSplited[idxPl + 1]); //declPlaces.add(new Pair<>(declFile, declLine)); ArrayDecl decl = new ArrayDecl(shortName, location, file, declLine); declPlaces.add(decl); file.array_decls.add(decl); //-- } int numRegs = Integer.parseInt(localSplited[idxPl++]); for (int i = 0; i < numRegs; ++i) regions.add(localSplited[idxPl++]); UniqKey = shortName + locName + dimSize; //короткое имя+ функция/модуль/комон+ размерность } public static String fill_binary(int d, String binary) { int delta = Math.abs(binary.length() - d); String res = binary; for (int i = 0; i < delta; ++i) { res = ("0" + res); } return res; } //длина должна быть равной, ищем есть ли совпадающие позиции с единицами public static boolean mask(String banned, String variant) { for (int i = 0; i < variant.length(); ++i) if ((variant.toCharArray()[i] == '1') && (banned.toCharArray()[i] == '1')) //попался, масконосец! return true; return false; } public String printLinks() { Vector res = links.keySet().stream().map(Object::toString).collect(Collectors.toCollection(Vector::new)); return String.join(" ", res); } //---------------------------------------------------------------------- @Override public Object getPK() { return id; } public boolean has_decl_place(String bg_file) { for (ArrayDecl decl : declPlaces) if (decl.file.startsWith(bg_file)) return true; return false; } public boolean has_region(String bg_region) { if (bg_region.equals("*")) return true; for (String region : regions) if (region.startsWith(bg_region)) return true; return false; } public String TypeString() { return (isLoopArrayFlag == 0) ? ((isTemplFlag == 0) ? "МАССИВ" : "ШАБЛОН") : "ЦИКЛ"; } public String state_symbol() { return State == ArrayState.Selected ? "☑" : "☐"; } @Override public String toString() { return id + " " + state_symbol() + " " + State + " " + shortName + " " + locName + " : " + location + " " + dimSize + " " + typeSize; } public String GetShortNameWithDim() { String res = shortName + "( "; if (sizes != null && sizes.size() != dimSize) { for (int i = 0; i < dimSize; ++i) { res += alignNames[i]; if (i < dimSize - 1) res += ", "; else res += ")"; } } else { for (int i = 0; i < dimSize; ++i) { if (sizes.get(i).getKey() != sizes.get(i).getValue() && sizes.get(i).getKey() != -1) res += sizes.get(i).getKey() + ":" + sizes.get(i).getValue(); else res += alignNames[i]; if (i < dimSize - 1) res += ", "; else res += ")"; } } return res; } //- //для таблицы вариантов, измерения (i,j,k,..) public String GetShortNameWithDimLetters() { String res = shortName + "("; for (int i = 0; i < dimSize; ++i) { res += alignNames[i]; if (i < dimSize - 1) res += ","; else res += ")"; } return res; } //- public Vector GetDeclPlacesList() { Vector links = new Vector<>(); for (ArrayDecl d : declPlaces) links.add(d.file + ":" + d.line); return links; } public String GetRegionsText() { String res = ""; for (int i = 0; i < regions.size(); ++i) res += regions.get(i) + ((i != regions.size() - 1) ? "," : ""); return res; } public boolean DimDisabled(int dim) { // не участвует в шаблонах. или явно запрещено return (mappedDims.get(dim) == 0) || (deprecateToDist.get(dim) == 1); } public void CreateDimensions() { for (BigInteger regID : regIDs) { ParallelRegion region = Global.mainModule.getProject().parallelRegions.get(regID); for (int i = 0; i < Global.mainModule.getProject().maxdim; ++i) { dimensions.add(new TemplateDimension( i, this, region )); } } } public Object[] CreateTemplateCells() { Vector res = new Vector<>(); res.add(this.shortName); for (int i = 0; i < dimensions.size(); ++i) { res.add(dimensions.get(i)); } return res.toArray(); } //получить двоичное представление варианта распределения и дополнить его нулями. public String get_binary(long varID) { String binary = Long.toBinaryString(varID); return fill_binary(dimSize, binary); } public Vector get_varIDs(boolean filter) { long d = (long) Math.pow(2, dimSize); Vector varIDs = new Vector<>(); Vector DimsDep = new Vector<>(); for (int z = 0; z < mappedDims.size(); ++z) DimsDep.add( String.valueOf((DimDisabled(z) ? 1 : 0))); String banned_dimensions = String.join("", DimsDep); //------ Дляполностью размноженного нужен d-1 ? for (long i = 0; i < d; ++i) { String binary = get_binary(i); if (!mask(banned_dimensions, binary)) { if (filter) { boolean valid = true; if (Global.mainModule.getProject().f_distributed()) valid = CheckFilterMask(i, true, binary); if (valid && Global.mainModule.getProject().f_multiplied()) valid = CheckFilterMask(i, false, binary); if (valid) varIDs.add(i); } else varIDs.add(i); } } return varIDs; } //проверка одиночного вар ида. нужна для минимального покрытия. public boolean checkVarID(long i, boolean filter) { Vector DimsDep = new Vector<>(); for (int z = 0; z < mappedDims.size(); ++z) DimsDep.add(String.valueOf((DimDisabled(z) ? 1 : 0))); String banned_dimensions = String.join("", DimsDep); String binary = get_binary(i); if (!mask(banned_dimensions, binary)) { if (filter) { boolean valid = true; if (Global.mainModule.getProject().f_distributed()) valid = CheckFilterMask(i, true, binary); if (valid && Global.mainModule.getProject().f_multiplied()) valid = CheckFilterMask(i, false, binary); return valid; } else return true; } return false; } public Vector get_varIDs() { return get_varIDs(true); } //для первичного заполнения рекурсии public Vector> get_triples(boolean filter) { Vector> res = new Vector<>(); Vector varIDs = get_varIDs(filter); for (long varID : varIDs) { for (BigInteger regID : regIDs) //для всех областей { Vector tripple = new Vector<>(); tripple.add(address); tripple.add(BigInteger.valueOf(varID)); tripple.add(regID); res.add(tripple); } } return res; } public String GetShortNameForVariant(long varID) { String binary = get_binary(varID); String res = shortName + "("; for (int i = 0; i < dimSize; ++i) { if (i < binary.length()) { switch (binary.toCharArray()[i]) { case '0': res += TemplateDimensionState.multiplied.getDescription(); break; case '1': res += TemplateDimensionState.distributed.getDescription(); break; default: break; } res += Utils_.ending(i == binary.length() - 1); } } return res; } // public String getFilterMask() { String res = ""; for (int i = 0; i < dimensions.size(); ++i) { res += (dimensions.get(i).state.ordinal()); } return res; } public boolean CheckFilterMask(long varID, boolean distributed, String binary_in) { char s = distributed ? '1' : '0'; String filterMask = getFilterMask(); String variant = binary_in.isEmpty() ? get_binary(varID) : binary_in; for (int i = 0; i < variant.length(); ++i) { if ((filterMask.toCharArray()[i] == s) && (variant.toCharArray()[i] != s)) return false; } return true; } public boolean CheckFilterMask(long varID, boolean distributed) { return CheckFilterMask(varID, distributed, ""); } public void SaveUserState() throws Exception { if (Global.mainModule.getProject().db.savedArrays.Data.containsKey(UniqKey)) { DBArray sa = Global.mainModule.getProject().db.savedArrays.Data.get(UniqKey); sa.State = State; Global.mainModule.getProject().db.Update(sa); } else Global.mainModule.getProject().db.Insert(new DBArray(this)); } //----------------------------------------------------------------------- @Override public boolean isSelectionEnabled() { return (State == ArrayState.Selected) || (State == ArrayState.None); } @Override public ImageIcon GetDisabledIcon() { return Utils_.getIcon("/icons/Arrays/" + State.toString() + ".png"); } @Override public void select(boolean flag) { Global.mainModule.getPass(PassCode.MassSelectArrays).Do(flag, this); } @Override public boolean isSelected() { return (State == ArrayState.Selected); } //- @Override public boolean isVisible() { if (isTemplFlag > 0) return true; return shortName.startsWith(filterName) && location.toString().startsWith(filterLocation) && locName.startsWith(filterLocationName) && has_decl_place(filterFile) && has_region(filterRegion); } public void init_new_ac() { ac_new.clear(); for (int dim : ac_current.keySet()) ac_new.put(dim, ac_current.get(dim).clone_()); } public boolean ac_need_change() { for (int dim : ac_current.keySet()) { Dimension old_ = ac_current.get(dim); Dimension new_ = ac_new.get(dim); if ((old_.K != new_.K) || (old_.B != new_.B)) return true; } return false; } public boolean canBeDistributed() { return (isLoopArrayFlag == 0) && (isTemplFlag == 0); } //---- }