Files
VisualSapfor/src/_VisualDVM/ProjectData/SapforData/Arrays/ProjectArray.java
2024-10-14 15:19:13 +03:00

398 lines
17 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package _VisualDVM.ProjectData.SapforData.Arrays;
import Common.Database.Objects.DBObject;
import Common.Utils.Index;
import Common.Utils.Utils_;
import _VisualDVM.Global;
import _VisualDVM.Passes.PassCode;
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 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<TemplateDimension> dimensions = new Vector<>();
public int isTemplFlag;
public int isLoopArrayFlag;
//----------------------------
public BigInteger address;
//----------------------------
public ParallelRegion parent_region = null; //родительяская область распараллеливания.
//связи->
public LinkedHashMap<Long, ProjectArray> links = new LinkedHashMap<>();
//------>
public ProjectArray align_template = null; //ссылка на шаблон на который идет выравнивание.
public String spaces_shift = ""; //смещение из пробелов
//ИЗМЕНЕНИЕ РАСПРЕДЕЛЕНИЯ
//------------------------------------------------------------------------------------------------------>
//текущие
public LinkedHashMap<Integer, Dimension> ac_current = new LinkedHashMap<>();
//кандидаты на замену.
public LinkedHashMap<Integer, Dimension> ac_new = new LinkedHashMap<>();
//https://stackoverflow.com/questions/4941372/how-to-insert-image-into-jtable-cell
public ArrayAlignmentBar bar = null;
//------------------------------------------------------------------------------------------------------>
//<editor-fold desc="Функционал шаблона">
public Vector<BigInteger> regIDs = new Vector<>();
Vector<Pair<Integer, Integer>> sizes = new Vector<>();
Vector<Integer> deprecateToDist = new Vector<>();
Vector<Integer> mappedDims = new Vector<>();
LinkedHashMap<BigInteger, TemplateLink> templateInfo = new LinkedHashMap<>();
Vector<ArrayDecl> declPlaces = new Vector<>();
Vector<String> 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<String> 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<String> GetDeclPlacesList() {
Vector<String> 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<Object> 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<Long> get_varIDs(boolean filter) {
long d = (long) Math.pow(2, dimSize);
Vector<Long> varIDs = new Vector<>();
Vector<String> 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<String> 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<Long> get_varIDs() {
return get_varIDs(true);
}
//для первичного заполнения рекурсии
public Vector<Vector<BigInteger>> get_triples(boolean filter) {
Vector<Vector<BigInteger>> res = new Vector<>();
Vector<Long> varIDs = get_varIDs(filter);
for (long varID : varIDs) {
for (BigInteger regID : regIDs) //для всех областей
{
Vector<BigInteger> 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;
}
//</editor-fold>
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);
}
//----
}