unqlite源码分析之unqlite_kv_fetch

现在只记录了使用文件系统的解析,后续添加使用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;
}

猜你喜欢

转载自blog.csdn.net/scdnshijiemengxiang/article/details/83808544