All Downloads are FREE. Search and download functionalities are using the official Maven repository.

template.incremental.DDGNode.tt Maven / Gradle / Ivy

There is a newer version: 2.3.6
Show newest version
# Copyright (c) 2013, The JastAdd Team
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the Lund University nor the names of its
#       contributors may be used to endorse or promote products derived from
#       this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# Code for DDG node
Grammar.emitDDGNode = [[
/** @apilevel internal */
public class $DDGNodeName {

$if (IncrementalLevelParam)
  // Level: param

  public $ASTNode fNode;
  public String fAttrID;
  protected Object fParams;

  public $DDGNodeName($ASTNode node, String attrID, Object params) {
    fNode = node;
    fAttrID = attrID;
    fParams = params;
    fState = node.inc_state;
    //createdHandlers.add(this);
  }

  public $DDGNodeName($DDGNodeName handler, $ASTNode node) {
    fNode = node;
    fAttrID = handler.fAttrID;
    fParams = handler.fParams;
    fState = node.inc_state;
    //createdHandlers.add(this);
  }

  public void setParams(Object params) {
    fParams = params;
  }

$if (IncrementalPropLimit)
  // Limit change propagation with the use of cache independence

  public boolean cacheInDependent = false;

  public $DDGNodeName($ASTNode node, String attrID, Object params, boolean cacheInDependent) {
    this(node, attrID, params);
    this.cacheInDependent = cacheInDependent;
  }

  public boolean isCacheInDependent() {
    return cacheInDependent;
  }

  public void setCacheInDependent(boolean b) {
    cacheInDependent = b;
  }

  public boolean noCacheRead = true;
$endif

$endif

$if (IncrementalLevelAttr)
  // Level: attr

  public $ASTNode fNode;
  public String fAttrID;

  public $DDGNodeName($ASTNode node, String attrID) {
    fNode = node;
    fAttrID = attrID;
    fState = node.inc_state;
    //createdHandlers.add(this);
  }

  public $DDGNodeName($DDGNodeName handler, $ASTNode node) {
    fNode = node;
    fAttrID = handler.fAttrID;
    fState = node.inc_state;
    //createdHandlers.add(this);
  }

  public void flushRegion() {
    // Remove dependencies
    java.util.HashSet<$DDGNodeName> k = fDependencySet;
    fDependencySet = new java.util.HashSet<$DDGNodeName>(4);
    for ($DDGNodeName node : k) {
      node.removeDependant(this);
    }
    fNode.reactToDependencyChange(fAttrID);
  }
$endif

$if (IncrementalLevelNode)
  // Level: node

  public $ASTNode fNode;

  public $DDGNodeName($ASTNode node) {
    fNode = node;
    fState = node.inc_state;
    //createdHandlers.add(this);
  }

  public $DDGNodeName($DDGNodeName handler, $ASTNode node) {
    fNode = node;
    fState = node.inc_state;
    //createdHandlers.add(this);
  }

  public void flushRegion() {
    // Remove dependencies
    java.util.HashSet<$DDGNodeName> k = fDependencySet;
    fDependencySet = new java.util.HashSet<$DDGNodeName>(4);
    for ($DDGNodeName node : k) {
      node.removeDependant(this);
    }
    fNode.reactToDependencyChange();
  }
$endif

$if (IncrementalLevelRegion)
  // Level: region

  public $ASTNode fNode;

  public $DDGNodeName($ASTNode node) {
    fNode = node;
    fState = node.inc_state;
    //createdHandlers.add(this);
  }

  public $DDGNodeName($DDGNodeName handler, $ASTNode node) {
    fNode = node;
    fState = node.inc_state;
    //createdHandlers.add(this);
  }

  public void flushRegion() {
    // Remove dependencies
    java.util.HashSet<$DDGNodeName> k = fDependencySet;
    fDependencySet = new java.util.HashSet<$DDGNodeName>(4);
    for ($DDGNodeName node : k) {
      node.removeDependant(this);
    }
    fNode.reactToDependencyChange();
  }
$endif

  // Dependency management

  public java.util.HashSet<$DDGNodeName> fListenerSet = new java.util.HashSet<$DDGNodeName>(4);
  public java.util.HashSet<$DDGNodeName> fDependencySet = new java.util.HashSet<$DDGNodeName>(4);

  public boolean hasDependants() {
    return !fListenerSet.isEmpty();
  }

  public void addDependant($DDGNodeName node) {
    fListenerSet.add(node);
    node.addDependency(this);
  }

  public void removeDependant($DDGNodeName node) {
    fListenerSet.remove(node);
  }

  public void clearDependants() {
    for ($DDGNodeName node : fListenerSet) {
      node.removeDependency(this);
    }
    fListenerSet.clear();
  }

  public void clearDependencies() {
    for ($DDGNodeName node : fDependencySet) {
      node.removeDependant(this);
    }
    fDependencySet.clear();
  }

  public void addDependency($DDGNodeName node) {
    fDependencySet.add(node);
  }

  public void removeDependency($DDGNodeName node) {
    fDependencySet.remove(node);
  }

  /*
   * Transfers listeners from another handler, used in rewrites.
   */
  public void transferSetsFrom($DDGNodeName node) {
    if (node == null || this == node)
      return;
    for ($DDGNodeName l : node.fListenerSet) {
      if (!l.isGarbage()) {
        this.addDependant(l);
      }
    }
    node.clearDependencies();
    node.clearDependants();
    node.throwAway();
  }

  /*
   * Transfers dependencies from another handler, used in rewrites.
   */
  public void transferDependenciesFrom($DDGNodeName node) {
    if (node == null || this == node)
      return;
    for ($DDGNodeName l : node.fDependencySet) {
      l.addDependant(this);
    }
$if (IncrementalPropLimit)
    setCacheInDependent(node.cacheInDependent);
$endif
    node.clearDependencies();
  }

  // Notification

  private boolean visited = false;

  public void notifyDependencies() {
    // Notify and remove listeners
    if (!visited) {
      visited = true;
      java.util.HashSet<$DDGNodeName> k = fListenerSet;
      fListenerSet = new java.util.HashSet<$DDGNodeName>(4);
      for ($DDGNodeName node : k) {
        if (!node.isGarbage()) {
          node.dependencyChanged();
        }
        node.removeDependency(this);
      }
      visited = false;
    }
  }

  // React to change

  private boolean visitedChange = false;

  public void dependencyChanged() {
    if (!visitedChange) {
      visitedChange = true;
$if (IncrementalTrack)
      trackedFlushes++;
      System.out.println("not(" + this + ")");
$endif
$if (IncrementalLevelParam)
$if (IncrementalPropLimit)
      if (noCacheRead && !fNode.inc_valueAffected(fAttrID, fParams)) {
      } else {
$endif
        if (!fDependencySet.isEmpty()) {
          // Remove dependencies
          java.util.HashSet<$DDGNodeName> k = fDependencySet;
          fDependencySet = new java.util.HashSet<$DDGNodeName>(4);
          for ($DDGNodeName node : k) {
            node.removeDependant(this);
          }
          fNode.reactToDependencyChange(fAttrID, fParams);
        }
$if (IncrementalPropLimit)
      }
$endif
$else
      if (!fDependencySet.isEmpty()) {
        // Remove dependencies
        java.util.HashSet<$DDGNodeName> k = fDependencySet;
        fDependencySet = new java.util.HashSet<$DDGNodeName>(4);
        for ($DDGNodeName node : k) {
          node.removeDependant(this);
        }
$if (IncrementalLevelAttr)
        fNode.reactToDependencyChange(fAttrID);
$endif
$if (IncrementalLevelNode)
        fNode.reactToDependencyChange();
$endif
$if (IncrementalLevelRegion)
        fNode.reactToDependencyChange();
$endif
	  }
$endif
      visitedChange = false;
    }
  }

  // State

  protected int fState = $ASTNode.inc_CREATED;

  public void changeState(int newState) {
    fState = newState;
  }

  public void throwAway() {
    fState = $ASTNode.inc_GARBAGE;
  }

  public void keepAlive() {
    fState = $ASTNode.inc_LIVE;
  }

  public boolean isGarbage() {
    return fState == $ASTNode.inc_GARBAGE;
  }

  public boolean isCreated() {
    return fState == $ASTNode.inc_CREATED;
  }

  public boolean isCloned() {
    return fState == $ASTNode.inc_CLONED;
  }

  public boolean isLive() {
    return fState == $ASTNode.inc_LIVE;
  }

$if (IncrementalDebug)
  // Debugging

  private int dumpDependents_visited = 0;

  public void dumpDependents(boolean changed, int visited) {
    if (visited != dumpDependents_visited) {
      dumpDependents_visited = visited;
      if (changed) {
        System.out.println("change(" + this + ")");
      } else {
        System.out.println("dep-change(" + this + ")");
      }
      class Entry implements Comparable {
        public String id;
        public $DDGNodeName node;
        public Entry(String id, $DDGNodeName node) {
          this.id = id; this.node = node;
        }
        public int compareTo(Entry e) {
          return id.compareTo(e.id);
        }
      }
      java.util.TreeSet sorted = new java.util.TreeSet();
      for ($DDGNodeName node : fListenerSet) {
        sorted.add(new Entry(node.toString(), node));
      }
      for (Entry e : sorted) {
        e.node.dumpDependents(false, visited);
      }
    }
  }

  public void dumpDeps() {
    java.util.TreeSet sorted = new java.util.TreeSet();
    for ($DDGNodeName node : fListenerSet) {
      sorted.add(node.toString());
    }
    for (String s : sorted) {
      System.out.println("dep(" + s + " -> " + this + ")");
    }
  }

  public String toString() {
$if (IncrementalLevelParam)
    return fNode.relativeNodeID() + ":" + fAttrID + (fParams != null ?
            ("[" + (fParams instanceof $ASTNode ? (($ASTNode) fParams).relativeNodeID() : fParams) + "]")
            : "");
$endif
$if (IncrementalLevelAttr)
    return fNode.relativeNodeID() + ":" + fAttrID;
$endif
$if (IncrementalLevelNode)
    return fNode.relativeNodeID();
$endif
$if (IncrementalLevelRegion)
    return fNode.relativeNodeID();
$endif
  }
$endif

  // Clean up

  public boolean visitedDuringCleanup = false;
  public static int nbr_cleanup = 0;

  public void cleanUpGarbage() {
    visitedDuringCleanup = true;
    nbr_cleanup++;
    // Clean up garbage
    java.util.Iterator<$DDGNodeName> itr = fListenerSet.iterator();
    while (itr.hasNext()) {
      $DDGNodeName cur = itr.next();
      if (cur.isGarbage()) {
        itr.remove();
      }
    }
  }

  /*
  public static LinkedList<$DDGNodeName> createdHandlers = new LinkedList<$DDGNodeName>();
  public static void doCleanUp() {
    Iterator itr = createdHandlers.iterator();
    while (itr.hasNext()) {
      $DDGNodeName node = ($DDGNodeName)itr.next();
      if (node.isGarbage() || node.isCreated())
        itr.remove();
      else node.cleanUpGarbage();
    }
  }
  */

$if(IncrementalTrack)
  // Tracking

  public static int trackedReads = 0;
  public static int trackedComputes = 0;
  public static int trackedFlushes = 0;

  public void trackChange() {
    System.out.println("change(" + this + ")");
  }

  public static void resetTrackingCounters() {
    trackedReads = 0;
    trackedComputes = 0;
    trackedFlushes = 0;
  }

  public static String getTrackingResult() {
    return "nbr.reads = " + trackedReads + ", nbr.computes = " + trackedComputes + ", nbr.flushes = " + trackedFlushes;
  }
$endif
}
]]

# Create DDG node for token
TokenComponent.incHookTokenHandler = [[
$if(IncrementalEnabled)
$if (!#isNTA)
$if (IncrementalLevelParam)
$if (IncrementalPropLimit)
  protected $DDGNodeName $Host.get$(Id)_handler = new $DDGNodeName(this, "get$Id", null, true);
$else
  protected $DDGNodeName $Host.get$(Id)_handler = new $DDGNodeName(this, "get$Id", null);
$endif
$endif
$if (IncrementalLevelAttr)
  protected $DDGNodeName $Host.get$(Id)_handler = new $DDGNodeName(this, "get$Id");
$endif
$endif
$endif
]]

# Create DDG nodes for AST
ASTDecl.createASTHandlers = [[
$if (IncrementalLevelParam)
$if (IncrementalPropLimit)
  protected $DDGNodeName $ASTNode.getParent_handler = new $DDGNodeName(this, "getParent", null, true);
  protected $DDGNodeName $ASTNode.numChildren_handler = new $DDGNodeName(this, "numChildren", null, true);
$else
  protected $DDGNodeName $ASTNode.getParent_handler = new $DDGNodeName(this, "getParent", null);
  protected $DDGNodeName $ASTNode.numChildren_handler = new $DDGNodeName(this, "numChildren", null);
$endif
  protected $DDGNodeName[] $ASTNode.getChild_handler;
$endif
$if (IncrementalLevelAttr)
  protected $DDGNodeName $ASTNode.getParent_handler = new $DDGNodeName(this, "getParent");
  protected $DDGNodeName $ASTNode.numChildren_handler = new $DDGNodeName(this, "numChildren");
  protected $DDGNodeName $ASTNode.getChild_handler = new $DDGNodeName(this, "getChild");
$endif
]]

# Create DDG node for AST node
ASTDecl.createNodeHandler = [[
  protected $DDGNodeName #name.handler = new $DDGNodeName(this);
]]

# Create DDG node for attribute
ASTDecl.createAttributeHandler = [[
$if (IncrementalLevelParam)
$if (IsParameterized)
  protected java.util.Map #name.$(AttributeName)_handler = new java.util.HashMap(4);
$else
  protected $DDGNodeName #name.$(AttributeName)_handler;
$endif
$endif
$if (IncrementalLevelAttr)
  protected $DDGNodeName #name.$(AttributeName)_handler;
$endif
]]

# Initialize DDG node for children
ASTDecl.incrementalInitChildHandlers = [[
$if (IncrementalLevelParam)
  getChild_handler = new $DDGNodeName[children.length];
$endif
]]




© 2015 - 2024 Weber Informatics LLC | Privacy Policy