Commit 3aad6343 authored by Carlos Galindo's avatar Carlos Galindo
Browse files

WorkList: documentation and cleanup.

parent 83d8b724
Loading
Loading
Loading
Loading
+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)
@@ -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;
+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;
@@ -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);
+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.*;
@@ -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);
+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
@@ -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())
@@ -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) {