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)
SRC_FILES += test_rbtree/test_rbtree.c
endif
endif
ifeq ($(CONFIG_USER_TEST_SOCKET),y)
SRC_FILES += test_socket.c

View File

@ -9,13 +9,15 @@
基数树节点设计为:
```c
typedef struct _node {
void* value;
struct _node* next[NODE_SIZE];
} node;
typedef struct radix_node
{
void *value;
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 个函数,分别为:
@ -32,20 +34,19 @@ typedef struct _node {
测试程序定义了以下键值对:
```c
char keys[][MAX_WORD_LEN] = {
char values[][16] = {
"what",
"where",
"why",
"how",
"hello!",
"apple",
"12345"
};
int values[] = {1, 2, 3, 4, 5, 6, 7};
"12345"};
unsigned int keys[] = {1, 2, 3, 4, 5, 6, 7};
```
1. 程序的第一部分创建了基数树,并且将定义的 7 个键值对的前 6 个插入了基数树,然后分别查找 7 个键,前 6 个均可以找到对应的值,最后一个未插入,因此无法找到
2. 程序的第二部分从基数树中删除了 `where``how` 两个键,再次分别查找 7 个键,删除的键值对和未插入的键值对均无法找到
2. 程序的第二部分从基数树中删除了 `where``how` 两个值的键,再次分别查找 7 个键,删除的键值对和未插入的键值对均无法找到
3. 程序的第三部分重新插入了已删除的 `where` 和未插入过的 `12345` ,再次分别查找 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
* @brief: Implement a simple radix tree
* @version: 1.0
* @date: 2023/5/24
*/
* @file: test_radix_tree.c
* @brief: Implement a simple radix tree
* @version: 1.0
* @date: 2023/5/24
*/
#include <transform.h>
#include "test_radix_tree.h"
/**
* @description: Create a radix tree node
* @return node pointer
*/
node* CreateNode()
radix_node *CreateNode()
{
node* n = (node*)malloc(sizeof(node));
n->value = NULL;
for (int i = 0; i < NODE_SIZE; i++) {
n->next[i] = NULL;
radix_node *n = (radix_node *)malloc(sizeof(radix_node));
if (n != NULL)
{
n->parent = NULL;
n->value = NULL;
for (int i = 0; i < NODE_SIZE; ++i)
{
n->child[i] = NULL;
}
}
return n;
}
@ -29,21 +33,32 @@ node* CreateNode()
* @param value - new node value
* @return void
*/
void InsertNode(node* root, const char* key, void* value)
int InsertNode(radix_node *root, unsigned int key, void *value)
{
if (root == NULL) {
return;
if (root == NULL)
{
return -1; // The root node is empty
}
node* cur = root;
size_t len = strlen(key);
for (size_t i = 0; i < len; i++) {
uint8_t b = (uint8_t)key[i];
if (cur->next[b] == NULL) {
cur->next[b] = CreateNode();
radix_node *cur = root;
int temp;
for (int i = radix_tree_height - 1; i >= 0; --i)
{
temp = CHECK_BITS(key, i);
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;
return 0;
}
/**
@ -52,38 +67,27 @@ void InsertNode(node* root, const char* key, void* value)
* @param key - key which is needed to delete
* @return void
*/
void DeleteNode(node* root, const char* key)
void DeleteNode(radix_node *root, unsigned int key)
{
if (root == NULL) {
if (root == NULL)
{
return;
}
node** cur = &root;
size_t len = strlen(key);
for (size_t i = 0; i < len; i++) {
uint8_t b = (uint8_t)key[i];
if ((*cur)->next[b] == NULL) {
return;
}
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;
radix_node *cur = root;
int temp;
for (int i = radix_tree_height - 1; i >= 0; --i)
{
temp = CHECK_BITS(key, i);
cur = cur->child[temp];
if (!cur)
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
* @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;
}
node* cur = root;
size_t len = strlen(key);
for (size_t i = 0; i < len; i++) {
uint8_t b = (uint8_t)key[i];
if (cur->next[b] == NULL) {
return NULL;
}
cur = cur->next[b];
radix_node *cur = root;
int temp;
for (int i = radix_tree_height - 1; i >= 0; --i)
{
temp = CHECK_BITS(key, i);
cur = cur->child[temp];
if (!cur)
break;
}
if (!cur)
return NULL;
return cur->value;
}
@ -114,73 +121,88 @@ void* FindNode(node* root, const char* key)
* @param root - radix tree root
* @return void
*/
void DestroyTree(node* root)
void DestroyTree(radix_node *root)
{
if (root == NULL) {
if (root == NULL)
{
return;
}
for (int i = 0; i < NODE_SIZE; i++) {
DestroyTree(root->next[i]);
for (int i = 0; i < NODE_SIZE; i++)
{
DestroyTree(root->child[i]);
}
free(root);
}
void TestRadix()
{
char keys[][MAX_WORD_LEN] = {
char values[][16] = {
"what",
"where",
"why",
"how",
"hello!",
"apple",
"12345"
};
int values[] = {1, 2, 3, 4, 5, 6, 7};
"12345"};
unsigned int keys[] = {1, 2, 3, 4, 5, 6, 7};
printf("\nCreate tree and add key & value:\n");
node* root = CreateNode();
if (!root) printf("Create node failed.\n");
radix_node *root = CreateNode();
if (!root)
printf("Create node failed.\n");
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]);
}
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]);
else printf("keys[%d] \"%s\" not found\n", i, keys[i]);
for (int i = 0; i < num; ++i)
{
char *v = (char *)FindNode(root, 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");
DeleteNode(root, keys[1]);
DeleteNode(root, keys[3]);
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]);
else printf("keys[%d] \"%s\" not found\n", i, keys[i]);
for (int i = 0; i < num; ++i)
{
char *v = (char *)FindNode(root, 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");
InsertNode(root, keys[1], &values[1]);
InsertNode(root, keys[6], &values[6]);
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]);
else printf("keys[%d] \"%s\" not found\n", i, keys[i]);
for (int i = 0; i < num; ++i)
{
char *v = (char *)FindNode(root, 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");
DestroyTree(root);
root = NULL;
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]);
else printf("keys[%d] \"%s\" not found\n", i, keys[i]);
for (int i = 0; i < num; ++i)
{
char *v = (char *)FindNode(root, 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
* @brief: Implement a simple radix tree
* @version: 1.0
* @date: 2023/5/24
*/
* @file: test_radix_tree.h
* @brief: Implement a simple radix tree
* @version: 1.0
* @date: 2023/5/24
*/
#define NODE_SIZE 128
#define MAX_WORD_LEN 128
#include <transform.h>
typedef struct _node {
void* value;
struct _node* next[NODE_SIZE];
} node;
#define NODE_SIZE 4
#define BITS 2
#define CHECK_BITS(key, pos) ((((unsigned int)(key)) << (sizeof(int) * 8 - (pos + 1) * BITS)) >> (sizeof(int) * 8 - BITS))
node* CreateNode();
void InsertNode(node* root, const char* key, void* value);
void DeleteNode(node* root, const char* key);
void* FindNode(node* root, const char* key);
void DestroyTree(node* root);
const int radix_tree_height = sizeof(void *) * 8 / BITS; // Height of tree
typedef struct radix_node
{
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);