1 /* 2 * Copyright (C) 2007 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 android.database.sqlite; 18 19 import java.util.ArrayList; 20 21 import android.os.Build; 22 import android.os.SystemProperties; 23 import android.util.Log; 24 25 /** 26 * Provides debugging info about all SQLite databases running in the current process. 27 * 28 * {@hide} 29 */ 30 public final class SQLiteDebug { 31 /** 32 * Controls the printing of SQL statements as they are executed. 33 */ 34 public static final boolean DEBUG_SQL_STATEMENTS = 35 Log.isLoggable("SQLiteStatements", Log.VERBOSE); 36 37 /** 38 * Controls the printing of wall-clock time taken to execute SQL statements 39 * as they are executed. 40 */ 41 public static final boolean DEBUG_SQL_TIME = 42 Log.isLoggable("SQLiteTime", Log.VERBOSE); 43 44 /** 45 * Controls the printing of compiled-sql-statement cache stats. 46 */ 47 public static final boolean DEBUG_SQL_CACHE = 48 Log.isLoggable("SQLiteCompiledSql", Log.VERBOSE); 49 50 /** 51 * Controls the stack trace reporting of active cursors being 52 * finalized. 53 */ 54 public static final boolean DEBUG_ACTIVE_CURSOR_FINALIZATION = 55 Log.isLoggable("SQLiteCursorClosing", Log.VERBOSE); 56 57 /** 58 * Controls the tracking of time spent holding the database lock. 59 */ 60 public static final boolean DEBUG_LOCK_TIME_TRACKING = 61 Log.isLoggable("SQLiteLockTime", Log.VERBOSE); 62 63 /** 64 * Controls the printing of stack traces when tracking the time spent holding the database lock. 65 */ 66 public static final boolean DEBUG_LOCK_TIME_TRACKING_STACK_TRACE = 67 Log.isLoggable("SQLiteLockStackTrace", Log.VERBOSE); 68 69 /** 70 * True to enable database performance testing instrumentation. 71 * @hide 72 */ 73 public static final boolean DEBUG_LOG_SLOW_QUERIES = Build.IS_DEBUGGABLE; 74 75 /** 76 * Determines whether a query should be logged. 77 * 78 * Reads the "db.log.slow_query_threshold" system property, which can be changed 79 * by the user at any time. If the value is zero, then all queries will 80 * be considered slow. If the value does not exist, then no queries will 81 * be considered slow. 82 * 83 * This value can be changed dynamically while the system is running. 84 * @hide 85 */ 86 public static final boolean shouldLogSlowQuery(long elapsedTimeMillis) { 87 int slowQueryMillis = SystemProperties.getInt("db.log.slow_query_threshold", -1); 88 return slowQueryMillis >= 0 && elapsedTimeMillis > slowQueryMillis; 89 } 90 91 /** 92 * Contains statistics about the active pagers in the current process. 93 * 94 * @see #getPagerStats(PagerStats) 95 */ 96 public static class PagerStats { 97 /** The total number of bytes in all pagers in the current process 98 * @deprecated not used any longer 99 */ 100 @Deprecated 101 public long totalBytes; 102 /** The number of bytes in referenced pages in all pagers in the current process 103 * @deprecated not used any longer 104 * */ 105 @Deprecated 106 public long referencedBytes; 107 /** The number of bytes in all database files opened in the current process 108 * @deprecated not used any longer 109 */ 110 @Deprecated 111 public long databaseBytes; 112 /** The number of pagers opened in the current process 113 * @deprecated not used any longer 114 */ 115 @Deprecated 116 public int numPagers; 117 118 /** the current amount of memory checked out by sqlite using sqlite3_malloc(). 119 * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html 120 */ 121 public int memoryUsed; 122 123 /** the number of bytes of page cache allocation which could not be sattisfied by the 124 * SQLITE_CONFIG_PAGECACHE buffer and where forced to overflow to sqlite3_malloc(). 125 * The returned value includes allocations that overflowed because they where too large 126 * (they were larger than the "sz" parameter to SQLITE_CONFIG_PAGECACHE) and allocations 127 * that overflowed because no space was left in the page cache. 128 * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html 129 */ 130 public int pageCacheOverflo; 131 132 /** records the largest memory allocation request handed to sqlite3. 133 * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html 134 */ 135 public int largestMemAlloc; 136 137 /** a list of {@link DbStats} - one for each main database opened by the applications 138 * running on the android device 139 */ 140 public ArrayList<DbStats> dbStats; 141 } 142 143 /** 144 * contains statistics about a database 145 */ 146 public static class DbStats { 147 /** name of the database */ 148 public String dbName; 149 150 /** the page size for the database */ 151 public long pageSize; 152 153 /** the database size */ 154 public long dbSize; 155 156 /** documented here http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html */ 157 public int lookaside; 158 159 /** statement cache stats: hits/misses/cachesize */ 160 public String cache; 161 162 public DbStats(String dbName, long pageCount, long pageSize, int lookaside, 163 int hits, int misses, int cachesize) { 164 this.dbName = dbName; 165 this.pageSize = pageSize / 1024; 166 dbSize = (pageCount * pageSize) / 1024; 167 this.lookaside = lookaside; 168 this.cache = hits + "/" + misses + "/" + cachesize; 169 } 170 } 171 172 /** 173 * return all pager and database stats for the current process. 174 * @return {@link PagerStats} 175 */ 176 public static PagerStats getDatabaseInfo() { 177 PagerStats stats = new PagerStats(); 178 getPagerStats(stats); 179 stats.dbStats = SQLiteDatabase.getDbStats(); 180 return stats; 181 } 182 183 /** 184 * Gathers statistics about all pagers in the current process. 185 */ 186 public static native void getPagerStats(PagerStats stats); 187 188 /** 189 * Returns the size of the SQLite heap. 190 * @return The size of the SQLite heap in bytes. 191 */ 192 public static native long getHeapSize(); 193 194 /** 195 * Returns the amount of allocated memory in the SQLite heap. 196 * @return The allocated size in bytes. 197 */ 198 public static native long getHeapAllocatedSize(); 199 200 /** 201 * Returns the amount of free memory in the SQLite heap. 202 * @return The freed size in bytes. 203 */ 204 public static native long getHeapFreeSize(); 205 206 /** 207 * Determines the number of dirty belonging to the SQLite 208 * heap segments of this process. pages[0] returns the number of 209 * shared pages, pages[1] returns the number of private pages 210 */ 211 public static native void getHeapDirtyPages(int[] pages); 212 213 private static int sNumActiveCursorsFinalized = 0; 214 215 /** 216 * Returns the number of active cursors that have been finalized. This depends on the GC having 217 * run but is still useful for tests. 218 */ 219 public static int getNumActiveCursorsFinalized() { 220 return sNumActiveCursorsFinalized; 221 } 222 223 static synchronized void notifyActiveCursorFinalized() { 224 sNumActiveCursorsFinalized++; 225 } 226 } 227