From 614fe4d575d289be6b8ab28b1a67b617636eea8f Mon Sep 17 00:00:00 2001 From: Yunai Date: Mon, 5 Jun 2023 00:00:22 +0800 Subject: [PATCH] Add radix_tree --- APP_Framework/Applications/app_test/Kconfig | 4 + APP_Framework/Applications/app_test/Makefile | 4 + .../app_test/test_radix_tree/Makefile | 11 ++ .../app_test/test_radix_tree/README.md | 21 +++ .../test_radix_tree/test_radix_tree.c | 154 ++++++++++++++++++ .../test_radix_tree/test_radix_tree.h | 49 ++++++ 6 files changed, 243 insertions(+) create mode 100644 APP_Framework/Applications/app_test/test_radix_tree/Makefile create mode 100644 APP_Framework/Applications/app_test/test_radix_tree/README.md create mode 100644 APP_Framework/Applications/app_test/test_radix_tree/test_radix_tree.c create mode 100644 APP_Framework/Applications/app_test/test_radix_tree/test_radix_tree.h diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index bffda4b64..937dc1af9 100644 --- a/APP_Framework/Applications/app_test/Kconfig +++ b/APP_Framework/Applications/app_test/Kconfig @@ -26,6 +26,10 @@ menu "test app" endif endif + menuconfig USER_TEST_RADIXTREE + bool "Config test radix tree" + default n + config USER_TEST_SEMC bool "Config test semc sdram" default n diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile index be43d9839..00227d582 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -29,6 +29,10 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_FILES += test_extsram.c endif + ifeq ($(CONFIG_USER_TEST_RADIXTREE),y) + SRC_DIR += test_radix_tree + endif + ifeq ($(CONFIG_USER_TEST_LCD),y) SRC_FILES += endif diff --git a/APP_Framework/Applications/app_test/test_radix_tree/Makefile b/APP_Framework/Applications/app_test/test_radix_tree/Makefile new file mode 100644 index 000000000..1a82b4b5e --- /dev/null +++ b/APP_Framework/Applications/app_test/test_radix_tree/Makefile @@ -0,0 +1,11 @@ +include $(KERNEL_ROOT)/.config +ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) + include $(APPDIR)/Make.defs + CSRCS += test_radix_tree.c + include $(APPDIR)/Application.mk +endif + +ifeq ($(CONFIG_ADD_XIZI_FETURES),y) + SRC_FILES += test_radix_tree.c + include $(KERNEL_ROOT)/compiler.mk +endif \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_radix_tree/README.md b/APP_Framework/Applications/app_test/test_radix_tree/README.md new file mode 100644 index 000000000..03a699255 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_radix_tree/README.md @@ -0,0 +1,21 @@ +# ##请填写赛题题目## +热身赛一级赛题3:基于k210-emulator实现基数树并测试验证 +## 1. 简介 +基数树,或称压缩前缀树,是一种更节省空间的Trie(前缀树)。基数树的空间使用更加灵活,只有当需要用到某节点时才会去创建它。除此之外,在寻找方式上基数树利用比如一个unsigned int的类型的每一个比特位作为树节点的判断。 + + +## 2. 数据结构设计说明 +基数树包含一个根节点,根节点不用于存储数据,其默认值为-1. 基数树利用unsigned int 类型的每两个比特位作为树节点的判断,因此对于一个32bit的key,基数树的层高为16(不包含根节点).每个节点包含4(2^2)个孩子节点,用指针数组实现存放;每个节点可以存放一个int类型的值value,以及一个是否key已使用的布尔型标志hasValue。 + + +## 3. 测试程序说明 +测试程序包含四个部分:增加键值对, 查找键值对, 修改键值对,删除键值对; +(1)增加键值对,依次向基数树中添加5个键值对,如果添加成功则输出"Insert successful.",反之输出"Insert fail"; +(2)查找键值对,依次查找已添加的键值对,如果查找成功则输出"Search successful." 并输出key所对应的value,反之输出"Search fail"; +(3)修改键值对,修改keys[0]所对应的值,如果修改成功则输出"Update successful." 并输出修改后keys[0]所对应的value,反之输出"Update fail"; +(4)删除键值对,删除keys[0]所对应的键值对,如果删除成功则输出"Delete successful.",反之输出"Delete fail"; + + +## 4. 运行结果(##需结合运行测试截图按步骤说明##) +图片名为result.png +![image](https://gitlink.org.cn/yunai/pictures.git) \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_radix_tree/test_radix_tree.c b/APP_Framework/Applications/app_test/test_radix_tree/test_radix_tree.c new file mode 100644 index 000000000..b39a0397c --- /dev/null +++ b/APP_Framework/Applications/app_test/test_radix_tree/test_radix_tree.c @@ -0,0 +1,154 @@ +/* +* Copyright (c) 2023 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: test_radix_tree.c +* @brief: a application of adc function +* @version: 1.1 +* @author: AIIT XUOS Lab +* @date: 2023/5/31 +*/ + +#include +#include +#include +#include + +#include "test_radix_tree.h" + + +// #ifdef ADD_XIZI_FETURES + +const int radix_tree_height = sizeof(Uint32Type) * 8 / BITS; + +RadixNode* RadixNodeAlloc() +{ + RadixNode* node = (RadixNode*) malloc(sizeof(RadixNode)); + for (int i = 0; i < 4; ++i) { + node->child[i] = NULL; + } + node->value = -1; + node->hasValue = false; + return node; +} + + +int RadixTreeInsert(RadixNode* tree, Uint32Type key, int value) +{ + RadixNode* node; + node = tree; + for (int i = 0; i < radix_tree_height; ++i) { + Uint32Type temp = GET_BITS(key, i); + if (!node->child[temp]) { + node->child[temp] = RadixNodeAlloc(); + node = node->child[temp]; + } + else { + node = node->child[temp]; + } + } + if (node->value == value) return RADIX_INSERT_VALUE_SAME; + if (node->hasValue == true) return RADIX_INSERT_VALUE_OCCUPY; + node->value = value; + node->hasValue = true; + return 0; +} + + +int RadixTreeDelete(RadixNode* tree, Uint32Type key) +{ + int i = 0; + int temp = 0; + RadixNode* node; + node = tree; + while (node && i < radix_tree_height) { + temp = GET_BITS(key, i++); + node = node->child[temp]; + } + if (node == NULL) return RADIX_KEY_NOEXIST; + node->value = -1; + node->hasValue = false; + return 0; +} + + +Uint32Type RadixTreeFind(RadixNode* tree, Uint32Type key) +{ + int i = 0; + int temp = 0; + RadixNode* node; + node = tree; + while (node && i < radix_tree_height) { + temp = GET_BITS(key, i++); + node = node->child[temp]; + } + if (node == NULL) return RADIX_KEY_NOEXIST; + + if (node->hasValue == false) return RADIX_KEY_NOEXIST; + return node->value; +} + + +int RadixTreeUpdate(RadixNode* tree, Uint32Type key, int value) +{ + int i = 0; + int temp = 0; + RadixNode* node; + node = tree; + while (node && i < radix_tree_height) { + temp = GET_BITS(key, i++); + node = node->child[temp]; + } + if (node == NULL) return RADIX_KEY_NOEXIST; + node -> value = value; + return 0; +} + + +void TestRadixTree(void) +{ + RadixNode* tree = RadixNodeAlloc(); + Uint32Type key = 123; + int value = 199; + Uint32Type keys[5] = { 13, 232, 1212, 38113, 843 }; + int values[5] = { 13, 232, 1212, 38113, 843 }; + // Insert operation + for (int i = 0; i < 5; ++i) { + int i_flag = RadixTreeInsert(tree, keys[i], values[i]); + if (i_flag == 0) printf("Insert successful.\n"); + else printf("Insert fail.\n"); + } + // Search operation + for (int i = 0; i < 5; ++i) { + Uint32Type ans = RadixTreeFind(tree, keys[i]); + if (ans == values[i]) { + printf("Search successful.\n"); + printf("ans = %d\n", ans); + } + else printf("Search fail.\n"); + + } + // Update operation + int up_flag = RadixTreeUpdate(tree, keys[0], 100); + if (up_flag == 0) { + printf("Update successful.\n"); + printf("keys[0] = %d\n", RadixTreeFind(tree, keys[0])); + } else printf("Update fail.\n"); + // Delete operation + int de_flag = RadixTreeDelete(tree, keys[0]); + if (de_flag == 0) printf("Delete successful.\n"); + else printf("Delete fail.\n"); + return; +} + +PRIV_SHELL_CMD_FUNCTION(TestRadixTree, a radix test example, PRIV_SHELL_CMD_MAIN_ATTR); +// #endif \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_radix_tree/test_radix_tree.h b/APP_Framework/Applications/app_test/test_radix_tree/test_radix_tree.h new file mode 100644 index 000000000..4fc17101e --- /dev/null +++ b/APP_Framework/Applications/app_test/test_radix_tree/test_radix_tree.h @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: test_radix_tree.c +* @brief: a application of adc function +* @version: 1.1 +* @author: AIIT XUOS Lab +* @date: 2023/5/31 +*/ +#ifndef TEST_RADIX_TREE_H +#define TEST_RADIX_TREE_H + +#pragma once +#include +#include +#include +#include + +typedef unsigned int Uint32Type; +#define RADIX_INSERT_VALUE_OCCUPY -1 +#define RADIX_INSERT_VALUE_SAME -2 +#define RADIX_KEY_NOEXIST -1; +#define RADIX_DELETE_ERROR -1; +#define BITS 2 +#define GET_BITS(key,pos) ((((unsigned int)(key))<>(sizeof(int)*8-BITS)) +//const int radix_tree_height = sizeof(Uint32Type) * 8 / BITS; +typedef struct RadixNode RadixNode; +struct RadixNode{ + RadixNode* child[4]; + int value; + bool hasValue; +}; +RadixNode* RadixNodeAlloc(); +int RadixTreeInsert(RadixNode* tree, Uint32Type key, int value); +int RadixTreeDelete(RadixNode* tree, Uint32Type key); +Uint32Type RadixTreeFind(RadixNode* tree, Uint32Type key); +int RadixTreeUpdate(RadixNode* tree, Uint32Type key, int value); +void TestRadixTree(); +#endif \ No newline at end of file