Android native CursorWindow資料儲存原理

來源:互聯網
上載者:User

標籤:android sqlite資料查詢結果   cursorwindow   android cursorwindow   

我們通過Uri查詢資料庫所得到的資料集,儲存在native層的CursorWindow中。CursorWindow的實質是共用記憶體的抽象,以實現跨進程資料共用。共用記憶體所採用的實現方式是檔案對應。

在ContentProvider端透過SQLiteDatabase的封裝查詢到的資料集儲存在CursorWindow所指向的共用記憶體中,然後通過Binder把這片共用記憶體傳遞到ContentResolver端,即查詢端。這樣客戶就可以通過Cursor來訪問這塊共用記憶體中的資料集了。

那麼CursorWindow是如何?的呢?

1.通過Create靜態函數來建立

status_t CursorWindow::create(const String8& name, size_t size, CursorWindow** outCursorWindow) {    String8 ashmemName("CursorWindow: ");    ashmemName.append(name);//檔案名稱    status_t result;    int ashmemFd = ashmem_create_region(ashmemName.string(), size);    if (ashmemFd < 0) {        result = -errno;    } else {        result = ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);        if (result >= 0) {            void* data = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);//檔案對應            if (data == MAP_FAILED) {                result = -errno;            } else {                result = ashmem_set_prot_region(ashmemFd, PROT_READ);                if (result >= 0) {                    CursorWindow* window = new CursorWindow(name, ashmemFd,                            data, size, false /*readOnly*/);                    result = window->clear();                    if (!result) {                        LOG_WINDOW("Created new CursorWindow: freeOffset=%d, "                                "numRows=%d, numColumns=%d, mSize=%d, mData=%p",                                window->mHeader->freeOffset,                                window->mHeader->numRows,                                window->mHeader->numColumns,                                window->mSize, window->mData);                        *outCursorWindow = window;                        return OK;                    }                    delete window;                }            }            ::munmap(data, size);        }        ::close(ashmemFd);    }    *outCursorWindow = NULL;    return result;}

2.通過檔案控制代碼來建立。這種case應該是在用戶端的建立出一個CursorWindow所採用。

status_t CursorWindow::createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow) {    String8 name = parcel->readString8();    status_t result;    int ashmemFd = parcel->readFileDescriptor();    if (ashmemFd == int(BAD_TYPE)) {        result = BAD_TYPE;    } else {        ssize_t size = ashmem_get_size_region(ashmemFd);        if (size < 0) {            result = UNKNOWN_ERROR;        } else {            int dupAshmemFd = ::dup(ashmemFd);            if (dupAshmemFd < 0) {                result = -errno;            } else {                void* data = ::mmap(NULL, size, PROT_READ, MAP_SHARED, dupAshmemFd, 0);                if (data == MAP_FAILED) {                    result = -errno;                } else {                    CursorWindow* window = new CursorWindow(name, dupAshmemFd,                            data, size, true /*readOnly*/);                    LOG_WINDOW("Created CursorWindow from parcel: freeOffset=%d, "                            "numRows=%d, numColumns=%d, mSize=%d, mData=%p",                            window->mHeader->freeOffset,                            window->mHeader->numRows,                            window->mHeader->numColumns,                            window->mSize, window->mData);                    *outCursorWindow = window;                    return OK;                }                ::close(dupAshmemFd);            }        }    }    *outCursorWindow = NULL;    return result;}

CursorWindow是如何儲存查詢到的資料集的呢?

原理圖如下:

沒一行所對應的資料採用FieldSlot數組來表示。圖中黃色部分表示一行所對應的資料。如果列所對應的資料是long或者double,那麼就直接儲存在FieldSlot中,如果是Blob或者String,那麼就在FieldSlot中儲存資料的便宜量。

FiledSlot的定義如下:

    struct FieldSlot {    private:        int32_t type;//列所對應的資料的類型        union {            double d;            int64_t l;            struct {                uint32_t offset;                uint32_t size;            } buffer;        } data;//data的資料類型是union,當type所表示的是String或者Blob的時候,offset表示的就是儲存真實資料的buffer的位移量,size表示buffer的大小        friend class CursorWindow;    } __attribute((packed));



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.