提交 1d4a569d 编写于 作者: H Hongze Cheng

Merge branch '3.0' of https://github.com/taosdata/TDengine into feat/vnode_compact

...@@ -210,7 +210,7 @@ _exit: ...@@ -210,7 +210,7 @@ _exit:
int32_t metaCacheUpsert(SMeta* pMeta, SMetaInfo* pInfo) { int32_t metaCacheUpsert(SMeta* pMeta, SMetaInfo* pInfo) {
int32_t code = 0; int32_t code = 0;
// ASSERT(metaIsWLocked(pMeta)); // meta is wlocked for calling this func.
// search // search
SMetaCache* pCache = pMeta->pCache; SMetaCache* pCache = pMeta->pCache;
...@@ -221,7 +221,10 @@ int32_t metaCacheUpsert(SMeta* pMeta, SMetaInfo* pInfo) { ...@@ -221,7 +221,10 @@ int32_t metaCacheUpsert(SMeta* pMeta, SMetaInfo* pInfo) {
} }
if (*ppEntry) { // update if (*ppEntry) { // update
ASSERT(pInfo->suid == (*ppEntry)->info.suid); if (pInfo->suid != (*ppEntry)->info.suid) {
metaError("meta/cache: suid should be same as the one in cache.");
return TSDB_CODE_FAILED;
}
if (pInfo->version > (*ppEntry)->info.version) { if (pInfo->version > (*ppEntry)->info.version) {
(*ppEntry)->info.version = pInfo->version; (*ppEntry)->info.version = pInfo->version;
(*ppEntry)->info.skmVer = pInfo->skmVer; (*ppEntry)->info.skmVer = pInfo->skmVer;
...@@ -340,7 +343,7 @@ _exit: ...@@ -340,7 +343,7 @@ _exit:
int32_t metaStatsCacheUpsert(SMeta* pMeta, SMetaStbStats* pInfo) { int32_t metaStatsCacheUpsert(SMeta* pMeta, SMetaStbStats* pInfo) {
int32_t code = 0; int32_t code = 0;
// ASSERT(metaIsWLocked(pMeta)); // meta is wlocked for calling this func.
// search // search
SMetaCache* pCache = pMeta->pCache; SMetaCache* pCache = pMeta->pCache;
...@@ -449,7 +452,11 @@ int32_t metaGetCachedTableUidList(SMeta* pMeta, tb_uid_t suid, const uint8_t* pK ...@@ -449,7 +452,11 @@ int32_t metaGetCachedTableUidList(SMeta* pMeta, tb_uid_t suid, const uint8_t* pK
// do some book mark work after acquiring the filter result from cache // do some book mark work after acquiring the filter result from cache
STagFilterResEntry** pEntry = taosHashGet(pTableMap, &suid, sizeof(uint64_t)); STagFilterResEntry** pEntry = taosHashGet(pTableMap, &suid, sizeof(uint64_t));
ASSERT(pEntry != NULL); if (NULL == pEntry) {
metaError("meta/cache: pEntry should not be NULL.");
return TSDB_CODE_FAILED;
}
*acquireRes = 1; *acquireRes = 1;
const char* p = taosLRUCacheValue(pCache, pHandle); const char* p = taosLRUCacheValue(pCache, pHandle);
...@@ -494,7 +501,7 @@ int32_t metaGetCachedTableUidList(SMeta* pMeta, tb_uid_t suid, const uint8_t* pK ...@@ -494,7 +501,7 @@ int32_t metaGetCachedTableUidList(SMeta* pMeta, tb_uid_t suid, const uint8_t* pK
taosMemoryFree(*p1); taosMemoryFree(*p1);
} }
atomic_store_32(&(*pEntry)->qTimes, 0); // reset the query times atomic_store_32(&(*pEntry)->qTimes, 0); // reset the query times
taosArrayDestroy(pInvalidRes); taosArrayDestroy(pInvalidRes);
taosThreadMutexUnlock(pLock); taosThreadMutexUnlock(pLock);
...@@ -550,7 +557,10 @@ int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int ...@@ -550,7 +557,10 @@ int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int
buf[0] = suid; buf[0] = suid;
memcpy(&buf[1], pKey, keyLen); memcpy(&buf[1], pKey, keyLen);
ASSERT(sizeof(uint64_t) + keyLen == 24); if (sizeof(uint64_t) + keyLen != 24) {
metaError("meta/cache: incorrect keyLen:%" PRId32 " length.", keyLen);
return TSDB_CODE_FAILED;
}
// add to cache. // add to cache.
taosLRUCacheInsert(pCache, buf, sizeof(uint64_t) + keyLen, pPayload, payloadLen, freePayload, NULL, taosLRUCacheInsert(pCache, buf, sizeof(uint64_t) + keyLen, pPayload, payloadLen, freePayload, NULL,
......
...@@ -51,7 +51,9 @@ int metaEncodeEntry(SEncoder *pCoder, const SMetaEntry *pME) { ...@@ -51,7 +51,9 @@ int metaEncodeEntry(SEncoder *pCoder, const SMetaEntry *pME) {
} else if (pME->type == TSDB_TSMA_TABLE) { } else if (pME->type == TSDB_TSMA_TABLE) {
if (tEncodeTSma(pCoder, pME->smaEntry.tsma) < 0) return -1; if (tEncodeTSma(pCoder, pME->smaEntry.tsma) < 0) return -1;
} else { } else {
ASSERT(0); metaError("meta/entry: invalide table type: %" PRId8 " encode failed.", pME->type);
return -1;
} }
tEndEncode(pCoder); tEndEncode(pCoder);
...@@ -99,7 +101,9 @@ int metaDecodeEntry(SDecoder *pCoder, SMetaEntry *pME) { ...@@ -99,7 +101,9 @@ int metaDecodeEntry(SDecoder *pCoder, SMetaEntry *pME) {
} }
if (tDecodeTSma(pCoder, pME->smaEntry.tsma, true) < 0) return -1; if (tDecodeTSma(pCoder, pME->smaEntry.tsma, true) < 0) return -1;
} else { } else {
ASSERT(0); metaError("meta/entry: invalide table type: %" PRId8 " decode failed.", pME->type);
return -1;
} }
tEndDecode(pCoder); tEndDecode(pCoder);
......
...@@ -358,7 +358,10 @@ static int tagIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kL ...@@ -358,7 +358,10 @@ static int tagIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kL
return -1; return -1;
} }
ASSERT(pTagIdxKey1->type == pTagIdxKey2->type); if (pTagIdxKey1->type != pTagIdxKey2->type) {
metaError("meta/open: incorrect tag idx type.");
return TSDB_CODE_FAILED;
}
// check NULL, NULL is always the smallest // check NULL, NULL is always the smallest
if (pTagIdxKey1->isNull && !pTagIdxKey2->isNull) { if (pTagIdxKey1->isNull && !pTagIdxKey2->isNull) {
......
...@@ -652,7 +652,11 @@ int32_t metaGetTbTSchemaEx(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sv ...@@ -652,7 +652,11 @@ int32_t metaGetTbTSchemaEx(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sv
goto _exit; goto _exit;
} }
ASSERT(c); if (c == 0) {
metaError("meta/query: incorrect c: %" PRId32 ".", c);
code = TSDB_CODE_FAILED;
goto _exit;
}
if (c < 0) { if (c < 0) {
tdbTbcMoveToPrev(pSkmDbC); tdbTbcMoveToPrev(pSkmDbC);
...@@ -676,7 +680,11 @@ int32_t metaGetTbTSchemaEx(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sv ...@@ -676,7 +680,11 @@ int32_t metaGetTbTSchemaEx(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sv
} }
} }
ASSERT(sver > 0); if (sver <= 0) {
metaError("meta/query: incorrect sver: %" PRId32 ".", sver);
code = TSDB_CODE_FAILED;
goto _exit;
}
skmDbKey.uid = suid ? suid : uid; skmDbKey.uid = suid ? suid : uid;
skmDbKey.sver = sver; skmDbKey.sver = sver;
......
...@@ -100,7 +100,10 @@ int32_t metaSnapRead(SMetaSnapReader* pReader, uint8_t** ppData) { ...@@ -100,7 +100,10 @@ int32_t metaSnapRead(SMetaSnapReader* pReader, uint8_t** ppData) {
break; break;
} }
ASSERT(pData && nData); if (!pData || !nData) {
metaError("meta/snap: invalide nData: %" PRId32 " meta snap read failed.", nData);
goto _exit;
}
*ppData = taosMemoryMalloc(sizeof(SSnapDataHdr) + nData); *ppData = taosMemoryMalloc(sizeof(SSnapDataHdr) + nData);
if (*ppData == NULL) { if (*ppData == NULL) {
...@@ -356,7 +359,11 @@ int32_t buildSnapContext(SMeta* pMeta, int64_t snapVersion, int64_t suid, int8_t ...@@ -356,7 +359,11 @@ int32_t buildSnapContext(SMeta* pMeta, int64_t snapVersion, int64_t suid, int8_t
for (int i = 0; i < taosArrayGetSize(ctx->idList); i++) { for (int i = 0; i < taosArrayGetSize(ctx->idList); i++) {
int64_t* uid = taosArrayGet(ctx->idList, i); int64_t* uid = taosArrayGet(ctx->idList, i);
SIdInfo* idData = (SIdInfo*)taosHashGet(ctx->idVersion, uid, sizeof(int64_t)); SIdInfo* idData = (SIdInfo*)taosHashGet(ctx->idVersion, uid, sizeof(int64_t));
ASSERT(idData); if (!idData) {
metaError("meta/snap: null idData");
return TSDB_CODE_FAILED;
}
idData->index = i; idData->index = i;
metaDebug("tmqsnap init idVersion uid:%" PRIi64 " version:%" PRIi64 " index:%d", *uid, idData->version, metaDebug("tmqsnap init idVersion uid:%" PRIi64 " version:%" PRIi64 " index:%d", *uid, idData->version,
idData->index); idData->index);
...@@ -473,7 +480,10 @@ int32_t getMetafromSnapShot(SSnapContext* ctx, void** pBuf, int32_t* contLen, in ...@@ -473,7 +480,10 @@ int32_t getMetafromSnapShot(SSnapContext* ctx, void** pBuf, int32_t* contLen, in
int64_t* uidTmp = taosArrayGet(ctx->idList, ctx->index); int64_t* uidTmp = taosArrayGet(ctx->idList, ctx->index);
ctx->index++; ctx->index++;
SIdInfo* idInfo = (SIdInfo*)taosHashGet(ctx->idVersion, uidTmp, sizeof(tb_uid_t)); SIdInfo* idInfo = (SIdInfo*)taosHashGet(ctx->idVersion, uidTmp, sizeof(tb_uid_t));
ASSERT(idInfo); if (!idInfo) {
metaError("meta/snap: null idInfo");
return TSDB_CODE_FAILED;
}
*uid = *uidTmp; *uid = *uidTmp;
ret = MoveToPosition(ctx, idInfo->version, *uidTmp); ret = MoveToPosition(ctx, idInfo->version, *uidTmp);
...@@ -507,7 +517,11 @@ int32_t getMetafromSnapShot(SSnapContext* ctx, void** pBuf, int32_t* contLen, in ...@@ -507,7 +517,11 @@ int32_t getMetafromSnapShot(SSnapContext* ctx, void** pBuf, int32_t* contLen, in
(ctx->subType == TOPIC_SUB_TYPE__TABLE && me.type == TSDB_CHILD_TABLE && me.ctbEntry.suid == ctx->suid)) { (ctx->subType == TOPIC_SUB_TYPE__TABLE && me.type == TSDB_CHILD_TABLE && me.ctbEntry.suid == ctx->suid)) {
STableInfoForChildTable* data = STableInfoForChildTable* data =
(STableInfoForChildTable*)taosHashGet(ctx->suidInfo, &me.ctbEntry.suid, sizeof(tb_uid_t)); (STableInfoForChildTable*)taosHashGet(ctx->suidInfo, &me.ctbEntry.suid, sizeof(tb_uid_t));
ASSERT(data); if (!data) {
metaError("meta/snap: null data");
return TSDB_CODE_FAILED;
}
SVCreateTbReq req = {0}; SVCreateTbReq req = {0};
req.type = TSDB_CHILD_TABLE; req.type = TSDB_CHILD_TABLE;
...@@ -528,7 +542,8 @@ int32_t getMetafromSnapShot(SSnapContext* ctx, void** pBuf, int32_t* contLen, in ...@@ -528,7 +542,8 @@ int32_t getMetafromSnapShot(SSnapContext* ctx, void** pBuf, int32_t* contLen, in
} else { } else {
SArray* pTagVals = NULL; SArray* pTagVals = NULL;
if (tTagToValArray((const STag*)p, &pTagVals) != 0) { if (tTagToValArray((const STag*)p, &pTagVals) != 0) {
ASSERT(0); metaError("meta/snap: tag to val array failed.");
return TSDB_CODE_FAILED;
} }
int16_t nCols = taosArrayGetSize(pTagVals); int16_t nCols = taosArrayGetSize(pTagVals);
for (int j = 0; j < nCols; ++j) { for (int j = 0; j < nCols; ++j) {
...@@ -572,7 +587,8 @@ int32_t getMetafromSnapShot(SSnapContext* ctx, void** pBuf, int32_t* contLen, in ...@@ -572,7 +587,8 @@ int32_t getMetafromSnapShot(SSnapContext* ctx, void** pBuf, int32_t* contLen, in
ret = buildNormalChildTableInfo(&req, pBuf, contLen); ret = buildNormalChildTableInfo(&req, pBuf, contLen);
*type = TDMT_VND_CREATE_TABLE; *type = TDMT_VND_CREATE_TABLE;
} else { } else {
ASSERT(0); metaError("meta/snap: invalid topic sub type: %" PRId8 " get meta from snap failed.", ctx->subType);
ret = -1;
} }
tDecoderClear(&dc); tDecoderClear(&dc);
...@@ -593,7 +609,10 @@ SMetaTableInfo getUidfromSnapShot(SSnapContext* ctx) { ...@@ -593,7 +609,10 @@ SMetaTableInfo getUidfromSnapShot(SSnapContext* ctx) {
int64_t* uidTmp = taosArrayGet(ctx->idList, ctx->index); int64_t* uidTmp = taosArrayGet(ctx->idList, ctx->index);
ctx->index++; ctx->index++;
SIdInfo* idInfo = (SIdInfo*)taosHashGet(ctx->idVersion, uidTmp, sizeof(tb_uid_t)); SIdInfo* idInfo = (SIdInfo*)taosHashGet(ctx->idVersion, uidTmp, sizeof(tb_uid_t));
ASSERT(idInfo); if (!idInfo) {
metaError("meta/snap: null idInfo");
return result;
}
int32_t ret = MoveToPosition(ctx, idInfo->version, *uidTmp); int32_t ret = MoveToPosition(ctx, idInfo->version, *uidTmp);
if (ret != 0) { if (ret != 0) {
......
...@@ -46,7 +46,7 @@ static void metaGetEntryInfo(const SMetaEntry *pEntry, SMetaInfo *pInfo) { ...@@ -46,7 +46,7 @@ static void metaGetEntryInfo(const SMetaEntry *pEntry, SMetaInfo *pInfo) {
pInfo->suid = 0; pInfo->suid = 0;
pInfo->skmVer = pEntry->ntbEntry.schemaRow.version; pInfo->skmVer = pEntry->ntbEntry.schemaRow.version;
} else { } else {
ASSERT(0); metaError("meta/table: invalide table type: %" PRId8 " get entry info failed.", pEntry->type);
} }
} }
...@@ -342,10 +342,18 @@ int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) { ...@@ -342,10 +342,18 @@ int metaAlterSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL); tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL);
ret = tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = pReq->suid, .version = oversion}), sizeof(STbDbKey), &c); ret = tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = pReq->suid, .version = oversion}), sizeof(STbDbKey), &c);
ASSERT(ret == 0 && c == 0); if (!(ret == 0 && c == 0)) {
metaError("meta/table: invalide ret: %" PRId32 " or c: %" PRId32 "alter stb failed.", ret, c);
return -1;
}
ret = tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData); ret = tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
ASSERT(ret == 0); if (ret < 0) {
tdbTbcClose(pTbDbc);
terrno = TSDB_CODE_TDB_STB_NOT_EXIST;
return -1;
}
oStbEntry.pBuf = taosMemoryMalloc(nData); oStbEntry.pBuf = taosMemoryMalloc(nData);
memcpy(oStbEntry.pBuf, pData, nData); memcpy(oStbEntry.pBuf, pData, nData);
...@@ -558,7 +566,8 @@ static void metaBuildTtlIdxKey(STtlIdxKey *ttlKey, const SMetaEntry *pME) { ...@@ -558,7 +566,8 @@ static void metaBuildTtlIdxKey(STtlIdxKey *ttlKey, const SMetaEntry *pME) {
ctime = pME->ntbEntry.ctime; ctime = pME->ntbEntry.ctime;
ttlDays = pME->ntbEntry.ttlDays; ttlDays = pME->ntbEntry.ttlDays;
} else { } else {
ASSERT(0); metaError("meta/table: invalide table type: %" PRId8 " build ttl idx key failed.", pME->type);
return;
} }
if (ttlDays <= 0) return; if (ttlDays <= 0) return;
...@@ -773,7 +782,10 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl ...@@ -773,7 +782,10 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl
tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL); tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL);
tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c); tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
ASSERT(c == 0); if (c != 0) {
metaError("meta/table: invalide c: %" PRId32 " alt tb column failed.", c);
return -1;
}
tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData); tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
oversion = ((SUidIdxVal *)pData)[0].version; oversion = ((SUidIdxVal *)pData)[0].version;
...@@ -783,7 +795,11 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl ...@@ -783,7 +795,11 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl
tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL); tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL);
tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c); tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
ASSERT(c == 0); if (c != 0) {
metaError("meta/table: invalide c: %" PRId32 " alt tb column failed.", c);
return -1;
}
tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData); tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
// get table entry // get table entry
...@@ -792,7 +808,11 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl ...@@ -792,7 +808,11 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl
memcpy(entry.pBuf, pData, nData); memcpy(entry.pBuf, pData, nData);
tDecoderInit(&dc, entry.pBuf, nData); tDecoderInit(&dc, entry.pBuf, nData);
ret = metaDecodeEntry(&dc, &entry); ret = metaDecodeEntry(&dc, &entry);
ASSERT(ret == 0); if (ret != 0) {
tDecoderClear(&dc);
metaError("meta/table: invalide ret: %" PRId32 " alt tb column failed.", ret);
return -1;
}
if (entry.type != TSDB_NORMAL_TABLE) { if (entry.type != TSDB_NORMAL_TABLE) {
terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION; terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
...@@ -812,7 +832,11 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl ...@@ -812,7 +832,11 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl
if (iCol >= pSchema->nCols) break; if (iCol >= pSchema->nCols) break;
pColumn = &pSchema->pSchema[iCol]; pColumn = &pSchema->pSchema[iCol];
ASSERT(pAlterTbReq->colName); if (NULL == pAlterTbReq->colName) {
metaError("meta/table: null pAlterTbReq->colName");
return -1;
}
if (strcmp(pColumn->name, pAlterTbReq->colName) == 0) break; if (strcmp(pColumn->name, pAlterTbReq->colName) == 0) break;
iCol++; iCol++;
} }
...@@ -964,7 +988,10 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA ...@@ -964,7 +988,10 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL); tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL);
tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c); tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
ASSERT(c == 0); if (c != 0) {
metaError("meta/table: invalide c: %" PRId32 " update tb tag val failed.", c);
return -1;
}
tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData); tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
oversion = ((SUidIdxVal *)pData)[0].version; oversion = ((SUidIdxVal *)pData)[0].version;
...@@ -977,7 +1004,11 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA ...@@ -977,7 +1004,11 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
/* get ctbEntry */ /* get ctbEntry */
tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL); tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL);
tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c); tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
ASSERT(c == 0); if (c != 0) {
metaError("meta/table: invalide c: %" PRId32 " update tb tag val failed.", c);
return -1;
}
tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData); tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
ctbEntry.pBuf = taosMemoryMalloc(nData); ctbEntry.pBuf = taosMemoryMalloc(nData);
...@@ -1075,7 +1106,11 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA ...@@ -1075,7 +1106,11 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA
metaUpdateTagIdx(pMeta, &ctbEntry); metaUpdateTagIdx(pMeta, &ctbEntry);
} }
ASSERT(ctbEntry.ctbEntry.pTags); if (NULL == ctbEntry.ctbEntry.pTags) {
metaError("meta/table: null tags, update tag val failed.");
goto _err;
}
SCtbIdxKey ctbIdxKey = {.suid = ctbEntry.ctbEntry.suid, .uid = uid}; SCtbIdxKey ctbIdxKey = {.suid = ctbEntry.ctbEntry.suid, .uid = uid};
tdbTbUpsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), ctbEntry.ctbEntry.pTags, tdbTbUpsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), ctbEntry.ctbEntry.pTags,
((STag *)(ctbEntry.ctbEntry.pTags))->len, pMeta->txn); ((STag *)(ctbEntry.ctbEntry.pTags))->len, pMeta->txn);
...@@ -1130,7 +1165,10 @@ static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *p ...@@ -1130,7 +1165,10 @@ static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *p
tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL); tdbTbcOpen(pMeta->pUidIdx, &pUidIdxc, NULL);
tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c); tdbTbcMoveTo(pUidIdxc, &uid, sizeof(uid), &c);
ASSERT(c == 0); if (c != 0) {
metaError("meta/table: invalide c: %" PRId32 " update tb options failed.", c);
return -1;
}
tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData); tdbTbcGet(pUidIdxc, NULL, NULL, &pData, &nData);
oversion = ((SUidIdxVal *)pData)[0].version; oversion = ((SUidIdxVal *)pData)[0].version;
...@@ -1140,7 +1178,11 @@ static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *p ...@@ -1140,7 +1178,11 @@ static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *p
tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL); tdbTbcOpen(pMeta->pTbDb, &pTbDbc, NULL);
tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c); tdbTbcMoveTo(pTbDbc, &((STbDbKey){.uid = uid, .version = oversion}), sizeof(STbDbKey), &c);
ASSERT(c == 0); if (c != 0) {
metaError("meta/table: invalide c: %" PRId32 " update tb options failed.", c);
return -1;
}
tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData); tdbTbcGet(pTbDbc, NULL, NULL, &pData, &nData);
// get table entry // get table entry
...@@ -1149,7 +1191,11 @@ static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *p ...@@ -1149,7 +1191,11 @@ static int metaUpdateTableOptions(SMeta *pMeta, int64_t version, SVAlterTbReq *p
memcpy(entry.pBuf, pData, nData); memcpy(entry.pBuf, pData, nData);
tDecoderInit(&dc, entry.pBuf, nData); tDecoderInit(&dc, entry.pBuf, nData);
ret = metaDecodeEntry(&dc, &entry); ret = metaDecodeEntry(&dc, &entry);
ASSERT(ret == 0); if (ret != 0) {
tDecoderClear(&dc);
metaError("meta/table: invalide ret: %" PRId32 " alt tb options failed.", ret);
return -1;
}
entry.version = version; entry.version = version;
metaWLock(pMeta); metaWLock(pMeta);
...@@ -1408,7 +1454,8 @@ static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME) { ...@@ -1408,7 +1454,8 @@ static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME) {
} else if (pME->type == TSDB_NORMAL_TABLE) { } else if (pME->type == TSDB_NORMAL_TABLE) {
pSW = &pME->ntbEntry.schemaRow; pSW = &pME->ntbEntry.schemaRow;
} else { } else {
ASSERT(0); metaError("meta/table: invalide table type: %" PRId8 " save skm db failed.", pME->type);
return TSDB_CODE_FAILED;
} }
skmDbKey.uid = pME->uid; skmDbKey.uid = pME->uid;
......
...@@ -74,7 +74,10 @@ int tdbBtreeOpen(int keyLen, int valLen, SPager *pPager, char const *tbname, SPg ...@@ -74,7 +74,10 @@ int tdbBtreeOpen(int keyLen, int valLen, SPager *pPager, char const *tbname, SPg
SBTree *pBt; SBTree *pBt;
int ret; int ret;
ASSERT(keyLen != 0); if (keyLen == 0) {
tdbError("tdb/btree-open: key len cannot be zero.");
return -1;
}
*ppBt = NULL; *ppBt = NULL;
...@@ -152,7 +155,11 @@ int tdbBtreeOpen(int keyLen, int valLen, SPager *pPager, char const *tbname, SPg ...@@ -152,7 +155,11 @@ int tdbBtreeOpen(int keyLen, int valLen, SPager *pPager, char const *tbname, SPg
tdbPostCommit(pPager->pEnv, txn); tdbPostCommit(pPager->pEnv, txn);
} }
ASSERT(pgno != 0); if (pgno == 0) {
tdbError("tdb/btree-open: pgno cannot be zero.");
tdbOsFree(pBt);
return -1;
}
pBt->root = pgno; pBt->root = pgno;
/* /*
// TODO: pBt->root // TODO: pBt->root
...@@ -192,7 +199,7 @@ int tdbBtreeInsert(SBTree *pBt, const void *pKey, int kLen, const void *pVal, in ...@@ -192,7 +199,7 @@ int tdbBtreeInsert(SBTree *pBt, const void *pKey, int kLen, const void *pVal, in
ret = tdbBtcMoveTo(&btc, pKey, kLen, &c); ret = tdbBtcMoveTo(&btc, pKey, kLen, &c);
if (ret < 0) { if (ret < 0) {
tdbBtcClose(&btc); tdbBtcClose(&btc);
ASSERT(0); tdbError("tdb/btree-insert: btc move to failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -202,17 +209,17 @@ int tdbBtreeInsert(SBTree *pBt, const void *pKey, int kLen, const void *pVal, in ...@@ -202,17 +209,17 @@ int tdbBtreeInsert(SBTree *pBt, const void *pKey, int kLen, const void *pVal, in
if (c > 0) { if (c > 0) {
btc.idx++; btc.idx++;
} else if (c == 0) { } else if (c == 0) {
// dup key not allowed // dup key not allowed with insert
tdbError("unable to insert dup key. pKey: %p, kLen: %d, btc: %p, pTxn: %p", pKey, kLen, &btc, pTxn); tdbBtcClose(&btc);
// ASSERT(0); tdbError("tdb/btree-insert: dup key. pKey: %p, kLen: %d, btc: %p, pTxn: %p", pKey, kLen, &btc, pTxn);
return -1; return -1;
} }
} }
ret = tdbBtcUpsert(&btc, pKey, kLen, pVal, vLen, 1); ret = tdbBtcUpsert(&btc, pKey, kLen, pVal, vLen, 1);
if (ret < 0) { if (ret < 0) {
ASSERT(0);
tdbBtcClose(&btc); tdbBtcClose(&btc);
tdbError("tdb/btree-insert: btc upsert failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -233,7 +240,7 @@ int tdbBtreeDelete(SBTree *pBt, const void *pKey, int kLen, TXN *pTxn) { ...@@ -233,7 +240,7 @@ int tdbBtreeDelete(SBTree *pBt, const void *pKey, int kLen, TXN *pTxn) {
ret = tdbBtcMoveTo(&btc, pKey, kLen, &c); ret = tdbBtcMoveTo(&btc, pKey, kLen, &c);
if (ret < 0) { if (ret < 0) {
tdbBtcClose(&btc); tdbBtcClose(&btc);
ASSERT(0); tdbError("tdb/btree-delete: btc move to failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -264,7 +271,7 @@ int tdbBtreeUpsert(SBTree *pBt, const void *pKey, int nKey, const void *pData, i ...@@ -264,7 +271,7 @@ int tdbBtreeUpsert(SBTree *pBt, const void *pKey, int nKey, const void *pData, i
// move the cursor // move the cursor
ret = tdbBtcMoveTo(&btc, pKey, nKey, &c); ret = tdbBtcMoveTo(&btc, pKey, nKey, &c);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btree-upsert: btc move to failed with ret: %d.", ret);
tdbBtcClose(&btc); tdbBtcClose(&btc);
return -1; return -1;
} }
...@@ -280,8 +287,8 @@ int tdbBtreeUpsert(SBTree *pBt, const void *pKey, int nKey, const void *pData, i ...@@ -280,8 +287,8 @@ int tdbBtreeUpsert(SBTree *pBt, const void *pKey, int nKey, const void *pData, i
ret = tdbBtcUpsert(&btc, pKey, nKey, pData, nData, c); ret = tdbBtcUpsert(&btc, pKey, nKey, pData, nData, c);
if (ret < 0) { if (ret < 0) {
ASSERT(0);
tdbBtcClose(&btc); tdbBtcClose(&btc);
tdbError("tdb/btree-upsert: btc upsert failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -309,7 +316,8 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL ...@@ -309,7 +316,8 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL
ret = tdbBtcMoveTo(&btc, pKey, kLen, &cret); ret = tdbBtcMoveTo(&btc, pKey, kLen, &cret);
if (ret < 0) { if (ret < 0) {
tdbBtcClose(&btc); tdbBtcClose(&btc);
ASSERT(0); tdbError("tdb/btree-pget: btc move to failed with ret: %d.", ret);
return -1;
} }
if (btc.idx < 0 || cret) { if (btc.idx < 0 || cret) {
...@@ -325,7 +333,7 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL ...@@ -325,7 +333,7 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL
pTKey = tdbRealloc(*ppKey, cd.kLen); pTKey = tdbRealloc(*ppKey, cd.kLen);
if (pTKey == NULL) { if (pTKey == NULL) {
tdbBtcClose(&btc); tdbBtcClose(&btc);
ASSERT(0); tdbError("tdb/btree-pget: realloc pTKey failed.");
return -1; return -1;
} }
*ppKey = pTKey; *ppKey = pTKey;
...@@ -337,7 +345,7 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL ...@@ -337,7 +345,7 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL
pTVal = tdbRealloc(*ppVal, cd.vLen); pTVal = tdbRealloc(*ppVal, cd.vLen);
if (pTVal == NULL) { if (pTVal == NULL) {
tdbBtcClose(&btc); tdbBtcClose(&btc);
ASSERT(0); tdbError("tdb/btree-pget: realloc pTVal failed.");
return -1; return -1;
} }
*ppVal = pTVal; *ppVal = pTVal;
...@@ -350,7 +358,7 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL ...@@ -350,7 +358,7 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL
} }
if (TDB_CELLDECODER_FREE_VAL(&cd)) { if (TDB_CELLDECODER_FREE_VAL(&cd)) {
tdbDebug("tdb btc/pget/2 decoder: %p pVal free: %p", &cd, cd.pVal); tdbTrace("tdb btc/pget/2 decoder: %p pVal free: %p", &cd, cd.pVal);
tdbFree(cd.pVal); tdbFree(cd.pVal);
} }
...@@ -366,7 +374,9 @@ static int tdbDefaultKeyCmprFn(const void *pKey1, int keyLen1, const void *pKey2 ...@@ -366,7 +374,9 @@ static int tdbDefaultKeyCmprFn(const void *pKey1, int keyLen1, const void *pKey2
int mlen; int mlen;
int cret; int cret;
ASSERT(keyLen1 > 0 && keyLen2 > 0 && pKey1 != NULL && pKey2 != NULL); if (ASSERT(keyLen1 > 0 && keyLen2 > 0 && pKey1 != NULL && pKey2 != NULL)) {
// -1 is less than
}
mlen = keyLen1 < keyLen2 ? keyLen1 : keyLen2; mlen = keyLen1 < keyLen2 ? keyLen1 : keyLen2;
cret = memcmp(pKey1, pKey2, mlen); cret = memcmp(pKey1, pKey2, mlen);
...@@ -381,36 +391,7 @@ static int tdbDefaultKeyCmprFn(const void *pKey1, int keyLen1, const void *pKey2 ...@@ -381,36 +391,7 @@ static int tdbDefaultKeyCmprFn(const void *pKey1, int keyLen1, const void *pKey2
} }
return cret; return cret;
} }
/*
static int tdbBtreeOpenImpl(SBTree *pBt) {
// Try to get the root page of the an existing btree
SPgno pgno;
SPage *pPage;
int ret;
{
// 1. TODO: Search the main DB to check if the DB exists
ret = tdbPagerOpenDB(pBt->pPager, &pgno, true, pBt);
ASSERT(ret == 0);
}
if (pgno != 0) {
pBt->root = pgno;
return 0;
}
// Try to create a new database
ret = tdbPagerAllocPage(pBt->pPager, &pgno);
if (ret < 0) {
ASSERT(0);
return -1;
}
ASSERT(pgno != 0);
pBt->root = pgno;
return 0;
}
*/
int tdbBtreeInitPage(SPage *pPage, void *arg, int init) { int tdbBtreeInitPage(SPage *pPage, void *arg, int init) {
SBTree *pBt; SBTree *pBt;
u8 flags; u8 flags;
...@@ -546,11 +527,15 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx ...@@ -546,11 +527,15 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
nOlds = 3; nOlds = 3;
} }
for (int i = 0; i < nOlds; i++) { for (int i = 0; i < nOlds; i++) {
ASSERT(sIdx + i <= nCells); if (ASSERT(sIdx + i <= nCells)) {
return -1;
}
SPgno pgno; SPgno pgno;
if (sIdx + i == nCells) { if (sIdx + i == nCells) {
ASSERT(!TDB_BTREE_PAGE_IS_LEAF(pParent)); if (ASSERT(!TDB_BTREE_PAGE_IS_LEAF(pParent))) {
return -1;
}
pgno = ((SIntHdr *)(pParent->pData))->pgno; pgno = ((SIntHdr *)(pParent->pData))->pgno;
} else { } else {
pCell = tdbPageGetCell(pParent, sIdx + i); pCell = tdbPageGetCell(pParent, sIdx + i);
...@@ -560,7 +545,7 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx ...@@ -560,7 +545,7 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
ret = tdbPagerFetchPage(pBt->pPager, &pgno, pOlds + i, tdbBtreeInitPage, ret = tdbPagerFetchPage(pBt->pPager, &pgno, pOlds + i, tdbBtreeInitPage,
&((SBtreeInitPageArg){.pBt = pBt, .flags = 0}), pTxn); &((SBtreeInitPageArg){.pBt = pBt, .flags = 0}), pTxn);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btree-balance: fetch page failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -679,7 +664,9 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx ...@@ -679,7 +664,9 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
szRCell = tdbBtreeCellSize(pPage, pCell, 0, NULL, NULL); szRCell = tdbBtreeCellSize(pPage, pCell, 0, NULL, NULL);
} }
ASSERT(infoNews[iNew - 1].cnt > 0); if (ASSERT(infoNews[iNew - 1].cnt > 0)) {
return -1;
}
if (infoNews[iNew].size + szRCell >= infoNews[iNew - 1].size - szRCell) { if (infoNews[iNew].size + szRCell >= infoNews[iNew - 1].size - szRCell) {
break; break;
...@@ -722,7 +709,8 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx ...@@ -722,7 +709,8 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
iarg.flags = flags; iarg.flags = flags;
ret = tdbPagerFetchPage(pBt->pPager, &pgno, pNews + iNew, tdbBtreeInitPage, &iarg, pTxn); ret = tdbPagerFetchPage(pBt->pPager, &pgno, pNews + iNew, tdbBtreeInitPage, &iarg, pTxn);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btree-balance: fetch page failed with ret: %d.", ret);
return -1;
} }
ret = tdbPagerWrite(pBt->pPager, pNews[iNew]); ret = tdbPagerWrite(pBt->pPager, pNews[iNew]);
...@@ -766,8 +754,12 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx ...@@ -766,8 +754,12 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
pCell = tdbPageGetCell(pPage, oIdx); pCell = tdbPageGetCell(pPage, oIdx);
szCell = tdbBtreeCellSize(pPage, pCell, 0, NULL, NULL); szCell = tdbBtreeCellSize(pPage, pCell, 0, NULL, NULL);
ASSERT(nNewCells <= infoNews[iNew].cnt); if (ASSERT(nNewCells <= infoNews[iNew].cnt)) {
ASSERT(iNew < nNews); return -1;
}
if (ASSERT(iNew < nNews)) {
return -1;
}
if (nNewCells < infoNews[iNew].cnt) { if (nNewCells < infoNews[iNew].cnt) {
tdbPageInsertCell(pNews[iNew], nNewCells, pCell, szCell, 0); tdbPageInsertCell(pNews[iNew], nNewCells, pCell, szCell, 0);
...@@ -806,14 +798,20 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx ...@@ -806,14 +798,20 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
} }
} }
} else { } else {
ASSERT(childNotLeaf); if (ASSERT(childNotLeaf)) {
ASSERT(iNew < nNews - 1); return -1;
}
if (ASSERT(iNew < nNews - 1)) {
return -1;
}
// set current new page right-most child // set current new page right-most child
((SIntHdr *)pNews[iNew]->pData)->pgno = ((SPgno *)pCell)[0]; ((SIntHdr *)pNews[iNew]->pData)->pgno = ((SPgno *)pCell)[0];
// insert to parent as divider cell // insert to parent as divider cell
ASSERT(iNew < nNews - 1); if (ASSERT(iNew < nNews - 1)) {
return -1;
}
((SPgno *)pCell)[0] = TDB_PAGE_PGNO(pNews[iNew]); ((SPgno *)pCell)[0] = TDB_PAGE_PGNO(pNews[iNew]);
tdbPageInsertCell(pParent, sIdx++, pCell, szCell, 0); tdbPageInsertCell(pParent, sIdx++, pCell, szCell, 0);
...@@ -828,7 +826,9 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx ...@@ -828,7 +826,9 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
} }
if (childNotLeaf) { if (childNotLeaf) {
ASSERT(TDB_PAGE_TOTAL_CELLS(pNews[nNews - 1]) == infoNews[nNews - 1].cnt); if (ASSERT(TDB_PAGE_TOTAL_CELLS(pNews[nNews - 1]) == infoNews[nNews - 1].cnt)) {
return -1;
}
((SIntHdr *)(pNews[nNews - 1]->pData))->pgno = rPgno; ((SIntHdr *)(pNews[nNews - 1]->pData))->pgno = rPgno;
SIntHdr *pIntHdr = (SIntHdr *)pParent->pData; SIntHdr *pIntHdr = (SIntHdr *)pParent->pData;
...@@ -1018,7 +1018,9 @@ static int tdbBtreeEncodePayload(SPage *pPage, SCell *pCell, int nHeader, const ...@@ -1018,7 +1018,9 @@ static int tdbBtreeEncodePayload(SPage *pPage, SCell *pCell, int nHeader, const
nLeft -= kLen; nLeft -= kLen;
// pack partial val to local if any space left // pack partial val to local if any space left
if (nLocal > nHeader + kLen + sizeof(SPgno)) { if (nLocal > nHeader + kLen + sizeof(SPgno)) {
ASSERT(pVal != NULL && vLen != 0); if (ASSERT(pVal != NULL && vLen != 0)) {
return -1;
}
memcpy(pCell + nHeader + kLen, pVal, nLocal - nHeader - kLen - sizeof(SPgno)); memcpy(pCell + nHeader + kLen, pVal, nLocal - nHeader - kLen - sizeof(SPgno));
nLeft -= nLocal - nHeader - kLen - sizeof(SPgno); nLeft -= nLocal - nHeader - kLen - sizeof(SPgno);
} }
...@@ -1180,9 +1182,15 @@ static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const vo ...@@ -1180,9 +1182,15 @@ static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const vo
int nPayload; int nPayload;
int ret; int ret;
ASSERT(pPage->kLen == TDB_VARIANT_LEN || pPage->kLen == kLen); if (ASSERT(pPage->kLen == TDB_VARIANT_LEN || pPage->kLen == kLen)) {
ASSERT(pPage->vLen == TDB_VARIANT_LEN || pPage->vLen == vLen); return -1;
ASSERT(pKey != NULL && kLen > 0); }
if (ASSERT(pPage->vLen == TDB_VARIANT_LEN || pPage->vLen == vLen)) {
return -1;
}
if (ASSERT(pKey != NULL && kLen > 0)) {
return -1;
}
nPayload = 0; nPayload = 0;
nHeader = 0; nHeader = 0;
...@@ -1191,7 +1199,10 @@ static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const vo ...@@ -1191,7 +1199,10 @@ static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const vo
// 1. Encode Header part // 1. Encode Header part
/* Encode SPgno if interior page */ /* Encode SPgno if interior page */
if (!leaf) { if (!leaf) {
ASSERT(pPage->vLen == sizeof(SPgno)); if (pPage->vLen != sizeof(SPgno)) {
tdbError("tdb/btree-encode-cell: invalid cell.");
return -1;
}
((SPgno *)(pCell + nHeader))[0] = ((SPgno *)pVal)[0]; ((SPgno *)(pCell + nHeader))[0] = ((SPgno *)pVal)[0];
nHeader = nHeader + sizeof(SPgno); nHeader = nHeader + sizeof(SPgno);
...@@ -1216,8 +1227,8 @@ static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const vo ...@@ -1216,8 +1227,8 @@ static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const vo
ret = tdbBtreeEncodePayload(pPage, pCell, nHeader, pKey, kLen, pVal, vLen, &nPayload, pTxn, pBt); ret = tdbBtreeEncodePayload(pPage, pCell, nHeader, pKey, kLen, pVal, vLen, &nPayload, pTxn, pBt);
if (ret < 0) { if (ret < 0) {
// TODO // TODO
ASSERT(0); tdbError("tdb/btree-encode-cell: encode payload failed with ret: %d.", ret);
return 0; return -1;
} }
*szCell = nHeader + nPayload; *szCell = nHeader + nPayload;
...@@ -1234,7 +1245,10 @@ static int tdbBtreeDecodePayload(SPage *pPage, const SCell *pCell, int nHeader, ...@@ -1234,7 +1245,10 @@ static int tdbBtreeDecodePayload(SPage *pPage, const SCell *pCell, int nHeader,
int vLen = pDecoder->vLen; int vLen = pDecoder->vLen;
if (pDecoder->pVal) { if (pDecoder->pVal) {
ASSERT(!TDB_BTREE_PAGE_IS_LEAF(pPage)); if (TDB_BTREE_PAGE_IS_LEAF(pPage)) {
tdbError("tdb/btree-decode-payload: leaf page with non-null pVal.");
return -1;
}
nPayload = pDecoder->kLen; nPayload = pDecoder->kLen;
} else { } else {
nPayload = pDecoder->kLen + pDecoder->vLen; nPayload = pDecoder->kLen + pDecoder->vLen;
...@@ -1435,7 +1449,10 @@ static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pD ...@@ -1435,7 +1449,10 @@ static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pD
// 1. Decode header part // 1. Decode header part
if (!leaf) { if (!leaf) {
ASSERT(pPage->vLen == sizeof(SPgno)); if (pPage->vLen != sizeof(SPgno)) {
tdbError("tdb/btree-decode-cell: invalid cell.");
return -1;
}
pDecoder->pgno = ((SPgno *)(pCell + nHeader))[0]; pDecoder->pgno = ((SPgno *)(pCell + nHeader))[0];
pDecoder->pVal = (u8 *)(&(pDecoder->pgno)); pDecoder->pVal = (u8 *)(&(pDecoder->pgno));
...@@ -1449,7 +1466,10 @@ static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pD ...@@ -1449,7 +1466,10 @@ static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pD
} }
if (pPage->vLen == TDB_VARIANT_LEN) { if (pPage->vLen == TDB_VARIANT_LEN) {
ASSERT(leaf); if (!leaf) {
tdbError("tdb/btree-decode-cell: not a leaf page.");
return -1;
}
nHeader += tdbGetVarInt(pCell + nHeader, &(pDecoder->vLen)); nHeader += tdbGetVarInt(pCell + nHeader, &(pDecoder->vLen));
} else { } else {
pDecoder->vLen = pPage->vLen; pDecoder->vLen = pPage->vLen;
...@@ -1481,7 +1501,10 @@ static int tdbBtreeCellSize(const SPage *pPage, SCell *pCell, int dropOfp, TXN * ...@@ -1481,7 +1501,10 @@ static int tdbBtreeCellSize(const SPage *pPage, SCell *pCell, int dropOfp, TXN *
} }
if (pPage->vLen == TDB_VARIANT_LEN) { if (pPage->vLen == TDB_VARIANT_LEN) {
ASSERT(leaf); if (!leaf) {
tdbError("tdb/btree-cell-size: not a leaf page.");
return -1;
}
nHeader += tdbGetVarInt(pCell + nHeader, &vLen); nHeader += tdbGetVarInt(pCell + nHeader, &vLen);
} else if (leaf) { } else if (leaf) {
vLen = pPage->vLen; vLen = pPage->vLen;
...@@ -1577,29 +1600,42 @@ int tdbBtcMoveToFirst(SBTC *pBtc) { ...@@ -1577,29 +1600,42 @@ int tdbBtcMoveToFirst(SBTC *pBtc) {
ret = tdbPagerFetchPage(pPager, &pBt->root, &(pBtc->pPage), tdbBtreeInitPage, ret = tdbPagerFetchPage(pPager, &pBt->root, &(pBtc->pPage), tdbBtreeInitPage,
&((SBtreeInitPageArg){.pBt = pBt, .flags = TDB_BTREE_ROOT | TDB_BTREE_LEAF}), pBtc->pTxn); &((SBtreeInitPageArg){.pBt = pBt, .flags = TDB_BTREE_ROOT | TDB_BTREE_LEAF}), pBtc->pTxn);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btc-move-tofirst: fetch page failed with ret: %d.", ret);
return -1; return -1;
} }
ASSERT(TDB_BTREE_PAGE_IS_ROOT(pBtc->pPage)); if (!TDB_BTREE_PAGE_IS_ROOT(pBtc->pPage)) {
tdbError("tdb/btc-move-tofirst: not a root page");
return -1;
}
pBtc->iPage = 0; pBtc->iPage = 0;
if (TDB_PAGE_TOTAL_CELLS(pBtc->pPage) > 0) { if (TDB_PAGE_TOTAL_CELLS(pBtc->pPage) > 0) {
pBtc->idx = 0; pBtc->idx = 0;
} else { } else {
// no any data, point to an invalid position // no any data, point to an invalid position
ASSERT(TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage)); if (!TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage)) {
tdbError("tdb/btc-move-to-first: not a leaf page.");
return -1;
}
pBtc->idx = -1; pBtc->idx = -1;
return 0; return 0;
} }
} else { } else {
ASSERT(0); // TODO
tdbError("tdb/btc-move-to-first: move from a dirty cursor.");
return -1;
#if 0 #if 0
// move from a position // move from a position
int iPage = 0; int iPage = 0;
for (; iPage < pBtc->iPage; iPage++) { for (; iPage < pBtc->iPage; iPage++) {
ASSERT(pBtc->idxStack[iPage] >= 0); if (pBtc->idxStack[iPage] < 0) {
tdbError("tdb/btc-move-to-first: invalid idx: %d.", pBtc->idxStack[iPage]);
return -1;
}
if (pBtc->idxStack[iPage]) break; if (pBtc->idxStack[iPage]) break;
} }
...@@ -1621,7 +1657,7 @@ int tdbBtcMoveToFirst(SBTC *pBtc) { ...@@ -1621,7 +1657,7 @@ int tdbBtcMoveToFirst(SBTC *pBtc) {
ret = tdbBtcMoveDownward(pBtc); ret = tdbBtcMoveDownward(pBtc);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btc-move-tofirst: btc move downward failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -1646,7 +1682,7 @@ int tdbBtcMoveToLast(SBTC *pBtc) { ...@@ -1646,7 +1682,7 @@ int tdbBtcMoveToLast(SBTC *pBtc) {
ret = tdbPagerFetchPage(pPager, &pBt->root, &(pBtc->pPage), tdbBtreeInitPage, ret = tdbPagerFetchPage(pPager, &pBt->root, &(pBtc->pPage), tdbBtreeInitPage,
&((SBtreeInitPageArg){.pBt = pBt, .flags = TDB_BTREE_ROOT | TDB_BTREE_LEAF}), pBtc->pTxn); &((SBtreeInitPageArg){.pBt = pBt, .flags = TDB_BTREE_ROOT | TDB_BTREE_LEAF}), pBtc->pTxn);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btc-move-tolast: fetch page failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -1656,18 +1692,28 @@ int tdbBtcMoveToLast(SBTC *pBtc) { ...@@ -1656,18 +1692,28 @@ int tdbBtcMoveToLast(SBTC *pBtc) {
pBtc->idx = TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage) ? nCells - 1 : nCells; pBtc->idx = TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage) ? nCells - 1 : nCells;
} else { } else {
// no data at all, point to an invalid position // no data at all, point to an invalid position
ASSERT(TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage)); if (!TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage)) {
tdbError("tdb/btc-move-to-last: not a leaf page.");
return -1;
}
pBtc->idx = -1; pBtc->idx = -1;
return 0; return 0;
} }
} else { } else {
ASSERT(0); // TODO
tdbError("tdb/btc-move-to-last: move from a dirty cursor.");
return -1;
#if 0 #if 0
int iPage = 0; int iPage = 0;
// downward search // downward search
for (; iPage < pBtc->iPage; iPage++) { for (; iPage < pBtc->iPage; iPage++) {
ASSERT(!TDB_BTREE_PAGE_IS_LEAF(pBtc->pgStack[iPage])); if (TDB_BTREE_PAGE_IS_LEAF(pBtc->pgStack[iPage])) {
tdbError("tdb/btc-move-to-last: leaf page in cursor stack.");
return -1;
}
nCells = TDB_PAGE_TOTAL_CELLS(pBtc->pgStack[iPage]); nCells = TDB_PAGE_TOTAL_CELLS(pBtc->pgStack[iPage]);
if (pBtc->idxStack[iPage] != nCells) break; if (pBtc->idxStack[iPage] != nCells) break;
} }
...@@ -1694,7 +1740,7 @@ int tdbBtcMoveToLast(SBTC *pBtc) { ...@@ -1694,7 +1740,7 @@ int tdbBtcMoveToLast(SBTC *pBtc) {
ret = tdbBtcMoveDownward(pBtc); ret = tdbBtcMoveDownward(pBtc);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btc-move-tolast: btc move downward failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -1752,7 +1798,7 @@ int tdbBtreeNext(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) { ...@@ -1752,7 +1798,7 @@ int tdbBtreeNext(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) {
ret = tdbBtcMoveToNext(pBtc); ret = tdbBtcMoveToNext(pBtc);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btree-next: btc move to next failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -1798,7 +1844,7 @@ int tdbBtreePrev(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) { ...@@ -1798,7 +1844,7 @@ int tdbBtreePrev(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) {
ret = tdbBtcMoveToPrev(pBtc); ret = tdbBtcMoveToPrev(pBtc);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btree-prev: btc move to prev failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -1810,7 +1856,10 @@ int tdbBtcMoveToNext(SBTC *pBtc) { ...@@ -1810,7 +1856,10 @@ int tdbBtcMoveToNext(SBTC *pBtc) {
int ret; int ret;
SCell *pCell; SCell *pCell;
ASSERT(TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage)); if (!TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage)) {
tdbError("tdb/btc-move-to-next: not a leaf page.");
return -1;
}
if (pBtc->idx < 0) return -1; if (pBtc->idx < 0) return -1;
...@@ -1829,7 +1878,10 @@ int tdbBtcMoveToNext(SBTC *pBtc) { ...@@ -1829,7 +1878,10 @@ int tdbBtcMoveToNext(SBTC *pBtc) {
tdbBtcMoveUpward(pBtc); tdbBtcMoveUpward(pBtc);
pBtc->idx++; pBtc->idx++;
ASSERT(!TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage)); if (TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage)) {
tdbError("tdb/btree-decode-cell: should not be a leaf page here.");
return -1;
}
if (pBtc->idx <= TDB_PAGE_TOTAL_CELLS(pBtc->pPage)) { if (pBtc->idx <= TDB_PAGE_TOTAL_CELLS(pBtc->pPage)) {
break; break;
} }
...@@ -1841,7 +1893,7 @@ int tdbBtcMoveToNext(SBTC *pBtc) { ...@@ -1841,7 +1893,7 @@ int tdbBtcMoveToNext(SBTC *pBtc) {
ret = tdbBtcMoveDownward(pBtc); ret = tdbBtcMoveDownward(pBtc);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btc-move-tonext: btc move downward failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -1893,8 +1945,15 @@ static int tdbBtcMoveDownward(SBTC *pBtc) { ...@@ -1893,8 +1945,15 @@ static int tdbBtcMoveDownward(SBTC *pBtc) {
SPgno pgno; SPgno pgno;
SCell *pCell; SCell *pCell;
ASSERT(pBtc->idx >= 0); if (pBtc->idx < 0) {
ASSERT(!TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage)); tdbError("tdb/btc-move-downward: invalid idx: %d.", pBtc->idx);
return -1;
}
if (TDB_BTREE_PAGE_IS_LEAF(pBtc->pPage)) {
tdbError("tdb/btc-move-downward: should not be a leaf page here.");
return -1;
}
if (pBtc->idx < TDB_PAGE_TOTAL_CELLS(pBtc->pPage)) { if (pBtc->idx < TDB_PAGE_TOTAL_CELLS(pBtc->pPage)) {
pCell = tdbPageGetCell(pBtc->pPage, pBtc->idx); pCell = tdbPageGetCell(pBtc->pPage, pBtc->idx);
...@@ -1903,7 +1962,10 @@ static int tdbBtcMoveDownward(SBTC *pBtc) { ...@@ -1903,7 +1962,10 @@ static int tdbBtcMoveDownward(SBTC *pBtc) {
pgno = ((SIntHdr *)pBtc->pPage->pData)->pgno; pgno = ((SIntHdr *)pBtc->pPage->pData)->pgno;
} }
ASSERT(pgno); if (!pgno) {
tdbError("tdb/btc-move-downward: invalid pgno.");
return -1;
}
pBtc->pgStack[pBtc->iPage] = pBtc->pPage; pBtc->pgStack[pBtc->iPage] = pBtc->pPage;
pBtc->idxStack[pBtc->iPage] = pBtc->idx; pBtc->idxStack[pBtc->iPage] = pBtc->idx;
...@@ -1914,7 +1976,7 @@ static int tdbBtcMoveDownward(SBTC *pBtc) { ...@@ -1914,7 +1976,7 @@ static int tdbBtcMoveDownward(SBTC *pBtc) {
ret = tdbPagerFetchPage(pBtc->pBt->pPager, &pgno, &pBtc->pPage, tdbBtreeInitPage, ret = tdbPagerFetchPage(pBtc->pBt->pPager, &pgno, &pBtc->pPage, tdbBtreeInitPage,
&((SBtreeInitPageArg){.pBt = pBtc->pBt, .flags = 0}), pBtc->pTxn); &((SBtreeInitPageArg){.pBt = pBtc->pBt, .flags = 0}), pBtc->pTxn);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btc-move-downward: fetch page failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -1969,7 +2031,10 @@ int tdbBtcDelete(SBTC *pBtc) { ...@@ -1969,7 +2031,10 @@ int tdbBtcDelete(SBTC *pBtc) {
int nKey; int nKey;
int ret; int ret;
ASSERT(idx >= 0 && idx < nCells); if (idx < 0 || idx >= nCells) {
tdbError("tdb/btc-delete: idx: %d out of range[%d, %d).", idx, 0, nCells);
return -1;
}
// drop the cell on the leaf // drop the cell on the leaf
ret = tdbPagerWrite(pPager, pBtc->pPage); ret = tdbPagerWrite(pPager, pBtc->pPage);
...@@ -2007,7 +2072,7 @@ int tdbBtcDelete(SBTC *pBtc) { ...@@ -2007,7 +2072,7 @@ int tdbBtcDelete(SBTC *pBtc) {
ret = tdbPageUpdateCell(pPage, idx, pCell, szCell, pBtc->pTxn, pBtc->pBt); ret = tdbPageUpdateCell(pPage, idx, pCell, szCell, pBtc->pTxn, pBtc->pBt);
if (ret < 0) { if (ret < 0) {
tdbOsFree(pCell); tdbOsFree(pCell);
ASSERT(0); tdbError("tdb/btc-delete: page update cell failed with ret: %d.", ret);
return -1; return -1;
} }
tdbOsFree(pCell); tdbOsFree(pCell);
...@@ -2018,11 +2083,14 @@ int tdbBtcDelete(SBTC *pBtc) { ...@@ -2018,11 +2083,14 @@ int tdbBtcDelete(SBTC *pBtc) {
} }
} else { } else {
// delete the leaf page and do balance // delete the leaf page and do balance
ASSERT(TDB_PAGE_TOTAL_CELLS(pBtc->pPage) == 0); if (TDB_PAGE_TOTAL_CELLS(pBtc->pPage) != 0) {
tdbError("tdb/btc-delete: page to be deleted should be empty.");
return -1;
}
ret = tdbBtreeBalance(pBtc); ret = tdbBtreeBalance(pBtc);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btc-delete: btree balance failed with ret: %d.", ret);
return -1; return -1;
} }
} }
...@@ -2039,13 +2107,16 @@ int tdbBtcUpsert(SBTC *pBtc, const void *pKey, int kLen, const void *pData, int ...@@ -2039,13 +2107,16 @@ int tdbBtcUpsert(SBTC *pBtc, const void *pKey, int kLen, const void *pData, int
void *pBuf; void *pBuf;
int ret; int ret;
ASSERT(pBtc->idx >= 0); if (pBtc->idx < 0) {
tdbError("tdb/btc-upsert: invalid idx: %d.", pBtc->idx);
return -1;
}
// alloc space // alloc space
szBuf = kLen + nData + 14; szBuf = kLen + nData + 14;
pBuf = tdbRealloc(pBtc->pBt->pBuf, pBtc->pBt->pageSize > szBuf ? szBuf : pBtc->pBt->pageSize); pBuf = tdbRealloc(pBtc->pBt->pBuf, pBtc->pBt->pageSize > szBuf ? szBuf : pBtc->pBt->pageSize);
if (pBuf == NULL) { if (pBuf == NULL) {
ASSERT(0); tdbError("tdb/btc-upsert: realloc pBuf failed.");
return -1; return -1;
} }
pBtc->pBt->pBuf = pBuf; pBtc->pBt->pBuf = pBuf;
...@@ -2054,7 +2125,7 @@ int tdbBtcUpsert(SBTC *pBtc, const void *pKey, int kLen, const void *pData, int ...@@ -2054,7 +2125,7 @@ int tdbBtcUpsert(SBTC *pBtc, const void *pKey, int kLen, const void *pData, int
// encode cell // encode cell
ret = tdbBtreeEncodeCell(pBtc->pPage, pKey, kLen, pData, nData, pCell, &szCell, pBtc->pTxn, pBtc->pBt); ret = tdbBtreeEncodeCell(pBtc->pPage, pKey, kLen, pData, nData, pCell, &szCell, pBtc->pTxn, pBtc->pBt);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btc-upsert: btree encode cell failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -2067,16 +2138,22 @@ int tdbBtcUpsert(SBTC *pBtc, const void *pKey, int kLen, const void *pData, int ...@@ -2067,16 +2138,22 @@ int tdbBtcUpsert(SBTC *pBtc, const void *pKey, int kLen, const void *pData, int
// insert or update // insert or update
if (insert) { if (insert) {
ASSERT(pBtc->idx <= nCells); if (pBtc->idx > nCells) {
tdbError("tdb/btc-upsert: invalid idx: %d, nCells: %d.", pBtc->idx, nCells);
return -1;
}
ret = tdbPageInsertCell(pBtc->pPage, pBtc->idx, pCell, szCell, 0); ret = tdbPageInsertCell(pBtc->pPage, pBtc->idx, pCell, szCell, 0);
} else { } else {
ASSERT(pBtc->idx < nCells); if (pBtc->idx >= nCells) {
tdbError("tdb/btc-upsert: invalid idx: %d, nCells: %d.", pBtc->idx, nCells);
return -1;
}
ret = tdbPageUpdateCell(pBtc->pPage, pBtc->idx, pCell, szCell, pBtc->pTxn, pBtc->pBt); ret = tdbPageUpdateCell(pBtc->pPage, pBtc->idx, pCell, szCell, pBtc->pTxn, pBtc->pBt);
} }
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btc-upsert: page insert/update cell failed with ret: %d.", ret);
return -1; return -1;
} }
...@@ -2084,7 +2161,7 @@ int tdbBtcUpsert(SBTC *pBtc, const void *pKey, int kLen, const void *pData, int ...@@ -2084,7 +2161,7 @@ int tdbBtcUpsert(SBTC *pBtc, const void *pKey, int kLen, const void *pData, int
if (pBtc->pPage->nOverflow > 0) { if (pBtc->pPage->nOverflow > 0) {
ret = tdbBtreeBalance(pBtc); ret = tdbBtreeBalance(pBtc);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/btc-upsert: btree balance failed with ret: %d.", ret);
return -1; return -1;
} }
} }
...@@ -2109,8 +2186,8 @@ int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) { ...@@ -2109,8 +2186,8 @@ int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
&((SBtreeInitPageArg){.pBt = pBt, .flags = TDB_BTREE_ROOT | TDB_BTREE_LEAF}), pBtc->pTxn); &((SBtreeInitPageArg){.pBt = pBt, .flags = TDB_BTREE_ROOT | TDB_BTREE_LEAF}), pBtc->pTxn);
if (ret < 0) { if (ret < 0) {
// TODO // TODO
ASSERT(0); tdbError("tdb/btc-move-to: fetch page failed with ret: %d.", ret);
return 0; return -1;
} }
pBtc->iPage = 0; pBtc->iPage = 0;
...@@ -2118,7 +2195,9 @@ int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) { ...@@ -2118,7 +2195,9 @@ int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
// for empty tree, just return with an invalid position // for empty tree, just return with an invalid position
if (TDB_PAGE_TOTAL_CELLS(pBtc->pPage) == 0) return 0; if (TDB_PAGE_TOTAL_CELLS(pBtc->pPage) == 0) return 0;
} else { } else {
ASSERT(0); // TODO
tdbError("tdb/btc-move-to: move from a dirty cursor.");
return -1;
#if 0 #if 0
SPage *pPage; SPage *pPage;
int idx; int idx;
...@@ -2130,7 +2209,10 @@ int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) { ...@@ -2130,7 +2209,10 @@ int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
idx = pBtc->idxStack[iPage]; idx = pBtc->idxStack[iPage];
nCells = TDB_PAGE_TOTAL_CELLS(pPage); nCells = TDB_PAGE_TOTAL_CELLS(pPage);
ASSERT(!TDB_BTREE_PAGE_IS_LEAF(pPage)); if (TDB_BTREE_PAGE_IS_LEAF(pPage)) {
tdbError("tdb/btc-move-to: leaf page in cursor stack.");
return -1;
}
// check if key <= current position // check if key <= current position
if (idx < nCells) { if (idx < nCells) {
...@@ -2233,7 +2315,10 @@ int tdbBtcClose(SBTC *pBtc) { ...@@ -2233,7 +2315,10 @@ int tdbBtcClose(SBTC *pBtc) {
if (pBtc->iPage < 0) return 0; if (pBtc->iPage < 0) return 0;
for (;;) { for (;;) {
ASSERT(pBtc->pPage); if (NULL == pBtc->pPage) {
tdbError("tdb/btc-close: null ptr pPage.");
return -1;
}
tdbPagerReturnPage(pBtc->pBt->pPager, pBtc->pPage, pBtc->pTxn); tdbPagerReturnPage(pBtc->pBt->pPager, pBtc->pPage, pBtc->pTxn);
......
...@@ -247,7 +247,10 @@ void tdbEnvRemovePager(TDB *pDb, SPager *pPager) { ...@@ -247,7 +247,10 @@ void tdbEnvRemovePager(TDB *pDb, SPager *pPager) {
// remove from the list // remove from the list
for (ppPager = &pDb->pgrList; *ppPager && (*ppPager != pPager); ppPager = &((*ppPager)->pNext)) { for (ppPager = &pDb->pgrList; *ppPager && (*ppPager != pPager); ppPager = &((*ppPager)->pNext)) {
} }
ASSERT(*ppPager == pPager); if (*ppPager != pPager) {
tdbError("tdb/db: invalid pPager: %p, *ppPager: %p", pPager, *ppPager);
return;
}
*ppPager = pPager->pNext; *ppPager = pPager->pNext;
// remove from hash // remove from hash
...@@ -255,7 +258,10 @@ void tdbEnvRemovePager(TDB *pDb, SPager *pPager) { ...@@ -255,7 +258,10 @@ void tdbEnvRemovePager(TDB *pDb, SPager *pPager) {
ppPager = &pDb->pgrHash[hash % pDb->nPgrHash]; ppPager = &pDb->pgrHash[hash % pDb->nPgrHash];
for (; *ppPager && *ppPager != pPager; ppPager = &((*ppPager)->pHashNext)) { for (; *ppPager && *ppPager != pPager; ppPager = &((*ppPager)->pHashNext)) {
} }
ASSERT(*ppPager == pPager); if (*ppPager != pPager) {
tdbError("tdb/db: invalid pPager: %p, *ppPager: %p", pPager, *ppPager);
return;
}
*ppPager = pPager->pNext; *ppPager = pPager->pNext;
// decrease the counter // decrease the counter
......
...@@ -236,10 +236,10 @@ void tdbPCacheInvalidatePage(SPCache *pCache, SPager *pPager, SPgno pgno) { ...@@ -236,10 +236,10 @@ void tdbPCacheInvalidatePage(SPCache *pCache, SPager *pPager, SPgno pgno) {
void tdbPCacheRelease(SPCache *pCache, SPage *pPage, TXN *pTxn) { void tdbPCacheRelease(SPCache *pCache, SPage *pPage, TXN *pTxn) {
i32 nRef; i32 nRef;
ASSERT(pTxn); if (!pTxn) {
tdbError("tdb/pcache: null ptr pTxn, release failed.");
// nRef = tdbUnrefPage(pPage); return;
// ASSERT(nRef >= 0); }
tdbPCacheLock(pCache); tdbPCacheLock(pCache);
nRef = tdbUnrefPage(pPage); nRef = tdbUnrefPage(pPage);
...@@ -275,7 +275,10 @@ static SPage *tdbPCacheFetchImpl(SPCache *pCache, const SPgid *pPgid, TXN *pTxn) ...@@ -275,7 +275,10 @@ static SPage *tdbPCacheFetchImpl(SPCache *pCache, const SPgid *pPgid, TXN *pTxn)
SPage *pPage = NULL; SPage *pPage = NULL;
SPage *pPageH = NULL; SPage *pPageH = NULL;
ASSERT(pTxn); if (!pTxn) {
tdbError("tdb/pcache: null ptr pTxn, fetch impl failed.");
return NULL;
}
// 1. Search the hash table // 1. Search the hash table
pPage = pCache->pgHash[tdbPCachePageHash(pPgid) % pCache->nHash]; pPage = pCache->pgHash[tdbPCachePageHash(pPgid) % pCache->nHash];
...@@ -315,8 +318,8 @@ static SPage *tdbPCacheFetchImpl(SPCache *pCache, const SPgid *pPgid, TXN *pTxn) ...@@ -315,8 +318,8 @@ static SPage *tdbPCacheFetchImpl(SPCache *pCache, const SPgid *pPgid, TXN *pTxn)
if (!pPage && pTxn->xMalloc != NULL) { if (!pPage && pTxn->xMalloc != NULL) {
ret = tdbPageCreate(pCache->szPage, &pPage, pTxn->xMalloc, pTxn->xArg); ret = tdbPageCreate(pCache->szPage, &pPage, pTxn->xMalloc, pTxn->xArg);
if (ret < 0 || pPage == NULL) { if (ret < 0 || pPage == NULL) {
// TODO tdbError("tdb/pcache: ret: %" PRId32 " pPage: %p, page create failed.", ret, pPage);
ASSERT(0); // TODO: recycle other backup pages
return NULL; return NULL;
} }
...@@ -370,7 +373,11 @@ static SPage *tdbPCacheFetchImpl(SPCache *pCache, const SPgid *pPgid, TXN *pTxn) ...@@ -370,7 +373,11 @@ static SPage *tdbPCacheFetchImpl(SPCache *pCache, const SPgid *pPgid, TXN *pTxn)
static void tdbPCachePinPage(SPCache *pCache, SPage *pPage) { static void tdbPCachePinPage(SPCache *pCache, SPage *pPage) {
if (pPage->pLruNext != NULL) { if (pPage->pLruNext != NULL) {
ASSERT(tdbGetPageRef(pPage) == 0); int32_t nRef = tdbGetPageRef(pPage);
if (nRef != 0) {
tdbError("tdb/pcache: pin page's ref not zero: %" PRId32, nRef);
return;
}
pPage->pLruPrev->pLruNext = pPage->pLruNext; pPage->pLruPrev->pLruNext = pPage->pLruNext;
pPage->pLruNext->pLruPrev = pPage->pLruPrev; pPage->pLruNext->pLruPrev = pPage->pLruPrev;
...@@ -383,13 +390,23 @@ static void tdbPCachePinPage(SPCache *pCache, SPage *pPage) { ...@@ -383,13 +390,23 @@ static void tdbPCachePinPage(SPCache *pCache, SPage *pPage) {
} }
static void tdbPCacheUnpinPage(SPCache *pCache, SPage *pPage) { static void tdbPCacheUnpinPage(SPCache *pCache, SPage *pPage) {
i32 nRef; i32 nRef = tdbGetPageRef(pPage);
if (nRef != 0) {
ASSERT(pPage->isLocal); tdbError("tdb/pcache: unpin page's ref not zero: %" PRId32, nRef);
ASSERT(!pPage->isDirty); return;
ASSERT(tdbGetPageRef(pPage) == 0); }
if (!pPage->isLocal) {
ASSERT(pPage->pLruNext == NULL); tdbError("tdb/pcache: unpin page's not local: %" PRIu8, pPage->isLocal);
return;
}
if (pPage->isDirty) {
tdbError("tdb/pcache: unpin page's dirty: %" PRIu8, pPage->isDirty);
return;
}
if (NULL != pPage->pLruNext) {
tdbError("tdb/pcache: unpin page's pLruNext not null.");
return;
}
tdbTrace("pCache:%p unpin page %p/%d, nPages:%d, pgno:%d, ", pCache, pPage, pPage->id, pCache->nPages, tdbTrace("pCache:%p unpin page %p/%d, nPages:%d, pgno:%d, ", pCache, pPage, pPage->id, pCache->nPages,
TDB_PAGE_PGNO(pPage)); TDB_PAGE_PGNO(pPage));
......
...@@ -43,9 +43,15 @@ int tdbPageCreate(int pageSize, SPage **ppPage, void *(*xMalloc)(void *, size_t) ...@@ -43,9 +43,15 @@ int tdbPageCreate(int pageSize, SPage **ppPage, void *(*xMalloc)(void *, size_t)
u8 *ptr; u8 *ptr;
int size; int size;
ASSERT(xMalloc); if (!xMalloc) {
tdbError("tdb/page-create: null xMalloc.");
return -1;
}
ASSERT(TDB_IS_PGSIZE_VLD(pageSize)); if (!TDB_IS_PGSIZE_VLD(pageSize)) {
tdbError("tdb/page-create: invalid pageSize: %d.", pageSize);
return -1;
}
*ppPage = NULL; *ppPage = NULL;
size = pageSize + sizeof(*pPage); size = pageSize + sizeof(*pPage);
...@@ -69,16 +75,24 @@ int tdbPageCreate(int pageSize, SPage **ppPage, void *(*xMalloc)(void *, size_t) ...@@ -69,16 +75,24 @@ int tdbPageCreate(int pageSize, SPage **ppPage, void *(*xMalloc)(void *, size_t)
*ppPage = pPage; *ppPage = pPage;
tdbTrace("page/create: %p/%d %p", pPage, pPage->id, xMalloc); tdbTrace("tdb/page-create: %p/%d %p", pPage, pPage->id, xMalloc);
return 0; return 0;
} }
int tdbPageDestroy(SPage *pPage, void (*xFree)(void *arg, void *ptr), void *arg) { int tdbPageDestroy(SPage *pPage, void (*xFree)(void *arg, void *ptr), void *arg) {
u8 *ptr; u8 *ptr;
tdbTrace("page/destroy: %p/%d %p", pPage, pPage->id, xFree); tdbTrace("tdb/page-destroy: %p/%d %p", pPage, pPage->id, xFree);
ASSERT(!pPage->isDirty);
ASSERT(xFree); if (pPage->isDirty) {
tdbError("tdb/page-destroy: dirty page: %" PRIu8 ".", pPage->isDirty);
return -1;
}
if (!xFree) {
tdbError("tdb/page-destroy: null xFree.");
return -1;
}
for (int iOvfl = 0; iOvfl < pPage->nOverflow; iOvfl++) { for (int iOvfl = 0; iOvfl < pPage->nOverflow; iOvfl++) {
tdbTrace("tdbPage/destroy/free ovfl cell: %p/%p", pPage->apOvfl[iOvfl], pPage); tdbTrace("tdbPage/destroy/free ovfl cell: %p/%p", pPage->apOvfl[iOvfl], pPage);
...@@ -105,7 +119,10 @@ void tdbPageZero(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell ...@@ -105,7 +119,10 @@ void tdbPageZero(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell
pPage->nOverflow = 0; pPage->nOverflow = 0;
pPage->xCellSize = xCellSize; pPage->xCellSize = xCellSize;
ASSERT((u8 *)pPage->pPageFtr == pPage->pFreeEnd); if ((u8 *)pPage->pPageFtr != pPage->pFreeEnd) {
tdbError("tdb/page-zero: invalid page, pFreeEnd: %p, pPageFtr: %p", pPage->pFreeEnd, pPage->pPageFtr);
return;
}
} }
void tdbPageInit(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *, int, TXN *, SBTree *pBt)) { void tdbPageInit(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *, int, TXN *, SBTree *pBt)) {
...@@ -121,8 +138,15 @@ void tdbPageInit(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell ...@@ -121,8 +138,15 @@ void tdbPageInit(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell
pPage->nOverflow = 0; pPage->nOverflow = 0;
pPage->xCellSize = xCellSize; pPage->xCellSize = xCellSize;
ASSERT(pPage->pFreeEnd >= pPage->pFreeStart); if (pPage->pFreeEnd < pPage->pFreeStart) {
ASSERT(pPage->pFreeEnd - pPage->pFreeStart <= TDB_PAGE_NFREE(pPage)); tdbError("tdb/page-init: invalid page, pFreeEnd: %p, pFreeStart: %p", pPage->pFreeEnd, pPage->pFreeStart);
return;
}
if (pPage->pFreeEnd - pPage->pFreeStart > TDB_PAGE_NFREE(pPage)) {
tdbError("tdb/page-init: invalid page, pFreeEnd: %p, pFreeStart: %p, NFREE: %d", pPage->pFreeEnd, pPage->pFreeStart,
TDB_PAGE_NFREE(pPage));
return;
}
} }
int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell, u8 asOvfl) { int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell, u8 asOvfl) {
...@@ -132,7 +156,11 @@ int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell, u8 asOvfl ...@@ -132,7 +156,11 @@ int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell, u8 asOvfl
int lidx; // local idx int lidx; // local idx
SCell *pNewCell; SCell *pNewCell;
ASSERT(szCell <= TDB_PAGE_MAX_FREE_BLOCK(pPage, pPage->pPageHdr - pPage->pData)); if (szCell > TDB_PAGE_MAX_FREE_BLOCK(pPage, pPage->pPageHdr - pPage->pData)) {
tdbError("tdb/page-insert-cell: invalid page, szCell: %d, max free: %lu", szCell,
TDB_PAGE_MAX_FREE_BLOCK(pPage, pPage->pPageHdr - pPage->pData));
return -1;
}
nFree = TDB_PAGE_NFREE(pPage); nFree = TDB_PAGE_NFREE(pPage);
nCells = TDB_PAGE_NCELLS(pPage); nCells = TDB_PAGE_NCELLS(pPage);
...@@ -176,7 +204,11 @@ int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell, u8 asOvfl ...@@ -176,7 +204,11 @@ int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell, u8 asOvfl
TDB_PAGE_CELL_OFFSET_AT_SET(pPage, lidx, pNewCell - pPage->pData); TDB_PAGE_CELL_OFFSET_AT_SET(pPage, lidx, pNewCell - pPage->pData);
TDB_PAGE_NCELLS_SET(pPage, nCells + 1); TDB_PAGE_NCELLS_SET(pPage, nCells + 1);
ASSERT(pPage->pFreeStart == pPage->pCellIdx + TDB_PAGE_OFFSET_SIZE(pPage) * (nCells + 1)); if (pPage->pFreeStart != pPage->pCellIdx + TDB_PAGE_OFFSET_SIZE(pPage) * (nCells + 1)) {
tdbError("tdb/page-insert-cell: invalid page, pFreeStart: %p, pCellIdx: %p, nCells: %d", pPage->pFreeStart,
pPage->pCellIdx, nCells);
return -1;
}
} }
for (; iOvfl < pPage->nOverflow; iOvfl++) { for (; iOvfl < pPage->nOverflow; iOvfl++) {
...@@ -200,7 +232,10 @@ int tdbPageDropCell(SPage *pPage, int idx, TXN *pTxn, SBTree *pBt) { ...@@ -200,7 +232,10 @@ int tdbPageDropCell(SPage *pPage, int idx, TXN *pTxn, SBTree *pBt) {
nCells = TDB_PAGE_NCELLS(pPage); nCells = TDB_PAGE_NCELLS(pPage);
ASSERT(idx >= 0 && idx < nCells + pPage->nOverflow); if (idx < 0 || idx >= nCells + pPage->nOverflow) {
tdbError("tdb/page-drop-cell: idx: %d out of range, nCells: %d, nOvfl: %d.", idx, nCells, pPage->nOverflow);
return -1;
}
iOvfl = 0; iOvfl = 0;
for (; iOvfl < pPage->nOverflow; iOvfl++) { for (; iOvfl < pPage->nOverflow; iOvfl++) {
...@@ -228,7 +263,10 @@ int tdbPageDropCell(SPage *pPage, int idx, TXN *pTxn, SBTree *pBt) { ...@@ -228,7 +263,10 @@ int tdbPageDropCell(SPage *pPage, int idx, TXN *pTxn, SBTree *pBt) {
for (; iOvfl < pPage->nOverflow; iOvfl++) { for (; iOvfl < pPage->nOverflow; iOvfl++) {
pPage->aiOvfl[iOvfl]--; pPage->aiOvfl[iOvfl]--;
ASSERT(pPage->aiOvfl[iOvfl] > 0); if (pPage->aiOvfl[iOvfl] <= 0) {
tdbError("tdb/page-drop-cell: invalid ai idx: %d", pPage->aiOvfl[iOvfl]);
return -1;
}
} }
return 0; return 0;
...@@ -240,12 +278,19 @@ void tdbPageCopy(SPage *pFromPage, SPage *pToPage, int deepCopyOvfl) { ...@@ -240,12 +278,19 @@ void tdbPageCopy(SPage *pFromPage, SPage *pToPage, int deepCopyOvfl) {
pToPage->pFreeStart = pToPage->pPageHdr + (pFromPage->pFreeStart - pFromPage->pPageHdr); pToPage->pFreeStart = pToPage->pPageHdr + (pFromPage->pFreeStart - pFromPage->pPageHdr);
pToPage->pFreeEnd = (u8 *)(pToPage->pPageFtr) - ((u8 *)pFromPage->pPageFtr - pFromPage->pFreeEnd); pToPage->pFreeEnd = (u8 *)(pToPage->pPageFtr) - ((u8 *)pFromPage->pPageFtr - pFromPage->pFreeEnd);
ASSERT(pToPage->pFreeEnd >= pToPage->pFreeStart); if (pToPage->pFreeEnd < pToPage->pFreeStart) {
tdbError("tdb/page-copy: invalid to page, pFreeStart: %p, pFreeEnd: %p", pToPage->pFreeStart, pToPage->pFreeEnd);
return;
}
memcpy(pToPage->pPageHdr, pFromPage->pPageHdr, pFromPage->pFreeStart - pFromPage->pPageHdr); memcpy(pToPage->pPageHdr, pFromPage->pPageHdr, pFromPage->pFreeStart - pFromPage->pPageHdr);
memcpy(pToPage->pFreeEnd, pFromPage->pFreeEnd, (u8 *)pFromPage->pPageFtr - pFromPage->pFreeEnd); memcpy(pToPage->pFreeEnd, pFromPage->pFreeEnd, (u8 *)pFromPage->pPageFtr - pFromPage->pFreeEnd);
ASSERT(TDB_PAGE_CCELLS(pToPage) == pToPage->pFreeEnd - pToPage->pData); if (TDB_PAGE_CCELLS(pToPage) != pToPage->pFreeEnd - pToPage->pData) {
tdbError("tdb/page-copy: invalid to page, cell body: %d, range: %ld", TDB_PAGE_CCELLS(pToPage),
pToPage->pFreeEnd - pToPage->pData);
return;
}
delta = (pToPage->pPageHdr - pToPage->pData) - (pFromPage->pPageHdr - pFromPage->pData); delta = (pToPage->pPageHdr - pToPage->pData) - (pFromPage->pPageHdr - pFromPage->pData);
if (delta != 0) { if (delta != 0) {
...@@ -295,8 +340,16 @@ static int tdbPageAllocate(SPage *pPage, int szCell, SCell **ppCell) { ...@@ -295,8 +340,16 @@ static int tdbPageAllocate(SPage *pPage, int szCell, SCell **ppCell) {
*ppCell = NULL; *ppCell = NULL;
nFree = TDB_PAGE_NFREE(pPage); nFree = TDB_PAGE_NFREE(pPage);
ASSERT(nFree >= szCell + TDB_PAGE_OFFSET_SIZE(pPage)); if (nFree < szCell + TDB_PAGE_OFFSET_SIZE(pPage)) {
ASSERT(TDB_PAGE_CCELLS(pPage) == pPage->pFreeEnd - pPage->pData); tdbError("tdb/page-allocate: invalid cell size, nFree: %d, szCell: %d, szOffset: %d", nFree, szCell,
TDB_PAGE_OFFSET_SIZE(pPage));
return -1;
}
if (TDB_PAGE_CCELLS(pPage) != pPage->pFreeEnd - pPage->pData) {
tdbError("tdb/page-allocate: invalid page, cell body: %d, range: %ld", TDB_PAGE_CCELLS(pPage),
pPage->pFreeEnd - pPage->pData);
return -1;
}
// 1. Try to allocate from the free space block area // 1. Try to allocate from the free space block area
if (pPage->pFreeEnd - pPage->pFreeStart >= szCell + TDB_PAGE_OFFSET_SIZE(pPage)) { if (pPage->pFreeEnd - pPage->pFreeStart >= szCell + TDB_PAGE_OFFSET_SIZE(pPage)) {
...@@ -308,7 +361,10 @@ static int tdbPageAllocate(SPage *pPage, int szCell, SCell **ppCell) { ...@@ -308,7 +361,10 @@ static int tdbPageAllocate(SPage *pPage, int szCell, SCell **ppCell) {
// 2. Try to allocate from the page free list // 2. Try to allocate from the page free list
cellFree = TDB_PAGE_FCELL(pPage); cellFree = TDB_PAGE_FCELL(pPage);
ASSERT(cellFree == 0 || cellFree >= pPage->pFreeEnd - pPage->pData); if (cellFree != 0 && cellFree < pPage->pFreeEnd - pPage->pData) {
tdbError("tdb/page-allocate: cellFree: %d, pFreeEnd: %p, pData: %p.", cellFree, pPage->pFreeEnd, pPage->pData);
return -1;
}
if (cellFree && pPage->pFreeEnd - pPage->pFreeStart >= TDB_PAGE_OFFSET_SIZE(pPage)) { if (cellFree && pPage->pFreeEnd - pPage->pFreeStart >= TDB_PAGE_OFFSET_SIZE(pPage)) {
SCell *pPrevFreeCell = NULL; SCell *pPrevFreeCell = NULL;
int szPrevFreeCell; int szPrevFreeCell;
...@@ -353,16 +409,30 @@ static int tdbPageAllocate(SPage *pPage, int szCell, SCell **ppCell) { ...@@ -353,16 +409,30 @@ static int tdbPageAllocate(SPage *pPage, int szCell, SCell **ppCell) {
// 3. Try to dfragment and allocate again // 3. Try to dfragment and allocate again
tdbPageDefragment(pPage); tdbPageDefragment(pPage);
ASSERT(pPage->pFreeEnd - pPage->pFreeStart == nFree); if (pPage->pFreeEnd - pPage->pFreeStart != nFree) {
ASSERT(nFree == TDB_PAGE_NFREE(pPage)); tdbError("tdb/page-allocate: nFree: %d, pFreeStart: %p, pFreeEnd: %p.", nFree, pPage->pFreeStart, pPage->pFreeEnd);
ASSERT(pPage->pFreeEnd - pPage->pData == TDB_PAGE_CCELLS(pPage)); return -1;
}
if (TDB_PAGE_NFREE(pPage) != nFree) {
tdbError("tdb/page-allocate: nFree: %d, page free: %d.", nFree, TDB_PAGE_NFREE(pPage));
return -1;
}
if (pPage->pFreeEnd - pPage->pData != TDB_PAGE_CCELLS(pPage)) {
tdbError("tdb/page-allocate: ccells: %d, pFreeStart: %p, pData: %p.", TDB_PAGE_CCELLS(pPage), pPage->pFreeStart,
pPage->pData);
return -1;
}
pPage->pFreeEnd -= szCell; pPage->pFreeEnd -= szCell;
pCell = pPage->pFreeEnd; pCell = pPage->pFreeEnd;
TDB_PAGE_CCELLS_SET(pPage, pPage->pFreeEnd - pPage->pData); TDB_PAGE_CCELLS_SET(pPage, pPage->pFreeEnd - pPage->pData);
_alloc_finish: _alloc_finish:
ASSERT(pCell); if (NULL == pCell) {
tdbError("tdb/page-allocate: null ptr pCell.");
return -1;
}
pPage->pFreeStart += TDB_PAGE_OFFSET_SIZE(pPage); pPage->pFreeStart += TDB_PAGE_OFFSET_SIZE(pPage);
TDB_PAGE_NFREE_SET(pPage, nFree - szCell - TDB_PAGE_OFFSET_SIZE(pPage)); TDB_PAGE_NFREE_SET(pPage, nFree - szCell - TDB_PAGE_OFFSET_SIZE(pPage));
*ppCell = pCell; *ppCell = pCell;
...@@ -375,9 +445,18 @@ static int tdbPageFree(SPage *pPage, int idx, SCell *pCell, int szCell) { ...@@ -375,9 +445,18 @@ static int tdbPageFree(SPage *pPage, int idx, SCell *pCell, int szCell) {
u8 *dest; u8 *dest;
u8 *src; u8 *src;
ASSERT(pCell >= pPage->pFreeEnd); if (pCell < pPage->pFreeEnd) {
ASSERT(pCell + szCell <= (u8 *)(pPage->pPageFtr)); tdbError("tdb/page-free: invalid cell, cell: %p, free end: %p", pCell, pPage->pFreeEnd);
ASSERT(pCell == TDB_PAGE_CELL_AT(pPage, idx)); return -1;
}
if (pCell + szCell > (u8 *)(pPage->pPageFtr)) {
tdbError("tdb/page-free: cell crosses page footer, cell: %p, size: %d footer: %p", pCell, szCell, pPage->pFreeEnd);
return -1;
}
if (pCell != TDB_PAGE_CELL_AT(pPage, idx)) {
tdbError("tdb/page-free: cell pos incorrect, cell: %p, pos: %p", pCell, TDB_PAGE_CELL_AT(pPage, idx));
return -1;
}
nFree = TDB_PAGE_NFREE(pPage); nFree = TDB_PAGE_NFREE(pPage);
...@@ -390,7 +469,8 @@ static int tdbPageFree(SPage *pPage, int idx, SCell *pCell, int szCell) { ...@@ -390,7 +469,8 @@ static int tdbPageFree(SPage *pPage, int idx, SCell *pCell, int szCell) {
pPage->pPageMethods->setFreeCellInfo(pCell, szCell, cellFree); pPage->pPageMethods->setFreeCellInfo(pCell, szCell, cellFree);
TDB_PAGE_FCELL_SET(pPage, pCell - pPage->pData); TDB_PAGE_FCELL_SET(pPage, pCell - pPage->pData);
} else { } else {
ASSERT(0); tdbError("tdb/page-free: invalid cell size: %d", szCell);
return -1;
} }
} }
...@@ -417,7 +497,10 @@ static int tdbPageDefragment(SPage *pPage) { ...@@ -417,7 +497,10 @@ static int tdbPageDefragment(SPage *pPage) {
nFree = TDB_PAGE_NFREE(pPage); nFree = TDB_PAGE_NFREE(pPage);
nCells = TDB_PAGE_NCELLS(pPage); nCells = TDB_PAGE_NCELLS(pPage);
ASSERT(pPage->pFreeEnd - pPage->pFreeStart < nFree); if (pPage->pFreeEnd - pPage->pFreeStart >= nFree) {
tdbError("tdb/page-defragment: invalid free range, nFree: %d.", nFree);
return -1;
}
// Loop to compact the page content // Loop to compact the page content
// Here we use an O(n^2) algorithm to do the job since // Here we use an O(n^2) algorithm to do the job since
...@@ -443,11 +526,19 @@ static int tdbPageDefragment(SPage *pPage) { ...@@ -443,11 +526,19 @@ static int tdbPageDefragment(SPage *pPage) {
} }
} }
ASSERT(pCell != NULL); if (NULL == pCell) {
tdbError("tdb/page-defragment: null ptr pCell.");
return -1;
}
szCell = (*pPage->xCellSize)(pPage, pCell, 0, NULL, NULL); szCell = (*pPage->xCellSize)(pPage, pCell, 0, NULL, NULL);
ASSERT(pCell + szCell <= pNextCell); if (pCell + szCell > pNextCell) {
tdbError("tdb/page-defragment: invalid cell range, pCell: %p, szCell: %d, pNextCell: %p.", pCell, szCell,
pNextCell);
return -1;
}
if (pCell + szCell < pNextCell) { if (pCell + szCell < pNextCell) {
memmove(pNextCell - szCell, pCell, szCell); memmove(pNextCell - szCell, pCell, szCell);
} }
...@@ -457,7 +548,11 @@ static int tdbPageDefragment(SPage *pPage) { ...@@ -457,7 +548,11 @@ static int tdbPageDefragment(SPage *pPage) {
TDB_PAGE_CELL_OFFSET_AT_SET(pPage, idx, pNextCell - pPage->pData); TDB_PAGE_CELL_OFFSET_AT_SET(pPage, idx, pNextCell - pPage->pData);
} }
ASSERT(pPage->pFreeEnd - pPage->pFreeStart == nFree); if (pPage->pFreeEnd - pPage->pFreeStart != nFree) {
tdbError("tdb/page-defragment: invalid free range, nFree: %d.", nFree);
return -1;
}
TDB_PAGE_CCELLS_SET(pPage, pPage->pFreeEnd - pPage->pData); TDB_PAGE_CCELLS_SET(pPage, pPage->pFreeEnd - pPage->pData);
TDB_PAGE_FCELL_SET(pPage, 0); TDB_PAGE_FCELL_SET(pPage, 0);
...@@ -483,39 +578,59 @@ typedef struct { ...@@ -483,39 +578,59 @@ typedef struct {
// cellNum // cellNum
static inline int getPageCellNum(SPage *pPage) { return ((SPageHdr *)(pPage->pPageHdr))[0].cellNum; } static inline int getPageCellNum(SPage *pPage) { return ((SPageHdr *)(pPage->pPageHdr))[0].cellNum; }
static inline void setPageCellNum(SPage *pPage, int cellNum) { static inline void setPageCellNum(SPage *pPage, int cellNum) {
ASSERT(cellNum < 65536); if (cellNum >= 65536) {
tdbError("tdb/page-set-cell-num: invalid cellNum: %d.", cellNum);
return;
}
((SPageHdr *)(pPage->pPageHdr))[0].cellNum = (u16)cellNum; ((SPageHdr *)(pPage->pPageHdr))[0].cellNum = (u16)cellNum;
} }
// cellBody // cellBody
static inline int getPageCellBody(SPage *pPage) { return ((SPageHdr *)(pPage->pPageHdr))[0].cellBody; } static inline int getPageCellBody(SPage *pPage) { return ((SPageHdr *)(pPage->pPageHdr))[0].cellBody; }
static inline void setPageCellBody(SPage *pPage, int cellBody) { static inline void setPageCellBody(SPage *pPage, int cellBody) {
ASSERT(cellBody < 65536); if (cellBody >= 65536) {
tdbError("tdb/page-set-cell-body: invalid cellBody: %d.", cellBody);
return;
}
((SPageHdr *)(pPage->pPageHdr))[0].cellBody = (u16)cellBody; ((SPageHdr *)(pPage->pPageHdr))[0].cellBody = (u16)cellBody;
} }
// cellFree // cellFree
static inline int getPageCellFree(SPage *pPage) { return ((SPageHdr *)(pPage->pPageHdr))[0].cellFree; } static inline int getPageCellFree(SPage *pPage) { return ((SPageHdr *)(pPage->pPageHdr))[0].cellFree; }
static inline void setPageCellFree(SPage *pPage, int cellFree) { static inline void setPageCellFree(SPage *pPage, int cellFree) {
ASSERT(cellFree < 65536); if (cellFree >= 65536) {
tdbError("tdb/page-set-cell-free: invalid cellFree: %d.", cellFree);
return;
}
((SPageHdr *)(pPage->pPageHdr))[0].cellFree = (u16)cellFree; ((SPageHdr *)(pPage->pPageHdr))[0].cellFree = (u16)cellFree;
} }
// nFree // nFree
static inline int getPageNFree(SPage *pPage) { return ((SPageHdr *)(pPage->pPageHdr))[0].nFree; } static inline int getPageNFree(SPage *pPage) { return ((SPageHdr *)(pPage->pPageHdr))[0].nFree; }
static inline void setPageNFree(SPage *pPage, int nFree) { static inline void setPageNFree(SPage *pPage, int nFree) {
ASSERT(nFree < 65536); if (nFree >= 65536) {
tdbError("tdb/page-set-nfree: invalid nFree: %d.", nFree);
return;
}
((SPageHdr *)(pPage->pPageHdr))[0].nFree = (u16)nFree; ((SPageHdr *)(pPage->pPageHdr))[0].nFree = (u16)nFree;
} }
// cell offset // cell offset
static inline int getPageCellOffset(SPage *pPage, int idx) { static inline int getPageCellOffset(SPage *pPage, int idx) {
ASSERT(idx >= 0 && idx < getPageCellNum(pPage)); int cellNum = getPageCellNum(pPage);
if (idx < 0 || idx >= cellNum) {
tdbError("tdb/page-cell-offset: idx: %d out of range[%d, %d).", idx, 0, cellNum);
return -1;
}
return ((u16 *)pPage->pCellIdx)[idx]; return ((u16 *)pPage->pCellIdx)[idx];
} }
static inline void setPageCellOffset(SPage *pPage, int idx, int offset) { static inline void setPageCellOffset(SPage *pPage, int idx, int offset) {
ASSERT(offset < 65536); if (offset >= 65536) {
tdbError("tdb/page-set-cell-offset: invalid offset: %d.", offset);
return;
}
((u16 *)pPage->pCellIdx)[idx] = (u16)offset; ((u16 *)pPage->pCellIdx)[idx] = (u16)offset;
} }
...@@ -590,7 +705,12 @@ static inline void setLPageNFree(SPage *pPage, int nFree) { ...@@ -590,7 +705,12 @@ static inline void setLPageNFree(SPage *pPage, int nFree) {
// cell offset // cell offset
static inline int getLPageCellOffset(SPage *pPage, int idx) { static inline int getLPageCellOffset(SPage *pPage, int idx) {
ASSERT(idx >= 0 && idx < getLPageCellNum(pPage)); int cellNum = getLPageCellNum(pPage);
if (idx < 0 || idx >= cellNum) {
tdbError("tdb/lpage-cell-offset: idx: %d out of range[%d, %d).", idx, 0, cellNum);
return -1;
}
return TDB_GET_U24(pPage->pCellIdx + 3 * idx); return TDB_GET_U24(pPage->pCellIdx + 3 * idx);
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
*/ */
#include "tdbInt.h" #include "tdbInt.h"
/*
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct { typedef struct {
u8 hdrString[16]; u8 hdrString[16];
...@@ -26,7 +26,7 @@ typedef struct { ...@@ -26,7 +26,7 @@ typedef struct {
#pragma pack(pop) #pragma pack(pop)
TDB_STATIC_ASSERT(sizeof(SFileHdr) == 128, "Size of file header is not correct"); TDB_STATIC_ASSERT(sizeof(SFileHdr) == 128, "Size of file header is not correct");
*/
struct hashset_st { struct hashset_st {
size_t nbits; size_t nbits;
size_t mask; size_t mask;
...@@ -234,7 +234,6 @@ int tdbPagerWrite(SPager *pPager, SPage *pPage) { ...@@ -234,7 +234,6 @@ int tdbPagerWrite(SPager *pPager, SPage *pPage) {
int ret; int ret;
SPage **ppPage; SPage **ppPage;
// ASSERT(pPager->inTran);
if (pPage->isDirty) return 0; if (pPage->isDirty) return 0;
// ref page one more time so the page will not be release // ref page one more time so the page will not be release
...@@ -243,23 +242,8 @@ int tdbPagerWrite(SPager *pPager, SPage *pPage) { ...@@ -243,23 +242,8 @@ int tdbPagerWrite(SPager *pPager, SPage *pPage) {
// Set page as dirty // Set page as dirty
pPage->isDirty = 1; pPage->isDirty = 1;
/*
// Add page to dirty list(TODO: NOT use O(n^2) algorithm)
for (ppPage = &pPager->pDirty; (*ppPage) && TDB_PAGE_PGNO(*ppPage) < TDB_PAGE_PGNO(pPage);
ppPage = &((*ppPage)->pDirtyNext)) {
}
if (*ppPage && TDB_PAGE_PGNO(*ppPage) == TDB_PAGE_PGNO(pPage)) {
tdbUnrefPage(pPage);
return 0; tdbTrace("tdb/pager-write: put page: %p %d to dirty tree: %p", pPage, TDB_PAGE_PGNO(pPage), &pPager->rbt);
}
ASSERT(*ppPage == NULL || TDB_PAGE_PGNO(*ppPage) > TDB_PAGE_PGNO(pPage));
pPage->pDirtyNext = *ppPage;
*ppPage = pPage;
*/
tdbTrace("put page: %p %d to dirty tree: %p", pPage, TDB_PAGE_PGNO(pPage), &pPager->rbt);
tRBTreePut(&pPager->rbt, (SRBTreeNode *)pPage); tRBTreePut(&pPager->rbt, (SRBTreeNode *)pPage);
// Write page to journal if neccessary // Write page to journal if neccessary
...@@ -327,7 +311,11 @@ int tdbPagerCommit(SPager *pPager, TXN *pTxn) { ...@@ -327,7 +311,11 @@ int tdbPagerCommit(SPager *pPager, TXN *pTxn) {
while ((pNode = tRBTreeIterNext(&iter)) != NULL) { while ((pNode = tRBTreeIterNext(&iter)) != NULL) {
pPage = (SPage *)pNode; pPage = (SPage *)pNode;
ASSERT(pPage->nOverflow == 0); if (pPage->nOverflow != 0) {
tdbError("tdb/pager-commit: %p, pPage: %p, ovfl: %d, commit page failed.", pPager, pPage, pPage->nOverflow);
return -1;
}
ret = tdbPagerPWritePageToDB(pPager, pPage); ret = tdbPagerPWritePageToDB(pPager, pPage);
if (ret < 0) { if (ret < 0) {
tdbError("failed to write page to db since %s", tstrerror(terrno)); tdbError("failed to write page to db since %s", tstrerror(terrno));
...@@ -652,12 +640,15 @@ int tdbPagerFetchPage(SPager *pPager, SPgno *ppgno, SPage **ppPage, int (*initPa ...@@ -652,12 +640,15 @@ int tdbPagerFetchPage(SPager *pPager, SPgno *ppgno, SPage **ppPage, int (*initPa
loadPage = 0; loadPage = 0;
ret = tdbPagerAllocPage(pPager, &pgno); ret = tdbPagerAllocPage(pPager, &pgno);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/pager: %p, ret: %d pgno: %" PRIu32 ", alloc page failed.", pPager, ret, pgno);
return -1; return -1;
} }
} }
ASSERT(pgno > 0); if (pgno == 0) {
tdbError("tdb/pager: %p, ret: %d pgno: %" PRIu32 ", alloc page failed.", pPager, ret, pgno);
return -1;
}
// fetch a page container // fetch a page container
memcpy(&pgid, pPager->fid, TDB_FILE_ID_LEN); memcpy(&pgid, pPager->fid, TDB_FILE_ID_LEN);
...@@ -671,7 +662,7 @@ int tdbPagerFetchPage(SPager *pPager, SPgno *ppgno, SPage **ppPage, int (*initPa ...@@ -671,7 +662,7 @@ int tdbPagerFetchPage(SPager *pPager, SPgno *ppgno, SPage **ppPage, int (*initPa
if (!TDB_PAGE_INITIALIZED(pPage)) { if (!TDB_PAGE_INITIALIZED(pPage)) {
ret = tdbPagerInitPage(pPager, pPage, initPage, arg, loadPage); ret = tdbPagerInitPage(pPager, pPage, initPage, arg, loadPage);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/pager: %p, pPage: %p, init page failed.", pPager, pPage);
return -1; return -1;
} }
} }
...@@ -679,8 +670,14 @@ int tdbPagerFetchPage(SPager *pPager, SPgno *ppgno, SPage **ppPage, int (*initPa ...@@ -679,8 +670,14 @@ int tdbPagerFetchPage(SPager *pPager, SPgno *ppgno, SPage **ppPage, int (*initPa
// printf("thread %" PRId64 " pager fetch page %d pgno %d ppage %p\n", taosGetSelfPthreadId(), pPage->id, // printf("thread %" PRId64 " pager fetch page %d pgno %d ppage %p\n", taosGetSelfPthreadId(), pPage->id,
// TDB_PAGE_PGNO(pPage), pPage); // TDB_PAGE_PGNO(pPage), pPage);
ASSERT(TDB_PAGE_INITIALIZED(pPage)); if (!TDB_PAGE_INITIALIZED(pPage)) {
ASSERT(pPage->pPager == pPager); tdbError("tdb/pager: %p, pPage: %p, fetch page uninited.", pPager, pPage);
return -1;
}
if (pPage->pPager != pPager) {
tdbError("tdb/pager: %p/%p, fetch page failed.", pPager, pPage->pPager);
return -1;
}
*ppgno = pgno; *ppgno = pgno;
*ppPage = pPage; *ppPage = pPage;
...@@ -722,8 +719,10 @@ int tdbPagerAllocPage(SPager *pPager, SPgno *ppgno) { ...@@ -722,8 +719,10 @@ int tdbPagerAllocPage(SPager *pPager, SPgno *ppgno) {
return -1; return -1;
} }
ASSERT(*ppgno != 0); if (*ppgno == 0) {
tdbError("tdb/pager:%p, alloc new page failed.", pPager);
return -1;
}
return 0; return 0;
} }
...@@ -752,7 +751,6 @@ static int tdbPagerInitPage(SPager *pPager, SPage *pPage, int (*initPage)(SPage ...@@ -752,7 +751,6 @@ static int tdbPagerInitPage(SPager *pPager, SPage *pPage, int (*initPage)(SPage
nRead = tdbOsPRead(pPager->fd, pPage->pData, pPage->pageSize, ((i64)pPage->pageSize) * (pgno - 1)); nRead = tdbOsPRead(pPager->fd, pPage->pData, pPage->pageSize, ((i64)pPage->pageSize) * (pgno - 1));
tdbTrace("tdb/pager:%p, pgno:%d, nRead:%" PRId64, pPager, pgno, nRead); tdbTrace("tdb/pager:%p, pgno:%d, nRead:%" PRId64, pPager, pgno, nRead);
if (nRead < pPage->pageSize) { if (nRead < pPage->pageSize) {
ASSERT(0);
tdbError("tdb/pager:%p, pgno:%d, nRead:%" PRId64 "pgSize:%" PRId32, pPager, pgno, nRead, pPage->pageSize); tdbError("tdb/pager:%p, pgno:%d, nRead:%" PRId64 "pgSize:%" PRId32, pPager, pgno, nRead, pPage->pageSize);
TDB_UNLOCK_PAGE(pPage); TDB_UNLOCK_PAGE(pPage);
return -1; return -1;
...@@ -763,7 +761,8 @@ static int tdbPagerInitPage(SPager *pPager, SPage *pPage, int (*initPage)(SPage ...@@ -763,7 +761,8 @@ static int tdbPagerInitPage(SPager *pPager, SPage *pPage, int (*initPage)(SPage
ret = (*initPage)(pPage, arg, init); ret = (*initPage)(pPage, arg, init);
if (ret < 0) { if (ret < 0) {
ASSERT(0); tdbError("tdb/pager:%p, pgno:%d, nRead:%" PRId64 "pgSize:%" PRId32 " init page failed.", pPager, pgno, nRead,
pPage->pageSize);
TDB_UNLOCK_PAGE(pPage); TDB_UNLOCK_PAGE(pPage);
return -1; return -1;
} }
...@@ -782,7 +781,8 @@ static int tdbPagerInitPage(SPager *pPager, SPage *pPage, int (*initPage)(SPage ...@@ -782,7 +781,8 @@ static int tdbPagerInitPage(SPager *pPager, SPage *pPage, int (*initPage)(SPage
} }
} }
} else { } else {
ASSERT(0); tdbError("tdb/pager:%p, pgno:%d, nRead:%" PRId64 "pgSize:%" PRId32 " lock page failed.", pPager, pgno, nRead,
pPage->pageSize);
return -1; return -1;
} }
......
...@@ -105,8 +105,6 @@ int tdbTbOpen(const char *tbname, int keyLen, int valLen, tdb_cmpr_fn_t keyCmprF ...@@ -105,8 +105,6 @@ int tdbTbOpen(const char *tbname, int keyLen, int valLen, tdb_cmpr_fn_t keyCmprF
#endif #endif
ASSERT(pPager != NULL);
if (rollback) { if (rollback) {
ret = tdbPagerRestoreJournals(pPager); ret = tdbPagerRestoreJournals(pPager);
if (ret < 0) { if (ret < 0) {
......
...@@ -18,7 +18,10 @@ ...@@ -18,7 +18,10 @@
int tdbTxnOpen(TXN *pTxn, int64_t txnid, void *(*xMalloc)(void *, size_t), void (*xFree)(void *, void *), void *xArg, int tdbTxnOpen(TXN *pTxn, int64_t txnid, void *(*xMalloc)(void *, size_t), void (*xFree)(void *, void *), void *xArg,
int flags) { int flags) {
// not support read-committed version at the moment // not support read-committed version at the moment
ASSERT(flags == 0 || flags == (TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED)); if (flags != 0 && flags != (TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED)) {
tdbError("tdb/txn: invalid txn flags: %" PRId32, flags);
return -1;
}
pTxn->flags = flags; pTxn->flags = flags;
pTxn->txnId = txnid; pTxn->txnId = txnid;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册