小巧、快速、可靠
選擇其中三項。

SQLite C 介面

應用程式定義的頁面快取

typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2;
struct sqlite3_pcache_methods2 {
  int iVersion;
  void *pArg;
  int (*xInit)(void*);
  void (*xShutdown)(void*);
  sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable);
  void (*xCachesize)(sqlite3_pcache*, int nCachesize);
  int (*xPagecount)(sqlite3_pcache*);
  sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
  void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard);
  void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*,
      unsigned oldKey, unsigned newKey);
  void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
  void (*xDestroy)(sqlite3_pcache*);
  void (*xShrink)(sqlite3_pcache*);
};

sqlite3_config(SQLITE_CONFIG_PCACHE2, ...) 介面可以透過傳入 sqlite3_pcache_methods2 結構的實例來註冊替代的頁面快取實作。在許多應用程式中,SQLite 分配的大部分堆積記憶體都用於頁面快取。透過使用此 API 實作自訂頁面快取,應用程式可以更好地控制 SQLite 消耗的記憶體量、記憶體的分配和釋放方式,以及用於確定資料庫檔案哪些部分被快取以及快取時間的策略。

替代頁面快取機制是一種極端措施,只有要求最嚴格的應用程式才需要。對於大多數用途,建議使用內建的頁面快取。

在呼叫 sqlite3_config 時,sqlite3_pcache_methods2 結構的內容會被 SQLite 複製到內部緩衝區。因此,應用程式可以在呼叫 sqlite3_config() 返回後捨棄該參數。

每次有效呼叫 sqlite3_initialize()(通常在程序的生命週期中只呼叫一次)時,都會呼叫 xInit() 方法。 xInit() 方法會傳入 sqlite3_pcache_methods2.pArg 值的副本。 xInit() 方法的目的是設定自訂頁面快取實作所需的全域資料結構。如果 xInit() 方法為 NULL,則會使用內建的預設頁面快取,而不是應用程式定義的頁面快取。

xShutdown() 方法會由 sqlite3_shutdown() 呼叫。如果需要,它可以用於在程序關閉之前清理任何未完成的資源。 xShutdown() 方法可以為 NULL。

SQLite 會自動序列化對 xInit 方法的呼叫,因此 xInit 方法不需要是執行緒安全的。 xShutdown 方法僅從 sqlite3_shutdown() 呼叫,因此它也不需要是執行緒安全的。所有其他方法在多執行緒應用程式中必須是執行緒安全的。

SQLite 永遠不會在沒有中間呼叫 xShutdown() 的情況下多次呼叫 xInit()。

SQLite 呼叫 xCreate() 方法來建構新的快取實例。 SQLite 通常會為每個開啟的資料庫檔案建立一個快取實例,但這並不能保證。第一個參數 szPage 是快取必須分配的頁面的大小(以位元組為單位)。 szPage 將始終是 2 的次方。第二個參數 szExtra 是與每個頁面快取項目關聯的額外儲存空間的位元組數。 szExtra 參數將是一個小於 250 的數字。SQLite 將使用每個頁面上額外的 szExtra 位元組來儲存磁碟上底層資料庫頁面的中繼資料。傳入 szExtra 的值取決於 SQLite 版本、目標平台以及 SQLite 的編譯方式。 xCreate() 的第三個參數 bPurgeable,如果建立的快取將用於快取儲存在磁碟上的檔案的資料庫頁面,則為 true;如果用於記憶體資料庫,則為 false。快取實作不需要根據 bPurgeable 的值執行任何特殊操作;它純粹是建議性的。在 bPurgeable 為 false 的快取上,SQLite 永遠不會呼叫 xUnpin(),除非是要故意刪除頁面。換句話說,在 bPurgeable 設定為 false 的快取上呼叫 xUnpin() 將始終將「捨棄」旗標設定為 true。因此,使用 bPurgeable false 建立的快取將永遠不會包含任何未固定的頁面。

SQLite 可以隨時呼叫 xCachesize() 方法來設定傳入的第一個參數所代表的快取執行個體的建議最大快取大小(儲存的頁面數量)。 這個值是使用 SQLite 的 "PRAGMA cache_size" 命令設定的。 與 bPurgeable 參數一樣,實作並不需要對此值執行任何操作;它僅供參考。

xPagecount() 方法必須返回目前儲存在快取中的頁面數量,包括已固定和未固定的頁面。

xFetch() 方法會在快取中找到一個頁面,並返回一個指向與該頁面相關聯的 sqlite3_pcache_page 物件的指標,或者返回一個 NULL 指標。 返回的 sqlite3_pcache_page 物件的 pBuf 元素將指向一個大小為 szPage 位元組的緩衝區,用於儲存單個資料庫頁面的內容。 sqlite3_pcache_page 的 pExtra 元素將指向 SQLite 為頁面快取中的每個項目請求的 szExtra 位元組的額外儲存空間。

要提取的頁面由鍵值決定。 最小鍵值為 1。 使用 xFetch 擷取後,該頁面被視為「已固定」。

如果請求的頁面已經在頁面快取中,則頁面快取實作必須返回一個指向頁面緩衝區的指標,且其內容保持不變。 如果請求的頁面不在快取中,則快取實作應使用 createFlag 參數的值來決定要採取的操作。

createFlag頁面不在快取中的行為
0 不要配置新的頁面。 返回 NULL。
1 如果容易且方便,則配置一個新的頁面。 否則返回 NULL。
2 盡一切努力配置一個新的頁面。 只有在實際不可能配置新頁面的情況下才返回 NULL。

SQLite 通常會以 0 或 1 的 createFlag 呼叫 xFetch()。 只有在先前以 createFlag 值為 1 的呼叫失敗後,SQLite 才會使用 createFlag 值為 2。 在 xFetch() 呼叫之間,SQLite 可能會嘗試透過將已固定頁面的內容寫入磁碟並同步作業系統磁碟快取來取消固定一個或多個快取頁面。

SQLite 呼叫 xUnpin(),並將指向目前已固定頁面的指標作為其第二個參數。 如果第三個參數 discard 不為零,則必須從快取中移除該頁面。 如果 discard 參數為零,則頁面快取實作可以自行決定是否捨棄或保留該頁面。 頁面快取實作可以隨時選擇移除未固定的頁面。

快取不得執行任何引用計數。 無論先前呼叫 xFetch() 的次數為何,單次呼叫 xUnpin() 就會取消固定該頁面。

xRekey() 方法用於更改與作為第二個參數傳入的頁面相關聯的鍵值。 如果快取先前包含與 newKey 相關聯的項目,則必須捨棄該項目。 任何先前與 newKey 相關聯的快取項目都保證不會被固定。

當 SQLite 呼叫 xTruncate() 方法時,快取必須捨棄所有頁碼(鍵值)大於或等於傳遞給 xTruncate() 的 iLimit 參數值的現有快取項目。 如果這些頁面中有任何頁面被固定,它們會被隱式取消固定,這表示可以安全地捨棄它們。

xDestroy() 方法用於刪除由 xCreate() 配置的快取。 應釋放與指定快取相關聯的所有資源。 呼叫 xDestroy() 方法後,SQLite 會將 sqlite3_pcache* 控制代碼視為無效,並且不會將其與任何其他 sqlite3_pcache_methods2 函式一起使用。

當 SQLite 想要頁面快取盡可能釋放堆積記憶體時,它會呼叫 xShrink() 方法。頁面快取的實作並非強制必須釋放任何記憶體,但良好的實作應該盡力而為。

另請參閱物件常數函式列表。