From: <jom...@us...> - 2016-04-06 16:21:20
|
Revision: 1883 http://sourceforge.net/p/jason/svn/1883 Author: jomifred Date: 2016-04-06 16:21:17 +0000 (Wed, 06 Apr 2016) Log Message: ----------- concurrent PlanLibrary Modified Paths: -------------- trunk/src/jason/asSyntax/PlanLibrary.java trunk/src/jason/asSyntax/Rule.java Modified: trunk/src/jason/asSyntax/PlanLibrary.java =================================================================== --- trunk/src/jason/asSyntax/PlanLibrary.java 2016-04-06 16:18:42 UTC (rev 1882) +++ trunk/src/jason/asSyntax/PlanLibrary.java 2016-04-06 16:21:17 UTC (rev 1883) @@ -33,10 +33,10 @@ import jason.jeditplugin.Config; import java.util.ArrayList; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import org.w3c.dom.Document; @@ -49,7 +49,7 @@ public class PlanLibrary implements Iterable<Plan> { /** a MAP from TE to a list of relevant plans */ - private Map<PredicateIndicator,List<Plan>> relPlans = new HashMap<PredicateIndicator,List<Plan>>(); + private Map<PredicateIndicator,List<Plan>> relPlans = new ConcurrentHashMap<PredicateIndicator,List<Plan>>(); /** * All plans as defined in the AS code (maintains the order of the plans) @@ -60,7 +60,7 @@ private List<Plan> varPlans = new ArrayList<Plan>(); /** A map from labels to plans */ - private Map<String,Plan> planLabels = new HashMap<String,Plan>(); + private Map<String,Plan> planLabels = new ConcurrentHashMap<String,Plan>(); private boolean hasMetaEventPlans = false; @@ -68,8 +68,14 @@ private boolean hasUserKqmlReceived = false; - //private Logger logger = Logger.getLogger(PlanLibrary.class.getName()); + //private Logger logger = Logger.getLogger(PlanLibrary.class.getName()); + private final Object lockPL = new Object(); + + public Object getLock() { + return lockPL; + } + /** * Add a new plan written as a String. The source * normally is "self" or the agent that sent this plan. @@ -126,18 +132,20 @@ * @returns the plan just added */ public Plan add(Plan p, Term source, boolean before) throws JasonException { - int i = plans.indexOf(p); - if (i < 0) { - // add label, if necessary - if (p.getLabel() == null) - p.setLabel(getUniqueLabel()); - p.getLabel().addSource(source); - add(p, before); - } else { - p = plans.get(i); - p.getLabel().addSource(source); + synchronized (lockPL) { + int i = plans.indexOf(p); + if (i < 0) { + // add label, if necessary + if (p.getLabel() == null) + p.setLabel(getUniqueLabel()); + p.getLabel().addSource(source); + add(p, before); + } else { + p = plans.get(i); + p.getLabel().addSource(source); + } + return p; } - return p; } public void add(Plan p) throws JasonException { @@ -155,83 +163,90 @@ * @throws JasonException */ public void add(Plan p, boolean before) throws JasonException { - // test p.label - if (p.getLabel() != null && planLabels.keySet().contains( getStringForLabel(p.getLabel()))) { - // test if the new plan is equal, in this case, just add a source - Plan planInPL = get(p.getLabel()); - if (p.equals(planInPL)) { - planInPL.getLabel().addSource(p.getLabel().getSources().get(0)); - return; - } else { - throw new JasonException("There already is a plan with label " + p.getLabel()); - } - } - - // add label, if necessary - if (p.getLabel() == null) - p.setLabel(getUniqueLabel()); + synchronized (lockPL) { - // add self source - if (!p.getLabel().hasSource()) - p.getLabel().addAnnot(BeliefBase.TSelf); - - if (p.getTrigger().getLiteral().getFunctor().equals(kqmlReceivedFunctor)) { - if (! (p.getSrcInfo() != null && "kqmlPlans.asl".equals(p.getSrcInfo().getSrcFile()))) { - hasUserKqmlReceived = true; + // test p.label + if (p.getLabel() != null && planLabels.keySet().contains( getStringForLabel(p.getLabel()))) { + // test if the new plan is equal, in this case, just add a source + Plan planInPL = get(p.getLabel()); + if (p.equals(planInPL)) { + planInPL.getLabel().addSource(p.getLabel().getSources().get(0)); + return; + } else { + throw new JasonException("There already is a plan with label " + p.getLabel()); + } } - } - - p.setAsPlanTerm(false); // it is not a term anymore - - planLabels.put( getStringForLabel(p.getLabel()), p); - - Trigger pte = p.getTrigger(); - if (pte.getLiteral().isVar()) { - if (before) - varPlans.add(0,p); - else - varPlans.add(p); - // add plan p in all entries - for (List<Plan> lp: relPlans.values()) - if (!lp.isEmpty() && lp.get(0).getTrigger().sameType(pte)) // only add if same type - if (before) - lp.add(0,p); - else - lp.add(p); - } else { - List<Plan> codesList = relPlans.get(pte.getPredicateIndicator()); - if (codesList == null) { - codesList = new ArrayList<Plan>(); - // copy plans from var plans - for (Plan vp: varPlans) - if (vp.getTrigger().sameType(pte)) - codesList.add(vp); - relPlans.put(pte.getPredicateIndicator(), codesList); + + // add label, if necessary + if (p.getLabel() == null) + p.setLabel(getUniqueLabel()); + + // add self source + if (!p.getLabel().hasSource()) + p.getLabel().addAnnot(BeliefBase.TSelf); + + if (p.getTrigger().getLiteral().getFunctor().equals(kqmlReceivedFunctor)) { + if (! (p.getSrcInfo() != null && "kqmlPlans.asl".equals(p.getSrcInfo().getSrcFile()))) { + hasUserKqmlReceived = true; + } } + + p.setAsPlanTerm(false); // it is not a term anymore + + planLabels.put( getStringForLabel(p.getLabel()), p); + + Trigger pte = p.getTrigger(); + if (pte.getLiteral().isVar()) { + if (before) + varPlans.add(0,p); + else + varPlans.add(p); + // add plan p in all entries + for (List<Plan> lp: relPlans.values()) + if (!lp.isEmpty() && lp.get(0).getTrigger().sameType(pte)) // only add if same type + if (before) + lp.add(0,p); + else + lp.add(p); + } else { + List<Plan> codesList = relPlans.get(pte.getPredicateIndicator()); + if (codesList == null) { + codesList = new ArrayList<Plan>(); + // copy plans from var plans + for (Plan vp: varPlans) + if (vp.getTrigger().sameType(pte)) + codesList.add(vp); + relPlans.put(pte.getPredicateIndicator(), codesList); + } + if (before) + codesList.add(0,p); + else + codesList.add(p); + } + + if (pte.getOperator() == TEOperator.goalState) + hasMetaEventPlans = true; + if (before) - codesList.add(0,p); + plans.add(0,p); else - codesList.add(p); + plans.add(p); } - - if (pte.getOperator() == TEOperator.goalState) - hasMetaEventPlans = true; - - if (before) - plans.add(0,p); - else - plans.add(p); } public void addAll(PlanLibrary pl) throws JasonException { - for (Plan p: pl) { - add(p, false); + synchronized (lockPL) { + for (Plan p: pl) { + add(p, false); + } } } public void addAll(List<Plan> plans) throws JasonException { - for (Plan p: plans) { - add(p, false); + synchronized (lockPL) { + for (Plan p: plans) { + add(p, false); + } } } @@ -309,33 +324,35 @@ /** remove the plan with label <i>pLabel</i> */ public Plan remove(Atom pLabel) { - Plan p = planLabels.remove( getStringForLabel(pLabel) ); - - // remove it from plans' list - plans.remove(p); - - if (p.getTrigger().getLiteral().isVar()) { - varPlans.remove(p); - // remove p from all entries and - // clean empty entries - Iterator<PredicateIndicator> ipi = relPlans.keySet().iterator(); - while (ipi.hasNext()) { - PredicateIndicator pi = ipi.next(); - List<Plan> lp = relPlans.get(pi); - lp.remove(p); - if (lp.isEmpty()) { - ipi.remove(); + synchronized (lockPL) { + Plan p = planLabels.remove( getStringForLabel(pLabel) ); + + // remove it from plans' list + plans.remove(p); + + if (p.getTrigger().getLiteral().isVar()) { + varPlans.remove(p); + // remove p from all entries and + // clean empty entries + Iterator<PredicateIndicator> ipi = relPlans.keySet().iterator(); + while (ipi.hasNext()) { + PredicateIndicator pi = ipi.next(); + List<Plan> lp = relPlans.get(pi); + lp.remove(p); + if (lp.isEmpty()) { + ipi.remove(); + } } + } else { + List<Plan> codesList = relPlans.get(p.getTrigger().getPredicateIndicator()); + codesList.remove(p); + if (codesList.isEmpty()) { + // no more plans for this TE + relPlans.remove(p.getTrigger().getPredicateIndicator()); + } } - } else { - List<Plan> codesList = relPlans.get(p.getTrigger().getPredicateIndicator()); - codesList.remove(p); - if (codesList.isEmpty()) { - // no more plans for this TE - relPlans.remove(p.getTrigger().getPredicateIndicator()); - } + return p; } - return p; } /** @deprecated use hasCandidatePlan(te) instead */ @@ -357,26 +374,28 @@ } public List<Plan> getCandidatePlans(Trigger te) { - List<Plan> l = null; - if (te.getLiteral().isVar()) { // add all plans! - for (Plan p: this) - if (p.getTrigger().sameType(te)) { - if (l == null) - l = new ArrayList<Plan>(); - l.add(p); - } - } else { - l = relPlans.get(te.getPredicateIndicator()); - if ((l == null || l.isEmpty()) && !varPlans.isEmpty() && te != TE_JAG_SLEEPING && te != TE_JAG_AWAKING) { // no rel plan, try varPlan - for (Plan p: varPlans) + synchronized (lockPL) { + List<Plan> l = null; + if (te.getLiteral().isVar()) { // add all plans! + for (Plan p: this) if (p.getTrigger().sameType(te)) { if (l == null) l = new ArrayList<Plan>(); l.add(p); - } + } + } else { + l = relPlans.get(te.getPredicateIndicator()); + if ((l == null || l.isEmpty()) && !varPlans.isEmpty() && te != TE_JAG_SLEEPING && te != TE_JAG_AWAKING) { // no rel plan, try varPlan + for (Plan p: varPlans) + if (p.getTrigger().sameType(te)) { + if (l == null) + l = new ArrayList<Plan>(); + l.add(p); + } + } } + return l; // if no rel plan, have to return null instead of empty list } - return l; // if no rel plan, have to return null instead of empty list } public static final Trigger TE_JAG_SLEEPING = new Trigger(TEOperator.add, TEType.achieve, new Atom("jag_sleeping")); @@ -385,8 +404,10 @@ public PlanLibrary clone() { PlanLibrary pl = new PlanLibrary(); try { - for (Plan p: this) { - pl.add((Plan)p.clone(), false); + synchronized (lockPL) { + for (Plan p: this) { + pl.add((Plan)p.clone(), false); + } } } catch (JasonException e) { e.printStackTrace(); @@ -402,13 +423,15 @@ public Element getAsDOM(Document document) { Element eplans = (Element) document.createElement("plans"); String lastFunctor = null; - for (Plan p: plans) { - String currentFunctor = p.getTrigger().getLiteral().getFunctor(); - if (lastFunctor != null && !currentFunctor.equals(lastFunctor)) { - eplans.appendChild((Element) document.createElement("new-set-of-plans")); + synchronized (lockPL) { + for (Plan p: plans) { + String currentFunctor = p.getTrigger().getLiteral().getFunctor(); + if (lastFunctor != null && !currentFunctor.equals(lastFunctor)) { + eplans.appendChild((Element) document.createElement("new-set-of-plans")); + } + lastFunctor = currentFunctor; + eplans.appendChild(p.getAsDOM(document)); } - lastFunctor = currentFunctor; - eplans.appendChild(p.getAsDOM(document)); } return eplans; } Modified: trunk/src/jason/asSyntax/Rule.java =================================================================== --- trunk/src/jason/asSyntax/Rule.java 2016-04-06 16:18:42 UTC (rev 1882) +++ trunk/src/jason/asSyntax/Rule.java 2016-04-06 16:21:17 UTC (rev 1883) @@ -107,6 +107,10 @@ return body; } + public Literal getHead() { + return new LiteralImpl(this); + } + @Override public Literal makeVarsAnnon(Unifier un) { if (body instanceof Literal) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |