OSDN Git Service

remove StackPattern class, move features to StackPatternBasedBirthmarkElement class
authortama3 <tama3@acee48c3-7b26-0410-bdac-b3d0e5314bbc>
Thu, 4 Dec 2008 08:51:12 +0000 (08:51 +0000)
committertama3 <tama3@acee48c3-7b26-0410-bdac-b3d0e5314bbc>
Thu, 4 Dec 2008 08:51:12 +0000 (08:51 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/stigmata/plugins/trunk@336 acee48c3-7b26-0410-bdac-b3d0e5314bbc

wsp/src/main/java/jp/sourceforge/stigmata/birthmarks/wsp/CurrentDepth.java
wsp/src/main/java/jp/sourceforge/stigmata/birthmarks/wsp/OpcodeManager.java
wsp/src/main/java/jp/sourceforge/stigmata/birthmarks/wsp/OpcodeWeightCalculatePreprocessor.java [moved from wsp/src/main/java/jp/sourceforge/stigmata/birthmarks/wsp/StackPatternBasedBirthmarkPreprocessor.java with 95% similarity]
wsp/src/main/java/jp/sourceforge/stigmata/birthmarks/wsp/StackPattern.java [deleted file]
wsp/src/main/java/jp/sourceforge/stigmata/birthmarks/wsp/StackPatternBasedBirthmarkComparator.java
wsp/src/main/java/jp/sourceforge/stigmata/birthmarks/wsp/StackPatternBasedBirthmarkElement.java
wsp/src/main/java/jp/sourceforge/stigmata/birthmarks/wsp/StackPatternBasedBirthmarkExtractor.java
wsp/src/main/java/jp/sourceforge/stigmata/birthmarks/wsp/StackPatternBasedBirthmarkService.java
wsp/src/test/java/jp/sourceforge/stigmata/birthmarks/wsp/WeightCalculatorTest.java [moved from wsp/src/test/java/jp/sourceforge/stigmata/birthmarks/wsp/StackPatternBasedBirthmarkComparatorTest.java with 64% similarity]

index 4a4bf0e..b635a2b 100644 (file)
@@ -25,4 +25,8 @@ public class CurrentDepth{
     public Opcode getOpcode(){
         return opcode;
     }
+
+    public String toString(){
+        return String.format("%d:%d:%d:%d", opcode.getOpcode(), depth, opcode.getWeight(), opcode.getAct());
+    }
 }
index 508e5c2..ccbf017 100644 (file)
@@ -5,7 +5,6 @@ package jp.sourceforge.stigmata.birthmarks.wsp;
  */
 
 import java.io.BufferedReader;
-import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.URL;
 import java.util.HashMap;
@@ -20,10 +19,13 @@ import jp.sourceforge.talisman.csvio.CsvParser;
  * @version $Revision$
  */
 public class OpcodeManager{
-    private static final Map<Integer, Opcode> OPCODE_MAP = new HashMap<Integer, Opcode>();
+    private Map<Integer, Opcode> opcodeMap = new HashMap<Integer, Opcode>();
     private static OpcodeManager manager = new OpcodeManager();
 
-    static{
+    /**
+     * private constructor for singleton pattern.
+     */
+    private OpcodeManager(){
         try{
             URL location = OpcodeManager.class.getResource("/META-INF/bytecode.def");
             BufferedReader in = new BufferedReader(new InputStreamReader(location.openStream()));
@@ -37,25 +39,19 @@ public class OpcodeManager{
                         Integer.parseInt(values[2]),
                         Integer.parseInt(values[3]), values[4]
                     );
-                    OPCODE_MAP.put(def.getOpcode(), def);
+                    opcodeMap.put(def.getOpcode(), def);
                 }
             }
-        } catch(IOException e){
+        } catch(Exception e){
             throw new InternalError(e.getMessage());
         }
     }
 
-    /**
-     * private constructor for singleton pattern.
-     */
-    private OpcodeManager(){
-    }
-
     public static OpcodeManager getInstance(){
         return manager;
     }
 
     public Opcode getOpcode(int opcode){
-        return OPCODE_MAP.get(opcode);
+        return opcodeMap.get(opcode);
     }
 }
@@ -27,8 +27,8 @@ import org.objectweb.asm.MethodVisitor;
  * @author Haruaki Tamada
  * @version $Revision$
  */
-public class StackPatternBasedBirthmarkPreprocessor extends AbstractBirthmarkPreprocessor{
-    public StackPatternBasedBirthmarkPreprocessor(BirthmarkSpi spi){
+public class OpcodeWeightCalculatePreprocessor extends AbstractBirthmarkPreprocessor{
+    public OpcodeWeightCalculatePreprocessor(BirthmarkSpi spi){
         super(spi);
     }
 
diff --git a/wsp/src/main/java/jp/sourceforge/stigmata/birthmarks/wsp/StackPattern.java b/wsp/src/main/java/jp/sourceforge/stigmata/birthmarks/wsp/StackPattern.java
deleted file mode 100644 (file)
index ca50313..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-package jp.sourceforge.stigmata.birthmarks.wsp;
-
-/*
- * $Id$
- */
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * 
- * @author Haruaki Tamada
- * @version $Revision$
- */
-public class StackPattern implements Iterable<CurrentDepth>{
-    private List<CurrentDepth> depthList = new ArrayList<CurrentDepth>();
-    private int weight = -1;
-
-    public StackPattern(){
-    }
-
-    public int getLength(){
-        return depthList.size();
-    }
-
-    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;
-    }
-}
index 1dbc118..787c248 100644 (file)
@@ -23,7 +23,7 @@ public class StackPatternBasedBirthmarkComparator extends AbstractBirthmarkCompa
     @Override
     public double compare(Birthmark b1, Birthmark b2, BirthmarkContext context){
         int[][] wcs = createMatrix(b1, b2);
-        int weightOfWcs = calculateWeight(wcs);
+        int weightOfWcs = new WeightCalculator().calculateWeight(wcs);
         int weightOfBirthmark1 = 0;
         for(BirthmarkElement element: b1){
             weightOfBirthmark1 += ((StackPatternBasedBirthmarkElement)element).getWeight();
@@ -32,46 +32,6 @@ public class StackPatternBasedBirthmarkComparator extends AbstractBirthmarkCompa
         return (double)weightOfWcs / (double)weightOfBirthmark1;
     }
 
-    int calculateWeight(int[][] wcs){
-        int weight = 0;
-        boolean[][] availableFlag = new boolean[wcs.length][wcs[0].length];
-        for(int i = 0; i < wcs.length; i++){
-            for(int j = 0; j < wcs[i].length; j++){
-                availableFlag[i][j] = true;
-            }
-        }
-
-        int length = wcs.length;
-        if(length < wcs[0].length){
-            length = wcs[0].length;
-        }
-        for(int k = 0; k < length; k++){
-            int max = Integer.MIN_VALUE;
-            int column = -1;
-            int row = -1;
-            for(int i = 0; i < wcs.length; i++){
-                for(int j = 0; j < wcs[i].length; j++){
-                    if(max < wcs[i][j] && availableFlag[i][j]){
-                        max = wcs[i][j];
-                        row = i;
-                        column = j;
-                    }
-                }
-            }
-            if(column >= 0 && row >= 0){
-                for(int i = 0; i < wcs.length; i++){
-                    availableFlag[i][column] = false;
-                }
-                for(int j = 0; j < wcs[0].length; j++){
-                    availableFlag[row][j] = false;
-                }
-                weight += wcs[column][row];
-            }
-        }
-
-        return weight;
-    }
-
     private int[][] createMatrix(Birthmark b1, Birthmark b2){
         BirthmarkElement[] elementsA = b1.getElements();
         BirthmarkElement[] elementsB = b2.getElements();
@@ -81,7 +41,7 @@ public class StackPatternBasedBirthmarkComparator extends AbstractBirthmarkCompa
             for(int j = 0; j < elementsB.length; j++){
                 StackPatternBasedBirthmarkElement wsp1 = (StackPatternBasedBirthmarkElement)elementsA[i];
                 StackPatternBasedBirthmarkElement wsp2 = (StackPatternBasedBirthmarkElement)elementsB[j];
-                matrix[i][j] = wsp1.getPattern().calculateWeight(wsp2.getPattern());
+                matrix[i][j] = wsp1.getWeight(wsp2);
             }
         }
         return matrix;
index b2e330a..1cb7770 100644 (file)
@@ -4,6 +4,11 @@ package jp.sourceforge.stigmata.birthmarks.wsp;
  * $Id$
  */
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
 import jp.sourceforge.stigmata.BirthmarkElement;
 
 /**
@@ -11,21 +16,97 @@ import jp.sourceforge.stigmata.BirthmarkElement;
  * @author Haruaki TAMADA
  * @version $Revision$ 
  */
-public class StackPatternBasedBirthmarkElement extends BirthmarkElement{
+public class StackPatternBasedBirthmarkElement extends BirthmarkElement implements Iterable<CurrentDepth>{
     private static final long serialVersionUID = 7965456413167854L;
 
-    private StackPattern pattern;
+    private List<CurrentDepth> list = new ArrayList<CurrentDepth>();
+    private int weight = -1;
+
+    public StackPatternBasedBirthmarkElement(CurrentDepth[] depthArray){
+        super(getStringRepresentation(depthArray));
+        for(CurrentDepth depth: depthArray){
+            list.add(depth);
+        }
+    }
+    public StackPatternBasedBirthmarkElement(String value){
+        super(value);
+        String[] depthList = value.split(", ");
+        for(int i = 0; i < depthList.length; i++){
+            String[] depthStringArray = depthList[i].split(":");
+            if(depthStringArray.length == 4){
+                int opcode = Integer.parseInt(depthStringArray[0]);
+                int depth = Integer.parseInt(depthStringArray[1]);
+                int weight = Integer.parseInt(depthStringArray[2]);
+                int act = Integer.parseInt(depthStringArray[3]);
+
+                Opcode o = new Opcode(OpcodeManager.getInstance().getOpcode(opcode));
+                o.setWeight(weight);
+                if(o.getCategory() == Opcode.Category.OBJECT || o.getCategory() == Opcode.Category.INVOKE){
+                    o.setAct(act);
+                }
+                list.add(new CurrentDepth(depth, o));
+            }
+        }
+    }
+
+    public int getLength(){
+        return list.size();
+    }
 
-    public StackPatternBasedBirthmarkElement(StackPattern pattern){
-        super(pattern.toString());
-        this.pattern = pattern;
+    public CurrentDepth getDepth(int index){
+        return list.get(index);
     }
 
-    public StackPattern getPattern(){
-        return pattern;
+    public Iterator<CurrentDepth> iterator(){
+        return Collections.unmodifiableList(list).iterator();
+    }
+
+    public int getWeight(StackPatternBasedBirthmarkElement element){
+        int[][] matrix = new int[element.getLength() + 1][getLength() + 1];
+
+        for(int i = 0; i <= element.getLength(); i++){
+            for(int j = 0; j <= getLength(); j++){
+                if(i == 0 || j == 0){
+                    matrix[i][j] = 0;
+                }
+                else if(element.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 = element.getLength();
+        for(int i = 0; i < matrix[last].length; i++){
+            if(matrix[last][i] > max){
+                max = matrix[last][i];
+            }
+        }
+        return max;
     }
 
     public int getWeight(){
-        return pattern.getWeight();
+        if(weight < 0){
+            int w = 0;
+            for(CurrentDepth depth: this){
+                w += depth.getOpcode().getWeight();
+            }
+            this.weight = w;
+        }
+        return weight;        
+    }
+
+    private static String getStringRepresentation(CurrentDepth[] depth){
+        StringBuilder builder = new StringBuilder();
+        for(int i = 0; i < depth.length; i++){
+            if(i != 0){
+                builder.append(", ");
+            }
+            builder.append(depth[i]);
+        }
+        return new String(builder);
     }
 }
index 8ca70d6..514633e 100644 (file)
@@ -46,26 +46,26 @@ public class StackPatternBasedBirthmarkExtractor extends ASMBirthmarkExtractor{
     }
 
     private BirthmarkElement[] buildElement(List<Opcode> opcodes, BirthmarkContext context){
-        StackPattern pattern = buildStackPattern(opcodes, context);
+        List<CurrentDepth> pattern = buildStackPattern(opcodes, context);
         List<BirthmarkElement> elements = new ArrayList<BirthmarkElement>();
 
-        StackPattern subpattern = new StackPattern();
+        List<CurrentDepth> subPattern = new ArrayList<CurrentDepth>();
         for(CurrentDepth depth: pattern){
-            subpattern.update(depth);
+            subPattern.add(depth);
             if(depth.getDepth() == 0){
-                elements.add(new StackPatternBasedBirthmarkElement(subpattern));
-                subpattern = new StackPattern();
+                elements.add(new StackPatternBasedBirthmarkElement(subPattern.toArray(new CurrentDepth[subPattern.size()])));
+                subPattern.clear();
             }
         }
-        elements.add(new StackPatternBasedBirthmarkElement(subpattern));
+        elements.add(new StackPatternBasedBirthmarkElement(subPattern.toArray(new CurrentDepth[subPattern.size()])));
 
         return elements.toArray(new BirthmarkElement[elements.size()]);
     }
 
     @SuppressWarnings("unchecked")
-    private StackPattern buildStackPattern(List<Opcode> opcodes, BirthmarkContext context){ 
+    private List<CurrentDepth> buildStackPattern(List<Opcode> opcodes, BirthmarkContext context){ 
         Map<Label, Integer> tableMap = new HashMap<Label, Integer>();
-        StackPattern pattern = new StackPattern();
+        List<CurrentDepth> pattern = new ArrayList<CurrentDepth>();
         Map<Integer, Integer> weights = (Map<Integer, Integer>)context.getProperty("birthmarks.wsp.weights");
 
         int currentDepth = 0;
@@ -84,7 +84,7 @@ public class StackPatternBasedBirthmarkExtractor extends ASMBirthmarkExtractor{
                 }
                 forwardedStatus = null;
 
-                pattern.update(currentDepth, opcode);
+                pattern.add(new CurrentDepth(currentDepth, opcode));
                 if(opcode.getCategory() == Opcode.Category.BRANCH){
                     for(Iterator<Label> i = opcode.labels(); i.hasNext(); ){
                         Label label = i.next();
index ea00338..d0a2778 100644 (file)
@@ -5,6 +5,7 @@ package jp.sourceforge.stigmata.birthmarks.wsp;
  */
 
 import jp.sourceforge.stigmata.BirthmarkComparator;
+import jp.sourceforge.stigmata.BirthmarkElement;
 import jp.sourceforge.stigmata.BirthmarkExtractor;
 import jp.sourceforge.stigmata.BirthmarkPreprocessor;
 import jp.sourceforge.stigmata.birthmarks.AbstractBirthmarkService;
@@ -27,9 +28,9 @@ import jp.sourceforge.stigmata.birthmarks.AbstractBirthmarkService;
  * @version $Revision$
  */
 public class StackPatternBasedBirthmarkService extends AbstractBirthmarkService{
-    private BirthmarkComparator comparator = new StackPatternBasedBirthmarkComparator(this);
+    private BirthmarkPreprocessor preprocessor = new OpcodeWeightCalculatePreprocessor(this);
     private BirthmarkExtractor extractor = new StackPatternBasedBirthmarkExtractor(this);
-    private BirthmarkPreprocessor preprocessor = new StackPatternBasedBirthmarkPreprocessor(this);
+    private BirthmarkComparator comparator = new StackPatternBasedBirthmarkComparator(this);
 
     @Override
     public String getDefaultDescription(){
@@ -55,4 +56,9 @@ public class StackPatternBasedBirthmarkService extends AbstractBirthmarkService{
     public BirthmarkPreprocessor getPreprocessor(){
         return preprocessor;
     }
+
+    @Override
+    public BirthmarkElement buildBirthmarkElement(String value){
+        return new StackPatternBasedBirthmarkElement(value);
+    }
 }
@@ -13,13 +13,12 @@ import org.junit.Test;
  * @author Haruaki Tamada
  * @version $Revision$
  */
-public class StackPatternBasedBirthmarkComparatorTest{
-    private StackPatternBasedBirthmarkComparator comparator;
+public class WeightCalculatorTest{
+    private WeightCalculator calculator;
 
     @Before
     public void setup(){
-        StackPatternBasedBirthmarkService service = new StackPatternBasedBirthmarkService();
-        comparator = new StackPatternBasedBirthmarkComparator(service);
+        calculator = new WeightCalculator();
     }
 
     @Test
@@ -30,7 +29,7 @@ public class StackPatternBasedBirthmarkComparatorTest{
             {  9,  6, 12,  3, },
             {  6,  9, 30,  9, },
         };
-        Assert.assertEquals(60, comparator.calculateWeight(wcs));
+        Assert.assertEquals(60, calculator.calculateWeight(wcs));
     }
 
     @Test
@@ -41,6 +40,6 @@ public class StackPatternBasedBirthmarkComparatorTest{
             {  2, 10,  0,  3, },
             {  0,  2,  3,  9, },
         };
-        Assert.assertEquals(50, comparator.calculateWeight(wcs));
+        Assert.assertEquals(50, calculator.calculateWeight(wcs));
     }
 }