diff --git a/mpp/base/inc/mpp_trie.h b/mpp/base/inc/mpp_trie.h index 90b8cc3f..acfe9c0b 100644 --- a/mpp/base/inc/mpp_trie.h +++ b/mpp/base/inc/mpp_trie.h @@ -39,36 +39,49 @@ typedef void* MppTrie; * +---------------+ * | MppTrieInfo | * +---------------+ - * | User context | - * +---------------+ * | name string | * +---------------+ + * | User context | + * +---------------+ */ typedef struct MppTrieInfo_t { - const char *name; - void *ctx; - RK_S16 index; - RK_S16 str_len; + RK_U32 index : 12; + RK_U32 ctx_len : 12; + RK_U32 str_len : 8; } MppTrieInfo; #ifdef __cplusplus extern "C" { #endif -MPP_RET mpp_trie_init(MppTrie *trie, RK_S32 info_size); +MPP_RET mpp_trie_init(MppTrie *trie, const char *name); MPP_RET mpp_trie_deinit(MppTrie trie); /* Add NULL info to mark the last trie entry */ -MPP_RET mpp_trie_add_info(MppTrie trie, const char *name, void *ctx); +MPP_RET mpp_trie_add_info(MppTrie trie, const char *name, void *ctx, RK_U32 ctx_len); +MPP_RET mpp_trie_import(MppTrie trie, void *root); RK_S32 mpp_trie_get_node_count(MppTrie trie); RK_S32 mpp_trie_get_info_count(MppTrie trie); RK_S32 mpp_trie_get_buf_size(MppTrie trie); +void *mpp_trie_get_node_root(MppTrie trie); + +static inline const char *mpp_trie_info_name(MppTrieInfo *info) +{ + return (info) ? (const char *)(info + 1) : NULL; +} + +static inline void *mpp_trie_info_ctx(MppTrieInfo *info) +{ + return (info) ? (void *)((char *)(info + 1) + info->str_len) : NULL; +} /* trie lookup function */ MppTrieInfo *mpp_trie_get_info(MppTrie trie, const char *name); MppTrieInfo *mpp_trie_get_info_first(MppTrie trie); MppTrieInfo *mpp_trie_get_info_next(MppTrie trie, MppTrieInfo *info); +/* root base lookup function */ +MppTrieInfo *mpp_trie_get_info_from_root(void *root, const char *name); void mpp_trie_dump(MppTrie trie, const char *func); #define mpp_trie_dump_f(trie) mpp_trie_dump(trie, __FUNCTION__) diff --git a/mpp/base/mpp_dec_cfg.cpp b/mpp/base/mpp_dec_cfg.cpp index 4f2a24d0..f2c5bf6c 100644 --- a/mpp/base/mpp_dec_cfg.cpp +++ b/mpp/base/mpp_dec_cfg.cpp @@ -84,7 +84,7 @@ public: (RK_U32)((long)&(((MppDecCfgSet *)0)->field_change.field_data)), \ sizeof((((MppDecCfgSet *)0)->field_change.field_data)), \ }; \ - mpp_trie_add_info(mTrie, #base":"#name, &tmp); \ + mpp_trie_add_info(mTrie, #base":"#name, &tmp, sizeof(tmp)); \ } while (0); #define ENTRY_TABLE(ENTRY) \ @@ -118,7 +118,7 @@ public: MppDecCfgService::MppDecCfgService() : mTrie(NULL) { - MPP_RET ret = mpp_trie_init(&mTrie, sizeof(MppCfgInfo)); + MPP_RET ret = mpp_trie_init(&mTrie, "MppDecCfg"); if (ret) { mpp_err_f("failed to init dec cfg set trie\n"); return ; @@ -126,7 +126,7 @@ MppDecCfgService::MppDecCfgService() : ENTRY_TABLE(EXPAND_AS_TRIE) - mpp_trie_add_info(mTrie, NULL, NULL); + mpp_trie_add_info(mTrie, NULL, NULL, 0); mHead.node_count = mpp_trie_get_node_count(mTrie); mHead.info_count = mpp_trie_get_info_count(mTrie); @@ -224,11 +224,11 @@ MPP_RET mpp_dec_cfg_deinit(MppDecCfg cfg) } \ MppDecCfgImpl *p = (MppDecCfgImpl *)cfg; \ MppTrieInfo *node = MppDecCfgService::get()->get_info(name); \ - MppCfgInfo *info = (MppCfgInfo *)(node ? node->ctx : NULL); \ + MppCfgInfo *info = (MppCfgInfo *)mpp_trie_info_ctx(node); \ if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \ return MPP_NOK; \ } \ - mpp_dec_cfg_dbg_set("name %s type %s\n", node->name, strof_cfg_type(info->data_type)); \ + mpp_dec_cfg_dbg_set("name %s type %s\n", mpp_trie_info_name(node), strof_cfg_type(info->data_type)); \ MPP_RET ret = MPP_CFG_SET_##cfg_type(info, &p->cfg, val); \ return ret; \ } @@ -249,11 +249,11 @@ DEC_CFG_SET_ACCESS(mpp_dec_cfg_set_st, void *, St); } \ MppDecCfgImpl *p = (MppDecCfgImpl *)cfg; \ MppTrieInfo *node = MppDecCfgService::get()->get_info(name); \ - MppCfgInfo *info = (MppCfgInfo *)(node ? node->ctx : NULL); \ + MppCfgInfo *info = (MppCfgInfo *)mpp_trie_info_ctx(node); \ if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \ return MPP_NOK; \ } \ - mpp_dec_cfg_dbg_set("name %s type %s\n", node->name, strof_cfg_type(info->data_type)); \ + mpp_dec_cfg_dbg_set("name %s type %s\n", mpp_trie_info_name(node), strof_cfg_type(info->data_type)); \ MPP_RET ret = MPP_CFG_GET_##cfg_type(info, &p->cfg, val); \ return ret; \ } @@ -276,9 +276,9 @@ void mpp_dec_cfg_show(void) MppTrieInfo *node = root; do { - MppCfgInfo *info = (MppCfgInfo *)node->ctx; + MppCfgInfo *info = (MppCfgInfo *)mpp_trie_info_ctx(node); - mpp_log("%-25s type %s\n", node->name, strof_cfg_type(info->data_type)); + mpp_log("%-25s type %s\n", mpp_trie_info_name(node), strof_cfg_type(info->data_type)); node = srv->get_info_next(node); if (!node) diff --git a/mpp/base/mpp_enc_cfg.cpp b/mpp/base/mpp_enc_cfg.cpp index fc2ab5ce..1130e469 100644 --- a/mpp/base/mpp_enc_cfg.cpp +++ b/mpp/base/mpp_enc_cfg.cpp @@ -85,7 +85,7 @@ public: (RK_U32)((long)&(((MppEncCfgSet *)0)->field_change.field_data)), \ sizeof((((MppEncCfgSet *)0)->field_change.field_data)), \ }; \ - mpp_trie_add_info(mTrie, #base":"#name, &tmp); \ + mpp_trie_add_info(mTrie, #base":"#name, &tmp, sizeof(tmp)); \ } while (0); #define ENTRY_TABLE(ENTRY) \ @@ -276,7 +276,7 @@ MppEncCfgService::MppEncCfgService() : mpp_env_get_u32("mpp_enc_cfg_debug", &mpp_enc_cfg_debug, 0); - ret = mpp_trie_init(&mTrie, sizeof(MppCfgInfo)); + ret = mpp_trie_init(&mTrie, "MppEncCfg"); if (ret) { mpp_err_f("failed to init enc cfg set trie ret %d\n", ret); return ; @@ -284,7 +284,7 @@ MppEncCfgService::MppEncCfgService() : ENTRY_TABLE(EXPAND_AS_TRIE) - mpp_trie_add_info(mTrie, NULL, NULL); + mpp_trie_add_info(mTrie, NULL, NULL, 0); mHead.node_count = mpp_trie_get_node_count(mTrie); mHead.info_count = mpp_trie_get_info_count(mTrie); @@ -390,11 +390,11 @@ MPP_RET mpp_enc_cfg_deinit(MppEncCfg cfg) } \ MppEncCfgImpl *p = (MppEncCfgImpl *)cfg; \ MppTrieInfo *node = MppEncCfgService::get()->get_info(name); \ - MppCfgInfo *info = (MppCfgInfo *)(node ? node->ctx : NULL); \ + MppCfgInfo *info = (MppCfgInfo *)mpp_trie_info_ctx(node); \ if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \ return MPP_NOK; \ } \ - mpp_enc_cfg_dbg_set("name %s type %s\n", node->name, strof_cfg_type(info->data_type)); \ + mpp_enc_cfg_dbg_set("name %s type %s\n", mpp_trie_info_name(node), strof_cfg_type(info->data_type)); \ MPP_RET ret = MPP_CFG_SET_##cfg_type(info, &p->cfg, val); \ return ret; \ } @@ -415,11 +415,11 @@ ENC_CFG_SET_ACCESS(mpp_enc_cfg_set_st, void *, St); } \ MppEncCfgImpl *p = (MppEncCfgImpl *)cfg; \ MppTrieInfo *node = MppEncCfgService::get()->get_info(name); \ - MppCfgInfo *info = (MppCfgInfo *)(node ? node->ctx : NULL); \ + MppCfgInfo *info = (MppCfgInfo *)mpp_trie_info_ctx(node); \ if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \ return MPP_NOK; \ } \ - mpp_enc_cfg_dbg_set("name %s type %s\n", node->name, strof_cfg_type(info->data_type)); \ + mpp_enc_cfg_dbg_set("name %s type %s\n", mpp_trie_info_name(node), strof_cfg_type(info->data_type)); \ MPP_RET ret = MPP_CFG_GET_##cfg_type(info, &p->cfg, val); \ return ret; \ } @@ -442,9 +442,9 @@ void mpp_enc_cfg_show(void) MppTrieInfo *node = root; do { - MppCfgInfo *info = (MppCfgInfo *)node->ctx; + MppCfgInfo *info = (MppCfgInfo *)mpp_trie_info_ctx(node); - mpp_log("%-25s type %s\n", node->name, strof_cfg_type(info->data_type)); + mpp_log("%-25s type %s\n", mpp_trie_info_name(node), strof_cfg_type(info->data_type)); node = srv->get_info_next(node); if (!node) diff --git a/mpp/base/mpp_trie.cpp b/mpp/base/mpp_trie.cpp index 24aac3cf..d066ef9f 100644 --- a/mpp/base/mpp_trie.cpp +++ b/mpp/base/mpp_trie.cpp @@ -34,6 +34,7 @@ #define MPP_TRIE_DBG_LAST (0x00000020) #define MPP_TRIE_DBG_LAST_STEP (0x00000040) #define MPP_TRIE_DBG_LAST_CHECK (0x00000080) +#define MPP_TRIE_DBG_IMPORT (0x00000100) #define trie_dbg(flag, fmt, ...) _mpp_dbg_f(mpp_trie_debug, flag, fmt, ## __VA_ARGS__) #define trie_dbg_func(fmt, ...) trie_dbg(MPP_TRIE_DBG_FUNC, fmt, ## __VA_ARGS__) @@ -43,6 +44,11 @@ #define trie_dbg_walk(fmt, ...) trie_dbg(MPP_TRIE_DBG_WALK, fmt, ## __VA_ARGS__) #define trie_dbg_last(fmt, ...) trie_dbg(MPP_TRIE_DBG_LAST, fmt, ## __VA_ARGS__) +#define MPP_TRIE_KEY_LEN (4) +#define MPP_TRIE_KEY_MAX (1 << (MPP_TRIE_KEY_LEN)) +#define MPP_TRIE_INFO_MAX (1 << 12) +#define MPP_TRIE_NAME_MAX (1 << 12) + #define DEFAULT_NODE_COUNT 900 #define DEFAULT_INFO_COUNT 80 #define INVALID_NODE_ID (-1) @@ -75,17 +81,18 @@ typedef struct MppTrieNode_t { } MppTrieNode; typedef struct MppTrieInfoInt_t { + RK_S32 index; + RK_S32 ctx_len; + RK_S32 str_len; RK_S32 ctx_offset; RK_S32 name_offset; - RK_S32 index; - RK_S32 str_len; } MppTrieInfoInt; typedef struct MppTrieImpl_t { - RK_S32 ctx_size; + char *name; + RK_S32 name_len; RK_S32 buf_size; - RK_S32 nodes_size; RK_S32 infos_size; RK_S32 info_count; @@ -99,6 +106,7 @@ typedef struct MppTrieImpl_t { void *info_buf; void *name_buf; RK_S32 info_buf_size; + RK_S32 info_buf_pos; RK_S32 name_buf_size; RK_S32 name_buf_pos; } MppTrieImpl; @@ -143,7 +151,7 @@ static RK_S32 trie_get_node(MppTrieImpl *trie, RK_S32 prev, RK_U64 key) return idx; } -MPP_RET mpp_trie_init(MppTrie *trie, RK_S32 info_size) +MPP_RET mpp_trie_init(MppTrie *trie, const char *name) { if (!trie) { mpp_err_f("invalid NULL input trie automation\n"); @@ -152,13 +160,18 @@ MPP_RET mpp_trie_init(MppTrie *trie, RK_S32 info_size) mpp_env_get_u32("mpp_trie_debug", &mpp_trie_debug, 0); + RK_S32 name_len = strnlen(name, MPP_TRIE_NAME_MAX) + 1; MPP_RET ret = MPP_ERR_NOMEM; - MppTrieImpl *p = mpp_calloc(MppTrieImpl, 1); + MppTrieImpl *p = mpp_calloc_size(MppTrieImpl, sizeof(MppTrieImpl) + name_len); if (!p) { mpp_err_f("create trie impl failed\n"); goto DONE; } + p->name = (char *)(p + 1); + p->name_len = name_len; + strncpy(p->name, name, name_len); + p->node_count = DEFAULT_NODE_COUNT; p->nodes = mpp_calloc(MppTrieNode, p->node_count); if (!p->nodes) { @@ -173,8 +186,7 @@ MPP_RET mpp_trie_init(MppTrie *trie, RK_S32 info_size) goto DONE; } - p->ctx_size = info_size; - p->info_buf_size = p->ctx_size * p->info_count; + p->info_buf_size = SZ_4K; p->info_buf = mpp_calloc_size(void, p->info_buf_size); if (!p->info_buf) { mpp_err_f("failed to alloc %d info buffer\n", p->info_buf_size); @@ -214,7 +226,9 @@ MPP_RET mpp_trie_deinit(MppTrie trie) MppTrieImpl *p = (MppTrieImpl *)trie; - MPP_FREE(p->nodes); + if (p->node_count) + MPP_FREE(p->nodes); + MPP_FREE(p->info); MPP_FREE(p->info_buf); MPP_FREE(p->name_buf); @@ -298,7 +312,7 @@ static MppTrieNode *mpp_trie_get_node(MppTrieNode *root, const char *name) return ret; } -static RK_S32 mpp_trie_check(MppTrie trie, const char *log) +static MPP_RET mpp_trie_check(MppTrie trie, const char *log) { MppTrieImpl *p = (MppTrieImpl *)trie; char *buf = (char *)p->name_buf; @@ -338,6 +352,13 @@ MPP_RET mpp_trie_last_info(MppTrie trie) return MPP_ERR_NULL_PTR; } + /* write trie self entry info */ + pos = p->info_used + 3; + mpp_trie_add_info(trie, "__name__", p->name, p->name_len); + mpp_trie_add_info(trie, "__info__", &pos, sizeof(pos)); + /* NOTE: node count need to be update after shrinking */ + mpp_trie_add_info(trie, "__node__", &p->node_used, sizeof(p->node_used)); + root = p->nodes; node_count = p->node_used; node_valid = node_count; @@ -463,50 +484,40 @@ MPP_RET mpp_trie_last_info(MppTrie trie) trie_dbg_last("create user buffer start\n"); nodes_size = sizeof(MppTrieNode) * p->node_used; - p->nodes_size = nodes_size; - p->infos_size = (sizeof(MppTrieInfo) + p->ctx_size) * p->info_used; + p->buf_size = nodes_size + sizeof(MppTrieInfo) * p->info_used + p->info_buf_pos + p->name_buf_pos; - pos += nodes_size; - /* update info size and string name size */ - for (i = 0; i < p->info_used; i++) { - len = p->info[i].str_len; - pos += sizeof(MppTrieInfo) + p->ctx_size + len; - } - - len = pos; - buf = mpp_calloc_size(char, len); + buf = mpp_calloc_size(char, p->buf_size); if (!buf) { mpp_loge("failed to alloc trie buffer size %d\n", len); return MPP_NOK; } p->nodes = (MppTrieNode *)buf; - p->buf_size = len; memcpy(p->nodes, root, nodes_size); pos = nodes_size; for (i = 0; i < p->info_used; i++) { - MppTrieInfo *info; - const char *name = (char *)p->name_buf + p->info[i].name_offset; + MppTrieInfoInt *src = &p->info[i]; + MppTrieInfo *dst; + const char *name = (char *)p->name_buf + src->name_offset; node = mpp_trie_get_node(p->nodes, name); node->id = pos; /* reserve node info */ - info = (MppTrieInfo *)(buf + pos); - info->index = p->info[i].index; - info->str_len = p->info[i].str_len; + dst = (MppTrieInfo *)(buf + pos); + dst->index = src->index; + dst->ctx_len = src->ctx_len; + dst->str_len = src->str_len; pos += sizeof(MppTrieInfo); - /* reserve user context space */ - info->ctx = (void *)(buf + pos); - memcpy(buf + pos, (char *)p->info_buf + p->info[i].ctx_offset, p->ctx_size); - pos += p->ctx_size; - /* copy info name */ - info->name = (char *)(buf + pos); - strncpy(buf + pos, name, info->str_len); - pos += info->str_len; + strncpy(buf + pos, name, dst->str_len); + pos += dst->str_len; + + /* reserve user context space */ + memcpy(buf + pos, (char *)p->info_buf + src->ctx_offset, src->ctx_len); + pos += dst->ctx_len; } MPP_FREE(root); @@ -514,16 +525,26 @@ MPP_RET mpp_trie_last_info(MppTrie trie) MPP_FREE(p->info_buf); MPP_FREE(p->name_buf); + /* NOTE: udpate final shrinked node count */ + { + MppTrieInfo *info = mpp_trie_get_info_from_root(p->nodes, "__node__"); + + if (info) + *(RK_U32 *)mpp_trie_info_ctx(info) = p->node_used; + } + return MPP_OK; } -MPP_RET mpp_trie_add_info(MppTrie trie, const char *name, void *ctx) +MPP_RET mpp_trie_add_info(MppTrie trie, const char *name, void *ctx, RK_U32 ctx_len) { MppTrieImpl *p; MppTrieInfoInt *info; MppTrieNode *node; const char *s; - RK_S32 act_id; + RK_S32 info_buf_pos; + RK_S32 name_buf_pos; + RK_S32 info_used; RK_S32 next; RK_S32 len; RK_S32 idx; @@ -539,34 +560,77 @@ MPP_RET mpp_trie_add_info(MppTrie trie, const char *name, void *ctx) p = (MppTrieImpl *)trie; - /* create */ - if (p->info_used >= p->info_count) { - RK_S32 new_count = p->info_count * 2; + info_buf_pos = p->info_buf_pos; + name_buf_pos = p->name_buf_pos; + info_used = p->info_used; + len = strnlen(name, MPP_TRIE_NAME_MAX); + + if (len >= MPP_TRIE_NAME_MAX) { + mpp_err_f("invalid trie name %s len %d larger than max %d\n", + name, len, MPP_TRIE_NAME_MAX); + return MPP_NOK; + } + if (info_used >= MPP_TRIE_INFO_MAX) { + mpp_err_f("invalid trie info count %d larger than max %d\n", + len, MPP_TRIE_INFO_MAX); + return MPP_NOK; + } + + /* check and enlarge info record buffer */ + if (info_used >= p->info_count) { + rk_s32 old_count = p->info_count; + rk_s32 new_count = old_count * 2; void *ptr = mpp_realloc_size(p->info, void, sizeof(MppTrieInfoInt) * new_count); if (!ptr) { mpp_err_f("failed to realloc new info %d\n", new_count); return MPP_ERR_MALLOC; } - p->info = (MppTrieInfoInt *)ptr; - trie_dbg_cnt("trie %p enlarge info %p:%d -> %p:%d\n", - trie, p->info, p->info_count, ptr, new_count); - ptr = mpp_realloc_size(p->info_buf, void, p->ctx_size * new_count); + trie_dbg_cnt("trie %p enlarge info %p:%d -> %p:%d\n", + trie, p->info, old_count, ptr, new_count); + + p->info = (MppTrieInfoInt *)ptr; + p->info_count = new_count; + } + + /* check and enlarge contex buffer */ + if (info_buf_pos + (RK_S32)ctx_len > p->info_buf_size) { + rk_s32 old_size = p->info_buf_size; + rk_s32 new_size = old_size * 2; + void *ptr = mpp_realloc_size(p->info_buf, void, new_size); if (!ptr) { - mpp_err_f("failed to realloc new info buffer %d\n", new_count); + mpp_err_f("failed to realloc new info buffer %d\n", new_size); return MPP_ERR_MALLOC; } - p->info_buf = ptr; - trie_dbg_cnt("trie %p enlarge info_buf %p:%d -> %p:%d\n", - trie, p->info_buf, p->info_count, ptr, new_count); - p->info_count = new_count; + trie_dbg_cnt("trie %p enlarge info_buf %p:%d -> %p:%d\n", + trie, p->info_buf, old_size, ptr, new_size); + + p->info_buf = ptr; + p->info_buf_size = new_size; + } + + /* check and enlarge name string buffer */ + if (name_buf_pos + len + 1 >= p->name_buf_size) { + rk_s32 old_size = p->name_buf_size; + rk_s32 new_size = old_size * 2; + void *ptr = mpp_realloc_size(p->name_buf, void, new_size); + + if (!ptr) { + mpp_err_f("failed to realloc new info buffer %d\n", new_size); + return MPP_ERR_MALLOC; + } + + trie_dbg_cnt("trie %p enlarge name %p:%d -> %p:%d\n", + trie, p->name_buf, old_size, ptr, new_size); + + p->name_buf = ptr; + p->name_buf_size = new_size; } node = NULL; s = name; - len = strnlen(s, SZ_1K); next = 0; idx = 0; @@ -616,38 +680,93 @@ MPP_RET mpp_trie_add_info(MppTrie trie, const char *name, void *ctx) trie, s, i, key, key, key0, key1, idx, next); } - act_id = p->info_used++; - p->nodes[idx].id = act_id; - - info = &p->info[act_id]; - info->index = act_id; - info->str_len = MPP_ALIGN(len + 1, sizeof(RK_U64)); - info->ctx_offset = act_id * p->ctx_size; - info->name_offset = p->name_buf_pos; - - memcpy((RK_U8 *)p->info_buf + info->ctx_offset, ctx, p->ctx_size); - - if (p->name_buf_pos + len + 1 >= p->name_buf_size) { - RK_S32 new_size = p->name_buf_size * 2; - void *ptr = mpp_realloc(p->name_buf, RK_U8, new_size); - - if (!ptr) { - mpp_err_f("failed to realloc new name buffer %d\n", new_size); - return MPP_ERR_MALLOC; - } - - trie_dbg_cnt("trie %p enlarge name %p:%d -> %p:%d\n", - trie, p->name_buf, p->name_buf_size, ptr, new_size); - - p->name_buf = ptr; - p->name_buf_size = new_size; + if (p->nodes[idx].id != -1) { + mpp_err_f("trie %p add info %s already exist\n", trie, name); + return MPP_NOK; } - snprintf((char *)p->name_buf + p->name_buf_pos, p->name_buf_size - p->name_buf_pos - 1, "%s", name); + p->nodes[idx].id = info_used; + p->info_used++; + + info = &p->info[info_used]; + info->index = info_used; + info->ctx_len = ctx_len; + info->str_len = MPP_ALIGN(len + 1, sizeof(rk_u32)); + info->ctx_offset = info_buf_pos; + info->name_offset = name_buf_pos; + + memcpy((char *)p->info_buf + info_buf_pos, ctx, ctx_len); + p->info_buf_pos += info->ctx_len; + + snprintf((char *)p->name_buf + p->name_buf_pos, + p->name_buf_size - p->name_buf_pos - 1, "%s", name); p->name_buf_pos += info->str_len; - trie_dbg_set("trie %p add %d info %s at node %d pos %d action %p done\n", - trie, i, s, idx, act_id, ctx); + trie_dbg_set("trie %p add %d info %s at node %d pos %d ctx %p size %d done\n", + trie, i, s, idx, info_used, ctx, ctx_len); + + return MPP_OK; +} + +MPP_RET mpp_trie_import(MppTrie trie, void *root) +{ + MppTrieImpl *p = (MppTrieImpl *)trie; + MppTrieInfo *info; + RK_S32 i; + + if (!p || !root) { + mpp_err_f("invalid trie %p root %p\n", trie, root); + return MPP_NOK; + } + + /* free all old buffer */ + MPP_FREE(p->nodes); + MPP_FREE(p->info); + MPP_FREE(p->info_buf); + MPP_FREE(p->name_buf); + + info = mpp_trie_get_info_from_root(root, "__name__"); + if (info) + p->name = (char *)mpp_trie_info_ctx(info); + + info = mpp_trie_get_info_from_root(root, "__node__"); + if (info) + p->node_used = *(rk_u32 *)mpp_trie_info_ctx(info); + + info = mpp_trie_get_info_from_root(root, "__info__"); + if (info) + p->info_used = *(rk_u32 *)mpp_trie_info_ctx(info); + + /* import and update new buffer */ + p->nodes = (MppTrieNode *)root; + + /* set count to zero to avoid free on deinit */ + p->node_count = 0; + p->info_count = 0; + p->info_buf_size = 0; + p->info_buf_pos = 0; + p->name_buf_size = 0; + p->name_buf_pos = 0; + + if (mpp_trie_debug & MPP_TRIE_DBG_LAST_STEP) + mpp_trie_dump(trie, "root import"); + + info = mpp_trie_get_info_first(trie); + + for (i = 0; i < p->info_used; i++) { + const char *name = mpp_trie_info_name(info); + MppTrieInfo *info_set = info; + MppTrieInfo *info_ret = mpp_trie_get_info(p, name); + + info = mpp_trie_get_info_next(trie, info); + + if (info_ret && info_set == info_ret && info_ret->index == i) + continue; + + mpp_loge("trie check on import found mismatch info %s [%d:%p] - [%d:%p]\n", + name, i, info_set, info_ret ? info_ret->index : -1, info_ret); + return MPP_NOK; + } return MPP_OK; } @@ -673,6 +792,13 @@ RK_S32 mpp_trie_get_buf_size(MppTrie trie) return (p) ? p->buf_size : 0; } +void *mpp_trie_get_node_root(MppTrie trie) +{ + MppTrieImpl *p = (MppTrieImpl *)trie; + + return (p) ? p->nodes : NULL; +} + MppTrieInfo *mpp_trie_get_info(MppTrie trie, const char *name) { MppTrieImpl *p = (MppTrieImpl *)trie; @@ -687,14 +813,14 @@ MppTrieInfo *mpp_trie_get_info(MppTrie trie, const char *name) if (!node || node->id < 0) return NULL; - return (MppTrieInfo *)(((RK_U8 *)p->nodes) + node->id); + return (MppTrieInfo *)(((char *)p->nodes) + node->id); } MppTrieInfo *mpp_trie_get_info_first(MppTrie trie) { MppTrieImpl *p = (MppTrieImpl *)trie; - return (p) ? (MppTrieInfo *)(((RK_U8 *)p->nodes) + p->node_used * sizeof(MppTrieNode)) : NULL; + return (p) ? (MppTrieInfo *)(((char *)p->nodes) + p->node_used * sizeof(MppTrieNode)) : NULL; } MppTrieInfo *mpp_trie_get_info_next(MppTrie trie, MppTrieInfo *info) @@ -704,7 +830,23 @@ MppTrieInfo *mpp_trie_get_info_next(MppTrie trie, MppTrieInfo *info) if (!p || !info || info->index >= p->info_used - 1) return NULL; - return (MppTrieInfo *)(info->name + info->str_len); + return (MppTrieInfo *)((char *)(info + 1) + info->str_len + info->ctx_len); +} + +MppTrieInfo *mpp_trie_get_info_from_root(void *root, const char *name) +{ + MppTrieNode *node; + + if (!root || !name) { + mpp_loge_f("invalid root %p name %p\n", root, name); + return NULL; + } + + node = mpp_trie_get_node((MppTrieNode *)root, name); + if (!node || node->id < 0) + return NULL; + + return (MppTrieInfo *)(((char *)root) + node->id); } void mpp_trie_dump(MppTrie trie, const char *func) @@ -717,7 +859,9 @@ void mpp_trie_dump(MppTrie trie, const char *func) memset(next_cnt, 0, sizeof(next_cnt)); memset(tag_len, 0, sizeof(tag_len)); - mpp_logi("%s dumping node count %d used %d\n", func, p->node_count, p->node_used); + mpp_logi("%s dumping trie %p\n", func, trie); + mpp_logi("name %s size %d node %d info %d\n", + p->name, p->buf_size, p->node_used, p->info_used); for (i = 0; i < p->node_used; i++) { MppTrieNode *node = &p->nodes[i]; @@ -731,10 +875,11 @@ void mpp_trie_dump(MppTrie trie, const char *func) /* check before and after last info */ if (node->id < (RK_S32)(p->node_used * sizeof(MppTrieNode))) mpp_logi("node %d key %x info %d - %s\n", node->idx, node->key, node->id, - (char *)p->name_buf + p->info[node->id].name_offset); + p->name_buf ? ((char *)p->name_buf + p->info[node->id].name_offset) : + mpp_trie_info_name(((MppTrieInfo *)((char *)p->nodes + node->id)))); else mpp_logi("node %d key %x info %d - %s\n", node->idx, node->key, node->id, - ((MppTrieInfo *)((char *)p->nodes + node->id))->name); + mpp_trie_info_name(((MppTrieInfo *)((char *)p->nodes + node->id)))); } else mpp_logi("node %d key %x\n", node->idx, node->key); diff --git a/mpp/base/test/mpp_trie_test.c b/mpp/base/test/mpp_trie_test.c index ee2de293..a063d9a2 100644 --- a/mpp/base/test/mpp_trie_test.c +++ b/mpp/base/test/mpp_trie_test.c @@ -77,15 +77,15 @@ int main() mpp_log("mpp_trie_test start\n"); - mpp_trie_init(&trie, sizeof(TestAction)); + mpp_trie_init(&trie, "test_trie"); start = mpp_time(); for (i = 0; i < info_cnt; i++) - mpp_trie_add_info(trie, test_info[i].name, &test_info[i]); + mpp_trie_add_info(trie, test_info[i].name, &test_info[i], sizeof(test_info[i])); end = mpp_time(); mpp_log("add act time %lld us\n", end - start); - ret = mpp_trie_add_info(trie, NULL, NULL); + ret = mpp_trie_add_info(trie, NULL, NULL, 0); if (ret) { mpp_loge("mpp_trie_add_info last failed\n"); goto DONE; @@ -100,8 +100,8 @@ int main() info = mpp_trie_get_info(trie, name); end = mpp_time(); - if (info && info->ctx) - act = (TestAction *)info->ctx; + if (info) + act = (TestAction *)mpp_trie_info_ctx(info); if (act && act->proc) act->proc(act->ctx, end - start); diff --git a/utils/mpp_opt.c b/utils/mpp_opt.c index 05d03e51..456e953b 100644 --- a/utils/mpp_opt.c +++ b/utils/mpp_opt.c @@ -62,7 +62,7 @@ MPP_RET mpp_opt_setup(MppOpt opt, void *ctx) if (NULL == impl) return MPP_NOK; - mpp_trie_init(&impl->trie, sizeof(MppOptInfo)); + mpp_trie_init(&impl->trie, "mpp_opt"); if (impl->trie) { impl->ctx = ctx; return MPP_OK; @@ -79,9 +79,9 @@ MPP_RET mpp_opt_add(MppOpt opt, MppOptInfo *info) return MPP_NOK; if (NULL == info) - return mpp_trie_add_info(impl->trie, NULL, NULL); + return mpp_trie_add_info(impl->trie, NULL, NULL, 0); - return mpp_trie_add_info(impl->trie, info->name, info); + return mpp_trie_add_info(impl->trie, info->name, info, sizeof(*info)); } MPP_RET mpp_opt_parse(MppOpt opt, int argc, char **argv) @@ -113,7 +113,7 @@ MPP_RET mpp_opt_parse(MppOpt opt, int argc, char **argv) continue; } - info = node->ctx; + info = mpp_trie_info_ctx(node); if (info->proc) step = info->proc(impl->ctx, next);