From 267463863ac54ed8fae4aa66d51007a0ac7b4104 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Fri, 13 May 2022 09:32:15 +0000 Subject: [PATCH] feat: tag index --- source/common/src/ttypes.c | 3 +- source/dnode/vnode/src/inc/meta.h | 6 ++- source/dnode/vnode/src/meta/metaOpen.c | 48 +++++++++-------- source/dnode/vnode/src/meta/metaTable.c | 71 +++++++++++++++++++++++-- 4 files changed, 99 insertions(+), 29 deletions(-) diff --git a/source/common/src/ttypes.c b/source/common/src/ttypes.c index 3fd2ef8e73..b3999a49e7 100644 --- a/source/common/src/ttypes.c +++ b/source/common/src/ttypes.c @@ -402,7 +402,8 @@ tDataTypeDescriptor tDataTypes[TSDB_DATA_TYPE_MAX] = { {TSDB_DATA_TYPE_UINT, 12, INT_BYTES, "INT UNSIGNED", 0, UINT32_MAX, tsCompressInt, tsDecompressInt, getStatics_u32}, {TSDB_DATA_TYPE_UBIGINT, 15, LONG_BYTES, "BIGINT UNSIGNED", 0, UINT64_MAX, tsCompressBigint, tsDecompressBigint, getStatics_u64}, - {TSDB_DATA_TYPE_JSON, 4, TSDB_MAX_JSON_TAG_LEN, "JSON", 0, 0, tsCompressString, tsDecompressString, getStatics_nchr}, + {TSDB_DATA_TYPE_JSON, 4, TSDB_MAX_JSON_TAG_LEN, "JSON", 0, 0, tsCompressString, tsDecompressString, + getStatics_nchr}, }; char tTokenTypeSwitcher[13] = { diff --git a/source/dnode/vnode/src/inc/meta.h b/source/dnode/vnode/src/inc/meta.h index f1917d5fea..60b3a889ef 100644 --- a/source/dnode/vnode/src/inc/meta.h +++ b/source/dnode/vnode/src/inc/meta.h @@ -96,8 +96,10 @@ typedef struct { #pragma pack(push, 1) typedef struct { tb_uid_t suid; - int16_t cid; - char data[]; + int32_t cid; + uint8_t isNull : 1; + uint8_t type : 7; + uint8_t data[]; // val + uid } STagIdxKey; #pragma pack(pop) diff --git a/source/dnode/vnode/src/meta/metaOpen.c b/source/dnode/vnode/src/meta/metaOpen.c index 8b3f555f4f..07422e3193 100644 --- a/source/dnode/vnode/src/meta/metaOpen.c +++ b/source/dnode/vnode/src/meta/metaOpen.c @@ -227,8 +227,7 @@ static int ctbIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kL static int tagIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) { STagIdxKey *pTagIdxKey1 = (STagIdxKey *)pKey1; STagIdxKey *pTagIdxKey2 = (STagIdxKey *)pKey2; - int8_t *p1, *p2; - int8_t type; + tb_uid_t uid1, uid2; int c; // compare suid @@ -245,31 +244,34 @@ static int tagIdxKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kL return -1; } - // compare value - p1 = pTagIdxKey1->data; - p2 = pTagIdxKey2->data; - ASSERT(p1[0] == p2[0]); - type = p1[0]; + ASSERT(pTagIdxKey1->type == pTagIdxKey2->type); - p1++; - p2++; - - c = doCompare(p1, p2, type, 0); - if (c) return c; - - if (IS_VAR_DATA_TYPE(type)) { - p1 = p1 + varDataTLen(p1); - p2 = p2 + varDataTLen(p2); - } else { - p1 = p1 + tDataTypes[type].bytes; - p2 = p2 + tDataTypes[type].bytes; + // check NULL, NULL is always the smallest + if (pTagIdxKey1->isNull && !pTagIdxKey2->isNull) { + return -1; + } else if (!pTagIdxKey1->isNull && pTagIdxKey2->isNull) { + return 1; + } else if (!pTagIdxKey1->isNull && !pTagIdxKey2->isNull) { + // all not NULL, compr tag vals + c = doCompare(pTagIdxKey1->data, pTagIdxKey2->data, pTagIdxKey1->type, 0); + if (c) return c; + + if (IS_VAR_DATA_TYPE(pTagIdxKey1->type)) { + uid1 = *(tb_uid_t *)(pTagIdxKey1->data + varDataTLen(pTagIdxKey1->data)); + uid2 = *(tb_uid_t *)(pTagIdxKey2->data + varDataTLen(pTagIdxKey2->data)); + } else { + uid1 = *(tb_uid_t *)(pTagIdxKey1->data + tDataTypes[pTagIdxKey1->type].bytes); + uid2 = *(tb_uid_t *)(pTagIdxKey2->data + tDataTypes[pTagIdxKey2->type].bytes); + } } - // compare suid - if (*(tb_uid_t *)p1 > *(tb_uid_t *)p2) { - return 1; - } else if (*(tb_uid_t *)p1 < *(tb_uid_t *)p2) { + // compare uid + if (uid1 < uid2) { return -1; + } else if (uid1 > uid2) { + return 1; + } else { + return 0; } return 0; diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c index 20248f39fb..d666bd22c1 100644 --- a/source/dnode/vnode/src/meta/metaTable.c +++ b/source/dnode/vnode/src/meta/metaTable.c @@ -22,7 +22,7 @@ static int metaUpdateNameIdx(SMeta *pMeta, const SMetaEntry *pME); static int metaUpdateTtlIdx(SMeta *pMeta, const SMetaEntry *pME); static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME); static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME); -static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pME); +static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry); int metaCreateSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) { SMetaEntry me = {0}; @@ -389,8 +389,73 @@ static int metaUpdateCtbIdx(SMeta *pMeta, const SMetaEntry *pME) { return tdbDbInsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), NULL, 0, &pMeta->txn); } -static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pME) { - // TODO +static int metaCreateTagIdxKey(tb_uid_t suid, int32_t cid, const void *pTagData, int8_t type, tb_uid_t uid, + STagIdxKey **ppTagIdxKey, int32_t *nTagIdxKey) { + int32_t nTagData = 0; + + if (pTagData) { + if (IS_VAR_DATA_TYPE(type)) { + nTagData = varDataTLen(pTagData); + } else { + nTagData = tDataTypes[type].bytes; + } + } + *nTagIdxKey = sizeof(STagIdxKey) + nTagData + sizeof(tb_uid_t); + + *ppTagIdxKey = (STagIdxKey *)taosMemoryMalloc(*nTagIdxKey); + if (*ppTagIdxKey == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + (*ppTagIdxKey)->suid = suid; + (*ppTagIdxKey)->cid = cid; + (*ppTagIdxKey)->isNull = (pTagData == NULL) ? 1 : 0; + (*ppTagIdxKey)->type = type; + if (nTagData) memcpy((*ppTagIdxKey)->data, pTagData, nTagData); + *(tb_uid_t *)((*ppTagIdxKey)->data + nTagData) = uid; + + return 0; +} + +static void metaDestroyTagIdxKey(STagIdxKey *pTagIdxKey) { + if (pTagIdxKey) taosMemoryFree(pTagIdxKey); +} + +static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) { + void *pData = NULL; + int nData = 0; + STbDbKey tbDbKey = {0}; + SMetaEntry stbEntry = {0}; + STagIdxKey *pTagIdxKey = NULL; + int32_t nTagIdxKey; + const SSchema *pTagColumn; // = &stbEntry.stbEntry.schema.pSchema[0]; + const void *pTagData = NULL; // + SDecoder dc = {0}; + + // get super table + tdbDbGet(pMeta->pUidIdx, &pCtbEntry->ctbEntry.suid, sizeof(tb_uid_t), &pData, &nData); + tbDbKey.uid = pCtbEntry->ctbEntry.suid; + tbDbKey.version = *(int64_t *)pData; + tdbDbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pData, &nData); + + tDecoderInit(&dc, pData, nData); + metaDecodeEntry(&dc, &stbEntry); + + pTagColumn = &stbEntry.stbEntry.schemaTag.pSchema[0]; + pTagData = tdGetKVRowValOfCol((const SKVRow)pCtbEntry->ctbEntry.pTags, pTagColumn->colId); + + // update tag index + if (metaCreateTagIdxKey(pCtbEntry->ctbEntry.suid, pTagColumn->colId, pTagData, pTagColumn->type, pCtbEntry->uid, + &pTagIdxKey, &nTagIdxKey) < 0) { + return -1; + } + tdbDbInsert(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, NULL, 0, &pMeta->txn); + metaDestroyTagIdxKey(pTagIdxKey); + + tDecoderClear(&dc); + tdbFree(pData); + return 0; } -- GitLab