OSDN Git Service

add method for calculating weights
authortama3 <tama3@acee48c3-7b26-0410-bdac-b3d0e5314bbc>
Tue, 2 Dec 2008 10:34:28 +0000 (10:34 +0000)
committertama3 <tama3@acee48c3-7b26-0410-bdac-b3d0e5314bbc>
Tue, 2 Dec 2008 10:34:28 +0000 (10:34 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/stigmata/plugins/trunk@331 acee48c3-7b26-0410-bdac-b3d0e5314bbc

wsp/src/main/java/jp/sourceforge/stigmata/birthmarks/wsp/StackPattern.java
wsp/src/test/java/jp/sourceforge/stigmata/birthmarks/wsp/StackPatternTest.java [new file with mode: 0644]

index e120ff6..25660d1 100644 (file)
@@ -7,6 +7,7 @@ import java.util.List;
 
 public class StackPattern implements Iterable<CurrentDepth>{
     private List<CurrentDepth> depthList = new ArrayList<CurrentDepth>();
+    private int weight = -1;
 
     public StackPattern(){
     }
@@ -17,13 +18,57 @@ public class StackPattern implements Iterable<CurrentDepth>{
 
     public void update(int depth, Opcode opcode){
         update(new CurrentDepth(depth, opcode));
+        weight = -1;
     }
 
     public void update(CurrentDepth depth){
         depthList.add(depth);
+        weight = -1;
     }
 
     public Iterator<CurrentDepth> iterator(){
         return Collections.unmodifiableList(depthList).iterator();
     }
+
+    public CurrentDepth getDepth(int index){
+        return depthList.get(index);
+    }
+
+    public int getWeight(){
+        if(weight < 0){
+            int w = 0;
+            for(CurrentDepth depth: this){
+                w += depth.getOpcode().getWeight();
+            }
+            this.weight = w;
+        }
+        return weight;
+    }
+
+    public int calculateWeight(StackPattern pattern){
+        int[][] matrix = new int[pattern.getLength() + 1][getLength() + 1];
+
+        for(int i = 0; i <= pattern.getLength(); i++){
+            for(int j = 0; j <= getLength(); j++){
+                if(i == 0 || j == 0){
+                    matrix[i][j] = 0;
+                }
+                else if(pattern.getDepth(i - 1).getOpcode().getOpcode() == getDepth(j - 1).getOpcode().getOpcode()){
+                    matrix[i][j] = (int)(matrix[i - 1][j - 1] + getDepth(j - 1).getOpcode().getWeight());
+                }
+                else{
+                    matrix[i][j] = Math.max(matrix[i - 1][j], matrix[i][j - 1]);
+                }
+            }
+        }
+
+        int max = 0;
+        int last = pattern.getLength();
+        for(int i = 0; i < matrix[last].length; i++){
+            if(matrix[last][i] > max){
+                max = matrix[last][i];
+            }
+        }
+        return max;
+    }
 }
diff --git a/wsp/src/test/java/jp/sourceforge/stigmata/birthmarks/wsp/StackPatternTest.java b/wsp/src/test/java/jp/sourceforge/stigmata/birthmarks/wsp/StackPatternTest.java
new file mode 100644 (file)
index 0000000..e37a67a
--- /dev/null
@@ -0,0 +1,64 @@
+package jp.sourceforge.stigmata.birthmarks.wsp;
+
+/*
+ * $Id$
+ */
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * 
+ * @author Haruaki Tamada
+ * @version $Revision$
+ */
+public class StackPatternTest{
+    private StackPattern pattern;
+
+    @Before
+    public void setup(){
+        pattern = new StackPattern();
+
+        pattern.update(new CurrentDepth(1, new Opcode( 26, "iload_0",      0,  1, Opcode.Category.NORMAL, 7)));
+        pattern.update(new CurrentDepth(2, new Opcode( 26, "iload_0",      0,  1, Opcode.Category.NORMAL, 7)));
+        pattern.update(new CurrentDepth(3, new Opcode(  4, "iconst_1",     0,  1, Opcode.Category.NORMAL, 1)));
+        pattern.update(new CurrentDepth(2, new Opcode(100, "isub",         0, -1, Opcode.Category.NORMAL, 4)));
+        pattern.update(new CurrentDepth(2, new Opcode(184, "invokestatic", 2,  0, Opcode.Category.INVOKE, 1)));
+        pattern.update(new CurrentDepth(1, new Opcode(104, "imul",         0, -1, Opcode.Category.NORMAL, 6)));
+        pattern.update(new CurrentDepth(0, new Opcode(172, "ireturn",      0, -1, Opcode.Category.NORMAL, 2)));
+    }
+
+    @Test
+    public void testBasic() throws Exception{
+        Assert.assertEquals(7, pattern.getLength());
+        Assert.assertEquals(28, pattern.getWeight());
+
+        Assert.assertEquals(1, pattern.getDepth(0).getDepth());
+        Assert.assertEquals(2, pattern.getDepth(1).getDepth());
+        Assert.assertEquals(3, pattern.getDepth(2).getDepth());
+        Assert.assertEquals(2, pattern.getDepth(3).getDepth());
+        Assert.assertEquals(2, pattern.getDepth(4).getDepth());
+        Assert.assertEquals(1, pattern.getDepth(5).getDepth());
+        Assert.assertEquals(0, pattern.getDepth(6).getDepth());
+    }
+
+    @Test
+    public void testCalculateWeightedCommonSubsequence(){
+        StackPattern pattern2 = new StackPattern();
+        
+        pattern2.update(new CurrentDepth(1, new Opcode( 26, "iload_0",      0,  1, Opcode.Category.NORMAL, 7)));
+        pattern2.update(new CurrentDepth(2, new Opcode(  4, "iconst_1",     0,  1, Opcode.Category.NORMAL, 1)));
+        pattern2.update(new CurrentDepth(1, new Opcode(100, "isub",         0, -1, Opcode.Category.NORMAL, 4)));
+        pattern2.update(new CurrentDepth(1, new Opcode(184, "invokestatic", 2,  0, Opcode.Category.INVOKE, 1)));
+        pattern2.update(new CurrentDepth(2, new Opcode( 26, "iload_0",      0,  1, Opcode.Category.NORMAL, 7)));
+        pattern2.update(new CurrentDepth(3, new Opcode(  5, "iconst_2",     0,  1, Opcode.Category.NORMAL, 1)));
+        pattern2.update(new CurrentDepth(2, new Opcode(100, "isub",         0, -1, Opcode.Category.NORMAL, 4)));
+        pattern2.update(new CurrentDepth(2, new Opcode(184, "invokestatic", 2,  0, Opcode.Category.INVOKE, 1)));
+        pattern2.update(new CurrentDepth(1, new Opcode( 96, "iadd",         0, -1, Opcode.Category.NORMAL, 3)));
+        pattern2.update(new CurrentDepth(0, new Opcode(172, "ireturn",      0, -1, Opcode.Category.NORMAL, 2)));
+
+        Assert.assertEquals(21, pattern.calculateWeight(pattern2));
+        Assert.assertEquals(21, pattern2.calculateWeight(pattern));
+    }
+}