示例#1
0
DWORD
VmDirMDBIndexIteratorInit(
    PVDIR_INDEX_CFG                 pIndexCfg,
    PSTR                            pszInitVal,
    PVDIR_BACKEND_INDEX_ITERATOR*   ppIterator
    )
{
    DWORD   dwError = 0;
    VDIR_DB mdbDBi = 0;
    PSTR            pszInitKey = NULL;
    VDIR_DB_DBT     key = {0};
    VDIR_DB_DBT     value = {0};
    PSTR            pszVal = NULL;
    ENTRYID         eId = 0;
    PVDIR_DB_TXN    pTxn = NULL;
    PVDIR_DB_DBC    pCursor = NULL;
    PVDIR_BACKEND_INDEX_ITERATOR    pIterator = NULL;
    PVDIR_MDB_INDEX_ITERATOR        pMdbIterator = NULL;

    if (!pIndexCfg || !ppIterator)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirAllocateMemory(
            sizeof(VDIR_BACKEND_INDEX_ITERATOR),
            (PVOID*)&pIterator);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateMemory(
            sizeof(VDIR_MDB_INDEX_ITERATOR),
            (PVOID*)&pMdbIterator);
    BAIL_ON_VMDIR_ERROR(dwError);

    pIterator->pIterator = (PVOID)pMdbIterator;

    dwError = VmDirMDBIndexGetDBi(pIndexCfg, &mdbDBi);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = mdb_txn_begin(gVdirMdbGlobals.mdbEnv, NULL, MDB_RDONLY, &pTxn);
    BAIL_ON_VMDIR_ERROR(dwError);

    pMdbIterator->pTxn = pTxn;

    dwError = mdb_cursor_open(pTxn, mdbDBi, &pCursor);
    BAIL_ON_VMDIR_ERROR(dwError);

    pMdbIterator->pCursor = pCursor;

    if (IsNullOrEmptyString(pszInitVal))
    {
        dwError = mdb_cursor_get(pCursor, &key, &value, MDB_FIRST);
    }
    else
    {
        dwError = VmDirAllocateStringPrintf(
                &pszInitKey, "%c%s", BE_INDEX_KEY_TYPE_FWD, pszInitVal);
        BAIL_ON_VMDIR_ERROR(dwError);

        key.mv_data = pszInitKey;
        key.mv_size = VmDirStringLenA(pszInitKey);

        dwError = mdb_cursor_get(pCursor, &key, &value, MDB_SET_RANGE);
    }

    if (dwError == 0 && *(char *)(key.mv_data) == BE_INDEX_KEY_TYPE_FWD)
    {
        dwError = VmDirAllocateMemory(key.mv_size, (PVOID*)&pszVal);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirCopyMemory(
                pszVal, key.mv_size, (char*)key.mv_data + 1, key.mv_size - 1);
        BAIL_ON_VMDIR_ERROR(dwError);

        MDBDBTToEntryId(&value, &eId);

        pIterator->bHasNext = TRUE;
    }
    else
    {
        pIterator->bHasNext = FALSE;
        dwError = dwError == MDB_NOTFOUND ? 0 : dwError;
        pMdbIterator->bAbort = dwError ? TRUE : FALSE;
    }
    BAIL_ON_VMDIR_ERROR(dwError);

    pMdbIterator->pszVal = pszVal;
    pMdbIterator->eId = eId;

    *ppIterator = pIterator;

cleanup:
    VMDIR_SAFE_FREE_MEMORY(pszInitKey);
    return dwError;

error:
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
            "%s failed, error (%d)", __FUNCTION__, dwError );

    VmDirMDBIndexIteratorFree(pIterator);
    VMDIR_SAFE_FREE_MEMORY(pszVal);
    goto cleanup;
}
示例#2
0
文件: entry.c 项目: vmware/lightwave
// To get the current max ENTRYID
// Entry database is separated from log databases.
DWORD
VmDirMDBMaxEntryId(
    PVDIR_BACKEND_INTERFACE pBE,
    ENTRYID*                pEId
    )
{
    DWORD           dwError = 0;
    VDIR_DB         mdbDBi = 0;
    PVDIR_DB_DBC    pCursor = NULL;
    MDB_val         key = {0};
    MDB_val         value  = {0};
    ENTRYID         eId = {0};
    unsigned char   EIDBytes[sizeof(ENTRYID)] = {0};
    VDIR_BACKEND_CTX    mdbBECtx = {0};
    BOOLEAN             bHasTxn = FALSE;

    PVDIR_MDB_DB pDB = VmDirSafeDBFromBE(pBE);

    assert(pEId && pDB);
    mdbBECtx.pBE = pBE;

    dwError = VmDirMDBTxnBegin(&mdbBECtx, VDIR_BACKEND_TXN_READ, &bHasTxn);
    BAIL_ON_VMDIR_ERROR(dwError);

    mdbDBi = pDB->mdbEntryDB.pMdbDataFiles[0].mdbDBi;

    dwError = mdb_cursor_open((PVDIR_DB_TXN)mdbBECtx.pBEPrivate, mdbDBi, &pCursor);
    BAIL_ON_VMDIR_ERROR(dwError);

    key.mv_data = &EIDBytes[0];

    if (pBE == VmDirBackendSelect(ALIAS_MAIN))
    {
       //Set cursor position equal or above LOG_ENTRY_EID_PREFIX
       // it would find the first entry id of raft log entry on legacy data
       // i.e. database creaded before we implemented a split log.
       eId = LOG_ENTRY_EID_PREFIX;
       MDBEntryIdToDBT(eId, &key);
       dwError = mdb_cursor_get(pCursor, &key, &value, MDB_SET_RANGE);
       if (dwError == MDB_NOTFOUND)
       {
           //mainDb was created after we implemented split log (no log entries in mainDb)
           // - simply find the last id which will be the last entry-id in normal entries.
           eId = 0;
           MDBEntryIdToDBT(eId, &key);
           dwError = mdb_cursor_get(pCursor, &key, &value, MDB_LAST);
           BAIL_ON_VMDIR_ERROR(dwError);

           MDBDBTToEntryId(&key, &eId);

       } else
       {
          BAIL_ON_VMDIR_ERROR(dwError);
          //Found an entry that is LOG_ENTRY_EID_PREFIX or above
          // - search backward, and the first one is the last normal entry
          do
          {
             dwError = mdb_cursor_get(pCursor, &key, &value, MDB_PREV);
             BAIL_ON_VMDIR_ERROR(dwError);

             MDBDBTToEntryId(&key, &eId);
          }
          while (eId >= LOG_ENTRY_EID_PREFIX);
       }
    } else
    {
       //For logDb, the last one is the log entry.
       eId = 0;
       MDBEntryIdToDBT(eId, &key);
       dwError = mdb_cursor_get(pCursor, &key, &value, MDB_LAST);
       BAIL_ON_VMDIR_ERROR(dwError);

       MDBDBTToEntryId(&key, &eId);
    }

    mdb_cursor_close(pCursor);
    pCursor = NULL;

    if (bHasTxn)
    {
        dwError = VmDirMDBTxnCommit(&mdbBECtx);
        bHasTxn = FALSE;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    *pEId = eId;

cleanup:
    return dwError;

error:
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
            "VmDirMDBMaxEntryId: failed with error (%d),(%s)",
             dwError, mdb_strerror(dwError) );

    mdb_cursor_close(pCursor);
    if (bHasTxn)
    {
        VmDirMDBTxnAbort(&mdbBECtx);
    }
    VMDIR_SET_BACKEND_ERROR(dwError);
    goto cleanup;
}
示例#3
0
DWORD
VmDirMDBIndexIterate(
    PVDIR_BACKEND_INDEX_ITERATOR    pIterator,
    PSTR*                           ppszVal,
    ENTRYID*                        pEId
    )
{
    DWORD   dwError = 0;
    PVDIR_MDB_INDEX_ITERATOR    pMdbIterator = NULL;
    PVDIR_DB_DBC    pCursor = NULL;
    VDIR_DB_DBT     key = {0};
    VDIR_DB_DBT     value = {0};
    PSTR            pszVal = NULL;
    ENTRYID         eId = 0;

    if (!pIterator || !ppszVal || !pEId)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    pMdbIterator = (PVDIR_MDB_INDEX_ITERATOR)pIterator->pIterator;

    pCursor = pMdbIterator->pCursor;
    if (pIterator->bHasNext)
    {
        *ppszVal = pMdbIterator->pszVal;
        *pEId = pMdbIterator->eId;

        dwError = mdb_cursor_get(pCursor, &key, &value, MDB_NEXT);
        if (dwError == 0 && *(char *)(key.mv_data) == BE_INDEX_KEY_TYPE_FWD)
        {
            dwError = VmDirAllocateMemory(key.mv_size, (PVOID*)&pszVal);
            BAIL_ON_VMDIR_ERROR(dwError);

            dwError = VmDirCopyMemory(
                    pszVal, key.mv_size, (char*)key.mv_data + 1, key.mv_size - 1);
            BAIL_ON_VMDIR_ERROR(dwError);

            MDBDBTToEntryId(&value, &eId);

            pIterator->bHasNext = TRUE;
        }
        else
        {
            pIterator->bHasNext = FALSE;
            dwError = dwError == MDB_NOTFOUND ? 0 : dwError;
            pMdbIterator->bAbort = dwError ? TRUE : FALSE;
        }
        BAIL_ON_VMDIR_ERROR(dwError);

        pMdbIterator->pszVal = pszVal;
        pMdbIterator->eId = eId;
    }

cleanup:
    return dwError;

error:
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
            "%s failed, error (%d)", __FUNCTION__, dwError );

    VMDIR_SAFE_FREE_MEMORY(pszVal);
    goto cleanup;
}