Merge "Return count of rows in a resultset only once (when startPos = 0)"

This commit is contained in:
Vasu Nori
2010-09-10 13:45:45 -07:00
committed by Android (Google) Code Review
4 changed files with 171 additions and 23 deletions

View File

@@ -56,7 +56,7 @@ public class SQLiteCursor extends AbstractWindowedCursor {
private final SQLiteCursorDriver mDriver;
/** The number of rows in the cursor */
private int mCount = NO_COUNT;
private volatile int mCount = NO_COUNT;
/** A mapping of column names to column indices, to speed up lookups */
private Map<String, Integer> mColumnNameMap;
@@ -138,13 +138,21 @@ public class SQLiteCursor extends AbstractWindowedCursor {
}
try {
int count = getQuery().fillWindow(cw, mMaxRead, mCount);
// return -1 means not finished
// return -1 means there is still more data to be retrieved from the resultset
if (count != 0) {
if (count == NO_COUNT){
mCount += mMaxRead;
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "received -1 from native_fill_window. read " +
mCount + " rows so far");
}
sendMessage();
} else {
mCount = count;
mCount += count;
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "received all data from native_fill_window. read " +
mCount + " rows.");
}
sendMessage();
break;
}
@@ -308,13 +316,23 @@ public class SQLiteCursor extends AbstractWindowedCursor {
}
}
mWindow.setStartPosition(startPos);
mCount = getQuery().fillWindow(mWindow, mInitialRead, 0);
// return -1 means not finished
if (mCount == NO_COUNT){
int count = getQuery().fillWindow(mWindow, mInitialRead, 0);
// return -1 means there is still more data to be retrieved from the resultset
if (count == NO_COUNT){
mCount = startPos + mInitialRead;
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "received -1 from native_fill_window. read " + mCount + " rows so far");
}
Thread t = new Thread(new QueryThread(mCursorState), "query thread");
t.start();
}
} else if (startPos == 0) { // native_fill_window returns count(*) only for startPos = 0
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "received count(*) from native_fill_window: " + count);
}
mCount = count;
} else if (mCount <= 0) {
throw new IllegalStateException("count should never be non-zero negative number");
}
}
private synchronized SQLiteQuery getQuery() {
@@ -504,4 +522,11 @@ public class SQLiteCursor extends AbstractWindowedCursor {
super.finalize();
}
}
/**
* this is only for testing purposes.
*/
/* package */ int getMCount() {
return mCount;
}
}

View File

@@ -18,6 +18,7 @@ package android.database.sqlite;
import android.database.CursorWindow;
import android.os.SystemClock;
import android.util.Log;
/**
* A SQLite program that represents a query that reads the resulting rows into a CursorWindow.
@@ -58,6 +59,7 @@ public class SQLiteQuery extends SQLiteProgram {
/* package */ SQLiteQuery(SQLiteDatabase db, SQLiteQuery query) {
super(db, query.mSql);
this.mBindArgs = query.mBindArgs;
this.mOffsetIndex = query.mOffsetIndex;
}
/**
@@ -78,8 +80,8 @@ public class SQLiteQuery extends SQLiteProgram {
// if the start pos is not equal to 0, then most likely window is
// too small for the data set, loading by another thread
// is not safe in this situation. the native code will ignore maxRead
int numRows = native_fill_window(window, window.getStartPosition(), mOffsetIndex,
maxRead, lastPos);
int numRows = native_fill_window(window, window.getStartPosition(),
mOffsetIndex, maxRead, lastPos);
mDatabase.logTimeStat(mSql, timeStart);
return numRows;
} catch (IllegalStateException e){
@@ -88,6 +90,9 @@ public class SQLiteQuery extends SQLiteProgram {
} catch (SQLiteDatabaseCorruptException e) {
mDatabase.onCorruption();
throw e;
} catch (SQLiteException e) {
Log.e(TAG, "exception: " + e.getMessage() + "; query: " + mSql);
throw e;
} finally {
window.releaseReference();
}