/* Soot - a J*va Optimization Framework
* Copyright (C) 2011 Richard Xiao
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
package soot.jimple.spark.geom.geomPA;
/**
* The implementation of prioritized worklist.
* The priority is computed by two parameters: the topsort code and the least recent fired code
* For two pointers p and q
* p has higher priority than q iff:
* 1. topsort_code(p) < topsort_code(q)
* 2. topsort_code(p) == topsort_code(q) && lrf(p) < lrf(q)
*
* @author xiao
*
*/
public class PQ_Worklist implements IWorklist {
private IVarAbstraction[] heap = null;
int cur_tail = 0;
public void initialize( int size )
{
heap = new IVarAbstraction[ size ];
cur_tail = 1;
}
public boolean has_job() {
return cur_tail > 1;
}
public IVarAbstraction next() {
IVarAbstraction ret = heap[1];
--cur_tail;
if ( cur_tail > 1 ) {
IVarAbstraction e = heap[cur_tail];
int k = 1;
while ( (k*2) < cur_tail ) {
int kk = k * 2;
if ( (kk+1) < cur_tail && heap[kk+1].lessThan(heap[kk]) )
kk++;
if ( e.lessThan(heap[kk]) )
break;
heap[k] = heap[kk];
heap[k].Qpos = k;
k = kk;
}
e.Qpos = k;
heap[k] = e;
}
ret.Qpos = 0;
return ret;
}
public void push(IVarAbstraction e) {
e.lrf_value++;
if ( e.Qpos == 0 ) {
// This element has not been inserted
int k = cur_tail;
while ( k > 1 ) {
int kk = k / 2;
if ( heap[kk].lessThan(e) )
break;
heap[k] = heap[kk];
heap[k].Qpos = k;
k /= 2;
}
e.Qpos = k;
heap[k] = e;
++cur_tail;
}
else {
// We decrease this element whenever possible
int k = e.Qpos;
while ( (k*2) < cur_tail ) {
int kk = k * 2;
if ( (kk+1) < cur_tail && heap[kk+1].lessThan(heap[kk]) )
kk++;
if ( e.lessThan(heap[kk]) )
break;
heap[k] = heap[kk];
heap[kk].Qpos = k;
k = kk;
}
e.Qpos = k;
heap[k] = e;
}
}
public int size() {
return cur_tail - 1;
}
public void clear() {
cur_tail = 1;
}
}