Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dfe515e4 authored by Jesse Wilson's avatar Jesse Wilson
Browse files

Remove LruCache.setMaxSize().

Dynamically changing a max cache size is clumsy; almost everyone
should set this when they create the cache.

Fix SQLiteDatabase to copy entries into a new cache when the size
is changed. In pratice this will always be immediately after the
SQLiteDatabase is created. Since the cache field is no longer
final, change the guard on the cache field to the SQLiteDatabase
instance itself.

Change-Id: I4e325f06edc551636723568a52770c0982e2d945
parent c2c9a249
Loading
Loading
Loading
Loading
+75 −73
Original line number Diff line number Diff line
@@ -276,17 +276,11 @@ public class SQLiteDatabase extends SQLiteClosable {
     * invoked.
     *
     * this cache's max size is settable by calling the method
     * (@link #setMaxSqlCacheSize(int)}).
     * (@link #setMaxSqlCacheSize(int)}.
     */
    // guarded by itself
    /* package */ final LruCache<String, SQLiteCompiledSql> mCompiledQueries =
        new LruCache<String, SQLiteCompiledSql>(DEFAULT_SQL_CACHE_SIZE) {
            @Override
            protected void entryEvicted(String key, SQLiteCompiledSql value) {
                verifyLockOwner();
                value.releaseIfNotInUse();
            }
        };
    // guarded by this
    private LruCache<String, SQLiteCompiledSql> mCompiledQueries;

    /**
     * absolute max value that can be set by {@link #setMaxSqlCacheSize(int)}
     * size of each prepared-statement is between 1K - 6K, depending on the complexity of the
@@ -1979,6 +1973,7 @@ public class SQLiteDatabase extends SQLiteClosable {
        if (path == null) {
            throw new IllegalArgumentException("path should not be null");
        }
        setMaxSqlCacheSize(DEFAULT_SQL_CACHE_SIZE);
        mFlags = flags;
        mPath = path;
        mSlowQueryThreshold = SystemProperties.getInt(LOG_SLOW_QUERIES_PROPERTY, -1);
@@ -1991,7 +1986,7 @@ public class SQLiteDatabase extends SQLiteClosable {
        mConnectionNum = connectionNum;
        /* sqlite soft heap limit http://www.sqlite.org/c3ref/soft_heap_limit64.html
         * set it to 4 times the default cursor window size.
         * TODO what is an appropriate value, considring the WAL feature which could burn
         * TODO what is an appropriate value, considering the WAL feature which could burn
         * a lot of memory with many connections to the database. needs testing to figure out
         * optimal value for this.
         */
@@ -2145,8 +2140,8 @@ public class SQLiteDatabase extends SQLiteClosable {
     * the new {@link SQLiteCompiledSql} object is NOT inserted into the cache (i.e.,the current
     * mapping is NOT replaced with the new mapping).
     */
    /* package */ void addToCompiledQueries(String sql, SQLiteCompiledSql compiledStatement) {
        synchronized(mCompiledQueries) {
    /* package */ synchronized void addToCompiledQueries(
            String sql, SQLiteCompiledSql compiledStatement) {
        // don't insert the new mapping if a mapping already exists
        if (mCompiledQueries.get(sql) != null) {
            return;
@@ -2162,8 +2157,7 @@ public class SQLiteDatabase extends SQLiteClosable {
                    mParentConnObj.mCompiledQueries.size() == maxCacheSz);
            if (printWarning) {
                /*
                     * cache size of {@link #mMaxSqlCacheSize} is not enough for this app.
                     * log a warning.
                 * cache size is not enough for this app. log a warning.
                 * chances are it is NOT using ? for bindargs - or cachesize is too small.
                 */
                Log.w(TAG, "Reached MAX size for compiled-sql statement cache for database " +
@@ -2177,27 +2171,24 @@ public class SQLiteDatabase extends SQLiteClosable {
        }
        /* add the given SQLiteCompiledSql compiledStatement to cache.
         * no need to worry about the cache size - because {@link #mCompiledQueries}
             * self-limits its size to {@link #mMaxSqlCacheSize}.
         * self-limits its size.
         */
        mCompiledQueries.put(sql, compiledStatement);
    }
    }

    /** package-level access for testing purposes */
    /* package */ void deallocCachedSqlStatements() {
        synchronized (mCompiledQueries) {
    /* package */ synchronized void deallocCachedSqlStatements() {
        for (SQLiteCompiledSql compiledSql : mCompiledQueries.snapshot().values()) {
            compiledSql.releaseSqlStatement();
        }
        mCompiledQueries.evictAll();
    }
    }

    /**
     * From the compiledQueries cache, returns the compiled-statement-id for the given SQL.
     * Returns null, if not found in the cache.
     */
    /* package */ SQLiteCompiledSql getCompiledStatementForSql(String sql) {
    /* package */ synchronized SQLiteCompiledSql getCompiledStatementForSql(String sql) {
        return mCompiledQueries.get(sql);
    }

@@ -2216,25 +2207,37 @@ public class SQLiteDatabase extends SQLiteClosable {
     * the value set with previous setMaxSqlCacheSize() call.
     */
    public void setMaxSqlCacheSize(int cacheSize) {
        synchronized(mCompiledQueries) {
        synchronized (this) {
            LruCache<String, SQLiteCompiledSql> oldCompiledQueries = mCompiledQueries;
            if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) {
                throw new IllegalStateException("expected value between 0 and " + MAX_SQL_CACHE_SIZE);
            } else if (cacheSize < mCompiledQueries.maxSize()) {
                throw new IllegalStateException("cannot set cacheSize to a value less than the value " +
                        "set with previous setMaxSqlCacheSize() call.");
                throw new IllegalStateException(
                        "expected value between 0 and " + MAX_SQL_CACHE_SIZE);
            } else if (oldCompiledQueries != null && cacheSize < oldCompiledQueries.maxSize()) {
                throw new IllegalStateException("cannot set cacheSize to a value less than the "
                        + "value set with previous setMaxSqlCacheSize() call.");
            }
            mCompiledQueries = new LruCache<String, SQLiteCompiledSql>(cacheSize) {
                @Override
                protected void entryEvicted(String key, SQLiteCompiledSql value) {
                    verifyLockOwner();
                    value.releaseIfNotInUse();
                }
            };
            if (oldCompiledQueries != null) {
                for (Map.Entry<String, SQLiteCompiledSql> entry
                        : oldCompiledQueries.snapshot().entrySet()) {
                    mCompiledQueries.put(entry.getKey(), entry.getValue());
                }
            }
            mCompiledQueries.setMaxSize(cacheSize);
        }
    }

    /* package */ boolean isInStatementCache(String sql) {
        synchronized (mCompiledQueries) {
    /* package */ synchronized boolean isInStatementCache(String sql) {
        return mCompiledQueries.get(sql) != null;
    }
    }

    /* package */ void releaseCompiledSqlObj(String sql, SQLiteCompiledSql compiledSql) {
        synchronized (mCompiledQueries) {
    /* package */ synchronized void releaseCompiledSqlObj(
            String sql, SQLiteCompiledSql compiledSql) {
        if (mCompiledQueries.get(sql) == compiledSql) {
            // it is in cache - reset its inUse flag
            compiledSql.release();
@@ -2243,17 +2246,16 @@ public class SQLiteDatabase extends SQLiteClosable {
            compiledSql.releaseSqlStatement();
        }
    }
    }

    private int getCacheHitNum() {
    private synchronized int getCacheHitNum() {
        return mCompiledQueries.hitCount();
    }

    private int getCacheMissNum() {
    private synchronized int getCacheMissNum() {
        return mCompiledQueries.missCount();
    }

    private int getCachesize() {
    private synchronized int getCachesize() {
        return mCompiledQueries.size();
    }

+0 −19
Original line number Diff line number Diff line
@@ -154,25 +154,6 @@ public class LruCache<K, V> {
        }
    }

    /**
     * Sets the maximum size of this cache. Decreasing the maximum size may
     * evict entries from this cache.
     *
     * @hide
     *
     * @param maxSize for caches that do not override {@link #sizeOf}, this is
     *     the maximum number of entries in the cache. For all other caches,
     *     this is the maximum sum of the sizes of the entries in this cache.
     */
    public synchronized final void setMaxSize(int maxSize) {
        if (maxSize <= 0) {
            throw new IllegalArgumentException("maxSize <= 0");
        }

        trimToSize(maxSize);
        this.maxSize = maxSize;
    }

    /**
     * Called for entries that have reached the tail of the least recently used
     * queue and are be removed. The default implementation does nothing.