Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
a581d9b3
T
TDengine
项目概览
taosdata
/
TDengine
大约 2 年 前同步成功
通知
1192
Star
22018
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
“1150dbc666e0b0c617ad90c74ff0d07333ce099b”上不存在“tests/git@gitcode.net:taosdata/tdengine.git”
提交
a581d9b3
编写于
2月 21, 2022
作者:
H
Hongze Cheng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
more
上级
7184778c
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
441 addition
and
370 deletion
+441
-370
source/libs/tdb/src/sqlite/btree.c
source/libs/tdb/src/sqlite/btree.c
+13
-13
source/libs/tdb/src/sqlite/pager.c
source/libs/tdb/src/sqlite/pager.c
+12
-12
source/libs/tdb/src/sqlite/pcache.c
source/libs/tdb/src/sqlite/pcache.c
+308
-335
source/libs/tdb/src/sqlite/wal.c
source/libs/tdb/src/sqlite/wal.c
+10
-10
source/libs/tdb/src/sqliteinc/sqlite3.h
source/libs/tdb/src/sqliteinc/sqlite3.h
+95
-0
source/libs/tdb/src/sqliteinc/sqliteInt.h
source/libs/tdb/src/sqliteinc/sqliteInt.h
+3
-0
未找到文件。
source/libs/tdb/src/sqlite/btree.c
浏览文件 @
a581d9b3
...
...
@@ -391,7 +391,7 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
if
(
!
pLock
){
pLock
=
(
BtLock
*
)
sqlite3MallocZero
(
sizeof
(
BtLock
));
if
(
!
pLock
){
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
pLock
->
iTable
=
iTable
;
pLock
->
pBtree
=
p
;
...
...
@@ -606,7 +606,7 @@ static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
assert
(
pgno
<=
pBt
->
nPage
);
pBt
->
pHasContent
=
sqlite3BitvecCreate
(
pBt
->
nPage
);
if
(
!
pBt
->
pHasContent
){
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
}
}
if
(
rc
==
SQLITE_OK
&&
pgno
<=
sqlite3BitvecSize
(
pBt
->
pHasContent
)
){
...
...
@@ -691,7 +691,7 @@ static int saveCursorKey(BtCursor *pCur){
sqlite3_free
(
pKey
);
}
}
else
{
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
}
}
assert
(
!
pCur
->
curIntKey
||
!
pCur
->
pKey
);
...
...
@@ -823,7 +823,7 @@ static int btreeMoveto(
KeyInfo
*
pKeyInfo
=
pCur
->
pKeyInfo
;
assert
(
nKey
==
(
i64
)(
int
)
nKey
);
pIdxKey
=
sqlite3VdbeAllocUnpackedRecord
(
pKeyInfo
);
if
(
pIdxKey
==
0
)
return
SQLITE_NOMEM
_BKPT
;
if
(
pIdxKey
==
0
)
return
SQLITE_NOMEM
;
sqlite3VdbeRecordUnpack
(
pKeyInfo
,
(
int
)
nKey
,
pKey
,
pIdxKey
);
if
(
pIdxKey
->
nField
==
0
||
pIdxKey
->
nField
>
pKeyInfo
->
nAllField
){
rc
=
SQLITE_CORRUPT_BKPT
;
...
...
@@ -2404,7 +2404,7 @@ int sqlite3BtreeOpen(
}
p
=
sqlite3MallocZero
(
sizeof
(
Btree
));
if
(
!
p
){
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
p
->
inTrans
=
TRANS_NONE
;
p
->
db
=
db
;
...
...
@@ -2428,7 +2428,7 @@ int sqlite3BtreeOpen(
p
->
sharable
=
1
;
if
(
!
zFullPathname
){
sqlite3_free
(
p
);
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
if
(
isMemdb
){
memcpy
(
zFullPathname
,
zFilename
,
nFilename
);
...
...
@@ -2500,7 +2500,7 @@ int sqlite3BtreeOpen(
pBt
=
sqlite3MallocZero
(
sizeof
(
*
pBt
)
);
if
(
pBt
==
0
){
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
goto
btree_open_out
;
}
rc
=
sqlite3PagerOpen
(
pVfs
,
&
pBt
->
pPager
,
zFilename
,
...
...
@@ -2571,7 +2571,7 @@ int sqlite3BtreeOpen(
if
(
SQLITE_THREADSAFE
&&
sqlite3GlobalConfig
.
bCoreMutex
){
pBt
->
mutex
=
sqlite3MutexAlloc
(
SQLITE_MUTEX_FAST
);
if
(
pBt
->
mutex
==
0
){
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
goto
btree_open_out
;
}
}
...
...
@@ -4459,7 +4459,7 @@ static int btreeCursor(
if
(
wrFlag
){
allocateTempSpace
(
pBt
);
if
(
pBt
->
pTmpSpace
==
0
)
return
SQLITE_NOMEM
_BKPT
;
if
(
pBt
->
pTmpSpace
==
0
)
return
SQLITE_NOMEM
;
}
if
(
iTable
<=
1
){
if
(
iTable
<
1
){
...
...
@@ -4919,7 +4919,7 @@ static int accessPayload(
pCur
->
aOverflow
,
nOvfl
*
2
*
sizeof
(
Pgno
)
);
if
(
aNew
==
0
){
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
else
{
pCur
->
aOverflow
=
aNew
;
}
...
...
@@ -5746,7 +5746,7 @@ int sqlite3BtreeIndexMoveto(
}
pCellKey
=
sqlite3Malloc
(
nCell
+
nOverrun
);
if
(
pCellKey
==
0
){
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
goto
moveto_index_finish
;
}
pCur
->
ix
=
(
u16
)
idx
;
...
...
@@ -7721,7 +7721,7 @@ static int balance_nonroot(
assert
(
pParent
->
nOverflow
==
0
||
pParent
->
aiOvfl
[
0
]
==
iParentIdx
);
if
(
!
aOvflSpace
){
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
assert
(
pParent
->
nFree
>=
0
);
...
...
@@ -7827,7 +7827,7 @@ static int balance_nonroot(
assert
(
szScratch
<=
7
*
(
int
)
pBt
->
pageSize
);
b
.
apCell
=
sqlite3StackAllocRaw
(
0
,
szScratch
);
if
(
b
.
apCell
==
0
){
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
goto
balance_cleanup
;
}
b
.
szCell
=
(
u16
*
)
&
b
.
apCell
[
nMaxCells
];
...
...
source/libs/tdb/src/sqlite/pager.c
浏览文件 @
a581d9b3
...
...
@@ -2499,7 +2499,7 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){
*/
pSuper
=
(
sqlite3_file
*
)
sqlite3MallocZero
(
pVfs
->
szOsFile
*
2
);
if
(
!
pSuper
){
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
pJournal
=
0
;
}
else
{
const
int
flags
=
(
SQLITE_OPEN_READONLY
|
SQLITE_OPEN_SUPER_JOURNAL
);
...
...
@@ -2518,7 +2518,7 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){
nSuperPtr
=
pVfs
->
mxPathname
+
1
;
zFree
=
sqlite3Malloc
(
4
+
nSuperJournal
+
nSuperPtr
+
2
);
if
(
!
zFree
){
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
goto
delsuper_out
;
}
zFree
[
0
]
=
zFree
[
1
]
=
zFree
[
2
]
=
zFree
[
3
]
=
0
;
...
...
@@ -3358,7 +3358,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
if
(
pSavepoint
){
pDone
=
sqlite3BitvecCreate
(
pSavepoint
->
nOrig
);
if
(
!
pDone
){
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
}
...
...
@@ -3725,7 +3725,7 @@ int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
* cell header parser will never run off the end of the allocation */
pNew
=
(
char
*
)
sqlite3PageMalloc
(
pageSize
+
8
);
if
(
!
pNew
){
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
}
else
{
memset
(
pNew
+
pageSize
,
0
,
8
);
}
...
...
@@ -4009,7 +4009,7 @@ static int pagerAcquireMapPage(
*
ppPage
=
p
=
(
PgHdr
*
)
sqlite3MallocZero
(
sizeof
(
PgHdr
)
+
pPager
->
nExtra
);
if
(
p
==
0
){
sqlite3OsUnfetch
(
pPager
->
fd
,
(
i64
)(
pgno
-
1
)
*
pPager
->
pageSize
,
pData
);
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
p
->
pExtra
=
(
void
*
)
&
p
[
1
];
p
->
flags
=
PGHDR_MMAP
;
...
...
@@ -4695,7 +4695,7 @@ int sqlite3PagerOpen(
memDb
=
1
;
if
(
zFilename
&&
zFilename
[
0
]
){
zPathname
=
sqlite3DbStrDup
(
0
,
zFilename
);
if
(
zPathname
==
0
)
return
SQLITE_NOMEM
_BKPT
;
if
(
zPathname
==
0
)
return
SQLITE_NOMEM
;
nPathname
=
sqlite3Strlen30
(
zPathname
);
zFilename
=
0
;
}
...
...
@@ -4711,7 +4711,7 @@ int sqlite3PagerOpen(
nPathname
=
pVfs
->
mxPathname
+
1
;
zPathname
=
sqlite3DbMallocRaw
(
0
,
nPathname
*
2
);
if
(
zPathname
==
0
){
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
zPathname
[
0
]
=
0
;
/* Make sure initialized even if FullPathname() fails */
rc
=
sqlite3OsFullPathname
(
pVfs
,
zFilename
,
nPathname
,
zPathname
);
...
...
@@ -4810,7 +4810,7 @@ int sqlite3PagerOpen(
assert
(
EIGHT_BYTE_ALIGNMENT
(
SQLITE_INT_TO_PTR
(
journalFileSize
))
);
if
(
!
pPtr
){
sqlite3DbFree
(
0
,
zPathname
);
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
pPager
=
(
Pager
*
)
pPtr
;
pPtr
+=
ROUND8
(
sizeof
(
*
pPager
));
pPager
->
pPCache
=
(
PCache
*
)
pPtr
;
pPtr
+=
ROUND8
(
pcacheSize
);
...
...
@@ -5490,7 +5490,7 @@ static int getPageNormal(
rc
=
sqlite3PcacheFetchStress
(
pPager
->
pPCache
,
pgno
,
&
pBase
);
if
(
rc
!=
SQLITE_OK
)
goto
pager_acquire_err
;
if
(
pBase
==
0
){
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
goto
pager_acquire_err
;
}
}
...
...
@@ -5760,7 +5760,7 @@ static int pager_open_journal(Pager *pPager){
if
(
!
pagerUseWal
(
pPager
)
&&
pPager
->
journalMode
!=
PAGER_JOURNALMODE_OFF
){
pPager
->
pInJournal
=
sqlite3BitvecCreate
(
pPager
->
dbSize
);
if
(
pPager
->
pInJournal
==
0
){
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
/* Open the journal file if it is not already open. */
...
...
@@ -6841,7 +6841,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){
pPager
->
aSavepoint
,
sizeof
(
PagerSavepoint
)
*
nSavepoint
);
if
(
!
aNew
){
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
memset
(
&
aNew
[
nCurrent
],
0
,
(
nSavepoint
-
nCurrent
)
*
sizeof
(
PagerSavepoint
));
pPager
->
aSavepoint
=
aNew
;
...
...
@@ -6858,7 +6858,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){
aNew
[
ii
].
pInSavepoint
=
sqlite3BitvecCreate
(
pPager
->
dbSize
);
aNew
[
ii
].
bTruncateOnRelease
=
1
;
if
(
!
aNew
[
ii
].
pInSavepoint
){
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
if
(
pagerUseWal
(
pPager
)
){
sqlite3WalSavepoint
(
pPager
->
pWal
,
aNew
[
ii
].
aWalData
);
...
...
source/libs/tdb/src/sqlite/pcache.c
浏览文件 @
a581d9b3
...
...
@@ -31,7 +31,7 @@
**
** The PCache.pSynced variable is used to optimize searching for a dirty
** page to eject from the cache mid-transaction. It is better to eject
** a page that does not require a journal sync than one that does.
** a page that does not require a journal sync than one that does.
** Therefore, pSynced is maintained so that it *almost* always points
** to either the oldest page in the pDirty/pDirtyTail list that has a
** clear PGHDR_NEED_SYNC flag or to a page that is older than this one
...
...
@@ -39,18 +39,18 @@
** pointers).
*/
struct
PCache
{
PgHdr
*
pDirty
,
*
pDirtyTail
;
/* List of dirty pages in LRU order */
PgHdr
*
pSynced
;
/* Last synced page in dirty page list */
int
nRefSum
;
/* Sum of ref counts over all pages */
int
szCache
;
/* Configured cache size */
int
szSpill
;
/* Size before spilling occurs */
int
szPage
;
/* Size of every page in this cache */
int
szExtra
;
/* Size of extra space for each page */
u8
bPurgeable
;
/* True if pages are on backing store */
u8
eCreate
;
/* eCreate value for for xFetch() */
int
(
*
xStress
)(
void
*
,
PgHdr
*
);
/* Call to try make a page clean */
void
*
pStress
;
/* Argument to xStress */
sqlite3_pcache
*
pCache
;
/* Pluggable cache module */
PgHdr
*
pDirty
,
*
pDirtyTail
;
/* List of dirty pages in LRU order */
PgHdr
*
pSynced
;
/* Last synced page in dirty page list */
int
nRefSum
;
/* Sum of ref counts over all pages */
int
szCache
;
/* Configured cache size */
int
szSpill
;
/* Size before spilling occurs */
int
szPage
;
/* Size of every page in this cache */
int
szExtra
;
/* Size of extra space for each page */
u8
bPurgeable
;
/* True if pages are on backing store */
u8
eCreate
;
/* eCreate value for for xFetch() */
int
(
*
xStress
)(
void
*
,
PgHdr
*
);
/* Call to try make a page clean */
void
*
pStress
;
/* Argument to xStress */
sqlite3_pcache
*
pCache
;
/* Pluggable cache module */
};
/********************************** Test and Debug Logic **********************/
...
...
@@ -63,91 +63,93 @@ struct PCache {
** is displayed for many operations, resulting in a lot of output.
*/
#if defined(SQLITE_DEBUG) && 0
int
sqlite3PcacheTrace
=
2
;
/* 0: off 1: simple 2: cache dumps */
int
sqlite3PcacheMxDump
=
9999
;
/* Max cache entries for pcacheDump() */
# define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;}
void
pcacheDump
(
PCache
*
pCache
){
int
N
;
int
i
,
j
;
sqlite3_pcache_page
*
pLower
;
PgHdr
*
pPg
;
unsigned
char
*
a
;
if
(
sqlite3PcacheTrace
<
2
)
return
;
if
(
pCache
->
pCache
==
0
)
return
;
N
=
sqlite3PcachePagecount
(
pCache
);
if
(
N
>
sqlite3PcacheMxDump
)
N
=
sqlite3PcacheMxDump
;
for
(
i
=
1
;
i
<=
N
;
i
++
){
pLower
=
pcache2
.
xFetch
(
pCache
->
pCache
,
i
,
0
);
if
(
pLower
==
0
)
continue
;
pPg
=
(
PgHdr
*
)
pLower
->
pExtra
;
printf
(
"%3d: nRef %2d flgs %02x data "
,
i
,
pPg
->
nRef
,
pPg
->
flags
);
a
=
(
unsigned
char
*
)
pLower
->
pBuf
;
for
(
j
=
0
;
j
<
12
;
j
++
)
printf
(
"%02x"
,
a
[
j
]);
printf
(
"
\n
"
);
if
(
pPg
->
pPage
==
0
){
pcache2
.
xUnpin
(
pCache
->
pCache
,
pLower
,
0
);
}
}
}
#else
# define pcacheTrace(X)
# define pcacheDump(X)
#endif
/*
** Check invariants on a PgHdr entry. Return true if everything is OK.
** Return false if any invariant is violated.
**
** This routine is for use inside of assert() statements only. For
** example:
**
** assert( sqlite3PcachePageSanity(pPg) );
*/
#ifdef SQLITE_DEBUG
int
sqlite3PcachePageSanity
(
PgHdr
*
pPg
){
PCache
*
pCache
;
assert
(
pPg
!=
0
);
assert
(
pPg
->
pgno
>
0
||
pPg
->
pPager
==
0
);
/* Page number is 1 or more */
pCache
=
pPg
->
pCache
;
assert
(
pCache
!=
0
);
/* Every page has an associated PCache */
if
(
pPg
->
flags
&
PGHDR_CLEAN
){
assert
(
(
pPg
->
flags
&
PGHDR_DIRTY
)
==
0
);
/* Cannot be both CLEAN and DIRTY */
assert
(
pCache
->
pDirty
!=
pPg
);
/* CLEAN pages not on dirty list */
assert
(
pCache
->
pDirtyTail
!=
pPg
);
int
sqlite3PcacheTrace
=
2
;
/* 0: off 1: simple 2: cache dumps */
int
sqlite3PcacheMxDump
=
9999
;
/* Max cache entries for pcacheDump() */
#define pcacheTrace(X) \
if (sqlite3PcacheTrace) { \
sqlite3DebugPrintf X; \
}
/* WRITEABLE pages must also be DIRTY */
if
(
pPg
->
flags
&
PGHDR_WRITEABLE
){
assert
(
pPg
->
flags
&
PGHDR_DIRTY
);
/* WRITEABLE implies DIRTY */
void
pcacheDump
(
PCache
*
pCache
)
{
int
N
;
int
i
,
j
;
sqlite3_pcache_page
*
pLower
;
PgHdr
*
pPg
;
unsigned
char
*
a
;
if
(
sqlite3PcacheTrace
<
2
)
return
;
if
(
pCache
->
pCache
==
0
)
return
;
N
=
sqlite3PcachePagecount
(
pCache
);
if
(
N
>
sqlite3PcacheMxDump
)
N
=
sqlite3PcacheMxDump
;
for
(
i
=
1
;
i
<=
N
;
i
++
)
{
pLower
=
pcache2
.
xFetch
(
pCache
->
pCache
,
i
,
0
);
if
(
pLower
==
0
)
continue
;
pPg
=
(
PgHdr
*
)
pLower
->
pExtra
;
printf
(
"%3d: nRef %2d flgs %02x data "
,
i
,
pPg
->
nRef
,
pPg
->
flags
);
a
=
(
unsigned
char
*
)
pLower
->
pBuf
;
for
(
j
=
0
;
j
<
12
;
j
++
)
printf
(
"%02x"
,
a
[
j
]);
printf
(
"
\n
"
);
if
(
pPg
->
pPage
==
0
)
{
pcache2
.
xUnpin
(
pCache
->
pCache
,
pLower
,
0
);
}
}
/* NEED_SYNC can be set independently of WRITEABLE. This can happen,
** for example, when using the sqlite3PagerDontWrite() optimization:
** (1) Page X is journalled, and gets WRITEABLE and NEED_SEEK.
** (2) Page X moved to freelist, WRITEABLE is cleared
** (3) Page X reused, WRITEABLE is set again
** If NEED_SYNC had been cleared in step 2, then it would not be reset
** in step 3, and page might be written into the database without first
** syncing the rollback journal, which might cause corruption on a power
** loss.
**
** Another example is when the database page size is smaller than the
** disk sector size. When any page of a sector is journalled, all pages
** in that sector are marked NEED_SYNC even if they are still CLEAN, just
** in case they are later modified, since all pages in the same sector
** must be journalled and synced before any of those pages can be safely
** written.
*/
return
1
;
}
#endif
/* SQLITE_DEBUG */
#else
#define pcacheTrace(X)
#define pcacheDump(X)
#endif
// /*
// ** Check invariants on a PgHdr entry. Return true if everything is OK.
// ** Return false if any invariant is violated.
// **
// ** This routine is for use inside of assert() statements only. For
// ** example:
// **
// ** assert( sqlite3PcachePageSanity(pPg) );
// */
// #ifdef SQLITE_DEBUG
// int sqlite3PcachePageSanity(PgHdr *pPg) {
// PCache *pCache;
// assert(pPg != 0);
// assert(pPg->pgno > 0 || pPg->pPager == 0); /* Page number is 1 or more */
// pCache = pPg->pCache;
// assert(pCache != 0); /* Every page has an associated PCache */
// if (pPg->flags & PGHDR_CLEAN) {
// assert((pPg->flags & PGHDR_DIRTY) == 0); /* Cannot be both CLEAN and DIRTY */
// assert(pCache->pDirty != pPg); /* CLEAN pages not on dirty list */
// assert(pCache->pDirtyTail != pPg);
// }
// /* WRITEABLE pages must also be DIRTY */
// if (pPg->flags & PGHDR_WRITEABLE) {
// assert(pPg->flags & PGHDR_DIRTY); /* WRITEABLE implies DIRTY */
// }
// /* NEED_SYNC can be set independently of WRITEABLE. This can happen,
// ** for example, when using the sqlite3PagerDontWrite() optimization:
// ** (1) Page X is journalled, and gets WRITEABLE and NEED_SEEK.
// ** (2) Page X moved to freelist, WRITEABLE is cleared
// ** (3) Page X reused, WRITEABLE is set again
// ** If NEED_SYNC had been cleared in step 2, then it would not be reset
// ** in step 3, and page might be written into the database without first
// ** syncing the rollback journal, which might cause corruption on a power
// ** loss.
// **
// ** Another example is when the database page size is smaller than the
// ** disk sector size. When any page of a sector is journalled, all pages
// ** in that sector are marked NEED_SYNC even if they are still CLEAN, just
// ** in case they are later modified, since all pages in the same sector
// ** must be journalled and synced before any of those pages can be safely
// ** written.
// */
// return 1;
// }
// #endif /* SQLITE_DEBUG */
/********************************** Linked List Management ********************/
/* Allowed values for second argument to pcacheManageDirtyList() */
#define PCACHE_DIRTYLIST_REMOVE
1
/* Remove pPage from dirty list */
#define PCACHE_DIRTYLIST_ADD
2
/* Add pPage to the dirty list */
#define PCACHE_DIRTYLIST_FRONT
3
/* Move pPage to the front of the list */
#define PCACHE_DIRTYLIST_REMOVE
1
/* Remove pPage from dirty list */
#define PCACHE_DIRTYLIST_ADD
2
/* Add pPage to the dirty list */
#define PCACHE_DIRTYLIST_FRONT
3
/* Move pPage to the front of the list */
/*
** Manage pPage's participation on the dirty list. Bits of the addRemove
...
...
@@ -155,66 +157,63 @@ int sqlite3PcachePageSanity(PgHdr *pPg){
** remove pPage from the dirty list. The 0x02 means add pPage back to
** the dirty list. Doing both moves pPage to the front of the dirty list.
*/
static
void
pcacheManageDirtyList
(
PgHdr
*
pPage
,
u8
addRemove
){
static
void
pcacheManageDirtyList
(
PgHdr
*
pPage
,
u8
addRemove
)
{
PCache
*
p
=
pPage
->
pCache
;
pcacheTrace
((
"%p.DIRTYLIST.%s %d
\n
"
,
p
,
addRemove
==
1
?
"REMOVE"
:
addRemove
==
2
?
"ADD"
:
"FRONT"
,
pPage
->
pgno
));
if
(
addRemove
&
PCACHE_DIRTYLIST_REMOVE
){
assert
(
pPage
->
pDirtyNext
||
pPage
==
p
->
pDirtyTail
);
assert
(
pPage
->
pDirtyPrev
||
pPage
==
p
->
pDirty
);
pcacheTrace
((
"%p.DIRTYLIST.%s %d
\n
"
,
p
,
addRemove
==
1
?
"REMOVE"
:
addRemove
==
2
?
"ADD"
:
"FRONT"
,
pPage
->
pgno
));
if
(
addRemove
&
PCACHE_DIRTYLIST_REMOVE
)
{
assert
(
pPage
->
pDirtyNext
||
pPage
==
p
->
pDirtyTail
);
assert
(
pPage
->
pDirtyPrev
||
pPage
==
p
->
pDirty
);
/* Update the PCache1.pSynced variable if necessary. */
if
(
p
->
pSynced
==
pPage
)
{
if
(
p
->
pSynced
==
pPage
)
{
p
->
pSynced
=
pPage
->
pDirtyPrev
;
}
if
(
pPage
->
pDirtyNext
)
{
if
(
pPage
->
pDirtyNext
)
{
pPage
->
pDirtyNext
->
pDirtyPrev
=
pPage
->
pDirtyPrev
;
}
else
{
assert
(
pPage
==
p
->
pDirtyTail
);
}
else
{
assert
(
pPage
==
p
->
pDirtyTail
);
p
->
pDirtyTail
=
pPage
->
pDirtyPrev
;
}
if
(
pPage
->
pDirtyPrev
)
{
if
(
pPage
->
pDirtyPrev
)
{
pPage
->
pDirtyPrev
->
pDirtyNext
=
pPage
->
pDirtyNext
;
}
else
{
/* If there are now no dirty pages in the cache, set eCreate to 2.
}
else
{
/* If there are now no dirty pages in the cache, set eCreate to 2.
** This is an optimization that allows sqlite3PcacheFetch() to skip
** searching for a dirty page to eject from the cache when it might
** otherwise have to. */
assert
(
pPage
==
p
->
pDirty
);
assert
(
pPage
==
p
->
pDirty
);
p
->
pDirty
=
pPage
->
pDirtyNext
;
assert
(
p
->
bPurgeable
||
p
->
eCreate
==
2
);
if
(
p
->
pDirty
==
0
){
/*OPTIMIZATION-IF-TRUE*/
assert
(
p
->
bPurgeable
==
0
||
p
->
eCreate
==
1
);
assert
(
p
->
bPurgeable
||
p
->
eCreate
==
2
);
if
(
p
->
pDirty
==
0
)
{
/*OPTIMIZATION-IF-TRUE*/
assert
(
p
->
bPurgeable
==
0
||
p
->
eCreate
==
1
);
p
->
eCreate
=
2
;
}
}
}
if
(
addRemove
&
PCACHE_DIRTYLIST_ADD
)
{
if
(
addRemove
&
PCACHE_DIRTYLIST_ADD
)
{
pPage
->
pDirtyPrev
=
0
;
pPage
->
pDirtyNext
=
p
->
pDirty
;
if
(
pPage
->
pDirtyNext
)
{
assert
(
pPage
->
pDirtyNext
->
pDirtyPrev
==
0
);
if
(
pPage
->
pDirtyNext
)
{
assert
(
pPage
->
pDirtyNext
->
pDirtyPrev
==
0
);
pPage
->
pDirtyNext
->
pDirtyPrev
=
pPage
;
}
else
{
}
else
{
p
->
pDirtyTail
=
pPage
;
if
(
p
->
bPurgeable
)
{
assert
(
p
->
eCreate
==
2
);
if
(
p
->
bPurgeable
)
{
assert
(
p
->
eCreate
==
2
);
p
->
eCreate
=
1
;
}
}
p
->
pDirty
=
pPage
;
/* If pSynced is NULL and this page has a clear NEED_SYNC flag, set
** pSynced to point to it. Checking the NEED_SYNC flag is an
** pSynced to point to it. Checking the NEED_SYNC flag is an
** optimization, as if pSynced points to a page with the NEED_SYNC
** flag set sqlite3PcacheFetchStress() searches through all newer
** flag set sqlite3PcacheFetchStress() searches through all newer
** entries of the dirty-list for a page with NEED_SYNC clear anyway. */
if
(
!
p
->
pSynced
&&
0
==
(
pPage
->
flags
&
PGHDR_NEED_SYNC
)
/*OPTIMIZATION-IF-FALSE*/
){
if
(
!
p
->
pSynced
&&
0
==
(
pPage
->
flags
&
PGHDR_NEED_SYNC
)
/*OPTIMIZATION-IF-FALSE*/
)
{
p
->
pSynced
=
pPage
;
}
}
...
...
@@ -225,8 +224,8 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
** Wrapper around the pluggable caches xUnpin method. If the cache is
** being used for an in-memory database, this function is a no-op.
*/
static
void
pcacheUnpin
(
PgHdr
*
p
){
if
(
p
->
pCache
->
bPurgeable
)
{
static
void
pcacheUnpin
(
PgHdr
*
p
)
{
if
(
p
->
pCache
->
bPurgeable
)
{
pcacheTrace
((
"%p.UNPIN %d
\n
"
,
p
->
pCache
,
p
->
pgno
));
pcache2
.
xUnpin
(
p
->
pCache
->
pCache
,
p
->
pPage
,
0
);
pcacheDump
(
p
->
pCache
);
...
...
@@ -237,33 +236,31 @@ static void pcacheUnpin(PgHdr *p){
** Compute the number of pages of cache requested. p->szCache is the
** cache size requested by the "PRAGMA cache_size" statement.
*/
static
int
numberOfCachePages
(
PCache
*
p
){
if
(
p
->
szCache
>=
0
)
{
static
int
numberOfCachePages
(
PCache
*
p
)
{
if
(
p
->
szCache
>=
0
)
{
/* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
** suggested cache size is set to N. */
return
p
->
szCache
;
}
else
{
}
else
{
i64
n
;
/* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the
** number of cache pages is adjusted to be a number of pages that would
** use approximately abs(N*1024) bytes of memory based on the current
** page size. */
n
=
((
-
1024
*
(
i64
)
p
->
szCache
)
/
(
p
->
szPage
+
p
->
szExtra
));
if
(
n
>
1000000000
)
n
=
1000000000
;
n
=
((
-
1024
*
(
i64
)
p
->
szCache
)
/
(
p
->
szPage
+
p
->
szExtra
));
if
(
n
>
1000000000
)
n
=
1000000000
;
return
(
int
)
n
;
}
}
/*************************************************** General Interfaces ******
**
** Initialize and shutdown the page cache subsystem. Neither of these
** Initialize and shutdown the page cache subsystem. Neither of these
** functions are threadsafe.
*/
int
sqlite3PcacheInitialize
(
void
){
return
pcache2
.
xInit
(
pcache2
.
pArg
);
}
void
sqlite3PcacheShutdown
(
void
){
if
(
pcache2
.
xShutdown
){
int
sqlite3PcacheInitialize
(
void
)
{
return
pcache2
.
xInit
(
pcache2
.
pArg
);
}
void
sqlite3PcacheShutdown
(
void
)
{
if
(
pcache2
.
xShutdown
)
{
/* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */
pcache2
.
xShutdown
(
pcache2
.
pArg
);
}
...
...
@@ -272,12 +269,12 @@ void sqlite3PcacheShutdown(void){
/*
** Return the size in bytes of a PCache object.
*/
int
sqlite3PcacheSize
(
void
){
return
sizeof
(
PCache
);
}
int
sqlite3PcacheSize
(
void
)
{
return
sizeof
(
PCache
);
}
/*
** Create a new PCache object. Storage space to hold the object
** has already been allocated and is passed in as the p pointer.
** The caller discovers how much space needs to be allocated by
** has already been allocated and is passed in as the p pointer.
** The caller discovers how much space needs to be allocated by
** calling sqlite3PcacheSize().
**
** szExtra is some extra space allocated for each page. The first
...
...
@@ -286,25 +283,24 @@ int sqlite3PcacheSize(void){ return sizeof(PCache); }
** to this module, the extra space really ends up being the MemPage
** structure in the pager.
*/
int
sqlite3PcacheOpen
(
int
szPage
,
/* Size of every page */
int
szExtra
,
/* Extra space associated with each page */
int
bPurgeable
,
/* True if pages are on backing store */
int
(
*
xStress
)(
void
*
,
PgHdr
*
),
/* Call to try to make pages clean */
void
*
pStress
,
/* Argument to xStress */
PCache
*
p
/* Preallocated space for the PCache */
){
int
sqlite3PcacheOpen
(
int
szPage
,
/* Size of every page */
int
szExtra
,
/* Extra space associated with each page */
int
bPurgeable
,
/* True if pages are on backing store */
int
(
*
xStress
)(
void
*
,
PgHdr
*
),
/* Call to try to make pages clean */
void
*
pStress
,
/* Argument to xStress */
PCache
*
p
/* Preallocated space for the PCache */
)
{
memset
(
p
,
0
,
sizeof
(
PCache
));
p
->
szPage
=
1
;
p
->
szExtra
=
szExtra
;
assert
(
szExtra
>=
8
);
/* First 8 bytes will be zeroed */
assert
(
szExtra
>=
8
);
/* First 8 bytes will be zeroed */
p
->
bPurgeable
=
bPurgeable
;
p
->
eCreate
=
2
;
p
->
xStress
=
xStress
;
p
->
pStress
=
pStress
;
p
->
szCache
=
100
;
p
->
szSpill
=
1
;
pcacheTrace
((
"%p.OPEN szPage %d bPurgeable %d
\n
"
,
p
,
szPage
,
bPurgeable
));
pcacheTrace
((
"%p.OPEN szPage %d bPurgeable %d
\n
"
,
p
,
szPage
,
bPurgeable
));
return
sqlite3PcacheSetPageSize
(
p
,
szPage
);
}
...
...
@@ -312,22 +308,19 @@ int sqlite3PcacheOpen(
** Change the page size for PCache object. The caller must ensure that there
** are no outstanding page references when this function is called.
*/
int
sqlite3PcacheSetPageSize
(
PCache
*
pCache
,
int
szPage
){
assert
(
pCache
->
nRefSum
==
0
&&
pCache
->
pDirty
==
0
);
if
(
pCache
->
szPage
)
{
int
sqlite3PcacheSetPageSize
(
PCache
*
pCache
,
int
szPage
)
{
assert
(
pCache
->
nRefSum
==
0
&&
pCache
->
pDirty
==
0
);
if
(
pCache
->
szPage
)
{
sqlite3_pcache
*
pNew
;
pNew
=
pcache2
.
xCreate
(
szPage
,
pCache
->
szExtra
+
ROUND8
(
sizeof
(
PgHdr
)),
pCache
->
bPurgeable
);
if
(
pNew
==
0
)
return
SQLITE_NOMEM_BKPT
;
pNew
=
pcache2
.
xCreate
(
szPage
,
pCache
->
szExtra
+
ROUND8
(
sizeof
(
PgHdr
)),
pCache
->
bPurgeable
);
if
(
pNew
==
0
)
return
SQLITE_NOMEM
;
pcache2
.
xCachesize
(
pNew
,
numberOfCachePages
(
pCache
));
if
(
pCache
->
pCache
)
{
if
(
pCache
->
pCache
)
{
pcache2
.
xDestroy
(
pCache
->
pCache
);
}
pCache
->
pCache
=
pNew
;
pCache
->
szPage
=
szPage
;
pcacheTrace
((
"%p.PAGESIZE %d
\n
"
,
pCache
,
szPage
));
pcacheTrace
((
"%p.PAGESIZE %d
\n
"
,
pCache
,
szPage
));
}
return
0
;
}
...
...
@@ -356,18 +349,17 @@ int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
** the stack on entry and pop them back off on exit, which saves a
** lot of pushing and popping.
*/
sqlite3_pcache_page
*
sqlite3PcacheFetch
(
PCache
*
pCache
,
/* Obtain the page from this cache */
Pgno
pgno
,
/* Page number to obtain */
int
createFlag
/* If true, create page if it does not exist already */
){
int
eCreate
;
sqlite3_pcache_page
*
sqlite3PcacheFetch
(
PCache
*
pCache
,
/* Obtain the page from this cache */
Pgno
pgno
,
/* Page number to obtain */
int
createFlag
/* If true, create page if it does not exist already */
)
{
int
eCreate
;
sqlite3_pcache_page
*
pRes
;
assert
(
pCache
!=
0
);
assert
(
pCache
->
pCache
!=
0
);
assert
(
createFlag
==
3
||
createFlag
==
0
);
assert
(
pCache
->
eCreate
==
((
pCache
->
bPurgeable
&&
pCache
->
pDirty
)
?
1
:
2
)
);
assert
(
pCache
!=
0
);
assert
(
pCache
->
pCache
!=
0
);
assert
(
createFlag
==
3
||
createFlag
==
0
);
assert
(
pCache
->
eCreate
==
((
pCache
->
bPurgeable
&&
pCache
->
pDirty
)
?
1
:
2
)
);
/* eCreate defines what to do if the page does not exist.
** 0 Do not allocate a new page. (createFlag==0)
...
...
@@ -377,19 +369,18 @@ sqlite3_pcache_page *sqlite3PcacheFetch(
** (createFlag==1 AND !(bPurgeable AND pDirty)
*/
eCreate
=
createFlag
&
pCache
->
eCreate
;
assert
(
eCreate
==
0
||
eCreate
==
1
||
eCreate
==
2
);
assert
(
createFlag
==
0
||
pCache
->
eCreate
==
eCreate
);
assert
(
createFlag
==
0
||
eCreate
==
1
+
(
!
pCache
->
bPurgeable
||!
pCache
->
pDirty
)
);
assert
(
eCreate
==
0
||
eCreate
==
1
||
eCreate
==
2
);
assert
(
createFlag
==
0
||
pCache
->
eCreate
==
eCreate
);
assert
(
createFlag
==
0
||
eCreate
==
1
+
(
!
pCache
->
bPurgeable
||
!
pCache
->
pDirty
)
);
pRes
=
pcache2
.
xFetch
(
pCache
->
pCache
,
pgno
,
eCreate
);
pcacheTrace
((
"%p.FETCH %d%s (result: %p)
\n
"
,
pCache
,
pgno
,
createFlag
?
" create"
:
""
,
pRes
));
pcacheTrace
((
"%p.FETCH %d%s (result: %p)
\n
"
,
pCache
,
pgno
,
createFlag
?
" create"
:
""
,
pRes
));
return
pRes
;
}
/*
** If the sqlite3PcacheFetch() routine is unable to allocate a new
** page because no clean pages are available for reuse and the cache
** size limit has been reached, then this routine can be invoked to
** size limit has been reached, then this routine can be invoked to
** try harder to allocate a page. This routine might invoke the stress
** callback to spill dirty pages to the journal. It will then try to
** allocate the new page and will only fail to allocate a new page on
...
...
@@ -397,51 +388,46 @@ sqlite3_pcache_page *sqlite3PcacheFetch(
**
** This routine should be invoked only after sqlite3PcacheFetch() fails.
*/
int
sqlite3PcacheFetchStress
(
PCache
*
pCache
,
/* Obtain the page from this cache */
Pgno
pgno
,
/* Page number to obtain */
sqlite3_pcache_page
**
ppPage
/* Write result here */
){
int
sqlite3PcacheFetchStress
(
PCache
*
pCache
,
/* Obtain the page from this cache */
Pgno
pgno
,
/* Page number to obtain */
sqlite3_pcache_page
**
ppPage
/* Write result here */
)
{
PgHdr
*
pPg
;
if
(
pCache
->
eCreate
==
2
)
return
0
;
if
(
pCache
->
eCreate
==
2
)
return
0
;
if
(
sqlite3PcachePagecount
(
pCache
)
>
pCache
->
szSpill
)
{
/* Find a dirty page to write-out and recycle. First try to find a
if
(
sqlite3PcachePagecount
(
pCache
)
>
pCache
->
szSpill
)
{
/* Find a dirty page to write-out and recycle. First try to find a
** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
** cleared), but if that is not possible settle for any other
** cleared), but if that is not possible settle for any other
** unreferenced dirty page.
**
** If the LRU page in the dirty list that has a clear PGHDR_NEED_SYNC
** flag is currently referenced, then the following may leave pSynced
** set incorrectly (pointing to other than the LRU page with NEED_SYNC
** cleared). This is Ok, as pSynced is just an optimization. */
for
(
pPg
=
pCache
->
pSynced
;
pPg
&&
(
pPg
->
nRef
||
(
pPg
->
flags
&
PGHDR_NEED_SYNC
));
pPg
=
pPg
->
pDirtyPrev
);
for
(
pPg
=
pCache
->
pSynced
;
pPg
&&
(
pPg
->
nRef
||
(
pPg
->
flags
&
PGHDR_NEED_SYNC
));
pPg
=
pPg
->
pDirtyPrev
)
;
pCache
->
pSynced
=
pPg
;
if
(
!
pPg
){
for
(
pPg
=
pCache
->
pDirtyTail
;
pPg
&&
pPg
->
nRef
;
pPg
=
pPg
->
pDirtyPrev
);
if
(
!
pPg
)
{
for
(
pPg
=
pCache
->
pDirtyTail
;
pPg
&&
pPg
->
nRef
;
pPg
=
pPg
->
pDirtyPrev
)
;
}
if
(
pPg
)
{
if
(
pPg
)
{
int
rc
;
#ifdef SQLITE_LOG_CACHE_SPILL
sqlite3_log
(
SQLITE_FULL
,
"spill page %d making room for %d - cache used: %d/%d"
,
pPg
->
pgno
,
pgno
,
pcache2
.
xPagecount
(
pCache
->
pCache
),
numberOfCachePages
(
pCache
));
sqlite3_log
(
SQLITE_FULL
,
"spill page %d making room for %d - cache used: %d/%d"
,
pPg
->
pgno
,
pgno
,
pcache2
.
xPagecount
(
pCache
->
pCache
),
numberOfCachePages
(
pCache
));
#endif
pcacheTrace
((
"%p.SPILL %d
\n
"
,
pCache
,
pPg
->
pgno
));
pcacheTrace
((
"%p.SPILL %d
\n
"
,
pCache
,
pPg
->
pgno
));
rc
=
pCache
->
xStress
(
pCache
->
pStress
,
pPg
);
pcacheDump
(
pCache
);
if
(
rc
!=
0
&&
rc
!=
SQLITE_BUSY
)
{
if
(
rc
!=
0
&&
rc
!=
SQLITE_BUSY
)
{
return
rc
;
}
}
}
*
ppPage
=
pcache2
.
xFetch
(
pCache
->
pCache
,
pgno
,
2
);
return
*
ppPage
==
0
?
SQLITE_NOMEM_BKPT
:
0
;
return
*
ppPage
==
0
?
SQLITE_NOMEM
:
0
;
}
/*
...
...
@@ -453,16 +439,15 @@ int sqlite3PcacheFetchStress(
** requires extra stack manipulation that can be avoided in the common
** case.
*/
static
SQLITE_NOINLINE
PgHdr
*
pcacheFetchFinishWithInit
(
PCache
*
pCache
,
/* Obtain the page from this cache */
Pgno
pgno
,
/* Page number obtained */
sqlite3_pcache_page
*
pPage
/* Page obtained by prior PcacheFetch() call */
){
static
PgHdr
*
pcacheFetchFinishWithInit
(
PCache
*
pCache
,
/* Obtain the page from this cache */
Pgno
pgno
,
/* Page number obtained */
sqlite3_pcache_page
*
pPage
/* Page obtained by prior PcacheFetch() call */
)
{
PgHdr
*
pPgHdr
;
assert
(
pPage
!=
0
);
pPgHdr
=
(
PgHdr
*
)
pPage
->
pExtra
;
assert
(
pPgHdr
->
pPage
==
0
);
memset
(
&
pPgHdr
->
pDirty
,
0
,
sizeof
(
PgHdr
)
-
offsetof
(
PgHdr
,
pDirty
));
assert
(
pPage
!=
0
);
pPgHdr
=
(
PgHdr
*
)
pPage
->
pExtra
;
assert
(
pPgHdr
->
pPage
==
0
);
memset
(
&
pPgHdr
->
pDirty
,
0
,
sizeof
(
PgHdr
)
-
offsetof
(
PgHdr
,
pDirty
));
pPgHdr
->
pPage
=
pPage
;
pPgHdr
->
pData
=
pPage
->
pBuf
;
pPgHdr
->
pExtra
=
(
void
*
)
&
pPgHdr
[
1
];
...
...
@@ -470,7 +455,7 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
pPgHdr
->
pCache
=
pCache
;
pPgHdr
->
pgno
=
pgno
;
pPgHdr
->
flags
=
PGHDR_CLEAN
;
return
sqlite3PcacheFetchFinish
(
pCache
,
pgno
,
pPage
);
return
sqlite3PcacheFetchFinish
(
pCache
,
pgno
,
pPage
);
}
/*
...
...
@@ -479,22 +464,21 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
** must be called after sqlite3PcacheFetch() in order to get a usable
** result.
*/
PgHdr
*
sqlite3PcacheFetchFinish
(
PCache
*
pCache
,
/* Obtain the page from this cache */
Pgno
pgno
,
/* Page number obtained */
sqlite3_pcache_page
*
pPage
/* Page obtained by prior PcacheFetch() call */
){
PgHdr
*
sqlite3PcacheFetchFinish
(
PCache
*
pCache
,
/* Obtain the page from this cache */
Pgno
pgno
,
/* Page number obtained */
sqlite3_pcache_page
*
pPage
/* Page obtained by prior PcacheFetch() call */
)
{
PgHdr
*
pPgHdr
;
assert
(
pPage
!=
0
);
assert
(
pPage
!=
0
);
pPgHdr
=
(
PgHdr
*
)
pPage
->
pExtra
;
if
(
!
pPgHdr
->
pPage
)
{
if
(
!
pPgHdr
->
pPage
)
{
return
pcacheFetchFinishWithInit
(
pCache
,
pgno
,
pPage
);
}
pCache
->
nRefSum
++
;
pPgHdr
->
nRef
++
;
assert
(
sqlite3PcachePageSanity
(
pPgHdr
)
);
// assert(sqlite3PcachePageSanity(pPgHdr)
);
return
pPgHdr
;
}
...
...
@@ -502,13 +486,13 @@ PgHdr *sqlite3PcacheFetchFinish(
** Decrement the reference count on a page. If the page is clean and the
** reference count drops to 0, then it is made eligible for recycling.
*/
void
SQLITE_NOINLINE
sqlite3PcacheRelease
(
PgHdr
*
p
)
{
assert
(
p
->
nRef
>
0
);
void
sqlite3PcacheRelease
(
PgHdr
*
p
)
{
assert
(
p
->
nRef
>
0
);
p
->
pCache
->
nRefSum
--
;
if
(
(
--
p
->
nRef
)
==
0
)
{
if
(
p
->
flags
&
PGHDR_CLEAN
)
{
if
((
--
p
->
nRef
)
==
0
)
{
if
(
p
->
flags
&
PGHDR_CLEAN
)
{
pcacheUnpin
(
p
);
}
else
{
}
else
{
pcacheManageDirtyList
(
p
,
PCACHE_DIRTYLIST_FRONT
);
}
}
...
...
@@ -517,9 +501,9 @@ void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
/*
** Increase the reference count of a supplied page by 1.
*/
void
sqlite3PcacheRef
(
PgHdr
*
p
){
assert
(
p
->
nRef
>
0
);
assert
(
sqlite3PcachePageSanity
(
p
)
);
void
sqlite3PcacheRef
(
PgHdr
*
p
)
{
assert
(
p
->
nRef
>
0
);
// assert(sqlite3PcachePageSanity(p)
);
p
->
nRef
++
;
p
->
pCache
->
nRefSum
++
;
}
...
...
@@ -529,10 +513,10 @@ void sqlite3PcacheRef(PgHdr *p){
** page. This function deletes that reference, so after it returns the
** page pointed to by p is invalid.
*/
void
sqlite3PcacheDrop
(
PgHdr
*
p
){
assert
(
p
->
nRef
==
1
);
assert
(
sqlite3PcachePageSanity
(
p
)
);
if
(
p
->
flags
&
PGHDR_DIRTY
)
{
void
sqlite3PcacheDrop
(
PgHdr
*
p
)
{
assert
(
p
->
nRef
==
1
);
// assert(sqlite3PcachePageSanity(p)
);
if
(
p
->
flags
&
PGHDR_DIRTY
)
{
pcacheManageDirtyList
(
p
,
PCACHE_DIRTYLIST_REMOVE
);
}
p
->
pCache
->
nRefSum
--
;
...
...
@@ -543,18 +527,18 @@ void sqlite3PcacheDrop(PgHdr *p){
** Make sure the page is marked as dirty. If it isn't dirty already,
** make it so.
*/
void
sqlite3PcacheMakeDirty
(
PgHdr
*
p
){
assert
(
p
->
nRef
>
0
);
assert
(
sqlite3PcachePageSanity
(
p
)
);
if
(
p
->
flags
&
(
PGHDR_CLEAN
|
PGHDR_DONT_WRITE
)
){
/*OPTIMIZATION-IF-FALSE*/
void
sqlite3PcacheMakeDirty
(
PgHdr
*
p
)
{
assert
(
p
->
nRef
>
0
);
// assert(sqlite3PcachePageSanity(p)
);
if
(
p
->
flags
&
(
PGHDR_CLEAN
|
PGHDR_DONT_WRITE
))
{
/*OPTIMIZATION-IF-FALSE*/
p
->
flags
&=
~
PGHDR_DONT_WRITE
;
if
(
p
->
flags
&
PGHDR_CLEAN
)
{
p
->
flags
^=
(
PGHDR_DIRTY
|
PGHDR_CLEAN
);
pcacheTrace
((
"%p.DIRTY %d
\n
"
,
p
->
pCache
,
p
->
pgno
));
assert
(
(
p
->
flags
&
(
PGHDR_DIRTY
|
PGHDR_CLEAN
))
==
PGHDR_DIRTY
);
if
(
p
->
flags
&
PGHDR_CLEAN
)
{
p
->
flags
^=
(
PGHDR_DIRTY
|
PGHDR_CLEAN
);
pcacheTrace
((
"%p.DIRTY %d
\n
"
,
p
->
pCache
,
p
->
pgno
));
assert
(
(
p
->
flags
&
(
PGHDR_DIRTY
|
PGHDR_CLEAN
))
==
PGHDR_DIRTY
);
pcacheManageDirtyList
(
p
,
PCACHE_DIRTYLIST_ADD
);
}
assert
(
sqlite3PcachePageSanity
(
p
)
);
// assert(sqlite3PcachePageSanity(p)
);
}
}
...
...
@@ -562,16 +546,16 @@ void sqlite3PcacheMakeDirty(PgHdr *p){
** Make sure the page is marked as clean. If it isn't clean already,
** make it so.
*/
void
sqlite3PcacheMakeClean
(
PgHdr
*
p
){
assert
(
sqlite3PcachePageSanity
(
p
)
);
assert
(
(
p
->
flags
&
PGHDR_DIRTY
)
!=
0
);
assert
(
(
p
->
flags
&
PGHDR_CLEAN
)
==
0
);
void
sqlite3PcacheMakeClean
(
PgHdr
*
p
)
{
// assert(sqlite3PcachePageSanity(p)
);
assert
(
(
p
->
flags
&
PGHDR_DIRTY
)
!=
0
);
assert
(
(
p
->
flags
&
PGHDR_CLEAN
)
==
0
);
pcacheManageDirtyList
(
p
,
PCACHE_DIRTYLIST_REMOVE
);
p
->
flags
&=
~
(
PGHDR_DIRTY
|
PGHDR_NEED_SYNC
|
PGHDR_WRITEABLE
);
p
->
flags
&=
~
(
PGHDR_DIRTY
|
PGHDR_NEED_SYNC
|
PGHDR_WRITEABLE
);
p
->
flags
|=
PGHDR_CLEAN
;
pcacheTrace
((
"%p.CLEAN %d
\n
"
,
p
->
pCache
,
p
->
pgno
));
assert
(
sqlite3PcachePageSanity
(
p
)
);
if
(
p
->
nRef
==
0
)
{
pcacheTrace
((
"%p.CLEAN %d
\n
"
,
p
->
pCache
,
p
->
pgno
));
// assert(sqlite3PcachePageSanity(p)
);
if
(
p
->
nRef
==
0
)
{
pcacheUnpin
(
p
);
}
}
...
...
@@ -579,10 +563,10 @@ void sqlite3PcacheMakeClean(PgHdr *p){
/*
** Make every page in the cache clean.
*/
void
sqlite3PcacheCleanAll
(
PCache
*
pCache
){
void
sqlite3PcacheCleanAll
(
PCache
*
pCache
)
{
PgHdr
*
p
;
pcacheTrace
((
"%p.CLEAN-ALL
\n
"
,
pCache
));
while
(
(
p
=
pCache
->
pDirty
)
!=
0
)
{
pcacheTrace
((
"%p.CLEAN-ALL
\n
"
,
pCache
));
while
((
p
=
pCache
->
pDirty
)
!=
0
)
{
sqlite3PcacheMakeClean
(
p
);
}
}
...
...
@@ -590,11 +574,11 @@ void sqlite3PcacheCleanAll(PCache *pCache){
/*
** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages.
*/
void
sqlite3PcacheClearWritable
(
PCache
*
pCache
){
void
sqlite3PcacheClearWritable
(
PCache
*
pCache
)
{
PgHdr
*
p
;
pcacheTrace
((
"%p.CLEAR-WRITEABLE
\n
"
,
pCache
));
for
(
p
=
pCache
->
pDirty
;
p
;
p
=
p
->
pDirtyNext
)
{
p
->
flags
&=
~
(
PGHDR_NEED_SYNC
|
PGHDR_WRITEABLE
);
pcacheTrace
((
"%p.CLEAR-WRITEABLE
\n
"
,
pCache
));
for
(
p
=
pCache
->
pDirty
;
p
;
p
=
p
->
pDirtyNext
)
{
p
->
flags
&=
~
(
PGHDR_NEED_SYNC
|
PGHDR_WRITEABLE
);
}
pCache
->
pSynced
=
pCache
->
pDirtyTail
;
}
...
...
@@ -602,26 +586,26 @@ void sqlite3PcacheClearWritable(PCache *pCache){
/*
** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
*/
void
sqlite3PcacheClearSyncFlags
(
PCache
*
pCache
){
void
sqlite3PcacheClearSyncFlags
(
PCache
*
pCache
)
{
PgHdr
*
p
;
for
(
p
=
pCache
->
pDirty
;
p
;
p
=
p
->
pDirtyNext
)
{
for
(
p
=
pCache
->
pDirty
;
p
;
p
=
p
->
pDirtyNext
)
{
p
->
flags
&=
~
PGHDR_NEED_SYNC
;
}
pCache
->
pSynced
=
pCache
->
pDirtyTail
;
}
/*
** Change the page number of page p to newPgno.
** Change the page number of page p to newPgno.
*/
void
sqlite3PcacheMove
(
PgHdr
*
p
,
Pgno
newPgno
){
void
sqlite3PcacheMove
(
PgHdr
*
p
,
Pgno
newPgno
)
{
PCache
*
pCache
=
p
->
pCache
;
assert
(
p
->
nRef
>
0
);
assert
(
newPgno
>
0
);
assert
(
sqlite3PcachePageSanity
(
p
)
);
pcacheTrace
((
"%p.MOVE %d -> %d
\n
"
,
pCache
,
p
->
pgno
,
newPgno
));
pcache2
.
xRekey
(
pCache
->
pCache
,
p
->
pPage
,
p
->
pgno
,
newPgno
);
assert
(
p
->
nRef
>
0
);
assert
(
newPgno
>
0
);
// assert(sqlite3PcachePageSanity(p)
);
pcacheTrace
((
"%p.MOVE %d -> %d
\n
"
,
pCache
,
p
->
pgno
,
newPgno
));
pcache2
.
xRekey
(
pCache
->
pCache
,
p
->
pPage
,
p
->
pgno
,
newPgno
);
p
->
pgno
=
newPgno
;
if
(
(
p
->
flags
&
PGHDR_DIRTY
)
&&
(
p
->
flags
&
PGHDR_NEED_SYNC
)
)
{
if
((
p
->
flags
&
PGHDR_DIRTY
)
&&
(
p
->
flags
&
PGHDR_NEED_SYNC
))
{
pcacheManageDirtyList
(
p
,
PCACHE_DIRTYLIST_FRONT
);
}
}
...
...
@@ -635,74 +619,72 @@ void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
** function is 0, then the data area associated with page 1 is zeroed, but
** the page object is not dropped.
*/
void
sqlite3PcacheTruncate
(
PCache
*
pCache
,
Pgno
pgno
){
if
(
pCache
->
pCache
)
{
void
sqlite3PcacheTruncate
(
PCache
*
pCache
,
Pgno
pgno
)
{
if
(
pCache
->
pCache
)
{
PgHdr
*
p
;
PgHdr
*
pNext
;
pcacheTrace
((
"%p.TRUNCATE %d
\n
"
,
pCache
,
pgno
));
for
(
p
=
pCache
->
pDirty
;
p
;
p
=
pNext
)
{
pcacheTrace
((
"%p.TRUNCATE %d
\n
"
,
pCache
,
pgno
));
for
(
p
=
pCache
->
pDirty
;
p
;
p
=
pNext
)
{
pNext
=
p
->
pDirtyNext
;
/* This routine never gets call with a positive pgno except right
** after sqlite3PcacheCleanAll(). So if there are dirty pages,
** it must be that pgno==0.
*/
assert
(
p
->
pgno
>
0
);
if
(
p
->
pgno
>
pgno
)
{
assert
(
p
->
flags
&
PGHDR_DIRTY
);
assert
(
p
->
pgno
>
0
);
if
(
p
->
pgno
>
pgno
)
{
assert
(
p
->
flags
&
PGHDR_DIRTY
);
sqlite3PcacheMakeClean
(
p
);
}
}
if
(
pgno
==
0
&&
pCache
->
nRefSum
)
{
if
(
pgno
==
0
&&
pCache
->
nRefSum
)
{
sqlite3_pcache_page
*
pPage1
;
pPage1
=
pcache2
.
xFetch
(
pCache
->
pCache
,
1
,
0
);
if
(
ALWAYS
(
pPage1
)
){
/* Page 1 is always available in cache, because
** pCache->nRefSum>0 */
pPage1
=
pcache2
.
xFetch
(
pCache
->
pCache
,
1
,
0
);
if
(
ALWAYS
(
pPage1
))
{
/* Page 1 is always available in cache, because
** pCache->nRefSum>0 */
memset
(
pPage1
->
pBuf
,
0
,
pCache
->
szPage
);
pgno
=
1
;
}
}
pcache2
.
xTruncate
(
pCache
->
pCache
,
pgno
+
1
);
pcache2
.
xTruncate
(
pCache
->
pCache
,
pgno
+
1
);
}
}
/*
** Close a cache.
*/
void
sqlite3PcacheClose
(
PCache
*
pCache
){
assert
(
pCache
->
pCache
!=
0
);
pcacheTrace
((
"%p.CLOSE
\n
"
,
pCache
));
void
sqlite3PcacheClose
(
PCache
*
pCache
)
{
assert
(
pCache
->
pCache
!=
0
);
pcacheTrace
((
"%p.CLOSE
\n
"
,
pCache
));
pcache2
.
xDestroy
(
pCache
->
pCache
);
}
/*
/*
** Discard the contents of the cache.
*/
void
sqlite3PcacheClear
(
PCache
*
pCache
){
sqlite3PcacheTruncate
(
pCache
,
0
);
}
void
sqlite3PcacheClear
(
PCache
*
pCache
)
{
sqlite3PcacheTruncate
(
pCache
,
0
);
}
/*
** Merge two lists of pages connected by pDirty and in pgno order.
** Do not bother fixing the pDirtyPrev pointers.
*/
static
PgHdr
*
pcacheMergeDirtyList
(
PgHdr
*
pA
,
PgHdr
*
pB
){
static
PgHdr
*
pcacheMergeDirtyList
(
PgHdr
*
pA
,
PgHdr
*
pB
)
{
PgHdr
result
,
*
pTail
;
pTail
=
&
result
;
assert
(
pA
!=
0
&&
pB
!=
0
);
for
(;;)
{
if
(
pA
->
pgno
<
pB
->
pgno
)
{
assert
(
pA
!=
0
&&
pB
!=
0
);
for
(;;)
{
if
(
pA
->
pgno
<
pB
->
pgno
)
{
pTail
->
pDirty
=
pA
;
pTail
=
pA
;
pA
=
pA
->
pDirty
;
if
(
pA
==
0
)
{
if
(
pA
==
0
)
{
pTail
->
pDirty
=
pB
;
break
;
}
}
else
{
}
else
{
pTail
->
pDirty
=
pB
;
pTail
=
pB
;
pB
=
pB
->
pDirty
;
if
(
pB
==
0
)
{
if
(
pB
==
0
)
{
pTail
->
pDirty
=
pA
;
break
;
}
...
...
@@ -721,25 +703,25 @@ static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){
** One extra bucket is added to catch overflow in case something
** ever changes to make the previous sentence incorrect.
*/
#define N_SORT_BUCKET
32
static
PgHdr
*
pcacheSortDirtyList
(
PgHdr
*
pIn
){
#define N_SORT_BUCKET 32
static
PgHdr
*
pcacheSortDirtyList
(
PgHdr
*
pIn
)
{
PgHdr
*
a
[
N_SORT_BUCKET
],
*
p
;
int
i
;
int
i
;
memset
(
a
,
0
,
sizeof
(
a
));
while
(
pIn
)
{
while
(
pIn
)
{
p
=
pIn
;
pIn
=
p
->
pDirty
;
p
->
pDirty
=
0
;
for
(
i
=
0
;
ALWAYS
(
i
<
N_SORT_BUCKET
-
1
);
i
++
)
{
if
(
a
[
i
]
==
0
)
{
for
(
i
=
0
;
ALWAYS
(
i
<
N_SORT_BUCKET
-
1
);
i
++
)
{
if
(
a
[
i
]
==
0
)
{
a
[
i
]
=
p
;
break
;
}
else
{
}
else
{
p
=
pcacheMergeDirtyList
(
a
[
i
],
p
);
a
[
i
]
=
0
;
}
}
if
(
NEVER
(
i
==
N_SORT_BUCKET
-
1
)
)
{
if
(
NEVER
(
i
==
N_SORT_BUCKET
-
1
))
{
/* To get here, there need to be 2^(N_SORT_BUCKET) elements in
** the input list. But that is impossible.
*/
...
...
@@ -747,8 +729,8 @@ static PgHdr *pcacheSortDirtyList(PgHdr *pIn){
}
}
p
=
a
[
0
];
for
(
i
=
1
;
i
<
N_SORT_BUCKET
;
i
++
)
{
if
(
a
[
i
]
==
0
)
continue
;
for
(
i
=
1
;
i
<
N_SORT_BUCKET
;
i
++
)
{
if
(
a
[
i
]
==
0
)
continue
;
p
=
p
?
pcacheMergeDirtyList
(
p
,
a
[
i
])
:
a
[
i
];
}
return
p
;
...
...
@@ -757,36 +739,32 @@ static PgHdr *pcacheSortDirtyList(PgHdr *pIn){
/*
** Return a list of all dirty pages in the cache, sorted by page number.
*/
PgHdr
*
sqlite3PcacheDirtyList
(
PCache
*
pCache
){
PgHdr
*
sqlite3PcacheDirtyList
(
PCache
*
pCache
)
{
PgHdr
*
p
;
for
(
p
=
pCache
->
pDirty
;
p
;
p
=
p
->
pDirtyNext
)
{
for
(
p
=
pCache
->
pDirty
;
p
;
p
=
p
->
pDirtyNext
)
{
p
->
pDirty
=
p
->
pDirtyNext
;
}
return
pcacheSortDirtyList
(
pCache
->
pDirty
);
}
/*
/*
** Return the total number of references to all pages held by the cache.
**
** This is not the total number of pages referenced, but the sum of the
** reference count for all pages.
*/
int
sqlite3PcacheRefCount
(
PCache
*
pCache
){
return
pCache
->
nRefSum
;
}
int
sqlite3PcacheRefCount
(
PCache
*
pCache
)
{
return
pCache
->
nRefSum
;
}
/*
** Return the number of references to the page supplied as an argument.
*/
int
sqlite3PcachePageRefcount
(
PgHdr
*
p
){
return
p
->
nRef
;
}
int
sqlite3PcachePageRefcount
(
PgHdr
*
p
)
{
return
p
->
nRef
;
}
/*
/*
** Return the total number of pages in the cache.
*/
int
sqlite3PcachePagecount
(
PCache
*
pCache
){
assert
(
pCache
->
pCache
!=
0
);
int
sqlite3PcachePagecount
(
PCache
*
pCache
)
{
assert
(
pCache
->
pCache
!=
0
);
return
pcache2
.
xPagecount
(
pCache
->
pCache
);
}
...
...
@@ -794,19 +772,16 @@ int sqlite3PcachePagecount(PCache *pCache){
/*
** Get the suggested cache-size value.
*/
int
sqlite3PcacheGetCachesize
(
PCache
*
pCache
){
return
numberOfCachePages
(
pCache
);
}
int
sqlite3PcacheGetCachesize
(
PCache
*
pCache
)
{
return
numberOfCachePages
(
pCache
);
}
#endif
/*
** Set the suggested cache-size value.
*/
void
sqlite3PcacheSetCachesize
(
PCache
*
pCache
,
int
mxPage
){
assert
(
pCache
->
pCache
!=
0
);
void
sqlite3PcacheSetCachesize
(
PCache
*
pCache
,
int
mxPage
)
{
assert
(
pCache
->
pCache
!=
0
);
pCache
->
szCache
=
mxPage
;
pcache2
.
xCachesize
(
pCache
->
pCache
,
numberOfCachePages
(
pCache
));
pcache2
.
xCachesize
(
pCache
->
pCache
,
numberOfCachePages
(
pCache
));
}
/*
...
...
@@ -814,25 +789,25 @@ void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
** argument is zero. Return the effective cache-spill size, which will
** be the larger of the szSpill and szCache.
*/
int
sqlite3PcacheSetSpillsize
(
PCache
*
p
,
int
mxPage
){
int
sqlite3PcacheSetSpillsize
(
PCache
*
p
,
int
mxPage
)
{
int
res
;
assert
(
p
->
pCache
!=
0
);
if
(
mxPage
)
{
if
(
mxPage
<
0
)
{
mxPage
=
(
int
)((
-
1024
*
(
i64
)
mxPage
)
/
(
p
->
szPage
+
p
->
szExtra
));
assert
(
p
->
pCache
!=
0
);
if
(
mxPage
)
{
if
(
mxPage
<
0
)
{
mxPage
=
(
int
)((
-
1024
*
(
i64
)
mxPage
)
/
(
p
->
szPage
+
p
->
szExtra
));
}
p
->
szSpill
=
mxPage
;
}
res
=
numberOfCachePages
(
p
);
if
(
res
<
p
->
szSpill
)
res
=
p
->
szSpill
;
if
(
res
<
p
->
szSpill
)
res
=
p
->
szSpill
;
return
res
;
}
/*
** Free up as much memory as possible from the page cache.
*/
void
sqlite3PcacheShrink
(
PCache
*
pCache
){
assert
(
pCache
->
pCache
!=
0
);
void
sqlite3PcacheShrink
(
PCache
*
pCache
)
{
assert
(
pCache
->
pCache
!=
0
);
pcache2
.
xShrink
(
pCache
->
pCache
);
}
...
...
@@ -840,27 +815,25 @@ void sqlite3PcacheShrink(PCache *pCache){
** Return the size of the header added by this middleware layer
** in the page-cache hierarchy.
*/
int
sqlite3HeaderSizePcache
(
void
){
return
ROUND8
(
sizeof
(
PgHdr
));
}
int
sqlite3HeaderSizePcache
(
void
)
{
return
ROUND8
(
sizeof
(
PgHdr
));
}
/*
** Return the number of dirty pages currently in the cache, as a percentage
** of the configured cache size.
*/
int
sqlite3PCachePercentDirty
(
PCache
*
pCache
){
int
sqlite3PCachePercentDirty
(
PCache
*
pCache
)
{
PgHdr
*
pDirty
;
int
nDirty
=
0
;
int
nCache
=
numberOfCachePages
(
pCache
);
for
(
pDirty
=
pCache
->
pDirty
;
pDirty
;
pDirty
=
pDirty
->
pDirtyNext
)
nDirty
++
;
int
nDirty
=
0
;
int
nCache
=
numberOfCachePages
(
pCache
);
for
(
pDirty
=
pCache
->
pDirty
;
pDirty
;
pDirty
=
pDirty
->
pDirtyNext
)
nDirty
++
;
return
nCache
?
(
int
)(((
i64
)
nDirty
*
100
)
/
nCache
)
:
0
;
}
#ifdef SQLITE_DIRECT_OVERFLOW_READ
/*
/*
** Return true if there are one or more dirty pages in the cache. Else false.
*/
int
sqlite3PCacheIsDirty
(
PCache
*
pCache
){
return
(
pCache
->
pDirty
!=
0
);
}
int
sqlite3PCacheIsDirty
(
PCache
*
pCache
)
{
return
(
pCache
->
pDirty
!=
0
);
}
#endif
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
...
...
@@ -869,9 +842,9 @@ int sqlite3PCacheIsDirty(PCache *pCache){
** callback. This is only used if the SQLITE_CHECK_PAGES macro is
** defined.
*/
void
sqlite3PcacheIterateDirty
(
PCache
*
pCache
,
void
(
*
xIter
)(
PgHdr
*
)){
void
sqlite3PcacheIterateDirty
(
PCache
*
pCache
,
void
(
*
xIter
)(
PgHdr
*
))
{
PgHdr
*
pDirty
;
for
(
pDirty
=
pCache
->
pDirty
;
pDirty
;
pDirty
=
pDirty
->
pDirtyNext
)
{
for
(
pDirty
=
pCache
->
pDirty
;
pDirty
;
pDirty
=
pDirty
->
pDirtyNext
)
{
xIter
(
pDirty
);
}
}
...
...
source/libs/tdb/src/sqlite/wal.c
浏览文件 @
a581d9b3
...
...
@@ -642,7 +642,7 @@ static SQLITE_NOINLINE int walIndexPageRealloc(
apNew
=
(
volatile
u32
**
)
sqlite3Realloc
((
void
*
)
pWal
->
apWiData
,
nByte
);
if
(
!
apNew
){
*
ppPage
=
0
;
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
memset
((
void
*
)
&
apNew
[
pWal
->
nWiData
],
0
,
sizeof
(
u32
*
)
*
(
iPage
+
1
-
pWal
->
nWiData
));
...
...
@@ -654,7 +654,7 @@ static SQLITE_NOINLINE int walIndexPageRealloc(
assert
(
pWal
->
apWiData
[
iPage
]
==
0
);
if
(
pWal
->
exclusiveMode
==
WAL_HEAPMEMORY_MODE
){
pWal
->
apWiData
[
iPage
]
=
(
u32
volatile
*
)
sqlite3MallocZero
(
WALINDEX_PGSZ
);
if
(
!
pWal
->
apWiData
[
iPage
]
)
rc
=
SQLITE_NOMEM
_BKPT
;
if
(
!
pWal
->
apWiData
[
iPage
]
)
rc
=
SQLITE_NOMEM
;
}
else
{
rc
=
sqlite3OsShmMap
(
pWal
->
pDbFd
,
iPage
,
WALINDEX_PGSZ
,
pWal
->
writeLock
,
(
void
volatile
**
)
&
pWal
->
apWiData
[
iPage
]
...
...
@@ -1310,7 +1310,7 @@ static int walIndexRecover(Wal *pWal){
szFrame
=
szPage
+
WAL_FRAME_HDRSIZE
;
aFrame
=
(
u8
*
)
sqlite3_malloc64
(
szFrame
+
WALINDEX_PGSZ
);
if
(
!
aFrame
){
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
goto
recovery_error
;
}
aData
=
&
aFrame
[
WAL_FRAME_HDRSIZE
];
...
...
@@ -1534,7 +1534,7 @@ int sqlite3WalOpen(
*
ppWal
=
0
;
pRet
=
(
Wal
*
)
sqlite3MallocZero
(
sizeof
(
Wal
)
+
pVfs
->
szOsFile
);
if
(
!
pRet
){
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
pRet
->
pVfs
=
pVfs
;
...
...
@@ -1799,7 +1799,7 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
+
iLast
*
sizeof
(
ht_slot
);
p
=
(
WalIterator
*
)
sqlite3_malloc64
(
nByte
);
if
(
!
p
){
return
SQLITE_NOMEM
_BKPT
;
return
SQLITE_NOMEM
;
}
memset
(
p
,
0
,
nByte
);
p
->
nSegment
=
nSegment
;
...
...
@@ -1811,7 +1811,7 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
sizeof
(
ht_slot
)
*
(
iLast
>
HASHTABLE_NPAGE
?
HASHTABLE_NPAGE
:
iLast
)
);
if
(
!
aTmp
){
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
}
for
(
i
=
walFramePage
(
nBackfill
+
1
);
rc
==
SQLITE_OK
&&
i
<
nSegment
;
i
++
){
...
...
@@ -2129,7 +2129,7 @@ static int walCheckpoint(
i64
iOffset
;
assert
(
walFramePgno
(
pWal
,
iFrame
)
==
iDbpage
);
if
(
AtomicLoad
(
&
db
->
u1
.
isInterrupted
)
){
rc
=
db
->
mallocFailed
?
SQLITE_NOMEM
_BKPT
:
SQLITE_INTERRUPT
;
rc
=
db
->
mallocFailed
?
SQLITE_NOMEM
:
SQLITE_INTERRUPT
;
break
;
}
if
(
iFrame
<=
nBackfill
||
iFrame
>
mxSafeFrame
||
iDbpage
>
mxPage
){
...
...
@@ -2606,7 +2606,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){
szFrame
=
pWal
->
hdr
.
szPage
+
WAL_FRAME_HDRSIZE
;
aFrame
=
(
u8
*
)
sqlite3_malloc64
(
szFrame
);
if
(
aFrame
==
0
){
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
goto
begin_unreliable_shm_out
;
}
aData
=
&
aFrame
[
WAL_FRAME_HDRSIZE
];
...
...
@@ -3559,7 +3559,7 @@ static int walRewriteChecksums(Wal *pWal, u32 iLast){
i64
iCksumOff
;
aBuf
=
sqlite3_malloc
(
szPage
+
WAL_FRAME_HDRSIZE
);
if
(
aBuf
==
0
)
return
SQLITE_NOMEM
_BKPT
;
if
(
aBuf
==
0
)
return
SQLITE_NOMEM
;
/* Find the checksum values to use as input for the recalculating the
** first checksum. If the first frame is frame 1 (implying that the current
...
...
@@ -4059,7 +4059,7 @@ int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){
}
pRet
=
(
WalIndexHdr
*
)
sqlite3_malloc
(
sizeof
(
WalIndexHdr
));
if
(
pRet
==
0
){
rc
=
SQLITE_NOMEM
_BKPT
;
rc
=
SQLITE_NOMEM
;
}
else
{
memcpy
(
pRet
,
&
pWal
->
hdr
,
sizeof
(
WalIndexHdr
));
*
ppSnapshot
=
(
sqlite3_snapshot
*
)
pRet
;
...
...
source/libs/tdb/src/sqliteinc/sqlite3.h
0 → 100644
浏览文件 @
a581d9b3
/*
** 2001-09-15
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs. If a C-function, structure, datatype,
** or constant definition does not appear in this file, then it is
** not a published API of SQLite, is subject to change without
** notice, and should not be referenced by programs that use SQLite.
**
** Some of the definitions that are in this file are marked as
** "experimental". Experimental interfaces are normally new
** features recently added to SQLite. We do not anticipate changes
** to experimental interfaces but reserve the right to make minor changes
** if experience from use "in the wild" suggest such changes are prudent.
**
** The official C-language API documentation for SQLite is derived
** from comments in this file. This file is the authoritative source
** on how SQLite interfaces are supposed to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
*/
#ifndef SQLITE3_H
#define SQLITE3_H
#include <stdarg.h>
/* Needed for the definition of va_list */
/*
** Make sure we can call this stuff from C++.
*/
#ifdef __cplusplus
extern
"C"
{
#endif
/*
** CAPI3REF: Result Codes
** KEYWORDS: {result code definitions}
**
** Many SQLite functions return an integer result code from the set shown
** here in order to indicate success or failure.
**
** New error codes may be added in future versions of SQLite.
**
** See also: [extended result code definitions]
*/
#define SQLITE_OK 0
/* Successful result */
/* beginning-of-error-codes */
#define SQLITE_ERROR 1
/* Generic error */
#define SQLITE_INTERNAL 2
/* Internal logic error in SQLite */
#define SQLITE_PERM 3
/* Access permission denied */
#define SQLITE_ABORT 4
/* Callback routine requested an abort */
#define SQLITE_BUSY 5
/* The database file is locked */
#define SQLITE_LOCKED 6
/* A table in the database is locked */
#define SQLITE_NOMEM 7
/* A malloc() failed */
#define SQLITE_READONLY 8
/* Attempt to write a readonly database */
#define SQLITE_INTERRUPT 9
/* Operation terminated by sqlite3_interrupt()*/
#define SQLITE_IOERR 10
/* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT 11
/* The database disk image is malformed */
#define SQLITE_NOTFOUND 12
/* Unknown opcode in sqlite3_file_control() */
#define SQLITE_FULL 13
/* Insertion failed because database is full */
#define SQLITE_CANTOPEN 14
/* Unable to open the database file */
#define SQLITE_PROTOCOL 15
/* Database lock protocol error */
#define SQLITE_EMPTY 16
/* Internal use only */
#define SQLITE_SCHEMA 17
/* The database schema changed */
#define SQLITE_TOOBIG 18
/* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT 19
/* Abort due to constraint violation */
#define SQLITE_MISMATCH 20
/* Data type mismatch */
#define SQLITE_MISUSE 21
/* Library used incorrectly */
#define SQLITE_NOLFS 22
/* Uses OS features not supported on host */
#define SQLITE_AUTH 23
/* Authorization denied */
#define SQLITE_FORMAT 24
/* Not used */
#define SQLITE_RANGE 25
/* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB 26
/* File opened that is not a database file */
#define SQLITE_NOTICE 27
/* Notifications from sqlite3_log() */
#define SQLITE_WARNING 28
/* Warnings from sqlite3_log() */
#define SQLITE_ROW 100
/* sqlite3_step() has another row ready */
#define SQLITE_DONE 101
/* sqlite3_step() has finished executing */
/* end-of-error-codes */
#ifdef __cplusplus
}
/* end of the 'extern "C"' block */
#endif
#endif
/* _FTS5_H */
/******** End of fts5.h *********/
source/libs/tdb/src/sqliteinc/sqliteInt.h
浏览文件 @
a581d9b3
...
...
@@ -15,12 +15,15 @@
#include <assert.h>
#include <pthread.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#ifndef SQLITEINT_H
#define SQLITEINT_H
#include "sqlite3.h"
typedef
int8_t
i8
;
typedef
int16_t
i16
;
typedef
int32_t
i32
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录