Merge branch '2023_open_source_contest' of https://gitlink.org.cn/JasenChao/xiuos into 2023_open_source_contest

This commit is contained in:
JasenChao 2023-08-23 18:34:47 +08:00
commit deb1f63d9e
6 changed files with 143 additions and 113 deletions

View File

@ -115,7 +115,7 @@ ifeq ($(CONFIG_ADD_XIZI_FEATURES),y)
ifeq ($(CONFIG_USER_TEST_RBTREE),y) ifeq ($(CONFIG_USER_TEST_RBTREE),y)
SRC_FILES += test_rbtree/test_rbtree.c SRC_FILES += test_rbtree/test_rbtree.c
endif endif
ifeq ($(CONFIG_USER_TEST_SOCKET),y) ifeq ($(CONFIG_USER_TEST_SOCKET),y)
SRC_FILES += test_socket.c SRC_FILES += test_socket.c

View File

@ -9,13 +9,15 @@
基数树节点设计为: 基数树节点设计为:
```c ```c
typedef struct _node { typedef struct radix_node
void* value; {
struct _node* next[NODE_SIZE]; void *value;
} node; struct radix_node *child[NODE_SIZE];
struct radix_node *parent;
} radix_node;
``` ```
其中,节点在树中的路径即为键,`value` 存储值,`NODE_SIZE` 定义为 128足以容纳所有 ASCII 值 其中,节点在树中的路径即为键,为`unsigned int`类型,`value` 存储值,`NODE_SIZE` 定义为 4即每个树节点包含2个bit位可以根据实际需求调整
一共实现了 5 个函数,分别为: 一共实现了 5 个函数,分别为:
@ -32,20 +34,19 @@ typedef struct _node {
测试程序定义了以下键值对: 测试程序定义了以下键值对:
```c ```c
char keys[][MAX_WORD_LEN] = { char values[][16] = {
"what", "what",
"where", "where",
"why", "why",
"how", "how",
"hello!", "hello!",
"apple", "apple",
"12345" "12345"};
}; unsigned int keys[] = {1, 2, 3, 4, 5, 6, 7};
int values[] = {1, 2, 3, 4, 5, 6, 7};
``` ```
1. 程序的第一部分创建了基数树,并且将定义的 7 个键值对的前 6 个插入了基数树,然后分别查找 7 个键,前 6 个均可以找到对应的值,最后一个未插入,因此无法找到 1. 程序的第一部分创建了基数树,并且将定义的 7 个键值对的前 6 个插入了基数树,然后分别查找 7 个键,前 6 个均可以找到对应的值,最后一个未插入,因此无法找到
2. 程序的第二部分从基数树中删除了 `where``how` 两个键,再次分别查找 7 个键,删除的键值对和未插入的键值对均无法找到 2. 程序的第二部分从基数树中删除了 `where``how` 两个值的键,再次分别查找 7 个键,删除的键值对和未插入的键值对均无法找到
3. 程序的第三部分重新插入了已删除的 `where` 和未插入过的 `12345` ,再次分别查找 7 个键,新插入的值可以检索到 3. 程序的第三部分重新插入了已删除的 `where` 和未插入过的 `12345` ,再次分别查找 7 个键,新插入的值可以检索到
4. 程序的第四部分将基数树销毁,再次分别查找 7 个键,所有的键值对均无法找到 4. 程序的第四部分将基数树销毁,再次分别查找 7 个键,所有的键值对均无法找到

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 96 KiB

View File

@ -1,23 +1,27 @@
/** /**
* @file: test_radix_tree.c * @file: test_radix_tree.c
* @brief: Implement a simple radix tree * @brief: Implement a simple radix tree
* @version: 1.0 * @version: 1.0
* @date: 2023/5/24 * @date: 2023/5/24
*/ */
#include <transform.h>
#include "test_radix_tree.h" #include "test_radix_tree.h"
/** /**
* @description: Create a radix tree node * @description: Create a radix tree node
* @return node pointer * @return node pointer
*/ */
node* CreateNode() radix_node *CreateNode()
{ {
node* n = (node*)malloc(sizeof(node)); radix_node *n = (radix_node *)malloc(sizeof(radix_node));
n->value = NULL; if (n != NULL)
for (int i = 0; i < NODE_SIZE; i++) { {
n->next[i] = NULL; n->parent = NULL;
n->value = NULL;
for (int i = 0; i < NODE_SIZE; ++i)
{
n->child[i] = NULL;
}
} }
return n; return n;
} }
@ -29,21 +33,32 @@ node* CreateNode()
* @param value - new node value * @param value - new node value
* @return void * @return void
*/ */
void InsertNode(node* root, const char* key, void* value) int InsertNode(radix_node *root, unsigned int key, void *value)
{ {
if (root == NULL) { if (root == NULL)
return; {
return -1; // The root node is empty
} }
node* cur = root; radix_node *cur = root;
size_t len = strlen(key); int temp;
for (size_t i = 0; i < len; i++) { for (int i = radix_tree_height - 1; i >= 0; --i)
uint8_t b = (uint8_t)key[i]; {
if (cur->next[b] == NULL) { temp = CHECK_BITS(key, i);
cur->next[b] = CreateNode(); if (!cur->child[temp])
{
cur->child[temp] = CreateNode();
if (!cur->child[temp])
return -2; // Failed to apply for a node
cur->child[temp]->parent = cur;
} }
cur = cur->next[b]; cur = cur->child[temp];
} }
if (cur->value == value)
return -3; // Repeat insertion
if (cur->value != NULL)
return -4; // Already occupied
cur->value = value; cur->value = value;
return 0;
} }
/** /**
@ -52,38 +67,27 @@ void InsertNode(node* root, const char* key, void* value)
* @param key - key which is needed to delete * @param key - key which is needed to delete
* @return void * @return void
*/ */
void DeleteNode(node* root, const char* key) void DeleteNode(radix_node *root, unsigned int key)
{ {
if (root == NULL) { if (root == NULL)
{
return; return;
} }
node** cur = &root; radix_node *cur = root;
size_t len = strlen(key); int temp;
for (size_t i = 0; i < len; i++) { for (int i = radix_tree_height - 1; i >= 0; --i)
uint8_t b = (uint8_t)key[i]; {
if ((*cur)->next[b] == NULL) { temp = CHECK_BITS(key, i);
return; cur = cur->child[temp];
} if (!cur)
cur = &((*cur)->next[b]);
}
if ((*cur)->value == NULL) {
return;
}
(*cur)->value = NULL;
int has_children = 0;
for (int i = 0; i < NODE_SIZE; i++) {
if ((*cur)->next[i] != NULL) {
has_children = 1;
break; break;
}
}
if (!has_children) {
free(*cur);
(*cur) = NULL;
} }
if (!cur)
return;
cur->parent->child[temp] = NULL;
free(cur);
} }
/** /**
@ -92,20 +96,23 @@ void DeleteNode(node* root, const char* key)
* @param key - key which is needed to find * @param key - key which is needed to find
* @return value pointer corresponding to key * @return value pointer corresponding to key
*/ */
void* FindNode(node* root, const char* key) void *FindNode(radix_node *root, unsigned int key)
{ {
if (root == NULL) { if (root == NULL)
{
return NULL; return NULL;
} }
node* cur = root; radix_node *cur = root;
size_t len = strlen(key); int temp;
for (size_t i = 0; i < len; i++) { for (int i = radix_tree_height - 1; i >= 0; --i)
uint8_t b = (uint8_t)key[i]; {
if (cur->next[b] == NULL) { temp = CHECK_BITS(key, i);
return NULL; cur = cur->child[temp];
} if (!cur)
cur = cur->next[b]; break;
} }
if (!cur)
return NULL;
return cur->value; return cur->value;
} }
@ -114,73 +121,88 @@ void* FindNode(node* root, const char* key)
* @param root - radix tree root * @param root - radix tree root
* @return void * @return void
*/ */
void DestroyTree(node* root) void DestroyTree(radix_node *root)
{ {
if (root == NULL) { if (root == NULL)
{
return; return;
} }
for (int i = 0; i < NODE_SIZE; i++) { for (int i = 0; i < NODE_SIZE; i++)
DestroyTree(root->next[i]); {
DestroyTree(root->child[i]);
} }
free(root); free(root);
} }
void TestRadix() void TestRadix()
{ {
char keys[][MAX_WORD_LEN] = { char values[][16] = {
"what", "what",
"where", "where",
"why", "why",
"how", "how",
"hello!", "hello!",
"apple", "apple",
"12345" "12345"};
}; unsigned int keys[] = {1, 2, 3, 4, 5, 6, 7};
int values[] = {1, 2, 3, 4, 5, 6, 7};
printf("\nCreate tree and add key & value:\n"); printf("\nCreate tree and add key & value:\n");
node* root = CreateNode(); radix_node *root = CreateNode();
if (!root) printf("Create node failed.\n"); if (!root)
printf("Create node failed.\n");
int num = sizeof(keys) / sizeof(keys[0]); int num = sizeof(keys) / sizeof(keys[0]);
for (int i = 0; i < num - 1; ++i) { for (int i = 0; i < num - 1; ++i)
{
InsertNode(root, keys[i], &values[i]); InsertNode(root, keys[i], &values[i]);
} }
for (int i = 0; i < num; ++i) { for (int i = 0; i < num; ++i)
int* v = (int*)FindNode(root, keys[i]); {
if (v) printf("keys[%d] \"%s\"'v = %d, values[%d] = %d\n", i, keys[i], *v, i, values[i]); char *v = (char *)FindNode(root, keys[i]);
else printf("keys[%d] \"%s\" not found\n", i, keys[i]); if (v)
printf("keys[%d] %x, values[%d] = %s\n", i, keys[i], i, v);
else
printf("keys[%d] %x not found\n", i, keys[i]);
} }
printf("\nDelete \"where\" and \"how\":\n"); printf("\nDelete \"where\" and \"how\":\n");
DeleteNode(root, keys[1]); DeleteNode(root, keys[1]);
DeleteNode(root, keys[3]); DeleteNode(root, keys[3]);
for (int i = 0; i < num; ++i) { for (int i = 0; i < num; ++i)
int* v = (int*)FindNode(root, keys[i]); {
if (v) printf("keys[%d] \"%s\"'v = %d, values[%d] = %d\n", i, keys[i], *v, i, values[i]); char *v = (char *)FindNode(root, keys[i]);
else printf("keys[%d] \"%s\" not found\n", i, keys[i]); if (v)
printf("keys[%d] %x, values[%d] = %s\n", i, keys[i], i, v);
else
printf("keys[%d] %x not found\n", i, keys[i]);
} }
printf("\nInsert \"where\" and \"12345\":\n"); printf("\nInsert \"where\" and \"12345\":\n");
InsertNode(root, keys[1], &values[1]); InsertNode(root, keys[1], &values[1]);
InsertNode(root, keys[6], &values[6]); InsertNode(root, keys[6], &values[6]);
for (int i = 0; i < num; ++i) { for (int i = 0; i < num; ++i)
int* v = (int*)FindNode(root, keys[i]); {
if (v) printf("keys[%d] \"%s\"'v = %d, values[%d] = %d\n", i, keys[i], *v, i, values[i]); char *v = (char *)FindNode(root, keys[i]);
else printf("keys[%d] \"%s\" not found\n", i, keys[i]); if (v)
printf("keys[%d] %x, values[%d] = %s\n", i, keys[i], i, v);
else
printf("keys[%d] %x not found\n", i, keys[i]);
} }
printf("\nDestroy tree:\n"); printf("\nDestroy tree:\n");
DestroyTree(root); DestroyTree(root);
root = NULL; root = NULL;
for (int i = 0; i < num; ++i) { for (int i = 0; i < num; ++i)
int* v = (int*)FindNode(root, keys[i]); {
if (v) printf("keys[%d] \"%s\"'v = %d, values[%d] = %d\n", i, keys[i], *v, i, values[i]); char *v = (char *)FindNode(root, keys[i]);
else printf("keys[%d] \"%s\" not found\n", i, keys[i]); if (v)
printf("keys[%d] %x, values[%d] = %s\n", i, keys[i], i, v);
else
printf("keys[%d] %x not found\n", i, keys[i]);
} }
} }

View File

@ -1,20 +1,27 @@
/** /**
* @file: test_radix_tree.h * @file: test_radix_tree.h
* @brief: Implement a simple radix tree * @brief: Implement a simple radix tree
* @version: 1.0 * @version: 1.0
* @date: 2023/5/24 * @date: 2023/5/24
*/ */
#define NODE_SIZE 128 #include <transform.h>
#define MAX_WORD_LEN 128
typedef struct _node { #define NODE_SIZE 4
void* value; #define BITS 2
struct _node* next[NODE_SIZE]; #define CHECK_BITS(key, pos) ((((unsigned int)(key)) << (sizeof(int) * 8 - (pos + 1) * BITS)) >> (sizeof(int) * 8 - BITS))
} node;
node* CreateNode(); const int radix_tree_height = sizeof(void *) * 8 / BITS; // Height of tree
void InsertNode(node* root, const char* key, void* value);
void DeleteNode(node* root, const char* key); typedef struct radix_node
void* FindNode(node* root, const char* key); {
void DestroyTree(node* root); void *value;
struct radix_node *child[NODE_SIZE];
struct radix_node *parent;
} radix_node;
radix_node *CreateNode();
int InsertNode(radix_node *root, unsigned int key, void *value);
void DeleteNode(radix_node *root, unsigned int key);
void *FindNode(radix_node *root, unsigned int key);
void DestroyTree(radix_node *root);