读取和写入是相互逆操作,这边只分析读操作,写操作简单介绍。
//从内存日志文件中读取数据
static int memjrnlRead(
sqlite3_file *pJfd, /* The journal file from which to read */ //读取文件的指针
void *zBuf, /* Put the results here */ //读取的结果
int iAmt, /* Number of bytes to read */ //读取的字节数
sqlite_int64 iOfst /* Begin reading at this offset */ //从该偏移量开始读取
){
MemJournal *p = (MemJournal *)pJfd;
u8 *zOut = zBuf;
int nRead = iAmt;
int iChunkOffset;
FileChunk *pChunk;
/* SQLite never tries to read past the end of a rollback journal file */
assert( iOfst+iAmt<=p->endpoint.iOffset );
//开始的偏移量加上读取的字节数 >文件结尾的偏移量 即溢出,则报警
if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
//不是从文件头或者文件尾开始读
sqlite3_int64 iOff = 0;
//总共需读取的偏移量
for(pChunk=p->pFirst;
ALWAYS(pChunk) && (iOff+JOURNAL_CHUNKSIZE)<=iOfst;
//# define ALWAYS(X) (X) 偏移量未读完则继续
pChunk=pChunk->pNext
){
iOff += JOURNAL_CHUNKSIZE;
//总读取数累加
}
}else{
pChunk = p->readpoint.pChunk;
//设置为文件块的结尾
}
iChunkOffset = (int)(iOfst%JOURNAL_CHUNKSIZE);
//定义iOfst长度
do {
int iSpace = JOURNAL_CHUNKSIZE - iChunkOffset;
//iSpace为所剩空间
int nCopy = MIN(nRead, (JOURNAL_CHUNKSIZE - iChunkOffset));
//输出最小的长度块
memcpy(zOut, &pChunk->zChunk[iChunkOffset], nCopy);
zOut += nCopy;
//输出长度加
nRead -= iSpace;
//剩余空间减
iChunkOffset = 0;
} while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
p->readpoint.iOffset = iOfst+iAmt;
p->readpoint.pChunk = pChunk;
return SQLITE_OK;
}
//写数据到内存日志文件
static int memjrnlWrite(
sqlite3_file *pJfd, /* The journal file into which to write */
const void *zBuf, /* Take data to be written from here */
int iAmt, /* Number of bytes to write */
sqlite_int64 iOfst /* Begin writing at this offset into the file */
){
MemJournal *p = (MemJournal *)pJfd;
int nWrite = iAmt;
u8 *zWrite = (u8 *)zBuf;
/* An in-memory journal file should only ever be appended to. Random
** access writes are not required by sqlite.
*/
//列表访问,不支持随机读写
assert( iOfst==p->endpoint.iOffset );
UNUSED_PARAMETER(iOfst);
while( nWrite>0 ){
FileChunk *pChunk = p->endpoint.pChunk;
int iChunkOffset = (int)(p->endpoint.iOffset%JOURNAL_CHUNKSIZE);
int iSpace = MIN(nWrite, JOURNAL_CHUNKSIZE - iChunkOffset);
if( iChunkOffset==0 ){
//偏移为0 需要新建一个文件块
/* New chunk is required to extend the file. */
FileChunk *pNew = sqlite3_malloc(sizeof(FileChunk));
if( !pNew ){
return SQLITE_IOERR_NOMEM;
}
pNew->pNext = 0;
//新建块的指针初始化
if( pChunk ){
assert( p->pFirst );
//文件头指针为0
pChunk->pNext = pNew;
}else{
assert( !p->pFirst );
//文件头指针不为0
p->pFirst = pNew;
}
p->endpoint.pChunk = pNew;
}
memcpy(&p->endpoint.pChunk->zChunk[iChunkOffset], zWrite, iSpace);
//复制一个文件块
zWrite += iSpace;
nWrite -= iSpace;
p->endpoint.iOffset += iSpace;
}
return SQLITE_OK;
}