Home | History | Annotate | Download | only in coretests
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.coretests;
     18 
     19 
     20 import junit.framework.Test;
     21 
     22 import java.io.File;
     23 import java.sql.Connection;
     24 import java.sql.DriverManager;
     25 import java.sql.PreparedStatement;
     26 import java.sql.ResultSet;
     27 import java.sql.SQLException;
     28 import java.sql.Statement;
     29 
     30 
     31 public class StatsStore {
     32 
     33     static final String sysVersion = "1.0";
     34 
     35     static Connection conn;
     36     static Statement stmt;
     37     static PreparedStatement insertStmt, selectByNameStmt, updateStmt;
     38     static PreparedStatement insertDetStmt, insertEventStmt;
     39     static PreparedStatement selectAllStmt;
     40 
     41     public static long now;
     42 
     43     static int compareDuration(long dur, long refDur) {
     44         long diff = dur - refDur;
     45         if (diff <= 0) {
     46             if ((double)-diff / refDur > 0.5) return 1; // remarkably faster
     47             else return 0; // equivalent duration (maybe a bit faster)
     48         }
     49         else if (diff < 20) return 0; // not measurably slower: equivalent duration
     50         else if ((double)diff / refDur < 0.2) return 0; // just little slower: equivalent duration
     51         else return -1; // relevantly SLOWer
     52     }
     53 
     54     static void initStats(PerfStatCollector.Item a) {
     55         a.statMinDuration = a.duration;
     56         a.statMaxDuration = a.duration;
     57         a.statAvgDuration = a.duration;
     58         a.statCount = 1;
     59     }
     60 
     61     static void adjustStats(PerfStatCollector.Item a) {
     62         if (a.duration < a.statMinDuration) a.statMinDuration = a.duration;
     63         else
     64         if (a.duration > a.statMaxDuration) a.statMaxDuration = a.duration;
     65         a.statAvgDuration = ((a.statAvgDuration * a.statCount + a.duration) / (a.statCount + 1));
     66         a.statCount++;
     67     }
     68 
     69     static void adjustStatsOptimistic(PerfStatCollector.Item a) {
     70         adjustStats(a);
     71         // Could consider reducing a.statMaxDuration.
     72     }
     73 
     74     static void use1(PerfStatCollector.Item a) {
     75         Test test;
     76         int pos;
     77         PreparedStatement selectStmt = selectByNameStmt;
     78         try {
     79             try {
     80                 insertStmt.setString(1, a.test.toString());
     81                 insertStmt.execute();
     82             } catch (SQLException e) {}
     83             selectStmt.setString(1, a.test.toString());
     84             ResultSet row = selectStmt.executeQuery();
     85             row.first();
     86             pos = 1;
     87             a.id = row.getInt(pos); pos++;
     88             a.bestRes = row.getInt(pos); pos++;
     89             a.lastBestAt = row.getLong(pos); pos++;
     90             a.lastRes = row.getInt(pos); pos++;
     91             a.lastDuration = row.getLong(pos); pos++;
     92             a.statCount = row.getInt(pos); pos++;
     93             a.statAvgDuration = row.getDouble(pos); pos++;
     94             a.statMinDuration = row.getLong(pos); pos++;
     95             a.statMaxDuration = row.getLong(pos); pos++;
     96             if (a.res == 0) {
     97                 if (a.bestRes == 100) {
     98                     a.bestRes = 0; a.lastBestAt = now;
     99                     a.histRelevance = 0; // Good from scratch.
    100                     a.isTransition = false;
    101                     initStats(a);
    102                 } else if (a.bestRes != 0) {
    103                     a.bestRes = 0; a.lastBestAt = now;
    104                     a.histRelevance = 4; // "Good" for the first time:
    105                     a.isTransition = true; // was bad before.
    106                     initStats(a);
    107                 } else if (a.lastRes != 0) {
    108                     a.bestRes = 0; a.lastBestAt = now;
    109                     a.histRelevance = 3; // "good" again:
    110                     a.isTransition = true; // was bad in between.
    111                     adjustStats(a);
    112                 } else {
    113                     // res == lastRes == bestRes == 0:
    114                     int cmp = compareDuration(a.duration, a.statMinDuration);
    115                     if (cmp >= 0) {
    116                         a.bestRes = 0; a.lastBestAt = now;
    117                         if (cmp > 0) {
    118                             a.histRelevance = 2; // "Fast"er than ever before.
    119                             a.isTransition = true;
    120                             adjustStatsOptimistic(a);
    121                         } else if (compareDuration(a.duration, a.lastDuration) > 0) {
    122                             // As fast as best but faster than last run:
    123                             a.histRelevance = 1; // "fast" again.
    124                             a.isTransition = true;
    125                             adjustStatsOptimistic(a);
    126                         } else {
    127                             a.histRelevance = 0; // Equivalent Duration:
    128                             a.isTransition = false; // usual good case.
    129                             adjustStats(a);
    130                         }
    131                     } else {
    132                         if (compareDuration(a.duration, a.lastDuration) < 0) {
    133                             a.histRelevance = -2; // "SLOW"!!!
    134                             a.isTransition = true;
    135                             adjustStats(a);
    136                         } else {
    137                             a.histRelevance = -2; // Still "SLOW"!!!
    138                             a.isTransition = false; // (But NO transition!)
    139                             adjustStats(a);
    140                         }
    141                     }
    142                 }
    143             } else if (a.bestRes == 0) {
    144                 if (a.lastRes == 0) {
    145                     a.histRelevance = -4; // "VBAD"!!!
    146                     a.isTransition = true;
    147                 } else {
    148                     a.histRelevance = -4; // Still "VBAD"!!!
    149                     a.isTransition = false; // (But NO transition!)
    150                 }
    151                 // DON'T adjust statistics: they should reflect good runs, only.
    152             } else if (a.bestRes == 100) {
    153                 a.bestRes = -3; // Just mark as NOT good.
    154                 a.histRelevance = -3; // Bad (initial run).
    155                 a.isTransition = true;
    156                 initStats(a);
    157             } else {
    158                 a.histRelevance = 0; // Still Failure or Error:
    159                 a.isTransition = false; // usual bad case.
    160                 adjustStats(a);
    161             }
    162             pos = 1;
    163             updateStmt.setInt(pos, a.bestRes); pos++;
    164             updateStmt.setLong(pos, a.lastBestAt); pos++;
    165             updateStmt.setInt(pos, a.res); pos++;
    166             updateStmt.setLong(pos, a.duration); pos++;
    167             updateStmt.setInt(pos, a.statCount); pos++;
    168             updateStmt.setDouble(pos, a.statAvgDuration); pos++;
    169             updateStmt.setLong(pos, a.statMinDuration); pos++;
    170             updateStmt.setLong(pos, a.statMaxDuration); pos++;
    171             updateStmt.setInt(pos, a.id); pos++;
    172             updateStmt.execute();
    173             pos = 1;
    174             insertDetStmt.setInt(pos, a.id); pos++;
    175             insertDetStmt.setLong(pos, now); pos++;
    176             insertDetStmt.setInt(pos, a.statCount); pos++;
    177             insertDetStmt.setInt(pos, a.res); pos++;
    178             insertDetStmt.setLong(pos, a.duration); pos++;
    179             insertDetStmt.execute();
    180             if (a.isTransition) {
    181                 pos = 1;
    182                 insertEventStmt.setInt(pos, a.id); pos++;
    183                 insertEventStmt.setLong(pos, now); pos++;
    184                 insertEventStmt.setInt(pos, a.histRelevance); pos++;
    185                 insertEventStmt.setInt(pos, a.res); pos++;
    186                 insertEventStmt.setLong(pos, a.duration); pos++;
    187                 insertEventStmt.execute();
    188             }
    189         }
    190         catch (SQLException e) {
    191             int x = 0;
    192         }
    193     }
    194 
    195 //    static void use2(PerfStatCollector.Item a) {
    196 //    }
    197 
    198     static void execOrIgnore(String sql) {
    199         try { stmt.execute(sql); }
    200         catch (SQLException e) {}
    201     }
    202 
    203     static void open(String jdbcDriver, String connectionURL)
    204     throws Exception {
    205 //        try {
    206             Class.forName(jdbcDriver).newInstance();
    207             conn = DriverManager.getConnection(connectionURL);
    208             stmt = conn.createStatement();
    209             String dbVersion;
    210             try {
    211                 ResultSet res = stmt.executeQuery("SELECT id FROM Version");
    212                 res.first();
    213                 dbVersion = res.getString(1);
    214             }
    215             catch (SQLException e) {
    216                 dbVersion = "";
    217             }
    218             if (!dbVersion.equals(sysVersion)) {
    219                 execOrIgnore("DROP TABLE Test_Cases;");
    220                 stmt.execute("CREATE TABLE Test_Cases (" +
    221                         "  id INTEGER PRIMARY KEY AUTOINCREMENT, " +
    222                         "  name VARCHAR(255) UNIQUE, " +
    223                         // (best_Res != 0) ==> (last_Best_At == 0) never ran good!
    224                         "  best_Res INTEGER, last_Best_At INTEGER, " +
    225                         "  last_Res INTEGER, last_Duration INTEGER, " +
    226                         "  stat_Cnt INTEGER, stat_Avg NUMBER(20, 2), " +
    227                         "  stat_Min INTEGER, stat_Max INTEGER);");
    228                 execOrIgnore("DROP TABLE Test_Case_Runs;");
    229                 stmt.execute("CREATE TABLE Test_Case_Runs (" +
    230                         "  test_Id INTEGER, run_At INTEGER, " +
    231                         "  iteration INTEGER, res INTEGER, duration INTEGER, " +
    232                         "  PRIMARY KEY (test_Id, run_At));");
    233                 execOrIgnore("DROP TABLE Test_Case_Events;");
    234                 stmt.execute("CREATE TABLE Test_Case_Events (" +
    235                         "  test_Id INTEGER, run_At INTEGER, " +
    236                         "  relevance INTEGER, " +
    237                         "  res INTEGER, duration INTEGER, " +
    238                         "  PRIMARY KEY (test_Id, run_At));");
    239 //                stmt.execute("CREATE PROCEDURE useSample (IN pName TEXT, " +
    240 //                        "pRes INTEGER, pDuration INTEGER, pTime INTEGER) " +
    241 //                        "BEGIN " +
    242 //                        "  INSERT OR IGNORE INTO TestCases (name)" +
    243 //                        "  VALUES (pName);" +
    244 //                        "END;");
    245                 execOrIgnore("DROP TABLE Version;");
    246                 stmt.execute("CREATE TABLE Version(id VARCHAR(31));");
    247                 stmt.execute("INSERT INTO Version (id) VALUES ('" + sysVersion + "');");
    248             }
    249 //            updateStmt = conn.prepareStatement("useSample(:name, :res, :duration, :time)");
    250     //        firstConnection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
    251     //        firstStmt = firstConnection.createStatement();
    252     //        firstStmt.execute("create table tbl1(one varchar(10), two smallint)");
    253             insertStmt = conn.prepareStatement("INSERT " +
    254                     "INTO Test_Cases (name, stat_Cnt) VALUES (?, 0);");
    255             selectByNameStmt = conn.prepareStatement("SELECT id, " +
    256                     "  IFNULL(best_Res, 100), IFNULL(last_Best_At, 0), " +
    257                     "  IFNULL(last_Res, 100), IFNULL(last_Duration, 0), " +
    258                     "  IFNULL(stat_Cnt, 0), IFNULL(stat_Avg, 0), " +
    259                     "  IFNULL(stat_Min, 0), IFNULL(stat_Max, 0) " +
    260                     "FROM Test_Cases WHERE name = ?;");
    261             updateStmt = conn.prepareStatement("UPDATE Test_Cases SET " +
    262                     "  best_Res = ?, last_Best_At = ?, " +
    263                     "  last_Res = ?, last_Duration = ?, " +
    264                     "  stat_Cnt = ?, stat_Avg = ?, " +
    265                     "  stat_Min = ?, stat_Max = ? " +
    266                     "WHERE id = ?;");
    267             insertDetStmt = conn.prepareStatement("INSERT " +
    268                     "INTO Test_Case_Runs (test_Id, run_At, iteration, res, duration) " +
    269                     "VALUES (?, ?, ?, ?, ?);");
    270             insertEventStmt = conn.prepareStatement("INSERT " +
    271                     "INTO Test_Case_Events (test_Id, run_At, relevance, res, duration) " +
    272                     "VALUES (?, ?, ?, ?, ?);");
    273             selectAllStmt = conn.prepareStatement("SELECT id, name, " +
    274                     "last_Res, stat_Cnt, " +
    275                     "last_Duration, stat_Avg, stat_Min, stat_Max " +
    276                     "FROM Test_Cases;");
    277 
    278             try {
    279 //                ResultSet res = stmt.executeQuery("PRAGMA CACHE_SIZE;");
    280 //                res.first();
    281 //                System.out.print("CACHE_SIZE = ");
    282 //                System.out.println(res.getString(1));
    283 //                stmt.execute("PRAGMA CACHE_SIZE = 5000;");
    284                 stmt.execute("PRAGMA SYNCHRONOUS = OFF;");
    285                 stmt.execute("PRAGMA temp_store = MEMORY;");
    286             }
    287             catch (SQLException e) {
    288                 dbVersion = "";
    289             }
    290             stmt.close();
    291             conn.commit();
    292 //        }
    293 //        catch (Exception e) {
    294 //            conn = null;
    295 //        }
    296 //        return conn != null;
    297     }
    298 
    299     static void close() {
    300         try {
    301             conn.commit();
    302             conn.close();
    303             conn = null;
    304         }
    305         catch (Exception e) {
    306             conn = null;
    307         }
    308     }
    309 }
    310