2023_open_source_contest_warmup_1st_issue1
This commit is contained in:
parent
062b70f073
commit
5675b77101
|
@ -1,9 +1,13 @@
|
||||||
menu "test app"
|
menu "test app"
|
||||||
menuconfig USER_TEST
|
menuconfig USER_TEST
|
||||||
bool "Enable application test function "
|
bool "Enable application test function "
|
||||||
default n
|
default y
|
||||||
|
|
||||||
if USER_TEST
|
if USER_TEST
|
||||||
|
menuconfig USER_TEST_HASH
|
||||||
|
bool "Config test hash"
|
||||||
|
default y
|
||||||
|
|
||||||
menuconfig USER_TEST_ADC
|
menuconfig USER_TEST_ADC
|
||||||
bool "Config test adc"
|
bool "Config test adc"
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -25,6 +25,10 @@ endif
|
||||||
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||||
SRC_FILES := test_shell.c
|
SRC_FILES := test_shell.c
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_USER_TEST_HASH),y)
|
||||||
|
SRC_FILES += test_hash/test_hash.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_USER_TEST_ADC),y)
|
ifeq ($(CONFIG_USER_TEST_ADC),y)
|
||||||
SRC_FILES += test_adc.c
|
SRC_FILES += test_adc.c
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -0,0 +1,301 @@
|
||||||
|
# 热身赛一级赛题1:基于cortex-m3-emulator实现哈希表并测试验证
|
||||||
|
|
||||||
|
## 1. 简介
|
||||||
|
本项目是基于cortex-m3-emulator实现哈希表并测试验证
|
||||||
|
test_hash.h定义所需要的宏,结构体,函数声明
|
||||||
|
test_hash.c用于实现哈希表的创建、删除、增删改查等具体操作,以及构建测试函数,并且注入到shell中
|
||||||
|
|
||||||
|
## 2. 数据结构设计说明
|
||||||
|
- 通过数组和链表实现哈希表,链地址法解决哈希冲突,默认数组长度TABLE_SIZE,节点数据结构Entry,哈希表数据结构HashTable
|
||||||
|
```c
|
||||||
|
/* the size of hash table */
|
||||||
|
#define TABLE_SIZE (1024)
|
||||||
|
/* element of the hash table's chain list */
|
||||||
|
struct Entry
|
||||||
|
{
|
||||||
|
char* key;
|
||||||
|
void* value;
|
||||||
|
struct Entry* next;
|
||||||
|
void (*FreeValue)(void*);
|
||||||
|
};
|
||||||
|
/* HashTable */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
struct Entry ** table;
|
||||||
|
}HashTable;
|
||||||
|
```
|
||||||
|
- 定义哈希表的创建、删除、增删改查
|
||||||
|
```c
|
||||||
|
/* new an instance of HashTable */
|
||||||
|
HashTable* HashTableNew();
|
||||||
|
|
||||||
|
/*
|
||||||
|
delete an instance of HashTable,
|
||||||
|
all values are removed auotmatically.
|
||||||
|
*/
|
||||||
|
void HashTableDelete(HashTable* ht);
|
||||||
|
|
||||||
|
/*
|
||||||
|
add or update a value to ht,
|
||||||
|
free_value(if not NULL) is called automatically when the value is removed.
|
||||||
|
return 0 if success, -1 if error occurred.
|
||||||
|
*/
|
||||||
|
int HashTablePut(HashTable* ht, char* key, void* value);
|
||||||
|
int HashTablePut2(HashTable* ht, char* key, void* value, void(*free_value)(void*));
|
||||||
|
|
||||||
|
/* get a value indexed by key, return NULL if not found. */
|
||||||
|
void* HashTableGet(HashTable* ht, char* key);
|
||||||
|
|
||||||
|
/* remove a value indexed by key */
|
||||||
|
void HashTableRemove(HashTable* ht, char* key);
|
||||||
|
```
|
||||||
|
- 实现哈希表的创建、删除、增删改查
|
||||||
|
```c
|
||||||
|
/* constructor of struct Entry */
|
||||||
|
static void InitEntry(struct Entry* entry)
|
||||||
|
{
|
||||||
|
entry->key = NULL;
|
||||||
|
entry->value = NULL;
|
||||||
|
entry->next = NULL;
|
||||||
|
entry->FreeValue = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* destructor of struct Entry */
|
||||||
|
static void FreeEntry(struct Entry* entry)
|
||||||
|
{
|
||||||
|
if (entry){
|
||||||
|
if (entry->FreeValue){
|
||||||
|
entry->FreeValue(entry->value);
|
||||||
|
}
|
||||||
|
free(entry->key);
|
||||||
|
entry->key = NULL;
|
||||||
|
free(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the classic Times33 hash function */
|
||||||
|
static unsigned int Hash33(char* key)
|
||||||
|
{
|
||||||
|
unsigned int hash = 0;
|
||||||
|
while (*key){
|
||||||
|
hash = (hash << 5) + hash + *key++;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* new a HashTable instance */
|
||||||
|
HashTable* HashTableNew()
|
||||||
|
{
|
||||||
|
HashTable* hash_table = malloc(sizeof(HashTable));
|
||||||
|
|
||||||
|
if (NULL == hash_table){
|
||||||
|
HashTableDelete(hash_table);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
hash_table->table = malloc(sizeof(struct Entry*) * TABLE_SIZE);
|
||||||
|
if (NULL == hash_table->table){
|
||||||
|
HashTableDelete(hash_table);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(hash_table->table, 0, sizeof(struct Entry*) * TABLE_SIZE);
|
||||||
|
|
||||||
|
return hash_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete a HashTable instance */
|
||||||
|
void HashTableDelete(HashTable* hash_table)
|
||||||
|
{
|
||||||
|
if (hash_table){
|
||||||
|
if (hash_table->table){
|
||||||
|
int i = 0;
|
||||||
|
for (i = 0; i < TABLE_SIZE; i++){
|
||||||
|
struct Entry* p = hash_table->table[i];
|
||||||
|
struct Entry* q = NULL;
|
||||||
|
while (p){
|
||||||
|
q = p->next;
|
||||||
|
FreeEntry(p);
|
||||||
|
p = q;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(hash_table->table);
|
||||||
|
hash_table->table = NULL;
|
||||||
|
}
|
||||||
|
free(hash_table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* insert or update a value indexed by key without FreeValue */
|
||||||
|
int HashTablePut(HashTable* hash_table, char* key, void* value)
|
||||||
|
{
|
||||||
|
return HashTablePut2(hash_table,key,value,NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* insert or update a value indexed by key with FreeValue */
|
||||||
|
int HashTablePut2(HashTable* hash_table, char* key, void* value, void(*FreeValue)(void*))
|
||||||
|
{
|
||||||
|
int i = Hash33(key) % TABLE_SIZE;
|
||||||
|
struct Entry* p = hash_table->table[i];
|
||||||
|
struct Entry* prep = p;
|
||||||
|
char* key_str = malloc(strlen(key) + 1);
|
||||||
|
if (key_str == NULL){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
char* value_str = malloc(strlen(value) + 1);
|
||||||
|
if (value_str == NULL){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy(key_str, key);
|
||||||
|
strcpy(value_str,value);
|
||||||
|
|
||||||
|
while (p){ /* if key is already stroed, update its value */
|
||||||
|
if (strcmp(p->key, key) == 0){
|
||||||
|
if (p->FreeValue) {
|
||||||
|
p->FreeValue(p->value);
|
||||||
|
}
|
||||||
|
p->value = value_str;
|
||||||
|
p->FreeValue = FreeValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prep = p;
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == NULL){ /* if key has not been stored, then add it */
|
||||||
|
struct Entry * entry = malloc(sizeof(struct Entry));
|
||||||
|
if (NULL == entry){
|
||||||
|
free(key_str);
|
||||||
|
key_str = NULL;
|
||||||
|
free(value_str);
|
||||||
|
value_str = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
InitEntry(entry);
|
||||||
|
entry->next = NULL;
|
||||||
|
entry->key = key_str;
|
||||||
|
entry->value = value_str;
|
||||||
|
entry->FreeValue = FreeValue;
|
||||||
|
|
||||||
|
if (prep == NULL){
|
||||||
|
hash_table->table[i] = entry;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
prep->next = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get a value indexed by key */
|
||||||
|
void* HashTableGet(HashTable* hash_table, char* key)
|
||||||
|
{
|
||||||
|
int i = Hash33(key) % TABLE_SIZE;
|
||||||
|
struct Entry* p = hash_table->table[i];
|
||||||
|
while (p){
|
||||||
|
if (strcmp(key, p->key) == 0){
|
||||||
|
return p->value;
|
||||||
|
}
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove a value indexed by key */
|
||||||
|
void HashTableRemove(HashTable* hash_table, char* key)
|
||||||
|
{
|
||||||
|
int i = Hash33(key) % TABLE_SIZE;
|
||||||
|
|
||||||
|
struct Entry* p = hash_table->table[i];
|
||||||
|
struct Entry* prep = p;
|
||||||
|
while (p){
|
||||||
|
if (strcmp(key, p->key) == 0) {
|
||||||
|
FreeEntry(p);
|
||||||
|
if (p == prep) {
|
||||||
|
hash_table->table[i] = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prep->next = p->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prep = p;
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## 3. 测试程序说明
|
||||||
|
- 测试哈希表的基本操作
|
||||||
|
```c
|
||||||
|
/* the test order menu */
|
||||||
|
void ShowMenu()
|
||||||
|
{
|
||||||
|
printf("================order menu================\n");
|
||||||
|
printf("==========0:insert(TestHash 0 x 2)========\n");
|
||||||
|
printf("==========1:get(TestHash 1 x)=============\n");
|
||||||
|
printf("==========2:update(TestHash 2 x 1)========\n");
|
||||||
|
printf("==========3:remove(TestHash 3 x)==========\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
HashTable* hash_table = NULL;
|
||||||
|
/* test for hash table*/
|
||||||
|
void TestHash(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc == 1){
|
||||||
|
printf("please use TestHash help to check orders\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (strcmp(argv[1],"help") == 0) ShowMenu();
|
||||||
|
|
||||||
|
if (strcmp(argv[1],"0") == 0){ // insert
|
||||||
|
if(hash_table == NULL){
|
||||||
|
hash_table = HashTableNew();
|
||||||
|
}
|
||||||
|
HashTablePut(hash_table,argv[2],argv[3]);
|
||||||
|
char* value = (char*)HashTableGet(hash_table,argv[2]);
|
||||||
|
printf("insert key=%s,val=%s; sucessful!\n",argv[2],value);
|
||||||
|
}else if (strcmp(argv[1],"1") == 0){ // get
|
||||||
|
if(hash_table == NULL){
|
||||||
|
printf("error: hash table is NULL. please insert first.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char* value = (char*)HashTableGet(hash_table,argv[2]);
|
||||||
|
if (value == NULL){
|
||||||
|
printf("without such key(%s)\n",argv[2]);
|
||||||
|
}else{
|
||||||
|
printf("get key=%s,value=%s; answer=%s\n",argv[2],value,value);
|
||||||
|
}
|
||||||
|
}else if (strcmp(argv[1],"2") == 0){ // update
|
||||||
|
if (hash_table == NULL){
|
||||||
|
printf("error: hash table is NULL. please insert first.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char* value = (char*)HashTableGet(hash_table,argv[2]);
|
||||||
|
if (value == NULL){
|
||||||
|
printf("without such key(%s). please insert first.\n",argv[2]);
|
||||||
|
}else{
|
||||||
|
HashTablePut(hash_table,argv[2],argv[3]);
|
||||||
|
printf("update key=%s,old_value=%s,value=%s; sucessful\n",argv[2],value,argv[3]);
|
||||||
|
}
|
||||||
|
}else if (strcmp(argv[1],"3") == 0){ // remove
|
||||||
|
if (hash_table == NULL){
|
||||||
|
printf("error: hash table is NULL. please insert first.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HashTableRemove(hash_table,argv[2]);
|
||||||
|
printf("remove key=%s; sucessful!\n",argv[2]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PRIV_SHELL_CMD_FUNCTION(TestHash, a hash test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. 运行结果(##需结合运行测试截图按步骤说明##)
|
||||||
|
1. 输入help查看letter shell可以调用的命令
|
||||||
|
2. 输入TestHash命令,提示用TestHash help查看TestHash的命令
|
||||||
|
3. 没有插入元素就查看元素:TestHash 1 x --> 哈希表为空,提示先插入
|
||||||
|
4. 没有插入就删除元素:TestHash 3 x --> 哈希表为空,提示先插入
|
||||||
|
5. 插入x=2: TestHash 0 x 2
|
||||||
|
6. 查找x: TestHash 1 x
|
||||||
|
7. 更新x=100: TestHash 2 x 100
|
||||||
|
8. 查找更新后的x: TestHash 1 x
|
||||||
|
9. 删除x: TestHash 3 x
|
||||||
|
10. 确认是否被删除: TestHash 1 x
|
||||||
|

|
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
|
@ -0,0 +1,260 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 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_hash.c
|
||||||
|
* @brief: a application of hash table
|
||||||
|
* @version: 1.0
|
||||||
|
* @author: bdislab_final
|
||||||
|
* @date: 2023/6/17
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "test_hash.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <transform.h>
|
||||||
|
|
||||||
|
#ifdef ADD_XIZI_FETURES
|
||||||
|
|
||||||
|
/* constructor of struct Entry */
|
||||||
|
static void InitEntry(struct Entry* entry)
|
||||||
|
{
|
||||||
|
entry->key = NULL;
|
||||||
|
entry->value = NULL;
|
||||||
|
entry->next = NULL;
|
||||||
|
entry->FreeValue = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* destructor of struct Entry */
|
||||||
|
static void FreeEntry(struct Entry* entry)
|
||||||
|
{
|
||||||
|
if (entry){
|
||||||
|
if (entry->FreeValue){
|
||||||
|
entry->FreeValue(entry->value);
|
||||||
|
}
|
||||||
|
free(entry->key);
|
||||||
|
entry->key = NULL;
|
||||||
|
free(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the classic Times33 hash function */
|
||||||
|
static unsigned int Hash33(char* key)
|
||||||
|
{
|
||||||
|
unsigned int hash = 0;
|
||||||
|
while (*key){
|
||||||
|
hash = (hash << 5) + hash + *key++;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* new a HashTable instance */
|
||||||
|
HashTable* HashTableNew()
|
||||||
|
{
|
||||||
|
HashTable* hash_table = malloc(sizeof(HashTable));
|
||||||
|
|
||||||
|
if (NULL == hash_table){
|
||||||
|
HashTableDelete(hash_table);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
hash_table->table = malloc(sizeof(struct Entry*) * TABLE_SIZE);
|
||||||
|
if (NULL == hash_table->table){
|
||||||
|
HashTableDelete(hash_table);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(hash_table->table, 0, sizeof(struct Entry*) * TABLE_SIZE);
|
||||||
|
|
||||||
|
return hash_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete a HashTable instance */
|
||||||
|
void HashTableDelete(HashTable* hash_table)
|
||||||
|
{
|
||||||
|
if (hash_table){
|
||||||
|
if (hash_table->table){
|
||||||
|
int i = 0;
|
||||||
|
for (i = 0; i < TABLE_SIZE; i++){
|
||||||
|
struct Entry* p = hash_table->table[i];
|
||||||
|
struct Entry* q = NULL;
|
||||||
|
while (p){
|
||||||
|
q = p->next;
|
||||||
|
FreeEntry(p);
|
||||||
|
p = q;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(hash_table->table);
|
||||||
|
hash_table->table = NULL;
|
||||||
|
}
|
||||||
|
free(hash_table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* insert or update a value indexed by key without FreeValue */
|
||||||
|
int HashTablePut(HashTable* hash_table, char* key, void* value)
|
||||||
|
{
|
||||||
|
return HashTablePut2(hash_table,key,value,NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* insert or update a value indexed by key with FreeValue */
|
||||||
|
int HashTablePut2(HashTable* hash_table, char* key, void* value, void(*FreeValue)(void*))
|
||||||
|
{
|
||||||
|
int i = Hash33(key) % TABLE_SIZE;
|
||||||
|
struct Entry* p = hash_table->table[i];
|
||||||
|
struct Entry* prep = p;
|
||||||
|
char* key_str = malloc(strlen(key) + 1);
|
||||||
|
if (key_str == NULL){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
char* value_str = malloc(strlen(value) + 1);
|
||||||
|
if (value_str == NULL){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy(key_str, key);
|
||||||
|
strcpy(value_str,value);
|
||||||
|
|
||||||
|
while (p){ /* if key is already stroed, update its value */
|
||||||
|
if (strcmp(p->key, key) == 0){
|
||||||
|
if (p->FreeValue) {
|
||||||
|
p->FreeValue(p->value);
|
||||||
|
}
|
||||||
|
p->value = value_str;
|
||||||
|
p->FreeValue = FreeValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prep = p;
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == NULL){ /* if key has not been stored, then add it */
|
||||||
|
struct Entry * entry = malloc(sizeof(struct Entry));
|
||||||
|
if (NULL == entry){
|
||||||
|
free(key_str);
|
||||||
|
key_str = NULL;
|
||||||
|
free(value_str);
|
||||||
|
value_str = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
InitEntry(entry);
|
||||||
|
entry->next = NULL;
|
||||||
|
entry->key = key_str;
|
||||||
|
entry->value = value_str;
|
||||||
|
entry->FreeValue = FreeValue;
|
||||||
|
|
||||||
|
if (prep == NULL){
|
||||||
|
hash_table->table[i] = entry;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
prep->next = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get a value indexed by key */
|
||||||
|
void* HashTableGet(HashTable* hash_table, char* key)
|
||||||
|
{
|
||||||
|
int i = Hash33(key) % TABLE_SIZE;
|
||||||
|
struct Entry* p = hash_table->table[i];
|
||||||
|
while (p){
|
||||||
|
if (strcmp(key, p->key) == 0){
|
||||||
|
return p->value;
|
||||||
|
}
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove a value indexed by key */
|
||||||
|
void HashTableRemove(HashTable* hash_table, char* key)
|
||||||
|
{
|
||||||
|
int i = Hash33(key) % TABLE_SIZE;
|
||||||
|
|
||||||
|
struct Entry* p = hash_table->table[i];
|
||||||
|
struct Entry* prep = p;
|
||||||
|
while (p){
|
||||||
|
if (strcmp(key, p->key) == 0) {
|
||||||
|
FreeEntry(p);
|
||||||
|
if (p == prep) {
|
||||||
|
hash_table->table[i] = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prep->next = p->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prep = p;
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the test order menu */
|
||||||
|
void ShowMenu()
|
||||||
|
{
|
||||||
|
printf("================order menu================\n");
|
||||||
|
printf("==========0:insert(TestHash 0 x 2)========\n");
|
||||||
|
printf("==========1:get(TestHash 1 x)=============\n");
|
||||||
|
printf("==========2:update(TestHash 2 x 1)========\n");
|
||||||
|
printf("==========3:remove(TestHash 3 x)==========\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
HashTable* hash_table = NULL;
|
||||||
|
/* test for hash table*/
|
||||||
|
void TestHash(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc == 1){
|
||||||
|
printf("please use TestHash help to check orders\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (strcmp(argv[1],"help") == 0) ShowMenu();
|
||||||
|
|
||||||
|
if (strcmp(argv[1],"0") == 0){ // insert
|
||||||
|
if(hash_table == NULL){
|
||||||
|
hash_table = HashTableNew();
|
||||||
|
}
|
||||||
|
HashTablePut(hash_table,argv[2],argv[3]);
|
||||||
|
char* value = (char*)HashTableGet(hash_table,argv[2]);
|
||||||
|
printf("insert key=%s,val=%s; sucessful!\n",argv[2],value);
|
||||||
|
}else if (strcmp(argv[1],"1") == 0){ // get
|
||||||
|
if(hash_table == NULL){
|
||||||
|
printf("error: hash table is NULL. please insert first.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char* value = (char*)HashTableGet(hash_table,argv[2]);
|
||||||
|
if (value == NULL){
|
||||||
|
printf("without such key(%s)\n",argv[2]);
|
||||||
|
}else{
|
||||||
|
printf("get key=%s,value=%s; answer=%s\n",argv[2],value,value);
|
||||||
|
}
|
||||||
|
}else if (strcmp(argv[1],"2") == 0){ // update
|
||||||
|
if (hash_table == NULL){
|
||||||
|
printf("error: hash table is NULL. please insert first.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char* value = (char*)HashTableGet(hash_table,argv[2]);
|
||||||
|
if (value == NULL){
|
||||||
|
printf("without such key(%s). please insert first.\n",argv[2]);
|
||||||
|
}else{
|
||||||
|
HashTablePut(hash_table,argv[2],argv[3]);
|
||||||
|
printf("update key=%s,old_value=%s,value=%s; sucessful\n",argv[2],value,argv[3]);
|
||||||
|
}
|
||||||
|
}else if (strcmp(argv[1],"3") == 0){ // remove
|
||||||
|
if (hash_table == NULL){
|
||||||
|
printf("error: hash table is NULL. please insert first.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HashTableRemove(hash_table,argv[2]);
|
||||||
|
printf("remove key=%s; sucessful!\n",argv[2]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PRIV_SHELL_CMD_FUNCTION(TestHash, a hash test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||||
|
#endif
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 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_hash.h
|
||||||
|
* @brief a application of hash table
|
||||||
|
* @version 1.0
|
||||||
|
* @author bdislab_final
|
||||||
|
* @date 2023/6/17
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TEST_HASH_H
|
||||||
|
#define TEST_HASH_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* the size of hash table */
|
||||||
|
#define TABLE_SIZE (1024)
|
||||||
|
|
||||||
|
/* element of the hash table's chain list */
|
||||||
|
struct Entry
|
||||||
|
{
|
||||||
|
char* key;
|
||||||
|
void* value;
|
||||||
|
struct Entry* next;
|
||||||
|
void (*FreeValue)(void*);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* HashTable */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
struct Entry ** table;
|
||||||
|
}HashTable;
|
||||||
|
|
||||||
|
|
||||||
|
/* new an instance of HashTable */
|
||||||
|
HashTable* HashTableNew();
|
||||||
|
|
||||||
|
/*
|
||||||
|
delete an instance of HashTable,
|
||||||
|
all values are removed auotmatically.
|
||||||
|
*/
|
||||||
|
void HashTableDelete(HashTable* ht);
|
||||||
|
|
||||||
|
/*
|
||||||
|
add or update a value to ht,
|
||||||
|
free_value(if not NULL) is called automatically when the value is removed.
|
||||||
|
return 0 if success, -1 if error occurred.
|
||||||
|
*/
|
||||||
|
int HashTablePut(HashTable* ht, char* key, void* value);
|
||||||
|
int HashTablePut2(HashTable* ht, char* key, void* value, void(*free_value)(void*));
|
||||||
|
|
||||||
|
/* get a value indexed by key, return NULL if not found. */
|
||||||
|
void* HashTableGet(HashTable* ht, char* key);
|
||||||
|
|
||||||
|
/* remove a value indexed by key */
|
||||||
|
void HashTableRemove(HashTable* ht, char* key);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
cd /home/yanglong/Desktop/xiuos/xiuos/Ubiquitous/XiZi_IIoT
|
||||||
|
make BOARD=cortex-m3-emulator distclean
|
||||||
|
make BOARD=cortex-m3-emulator menuconfig
|
||||||
|
make BOARD=cortex-m3-emulator
|
||||||
|
sleep
|
||||||
|
qemu-system-arm -machine lm3s6965evb -nographic -kernel build/XiZi-cortex-m3-emulator.elf
|
Loading…
Reference in New Issue