diff options
author | Jeff Brown <jeffbrown@google.com> | 2011-10-27 14:52:28 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2011-10-28 01:46:18 -0700 |
commit | 650de3dcfcbc7635da3c070410ef1dc4027ae464 (patch) | |
tree | 93cb485d70a4388a76397e6f65a80c1a059425fb /core/java/android/database/sqlite/SQLiteCursor.java | |
parent | 4257e3b18118200e29a3125a12044c4572c1baf5 (diff) | |
download | frameworks_base-650de3dcfcbc7635da3c070410ef1dc4027ae464.zip frameworks_base-650de3dcfcbc7635da3c070410ef1dc4027ae464.tar.gz frameworks_base-650de3dcfcbc7635da3c070410ef1dc4027ae464.tar.bz2 |
Optimize fillWindow to improve reverse-seek performance.
Bug: 5520301
When an application requests a row from a SQLiteCursor that
is not in the window, instead of filling from the requested
row position onwards, fill from a little bit ahead of the
requested row position.
This fixes a problem with applications that seek backwards
in large cursor windows. Previously the application could
end up refilling the window every time it moved back
one position.
We try to fill about 1/3 before the requested position and
2/3 after which substantially improves scrolling responsiveness
when the list is bound to a data set that does not fit
entirely within one cursor window.
Change-Id: I168ff1d3aed1a41ac96267be34a026c108590e52
Diffstat (limited to 'core/java/android/database/sqlite/SQLiteCursor.java')
-rw-r--r-- | core/java/android/database/sqlite/SQLiteCursor.java | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java index c24acd4..8dcedf2 100644 --- a/core/java/android/database/sqlite/SQLiteCursor.java +++ b/core/java/android/database/sqlite/SQLiteCursor.java @@ -18,6 +18,7 @@ package android.database.sqlite; import android.database.AbstractWindowedCursor; import android.database.CursorWindow; +import android.database.DatabaseUtils; import android.os.StrictMode; import android.util.Log; @@ -48,7 +49,10 @@ public class SQLiteCursor extends AbstractWindowedCursor { private final SQLiteCursorDriver mDriver; /** The number of rows in the cursor */ - private volatile int mCount = NO_COUNT; + private int mCount = NO_COUNT; + + /** The number of rows that can fit in the cursor window, 0 if unknown */ + private int mCursorWindowCapacity; /** A mapping of column names to column indices, to speed up lookups */ private Map<String, Integer> mColumnNameMap; @@ -158,18 +162,20 @@ public class SQLiteCursor extends AbstractWindowedCursor { return mCount; } - private void fillWindow(int startPos) { + private void fillWindow(int requiredPos) { clearOrCreateWindow(getDatabase().getPath()); - mWindow.setStartPosition(startPos); - int count = getQuery().fillWindow(mWindow); - if (startPos == 0) { // fillWindow returns count(*) only for startPos = 0 + + if (mCount == NO_COUNT) { + int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos, 0); + mCount = getQuery().fillWindow(mWindow, startPos, requiredPos, true); + mCursorWindowCapacity = mWindow.getNumRows(); if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "received count(*) from native_fill_window: " + count); + Log.d(TAG, "received count(*) from native_fill_window: " + mCount); } - mCount = count; - } else if (mCount <= 0) { - throw new IllegalStateException("Row count should never be zero or negative " - + "when the start position is non-zero"); + } else { + int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos, + mCursorWindowCapacity); + getQuery().fillWindow(mWindow, startPos, requiredPos, false); } } |