Skip to content

Commit 84146a1

Browse files
authored
libsql-sqlite3: Optimize libsql_pager_has_codec() function (#2185)
Cache the result of libsql_pager_has_codec() in Pager struct to avoid walking through all VFSes every time a page is read.
2 parents 15da419 + 6d6ba1e commit 84146a1

File tree

4 files changed

+50
-6
lines changed

4 files changed

+50
-6
lines changed

libsql-ffi/bundled/SQLite3MultipleCiphers/src/codecext.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
** License: MIT
88
*/
99

10+
/*
11+
** Forward declaration for pager codec cache update function.
12+
** This should be called after encryption is added, removed, or changed.
13+
*/
14+
void libsql_pager_update_codec_cache(struct Pager *pPager);
15+
1016
/*
1117
** "Special" version of function sqlite3BtreeSetPageSize
1218
** This version allows to reduce the number of reserved bytes per page,
@@ -585,6 +591,8 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey)
585591
{
586592
sqlite3mcSetIsEncrypted(codec, 0);
587593
}
594+
/* Update the pager's cached codec status after changing encryption */
595+
libsql_pager_update_codec_cache(pPager);
588596
}
589597
else
590598
{

libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58152,6 +58152,7 @@ struct Pager {
5815258152
u8 readOnly; /* True for a read-only database */
5815358153
u8 memDb; /* True to inhibit all file I/O */
5815458154
u8 memVfs; /* VFS-implemented memory database */
58155+
u8 hasCodec; /* True if pager has encryption codec */
5815558156

5815658157
/**************************************************************************
5815758158
** The following block contains those class members that change during
@@ -58243,6 +58244,15 @@ int libsql_pager_has_codec(struct Pager *_p) {
5824358244
#endif
5824458245
}
5824558246

58247+
/*
58248+
** Update the cached codec status.
58249+
** This should be called after encryption is added, removed, or changed
58250+
** via sqlite3_rekey_v2() to ensure the cached hasCodec value is correct.
58251+
*/
58252+
void libsql_pager_update_codec_cache(struct Pager *pPager) {
58253+
pPager->hasCodec = libsql_pager_has_codec(pPager);
58254+
}
58255+
5824658256
int libsql_pager_codec(libsql_pghdr *hdr, void **ret) {
5824758257
if (!ret) {
5824858258
return SQLITE_MISUSE_BKPT;
@@ -58380,7 +58390,7 @@ static const unsigned char aJournalMagic[] = {
5838058390
SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
5838158391
if( pPager->fd->pMethods==0 ) return 0;
5838258392
if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
58383-
if( libsql_pager_has_codec(pPager) != 0 ) return 0;
58393+
if( pPager->hasCodec ) return 0;
5838458394
#ifndef SQLITE_OMIT_WAL
5838558395
if( pagerUseWal(pPager) ){
5838658396
u32 iRead = 0;
@@ -58603,7 +58613,7 @@ static void setGetterMethod(Pager *pPager){
5860358613
if( pPager->errCode ){
5860458614
pPager->xGet = getPageError;
5860558615
#if SQLITE_MAX_MMAP_SIZE>0
58606-
}else if( USEFETCH(pPager) && libsql_pager_has_codec(pPager) == 0 ){
58616+
}else if( USEFETCH(pPager) && !pPager->hasCodec ){
5860758617
pPager->xGet = getPageMMap;
5860858618
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
5860958619
}else{
@@ -62625,6 +62635,8 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
6262562635
/* pPager->xBusyHandler = 0; */
6262662636
/* pPager->pBusyHandlerArg = 0; */
6262762637
pPager->xReiniter = xReinit;
62638+
/* Cache the codec check result to avoid expensive VFS stack traversal on every page read */
62639+
pPager->hasCodec = libsql_pager_has_codec(pPager);
6262862640
setGetterMethod(pPager);
6262962641
/* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
6263062642
/* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */

libsql-ffi/bundled/src/sqlite3.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58152,6 +58152,7 @@ struct Pager {
5815258152
u8 readOnly; /* True for a read-only database */
5815358153
u8 memDb; /* True to inhibit all file I/O */
5815458154
u8 memVfs; /* VFS-implemented memory database */
58155+
u8 hasCodec; /* True if pager has encryption codec */
5815558156

5815658157
/**************************************************************************
5815758158
** The following block contains those class members that change during
@@ -58243,6 +58244,15 @@ int libsql_pager_has_codec(struct Pager *_p) {
5824358244
#endif
5824458245
}
5824558246

58247+
/*
58248+
** Update the cached codec status.
58249+
** This should be called after encryption is added, removed, or changed
58250+
** via sqlite3_rekey_v2() to ensure the cached hasCodec value is correct.
58251+
*/
58252+
void libsql_pager_update_codec_cache(struct Pager *pPager) {
58253+
pPager->hasCodec = libsql_pager_has_codec(pPager);
58254+
}
58255+
5824658256
int libsql_pager_codec(libsql_pghdr *hdr, void **ret) {
5824758257
if (!ret) {
5824858258
return SQLITE_MISUSE_BKPT;
@@ -58380,7 +58390,7 @@ static const unsigned char aJournalMagic[] = {
5838058390
SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
5838158391
if( pPager->fd->pMethods==0 ) return 0;
5838258392
if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
58383-
if( libsql_pager_has_codec(pPager) != 0 ) return 0;
58393+
if( pPager->hasCodec ) return 0;
5838458394
#ifndef SQLITE_OMIT_WAL
5838558395
if( pagerUseWal(pPager) ){
5838658396
u32 iRead = 0;
@@ -58603,7 +58613,7 @@ static void setGetterMethod(Pager *pPager){
5860358613
if( pPager->errCode ){
5860458614
pPager->xGet = getPageError;
5860558615
#if SQLITE_MAX_MMAP_SIZE>0
58606-
}else if( USEFETCH(pPager) && libsql_pager_has_codec(pPager) == 0 ){
58616+
}else if( USEFETCH(pPager) && !pPager->hasCodec ){
5860758617
pPager->xGet = getPageMMap;
5860858618
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
5860958619
}else{
@@ -62625,6 +62635,8 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
6262562635
/* pPager->xBusyHandler = 0; */
6262662636
/* pPager->pBusyHandlerArg = 0; */
6262762637
pPager->xReiniter = xReinit;
62638+
/* Cache the codec check result to avoid expensive VFS stack traversal on every page read */
62639+
pPager->hasCodec = libsql_pager_has_codec(pPager);
6262862640
setGetterMethod(pPager);
6262962641
/* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
6263062642
/* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */

libsql-sqlite3/src/pager.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ struct Pager {
630630
u8 readOnly; /* True for a read-only database */
631631
u8 memDb; /* True to inhibit all file I/O */
632632
u8 memVfs; /* VFS-implemented memory database */
633+
u8 hasCodec; /* True if pager has encryption codec */
633634

634635
/**************************************************************************
635636
** The following block contains those class members that change during
@@ -721,6 +722,15 @@ int libsql_pager_has_codec(struct Pager *_p) {
721722
#endif
722723
}
723724

725+
/*
726+
** Update the cached codec status.
727+
** This should be called after encryption is added, removed, or changed
728+
** via sqlite3_rekey_v2() to ensure the cached hasCodec value is correct.
729+
*/
730+
void libsql_pager_update_codec_cache(struct Pager *pPager) {
731+
pPager->hasCodec = libsql_pager_has_codec(pPager);
732+
}
733+
724734
int libsql_pager_codec(libsql_pghdr *hdr, void **ret) {
725735
if (!ret) {
726736
return SQLITE_MISUSE_BKPT;
@@ -858,7 +868,7 @@ static const unsigned char aJournalMagic[] = {
858868
int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
859869
if( pPager->fd->pMethods==0 ) return 0;
860870
if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
861-
if( libsql_pager_has_codec(pPager) != 0 ) return 0;
871+
if( pPager->hasCodec ) return 0;
862872
#ifndef SQLITE_OMIT_WAL
863873
if( pagerUseWal(pPager) ){
864874
u32 iRead = 0;
@@ -1081,7 +1091,7 @@ static void setGetterMethod(Pager *pPager){
10811091
if( pPager->errCode ){
10821092
pPager->xGet = getPageError;
10831093
#if SQLITE_MAX_MMAP_SIZE>0
1084-
}else if( USEFETCH(pPager) && libsql_pager_has_codec(pPager) == 0 ){
1094+
}else if( USEFETCH(pPager) && !pPager->hasCodec ){
10851095
pPager->xGet = getPageMMap;
10861096
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
10871097
}else{
@@ -5103,6 +5113,8 @@ int sqlite3PagerOpen(
51035113
/* pPager->xBusyHandler = 0; */
51045114
/* pPager->pBusyHandlerArg = 0; */
51055115
pPager->xReiniter = xReinit;
5116+
/* Cache the codec check result to avoid expensive VFS stack traversal on every page read */
5117+
pPager->hasCodec = libsql_pager_has_codec(pPager);
51065118
setGetterMethod(pPager);
51075119
/* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
51085120
/* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */

0 commit comments

Comments
 (0)