From 284acb1f3452a4cd7ce1d91b89d4fbb322f06b7c Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 15 Dec 2022 17:17:18 +0800 Subject: [PATCH] opti:json parser --- source/client/inc/clientSml.h | 1 + source/client/src/clientSmlJson.c | 79 ++++++++++++++++++++++++++++++- source/client/test/smlTest.cpp | 7 ++- 3 files changed, 84 insertions(+), 3 deletions(-) diff --git a/source/client/inc/clientSml.h b/source/client/inc/clientSml.h index 6a445432f0..e43d2a9177 100644 --- a/source/client/inc/clientSml.h +++ b/source/client/inc/clientSml.h @@ -178,6 +178,7 @@ typedef struct { SSmlMsgBuf msgBuf; // cJSON *root; // for parse json + int8_t offset[4]; SSmlLineInfo *lines; // element is SSmlLineInfo // diff --git a/source/client/src/clientSmlJson.c b/source/client/src/clientSmlJson.c index b36cad5ed9..1c2f62abf6 100644 --- a/source/client/src/clientSmlJson.c +++ b/source/client/src/clientSmlJson.c @@ -233,12 +233,19 @@ static char* smlJsonGetObj(char *payload){ return NULL; } -static inline void smlJsonParseObj(char **start, SSmlLineInfo *element){ +static inline void smlJsonParseObjFirst(char **start, SSmlLineInfo *element, int8_t *offset){ + int index = 0; while(*(*start)){ if((*start)[0] != '"'){ (*start)++; continue; } + + if(unlikely(index >= 4)) { + uError("index >= 4, %s", *start) + break; + } + char *sTmp = *start; if((*start)[1] == 'm' && (*start)[2] == 'e' && (*start)[3] == 't' && (*start)[4] == 'r' && (*start)[5] == 'i' && (*start)[6] == 'c' && (*start)[7] == '"'){ @@ -247,6 +254,7 @@ static inline void smlJsonParseObj(char **start, SSmlLineInfo *element){ while(*(*start)){ if(unlikely(!isInQuote && *(*start) == '"')){ (*start)++; + offset[index++] = *start - sTmp; element->measure = (*start); isInQuote = true; continue; @@ -267,6 +275,7 @@ static inline void smlJsonParseObj(char **start, SSmlLineInfo *element){ if(unlikely(!hasColon && *(*start) == ':')){ (*start)++; JUMP_JSON_SPACE((*start)) + offset[index++] = *start - sTmp; element->timestamp = (*start); hasColon = true; continue; @@ -287,6 +296,7 @@ static inline void smlJsonParseObj(char **start, SSmlLineInfo *element){ if(unlikely(!hasColon && *(*start) == ':')){ (*start)++; JUMP_JSON_SPACE((*start)) + offset[index++] = *start - sTmp; element->cols = (*start); hasColon = true; continue; @@ -305,6 +315,7 @@ static inline void smlJsonParseObj(char **start, SSmlLineInfo *element){ if(unlikely(*(*start) == ':')){ (*start)++; JUMP_JSON_SPACE((*start)) + offset[index++] = *start - sTmp; element->tags = (*start); char* tmp = smlJsonGetObj((*start)); if(tmp){ @@ -324,10 +335,74 @@ static inline void smlJsonParseObj(char **start, SSmlLineInfo *element){ } } +static inline void smlJsonParseObj(char **start, SSmlLineInfo *element, int8_t *offset){ + int index = 0; + while(*(*start)){ + if((*start)[0] != '"'){ + (*start)++; + continue; + } + + if(unlikely(index >= 4)) { + uError("index >= 4, %s", *start) + break; + } + if((*start)[1] == 'm'){ + (*start) += offset[index++]; + element->measure = *start; + while(*(*start)){ + if(unlikely(*(*start) == '"')){ + element->measureLen = (*start) - element->measure; + break; + } + (*start)++; + } + }else if((*start)[1] == 't' && (*start)[2] == 'i'){ + (*start) += offset[index++]; + element->timestamp = *start; + while(*(*start)){ + if(unlikely(*(*start) == ',' || *(*start) == '}' || (*(*start)) <= 32)){ + element->timestampLen = (*start) - element->timestamp; + break; + } + (*start)++; + } + }else if((*start)[1] == 'v'){ + (*start) += offset[index++]; + element->cols = *start; + while(*(*start)){ + if(unlikely( *(*start) == ',' || *(*start) == '}' || (*(*start)) <= 32)){ + element->colsLen = (*start) - element->cols; + break; + } + (*start)++; + } + }else if((*start)[1] == 't' && (*start)[2] == 'a'){ + (*start) += offset[index++]; + element->tags = (*start); + char* tmp = smlJsonGetObj((*start)); + if(tmp){ + element->tagsLen = tmp - (*start); + *start = tmp; + } + break; + } + if(*(*start) == '}'){ + (*start)++; + break; + } + (*start)++; + } +} + static int32_t smlParseJSONString(SSmlHandle *info, char **start, SSmlLineInfo *elements) { int32_t ret = TSDB_CODE_SUCCESS; - smlJsonParseObj(start, elements); + if(info->offset[0] == 0){ + smlJsonParseObjFirst(start, elements, info->offset); + }else{ + smlJsonParseObj(start, elements, info->offset); + } if(**start == '\0') return TSDB_CODE_SUCCESS; SSmlKv kv = {.key = VALUE, .keyLen = VALUE_LEN, .value = elements->cols, .length = (size_t)elements->colsLen}; diff --git a/source/client/test/smlTest.cpp b/source/client/test/smlTest.cpp index ecad51698c..91486aa96a 100644 --- a/source/client/test/smlTest.cpp +++ b/source/client/test/smlTest.cpp @@ -497,9 +497,14 @@ TEST(testCase, smlParseTelnetLine_diff_json_type2_Test) { }; for (int i = 0; i < sizeof(sql) / sizeof(sql[0]); i++) { char *dataPointStart = (char *)sql[i]; + int8_t offset[4] = {0}; while (1) { SSmlLineInfo elements = {0}; - smlJsonParseObj(&dataPointStart, &elements); + if(offset[0] == 0){ + smlJsonParseObjFirst(&dataPointStart, &elements, offset); + }else{ + smlJsonParseObj(&dataPointStart, &elements, offset); + } if(*dataPointStart == '\0') break; SArray *tags = smlJsonParseTags(elements.tags, elements.tags + elements.tagsLen);