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

Commit 104798b7 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick Committed by Android (Google) Code Review
Browse files

Merge "Speed up ContentProvider.query() in simple case by ~30%"

parents 28ada962 9ffdfa0c
Loading
Loading
Loading
Loading
+54 −9
Original line number Diff line number Diff line
@@ -73,7 +73,10 @@ abstract public class ContentProviderNative extends Binder implements IContentPr
                case QUERY_TRANSACTION:
                {
                    data.enforceInterface(IContentProvider.descriptor);

                    Uri url = Uri.CREATOR.createFromParcel(data);

                    // String[] projection
                    int num = data.readInt();
                    String[] projection = null;
                    if (num > 0) {
@@ -82,6 +85,8 @@ abstract public class ContentProviderNative extends Binder implements IContentPr
                            projection[i] = data.readString();
                        }
                    }

                    // String selection, String[] selectionArgs...
                    String selection = data.readString();
                    num = data.readInt();
                    String[] selectionArgs = null;
@@ -91,19 +96,33 @@ abstract public class ContentProviderNative extends Binder implements IContentPr
                            selectionArgs[i] = data.readString();
                        }
                    }

                    String sortOrder = data.readString();
                    IContentObserver observer = IContentObserver.Stub.
                        asInterface(data.readStrongBinder());
                    CursorWindow window = CursorWindow.CREATOR.createFromParcel(data);

                    // Flag for whether caller wants the number of
                    // rows in the cursor and the position of the
                    // "_id" column index (or -1 if non-existent)
                    // Only to be returned if binder != null.
                    boolean wantsCursorMetadata = data.readInt() != 0;

                    IBulkCursor bulkCursor = bulkQuery(url, projection, selection,
                            selectionArgs, sortOrder, observer, window);
                    reply.writeNoException();
                    if (bulkCursor != null) {
                        reply.writeStrongBinder(bulkCursor.asBinder());

                        if (wantsCursorMetadata) {
                            reply.writeInt(bulkCursor.count());
                            reply.writeInt(BulkCursorToCursorAdaptor.findRowIdColumnIndex(
                                bulkCursor.getColumnNames()));
                        }
                    } else {
                        reply.writeStrongBinder(null);
                    }

                    return true;
                }

@@ -266,9 +285,12 @@ final class ContentProviderProxy implements IContentProvider
        return mRemote;
    }

    public IBulkCursor bulkQuery(Uri url, String[] projection,
            String selection, String[] selectionArgs, String sortOrder, IContentObserver observer,
            CursorWindow window) throws RemoteException {
    // Like bulkQuery() but sets up provided 'adaptor' if not null.
    private IBulkCursor bulkQueryInternal(
        Uri url, String[] projection,
        String selection, String[] selectionArgs, String sortOrder,
        IContentObserver observer, CursorWindow window,
        BulkCursorToCursorAdaptor adaptor) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();

@@ -297,6 +319,12 @@ final class ContentProviderProxy implements IContentProvider
        data.writeStrongBinder(observer.asBinder());
        window.writeToParcel(data, 0);

        // Flag for whether or not we want the number of rows in the
        // cursor and the position of the "_id" column index (or -1 if
        // non-existent).  Only to be returned if binder != null.
        final boolean wantsCursorMetadata = (adaptor != null);
        data.writeInt(wantsCursorMetadata ? 1 : 0);

        mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);

        DatabaseUtils.readExceptionFromParcel(reply);
@@ -305,6 +333,14 @@ final class ContentProviderProxy implements IContentProvider
        IBinder bulkCursorBinder = reply.readStrongBinder();
        if (bulkCursorBinder != null) {
            bulkCursor = BulkCursorNative.asInterface(bulkCursorBinder);

            if (wantsCursorMetadata) {
                int rowCount = reply.readInt();
                int idColumnPosition = reply.readInt();
                if (bulkCursor != null) {
                    adaptor.set(bulkCursor, rowCount, idColumnPosition);
                }
            }
        }

        data.recycle();
@@ -313,18 +349,27 @@ final class ContentProviderProxy implements IContentProvider
        return bulkCursor;
    }

    public IBulkCursor bulkQuery(Uri url, String[] projection,
            String selection, String[] selectionArgs, String sortOrder, IContentObserver observer,
            CursorWindow window) throws RemoteException {
        return bulkQueryInternal(
            url, projection, selection, selectionArgs, sortOrder,
            observer, window,
            null /* BulkCursorToCursorAdaptor */);
    }

    public Cursor query(Uri url, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) throws RemoteException {
        //TODO make a pool of windows so we can reuse memory dealers
        CursorWindow window = new CursorWindow(false /* window will be used remotely */);
        BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor();
        IBulkCursor bulkCursor = bulkQuery(url, projection, selection, selectionArgs, sortOrder,
                adaptor.getObserver(), window);

        IBulkCursor bulkCursor = bulkQueryInternal(
            url, projection, selection, selectionArgs, sortOrder,
            adaptor.getObserver(), window,
            adaptor);
        if (bulkCursor == null) {
            return null;
        }
        adaptor.set(bulkCursor);
        return adaptor;
    }

+35 −10
Original line number Diff line number Diff line
@@ -46,18 +46,36 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor {

            // Search for the rowID column index and set it for our parent
            mColumns = mBulkCursor.getColumnNames();
            int length = mColumns.length;
            for (int i = 0; i < length; i++) {
                if (mColumns[i].equals("_id")) {
                    mRowIdColumnIndex = i;
                    break;
                }
            }
            mRowIdColumnIndex = findRowIdColumnIndex(mColumns);
        } catch (RemoteException ex) {
            Log.e(TAG, "Setup failed because the remote process is dead");
        }
    }

    /**
     * Version of set() that does fewer Binder calls if the caller
     * already knows BulkCursorToCursorAdaptor's properties.
     */
    public void set(IBulkCursor bulkCursor, int count, int idIndex) {
        mBulkCursor = bulkCursor;
        mColumns = null;  // lazily retrieved
        mCount = count;
        mRowIdColumnIndex = idIndex;
    }

    /**
     * Returns column index of "_id" column, or -1 if not found.
     */
    public static int findRowIdColumnIndex(String[] columnNames) {
        int length = columnNames.length;
        for (int i = 0; i < length; i++) {
            if (columnNames[i].equals("_id")) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Gets a SelfDataChangeOberserver that can be sent to a remote
     * process to receive change notifications over IPC.
@@ -190,6 +208,14 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor {

    @Override
    public String[] getColumnNames() {
        if (mColumns == null) {
            try {
                mColumns = mBulkCursor.getColumnNames();
            } catch (RemoteException ex) {
                Log.e(TAG, "Unable to fetch column names because the remote process is dead");
                return null;
            }
        }
        return mColumns;
    }

@@ -255,4 +281,3 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor {
        }
    }
}
+3 −5
Original line number Diff line number Diff line
@@ -30,8 +30,7 @@ import java.util.Map;
 *
 * {@hide}
 */
public interface IBulkCursor extends IInterface 
{
public interface IBulkCursor extends IInterface  {
    /**
     * Returns a BulkCursorWindow, which either has a reference to a shared
     * memory segment with the rows, or an array of JSON strings.
@@ -87,4 +86,3 @@ public interface IBulkCursor extends IInterface
    static final int RESPOND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 10;
    static final int CLOSE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 11;
}
+8 −7
Original line number Diff line number Diff line
@@ -19,11 +19,12 @@ package android.database.sqlite;
import android.database.CursorWindow;

/**
 * An object create from a SQLiteDatabase that can be closed.
 * An object created from a SQLiteDatabase that can be closed.
 */
public abstract class SQLiteClosable {
    private int mReferenceCount = 1;
    private Object mLock = new Object();

    protected abstract void onAllReferencesReleased();
    protected void onAllReferencesReleasedFromContainer() {}

+1 −1

File changed.

Contains only whitespace changes.