Loading EDG/src/main/java/edg/edge/SummaryEdgeGenerator.java +25 −5 Original line number Diff line number Diff line package edg.edge; /* * EDG, a library to generate and slice Expression Dependence Graphs. * Copyright (c) 2021-2023. David Insa, Carlos Galindo, Sergio Pérez, Josep Silva, Salvador Tamarit. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ import java.util.*; package edg.edge; import edg.constraint.*; import edg.graph.*; import edg.graph.LAST.Direction; import edg.slicing.ConstrainedAlgorithm; import edg.slicing.Phase; import edg.graph.LAST.Direction; import edg.work.NodeWork; import edg.work.Work; import edg.work.WorkList; import java.util.LinkedList; import java.util.List; import java.util.Set; public class SummaryEdgeGenerator extends EdgeGenerator { public SummaryEdgeGenerator(EDG edg) Loading Loading @@ -103,9 +123,9 @@ public class SummaryEdgeGenerator extends EdgeGenerator final WorkList workList = new WorkList(initialWorks); final ConstrainedAlgorithm slicingAlgorithm = new ConstrainedAlgorithm(edg); while (workList.hasMore()) while (workList.hasNext()) { final Work work = workList.next(); final Work work = workList.removeNext(); final Node initialNode = work.getInitialNode(); final Constraints constraints = work.getConstraints(); boolean isFormalIn = false; Loading EDG/src/main/java/edg/slicing/ConstrainedAlgorithm.java +20 −3 Original line number Diff line number Diff line /* * EDG, a library to generate and slice Expression Dependence Graphs. * Copyright (c) 2021-2023. David Insa, Carlos Galindo, Sergio Pérez, Josep Silva, Salvador Tamarit. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package edg.slicing; import edg.config.Config; import edg.constraint.Constraints; import edg.constraint.EdgeConstraint; import edg.constraint.NodeConstraint; Loading Loading @@ -47,9 +64,9 @@ public class ConstrainedAlgorithm implements SlicingAlgorithm private void traverse(Phase phase, WorkList workList) { while (workList.hasMore()) while (workList.hasNext()) { final Work pendingWork = workList.next(); final Work pendingWork = workList.removeNext(); final List<Work> newWorks = this.processWork(phase, pendingWork); workList.done(pendingWork); Loading EDG/src/main/java/edg/slicing/OnePassConstrainedAlgorithm.java +20 −2 Original line number Diff line number Diff line /* * EDG, a library to generate and slice Expression Dependence Graphs. * Copyright (c) 2021-2023. David Insa, Carlos Galindo, Sergio Pérez, Josep Silva, Salvador Tamarit. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package edg.slicing; import edg.constraint.*; Loading Loading @@ -42,9 +60,9 @@ public class OnePassConstrainedAlgorithm implements SlicingAlgorithm private void traverse(Phase phase, WorkList workList) { while (workList.hasMore()) while (workList.hasNext()) { final Work pendingWork = workList.next(); final Work pendingWork = workList.removeNext(); final List<Work> newWorks = this.processWork(phase, pendingWork); workList.done(pendingWork); Loading EDG/src/main/java/edg/work/WorkList.java +50 −103 Original line number Diff line number Diff line /* * EDG, a library to generate and slice Expression Dependence Graphs. * Copyright (c) 2021. David Insa, Sergio Pérez, Josep Silva, Salvador Tamarit. * Copyright (c) 2021-2023. David Insa, Carlos Galindo, Sergio Pérez, Josep Silva, Salvador Tamarit. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as Loading @@ -18,98 +18,59 @@ package edg.work; import java.util.Collection; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import edg.graph.Node; import java.util.*; import java.util.Map.Entry; import java.util.Set; import edg.graph.Node; /** * Base for a work-list approach to slicing. Uses two maps, which index * works by their id, splitting them into completed and pending works. */ public class WorkList { private final Map<String, Set<Work>> doneWorks = new Hashtable<>(); private final Map<String, Set<Work>> pendingWorks = new Hashtable<>(); public class WorkList { private final Map<String, Set<Work>> doneWorks = new Hashtable<String, Set<Work>>(); private final Map<String, Set<Work>> pendingWorks = new Hashtable<String, Set<Work>>(); public WorkList() {} public WorkList(Work... works) { this.pendAll(works); } public WorkList(Iterable<Work> works) { /** Create a new work-list and mark the given works as pending. */ public WorkList(Iterable<Work> works) { this.pendAll(works); } public Set<Node> getPendingNodes() { public Set<Node> getPendingNodes() { return this.getNodes(this.pendingWorks); } public Set<Node> getDoneNodes() { public Set<Node> getDoneNodes() { return this.getNodes(this.doneWorks); } private Set<Node> getNodes(Map<String, Set<Work>> workMap) { private Set<Node> getNodes(Map<String, Set<Work>> workMap) { final Collection<Set<Work>> workCollection = workMap.values(); final Set<Node> nodes = new HashSet<Node>(); final Set<Node> nodes = new HashSet<>(); for (Set<Work> workSet : workCollection) for (Work work : workSet) if (work instanceof NodeWork) { final NodeWork nodeWork = (NodeWork) work; nodes.add(nodeWork.getCurrentNode()); if (work instanceof NodeWork) { nodes.add(((NodeWork) work).getCurrentNode()); break; } return nodes; } public Set<Work> getPendingWorks(String key) { return this.pendingWorks.get(key); } public Set<Work> getDoneWorks(String key) { return this.doneWorks.get(key); } private Set<Work> createPendingWorks(String key) { Set<Work> pendingWorks = this.getPendingWorks(key); if (pendingWorks == null) { pendingWorks = new HashSet<Work>(); this.pendingWorks.put(key, pendingWorks); } return pendingWorks; } private Set<Work> createDoneWorks(String key) { Set<Work> doneWorks = this.getDoneWorks(key); if (doneWorks == null) { doneWorks = new HashSet<Work>(); this.doneWorks.put(key, doneWorks); } return doneWorks; } public boolean hasMore() { /** Checks whether there are elements pending to be processed. */ public boolean hasNext() { return !this.pendingWorks.isEmpty(); } public Work next() { final Iterator<Entry<String, Set<Work>>> iterator = this.pendingWorks.entrySet().iterator(); final Entry<String, Set<Work>> entry = iterator.next(); final Set<Work> pendingWorks = entry.getValue(); final Iterator<Work> workIterator = pendingWorks.iterator(); final Work work = workIterator.next(); /** Obtains and removes from the work-list a node that is pending processing. */ public Work removeNext() { Iterator<Entry<String, Set<Work>>> iterator = this.pendingWorks.entrySet().iterator(); Set<Work> pendingWorks = iterator.next().getValue(); Iterator<Work> workIterator = pendingWorks.iterator(); Work work = workIterator.next(); workIterator.remove(); if (pendingWorks.isEmpty()) Loading @@ -117,56 +78,42 @@ public class WorkList return work; } public void done(Work work) { final String key = work.getId(); final Set<Work> doneWorks = this.createDoneWorks(key); doneWorks.add(work); /** Marks a work as done. */ public void done(Work work) { this.doneWorks.computeIfAbsent(work.getId(), k -> new HashSet<>()).add(work); } public void pendAll(Work... works) { public void pendAll(Iterable<Work> works) { for (Work work : works) this.pend(work); } public void pendAll(Iterable<Work> works) { for (Work work : works) this.pend(work); } public void pend(Work work) { if (this.contains(work)) return; final String key = work.getId(); final Set<Work> pendingWorks = this.createPendingWorks(key); pendingWorks.add(work); /** Marks a work as pending, if it wasn't pending or done before. Otherwise, does nothing. */ public void pend(Work work) { if (!contains(work)) this.pendingWorks.computeIfAbsent(work.getId(), k -> new HashSet<>()).add(work); } public void repend() { final Set<String> keys0 = this.doneWorks.keySet(); final Set<String> keys = new HashSet<String>(keys0); for (String key : keys) /** Marks all completed works as pending. */ public void repend() { for (String key : new HashSet<>(doneWorks.keySet())) this.repend(key); } public void repend(String key) { /** Marks all completed works identified by the given key as pending. */ public void repend(String key) { final Set<Work> doneWorks = this.doneWorks.get(key); if (doneWorks == null) return; final Set<Work> pendingWorks = this.createPendingWorks(key); pendingWorks.addAll(doneWorks); this.pendingWorks.computeIfAbsent(key, k -> new HashSet<>()).addAll(doneWorks); this.doneWorks.remove(key); } public boolean contains(Work work) { return contains(work, getDoneWorks(work.getId())) || contains(work, getPendingWorks(work.getId())); /** Checks whether the given work has been marked as pending or complete. */ public boolean contains(Work work) { return contains(work, doneWorks.get(work.getId())) || contains(work, pendingWorks.get(work.getId())); } private static boolean contains(Work work, Set<Work> set) { Loading Loading
EDG/src/main/java/edg/edge/SummaryEdgeGenerator.java +25 −5 Original line number Diff line number Diff line package edg.edge; /* * EDG, a library to generate and slice Expression Dependence Graphs. * Copyright (c) 2021-2023. David Insa, Carlos Galindo, Sergio Pérez, Josep Silva, Salvador Tamarit. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ import java.util.*; package edg.edge; import edg.constraint.*; import edg.graph.*; import edg.graph.LAST.Direction; import edg.slicing.ConstrainedAlgorithm; import edg.slicing.Phase; import edg.graph.LAST.Direction; import edg.work.NodeWork; import edg.work.Work; import edg.work.WorkList; import java.util.LinkedList; import java.util.List; import java.util.Set; public class SummaryEdgeGenerator extends EdgeGenerator { public SummaryEdgeGenerator(EDG edg) Loading Loading @@ -103,9 +123,9 @@ public class SummaryEdgeGenerator extends EdgeGenerator final WorkList workList = new WorkList(initialWorks); final ConstrainedAlgorithm slicingAlgorithm = new ConstrainedAlgorithm(edg); while (workList.hasMore()) while (workList.hasNext()) { final Work work = workList.next(); final Work work = workList.removeNext(); final Node initialNode = work.getInitialNode(); final Constraints constraints = work.getConstraints(); boolean isFormalIn = false; Loading
EDG/src/main/java/edg/slicing/ConstrainedAlgorithm.java +20 −3 Original line number Diff line number Diff line /* * EDG, a library to generate and slice Expression Dependence Graphs. * Copyright (c) 2021-2023. David Insa, Carlos Galindo, Sergio Pérez, Josep Silva, Salvador Tamarit. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package edg.slicing; import edg.config.Config; import edg.constraint.Constraints; import edg.constraint.EdgeConstraint; import edg.constraint.NodeConstraint; Loading Loading @@ -47,9 +64,9 @@ public class ConstrainedAlgorithm implements SlicingAlgorithm private void traverse(Phase phase, WorkList workList) { while (workList.hasMore()) while (workList.hasNext()) { final Work pendingWork = workList.next(); final Work pendingWork = workList.removeNext(); final List<Work> newWorks = this.processWork(phase, pendingWork); workList.done(pendingWork); Loading
EDG/src/main/java/edg/slicing/OnePassConstrainedAlgorithm.java +20 −2 Original line number Diff line number Diff line /* * EDG, a library to generate and slice Expression Dependence Graphs. * Copyright (c) 2021-2023. David Insa, Carlos Galindo, Sergio Pérez, Josep Silva, Salvador Tamarit. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package edg.slicing; import edg.constraint.*; Loading Loading @@ -42,9 +60,9 @@ public class OnePassConstrainedAlgorithm implements SlicingAlgorithm private void traverse(Phase phase, WorkList workList) { while (workList.hasMore()) while (workList.hasNext()) { final Work pendingWork = workList.next(); final Work pendingWork = workList.removeNext(); final List<Work> newWorks = this.processWork(phase, pendingWork); workList.done(pendingWork); Loading
EDG/src/main/java/edg/work/WorkList.java +50 −103 Original line number Diff line number Diff line /* * EDG, a library to generate and slice Expression Dependence Graphs. * Copyright (c) 2021. David Insa, Sergio Pérez, Josep Silva, Salvador Tamarit. * Copyright (c) 2021-2023. David Insa, Carlos Galindo, Sergio Pérez, Josep Silva, Salvador Tamarit. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as Loading @@ -18,98 +18,59 @@ package edg.work; import java.util.Collection; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import edg.graph.Node; import java.util.*; import java.util.Map.Entry; import java.util.Set; import edg.graph.Node; /** * Base for a work-list approach to slicing. Uses two maps, which index * works by their id, splitting them into completed and pending works. */ public class WorkList { private final Map<String, Set<Work>> doneWorks = new Hashtable<>(); private final Map<String, Set<Work>> pendingWorks = new Hashtable<>(); public class WorkList { private final Map<String, Set<Work>> doneWorks = new Hashtable<String, Set<Work>>(); private final Map<String, Set<Work>> pendingWorks = new Hashtable<String, Set<Work>>(); public WorkList() {} public WorkList(Work... works) { this.pendAll(works); } public WorkList(Iterable<Work> works) { /** Create a new work-list and mark the given works as pending. */ public WorkList(Iterable<Work> works) { this.pendAll(works); } public Set<Node> getPendingNodes() { public Set<Node> getPendingNodes() { return this.getNodes(this.pendingWorks); } public Set<Node> getDoneNodes() { public Set<Node> getDoneNodes() { return this.getNodes(this.doneWorks); } private Set<Node> getNodes(Map<String, Set<Work>> workMap) { private Set<Node> getNodes(Map<String, Set<Work>> workMap) { final Collection<Set<Work>> workCollection = workMap.values(); final Set<Node> nodes = new HashSet<Node>(); final Set<Node> nodes = new HashSet<>(); for (Set<Work> workSet : workCollection) for (Work work : workSet) if (work instanceof NodeWork) { final NodeWork nodeWork = (NodeWork) work; nodes.add(nodeWork.getCurrentNode()); if (work instanceof NodeWork) { nodes.add(((NodeWork) work).getCurrentNode()); break; } return nodes; } public Set<Work> getPendingWorks(String key) { return this.pendingWorks.get(key); } public Set<Work> getDoneWorks(String key) { return this.doneWorks.get(key); } private Set<Work> createPendingWorks(String key) { Set<Work> pendingWorks = this.getPendingWorks(key); if (pendingWorks == null) { pendingWorks = new HashSet<Work>(); this.pendingWorks.put(key, pendingWorks); } return pendingWorks; } private Set<Work> createDoneWorks(String key) { Set<Work> doneWorks = this.getDoneWorks(key); if (doneWorks == null) { doneWorks = new HashSet<Work>(); this.doneWorks.put(key, doneWorks); } return doneWorks; } public boolean hasMore() { /** Checks whether there are elements pending to be processed. */ public boolean hasNext() { return !this.pendingWorks.isEmpty(); } public Work next() { final Iterator<Entry<String, Set<Work>>> iterator = this.pendingWorks.entrySet().iterator(); final Entry<String, Set<Work>> entry = iterator.next(); final Set<Work> pendingWorks = entry.getValue(); final Iterator<Work> workIterator = pendingWorks.iterator(); final Work work = workIterator.next(); /** Obtains and removes from the work-list a node that is pending processing. */ public Work removeNext() { Iterator<Entry<String, Set<Work>>> iterator = this.pendingWorks.entrySet().iterator(); Set<Work> pendingWorks = iterator.next().getValue(); Iterator<Work> workIterator = pendingWorks.iterator(); Work work = workIterator.next(); workIterator.remove(); if (pendingWorks.isEmpty()) Loading @@ -117,56 +78,42 @@ public class WorkList return work; } public void done(Work work) { final String key = work.getId(); final Set<Work> doneWorks = this.createDoneWorks(key); doneWorks.add(work); /** Marks a work as done. */ public void done(Work work) { this.doneWorks.computeIfAbsent(work.getId(), k -> new HashSet<>()).add(work); } public void pendAll(Work... works) { public void pendAll(Iterable<Work> works) { for (Work work : works) this.pend(work); } public void pendAll(Iterable<Work> works) { for (Work work : works) this.pend(work); } public void pend(Work work) { if (this.contains(work)) return; final String key = work.getId(); final Set<Work> pendingWorks = this.createPendingWorks(key); pendingWorks.add(work); /** Marks a work as pending, if it wasn't pending or done before. Otherwise, does nothing. */ public void pend(Work work) { if (!contains(work)) this.pendingWorks.computeIfAbsent(work.getId(), k -> new HashSet<>()).add(work); } public void repend() { final Set<String> keys0 = this.doneWorks.keySet(); final Set<String> keys = new HashSet<String>(keys0); for (String key : keys) /** Marks all completed works as pending. */ public void repend() { for (String key : new HashSet<>(doneWorks.keySet())) this.repend(key); } public void repend(String key) { /** Marks all completed works identified by the given key as pending. */ public void repend(String key) { final Set<Work> doneWorks = this.doneWorks.get(key); if (doneWorks == null) return; final Set<Work> pendingWorks = this.createPendingWorks(key); pendingWorks.addAll(doneWorks); this.pendingWorks.computeIfAbsent(key, k -> new HashSet<>()).addAll(doneWorks); this.doneWorks.remove(key); } public boolean contains(Work work) { return contains(work, getDoneWorks(work.getId())) || contains(work, getPendingWorks(work.getId())); /** Checks whether the given work has been marked as pending or complete. */ public boolean contains(Work work) { return contains(work, doneWorks.get(work.getId())) || contains(work, pendingWorks.get(work.getId())); } private static boolean contains(Work work, Set<Work> set) { Loading