SQLiteDebug.java revision 89101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2
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
17package android.database.sqlite;
18
19import java.util.ArrayList;
20
21import android.os.Build;
22import android.os.SystemProperties;
23import android.util.Log;
24
25/**
26 * Provides debugging info about all SQLite databases running in the current process.
27 *
28 * {@hide}
29 */
30public 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