/*******************************************************************************
* Copyright (c) 2011-2013 CWI
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* * Arnold Lankamp - Arnold.Lankamp@cwi.nl
* * Anya Helene Bagge - anya@ii.uib.no
* * Jurgen Vinju - Jurgen.Vinju@cwi.nl
*******************************************************************************/
package org.rascalmpl.parser.gtd.stack.edge;
import org.rascalmpl.parser.gtd.result.AbstractContainerNode;
import org.rascalmpl.parser.gtd.stack.AbstractStackNode;
import org.rascalmpl.parser.gtd.util.IntegerMap;
import org.rascalmpl.parser.gtd.util.IntegerObjectList;
@SuppressWarnings({"unchecked", "cast"})
public class EdgesSet<P>{
public final static int DEFAULT_RESULT_STORE_ID = -1;
private final static int DEFAULT_SIZE = 8;
private AbstractStackNode<P>[] edges;
private int size;
private int lastVisitedLevel = -1;
private IntegerMap lastVisitedFilteredLevel;
private AbstractContainerNode<P> lastResults;
private IntegerObjectList<AbstractContainerNode<P>> lastFilteredResults;
public EdgesSet(){
super();
edges = (AbstractStackNode<P>[]) new AbstractStackNode[DEFAULT_SIZE];
size = 0;
}
public EdgesSet(int initialSize){
super();
edges = (AbstractStackNode<P>[]) new AbstractStackNode[initialSize];
size = 0;
}
private void enlarge(){
AbstractStackNode<P>[] oldEdges = edges;
edges = (AbstractStackNode<P>[]) new AbstractStackNode[size << 1];
System.arraycopy(oldEdges, 0, edges, 0, size);
}
public void add(AbstractStackNode<P> edge){
while(size >= edges.length){ // While instead of if to enable the JIT to eliminate the bounds check on the edges array
enlarge();
}
edges[size++] = edge;
}
public boolean contains(AbstractStackNode<P> node){
for(int i = size - 1; i >= 0; --i){
if(edges[i] == node) return true;
}
return false;
}
public boolean containsBefore(AbstractStackNode<P> node, int limit){
for(int i = limit - 1; i >= 0; --i){
if(edges[i] == node) return true;
}
return false;
}
public boolean containsAfter(AbstractStackNode<P> node, int limit){
if(limit >= 0){ // Bounds check elimination helper.
for(int i = size - 1; i >= limit; --i){
if(edges[i] == node) return true;
}
}
return false;
}
public AbstractStackNode<P> get(int index){
return edges[index];
}
public void setLastVisitedLevel(int level, int resultStoreId){
if(resultStoreId == DEFAULT_RESULT_STORE_ID){
lastVisitedLevel = level;
}else{
if(lastVisitedFilteredLevel == null){
lastVisitedFilteredLevel = new IntegerMap();
}
lastVisitedFilteredLevel.put(resultStoreId, level);
}
}
public int getLastVisitedLevel(int resultStoreId){
if(resultStoreId == DEFAULT_RESULT_STORE_ID) return lastVisitedLevel;
if(lastVisitedFilteredLevel == null){
lastVisitedFilteredLevel = new IntegerMap();
return -1;
}
return lastVisitedFilteredLevel.get(resultStoreId);
}
public void setLastResult(AbstractContainerNode<P> lastResult, int resultStoreId){
if(resultStoreId == DEFAULT_RESULT_STORE_ID){
lastResults = lastResult;
}else{
if(lastFilteredResults == null){
lastFilteredResults = new IntegerObjectList<AbstractContainerNode<P>>(DEFAULT_SIZE);
}
lastFilteredResults.add(resultStoreId, lastResult);
}
}
public AbstractContainerNode<P> getLastResult(int resultStoreId){
if(resultStoreId == DEFAULT_RESULT_STORE_ID) return lastResults;
if(lastFilteredResults == null){
lastFilteredResults = new IntegerObjectList<AbstractContainerNode<P>>(DEFAULT_SIZE);
return null;
}
return lastFilteredResults.findValue(resultStoreId);
}
public int size(){
return size;
}
public void clear(){
size = 0;
}
}