现在只记录了使用文件系统的解析,后续添加使用mem的解析
/*
* [CAPIREF: unqlite_kv_fetch()]
* Please refer to the official documentation for function purpose and expected parameters.
*/
int unqlite_kv_fetch(unqlite *pDb,const void *pKey,int nKeyLen,void *pBuf,unqlite_int64 *pBufLen)
{
...
/* Seek to the record position */
rc = pMethods->xSeek(pCur,pKey,nKeyLen,UNQLITE_CURSOR_MATCH_EXACT);
}
if( rc == UNQLITE_OK ){
if( pBuf == 0 ){
/* Data length only */
rc = pMethods->xDataLength(pCur,pBufLen);
}else{
SyBlob sBlob;
/* Initialize the data consumer */
SyBlobInitFromBuf(&sBlob,pBuf,(sxu32)*pBufLen);
/* Consume the data */
rc = pMethods->xData(pCur,unqliteDataConsumer,&sBlob);
/* Data length */
*pBufLen = (unqlite_int64)SyBlobLength(&sBlob);
/* Cleanup */
SyBlobRelease(&sBlob);
}
}
...
return rc;
}
上面只保留了源码中的重点,通过上面的代码可以看出,先通过seek获取指向key的cursor,然后再从cursor中解析出data。xseek将会重定向到lhCursorSeek,而lhCursorSeek里面重点是通过调用lhRecordLookup。lhRecordLookup和lh_record_insert有相同的流程.
struct lhash_kv_cursor
{
unqlite_kv_engine *pStore; /* Must be first */
/* Private fields */
int iState; /* Current state of the cursor */
int is_first; /* True to read the database header */
lhcell *pCell; /* Current cell we are processing */
unqlite_page *pRaw; /* Raw disk page */
lhash_bmap_rec *pRec; /* Logical to real bucket map */
};
static int lhRecordLookup(
lhash_kv_engine *pEngine, /* KV storage engine */
const void *pKey, /* Lookup key */
sxu32 nByte, /* Key length */
lhcell **ppCell /* OUT: Target cell on success */
)
{
...
rc = pEngine->pIo->xGet(pEngine->pIo->pHandle,1,0);
if( rc != UNQLITE_OK ){
return rc;
}
nHash = pEngine->xHash(pKey,nByte);
iBucket = nHash & (pEngine->nmax_split_nucket - 1);
if( iBucket >= (pEngine->split_bucket + pEngine->max_split_bucket) ){
/* Low mask */
iBucket = nHash & (pEngine->max_split_bucket - 1);
}
pRec = lhMapFindBucket(pEngine,iBucket);
if( pRec == 0 ){
return UNQLITE_NOTFOUND;
}
rc = lhLoadPage(pEngine,pRec->iReal,0,&pPage,0);
if( rc != UNQLITE_OK ){
return rc;
}
pCell = lhFindCell(pPage,pKey,nByte,nHash);
if( pCell == 0 ){
return UNQLITE_NOTFOUND;
}
if( ppCell ){
*ppCell = pCell;
}
return UNQLITE_OK;
}