parent
dcfab6f1c0
commit
f766d17fb0
@ -1,43 +1,53 @@
|
|||||||
import unittest,importlib,BeautifulReport,cffi
|
import unittest,importlib,BeautifulReport
|
||||||
|
import cffi
|
||||||
|
|
||||||
def load():
|
def load():
|
||||||
src = open("add.c").read()
|
with open("/home/hai/sledge-serverless-framework/runtime/include/hash.h", "r") as f:
|
||||||
inc = open("add.h").read()
|
inc = ""
|
||||||
|
for line in f:
|
||||||
|
if not line.strip().startswith('#'):
|
||||||
|
inc += line
|
||||||
|
src = open("/home/hai/sledge-serverless-framework/runtime/Utest_py/hash.c").read()
|
||||||
|
|
||||||
builder = cffi.FFI()
|
builder = cffi.FFI()
|
||||||
|
|
||||||
builder.cdef(inc)
|
builder.cdef(inc)
|
||||||
builder.set_source("addLib",src)
|
builder.set_source("hashlib",src)
|
||||||
builder.compile()
|
builder.compile()
|
||||||
|
|
||||||
md = importlib.import_module("addLib")
|
md = importlib.import_module("hashlib")
|
||||||
|
|
||||||
return md.lib
|
return md.lib
|
||||||
|
|
||||||
md = load()
|
md = load()
|
||||||
|
class HashTableTestCase(unittest.TestCase):
|
||||||
class AddTestCase(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_case1(self):
|
def test_case1(self):
|
||||||
'''
|
'''
|
||||||
第1个case
|
测试添加和查找功能
|
||||||
:return:
|
|
||||||
'''
|
'''
|
||||||
self.assertEqual(md.addition(1,2),1+2)
|
table = md.create_table()
|
||||||
print('md.addition(1,2),1+2')
|
md.add_item(table, b"key1", "Hello World")
|
||||||
|
value = md.find_value(table, b"key1")
|
||||||
|
self.assertEqual(value, "Hello World")
|
||||||
|
print('Value for "key1":', value)
|
||||||
|
|
||||||
def test_case2(self):
|
def test_case2(self):
|
||||||
'''
|
'''
|
||||||
第2个case
|
测试查找不存在的键
|
||||||
:return:
|
|
||||||
'''
|
'''
|
||||||
self.assertEqual(md.addition(1,5),1+2)
|
table = md.create_table()
|
||||||
|
value = md.find_value(table, b"nonexistent")
|
||||||
print('md.addition(1,5),1+2')
|
self.assertIsNone(value)
|
||||||
|
print('Value for "nonexistent":', value)
|
||||||
|
|
||||||
|
def test_case3(self):
|
||||||
|
# 确保每个测试后表被释放
|
||||||
|
md.free_table(self.table)
|
||||||
|
|
||||||
sut = unittest.TestSuite()
|
sut = unittest.TestSuite()
|
||||||
sut.addTest(unittest(AddTestCase))
|
sut.addTest(unittest.makeSuite(HashTableTestCase))
|
||||||
run = BeautifulReport.BeautifulReport(sut)
|
run = BeautifulReport.BeautifulReport(sut)
|
||||||
|
|
||||||
run.report(filename="test.html",description="add单元测试")
|
run.report(filename="test.html",description="单元测试")
|
||||||
|
|
||||||
|
Binary file not shown.
@ -0,0 +1,49 @@
|
|||||||
|
// hash_test.c
|
||||||
|
#include "../include/hash.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
typedef struct test
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
}test;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
test *test1 = malloc(sizeof(test));
|
||||||
|
test *test2 = malloc(sizeof(test));
|
||||||
|
test1->name = "test1";
|
||||||
|
test2->name = "test2";
|
||||||
|
HashTable *myTable = create_table();
|
||||||
|
add_item(myTable, "key1", test1);
|
||||||
|
add_item(myTable, "key2", test2);
|
||||||
|
char *input = argv[1];
|
||||||
|
test *value = find_value(myTable, input);
|
||||||
|
if (value) {
|
||||||
|
printf("Test Passed: %s\n", value->name);
|
||||||
|
} else {
|
||||||
|
printf("Test Failed: Key not found.\n");
|
||||||
|
}
|
||||||
|
remove_item(myTable, "key1");
|
||||||
|
printf("remove key1.\n");
|
||||||
|
test *value2 = find_value(myTable, input);
|
||||||
|
if (value2) {
|
||||||
|
printf("Test Passed: %s\n", value2->name);
|
||||||
|
} else {
|
||||||
|
printf("Test Failed: Key not found.\n");
|
||||||
|
}
|
||||||
|
add_item(myTable, "key1", test1);
|
||||||
|
test *value4 = find_value(myTable, "key1");
|
||||||
|
if (value4) {
|
||||||
|
printf("Test Passed: %s\n", value4->name);
|
||||||
|
} else {
|
||||||
|
printf("Test Failed: Key not found.\n");
|
||||||
|
}
|
||||||
|
test *value3 = find_value(myTable, "key2");
|
||||||
|
if (value3) {
|
||||||
|
printf("Test Passed: %s\n", value3->name);
|
||||||
|
} else {
|
||||||
|
printf("Test Failed: Key not found.\n");
|
||||||
|
}
|
||||||
|
free(test1);
|
||||||
|
free(test2);
|
||||||
|
free_table(myTable);
|
||||||
|
return 0;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,144 @@
|
|||||||
|
#ifndef HASH_H
|
||||||
|
#define HASH_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#define TABLE_SIZE 32 // the size of hash table
|
||||||
|
#define MAX_KEY_LENGTH 32 // the maximum length of key
|
||||||
|
typedef struct {
|
||||||
|
char key[MAX_KEY_LENGTH];
|
||||||
|
void *value;
|
||||||
|
int is_deleted; // Flag to mark items as deleted
|
||||||
|
} HashItem;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HashItem **items;
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
} HashTable;
|
||||||
|
|
||||||
|
static inline unsigned long
|
||||||
|
hash_function(const char *str) {
|
||||||
|
unsigned long i = 0;
|
||||||
|
for (int j = 0; str[j]; j++)
|
||||||
|
i += str[j];
|
||||||
|
return i % TABLE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline HashTable
|
||||||
|
*create_table() {
|
||||||
|
HashTable *table = (HashTable *)malloc(sizeof(HashTable));
|
||||||
|
if (!table) {
|
||||||
|
fprintf(stderr, "Failed to allocate memory for hash table struct.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
table->items = (HashItem **)malloc(sizeof(HashItem*) * TABLE_SIZE);
|
||||||
|
if (!table->items) {
|
||||||
|
fprintf(stderr, "Failed to allocate memory for items.\n");
|
||||||
|
free(table); // Free the table if item allocation fails
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_init(&table->lock, NULL);
|
||||||
|
|
||||||
|
for (int i = 0; i < TABLE_SIZE; i++) {
|
||||||
|
table->items[i] = NULL;
|
||||||
|
}
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
add_item(HashTable *table, const char *key, void *value) {
|
||||||
|
assert(table != NULL);
|
||||||
|
assert(key != NULL);
|
||||||
|
assert(value != NULL);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&table->lock);
|
||||||
|
|
||||||
|
unsigned long index = hash_function(key);
|
||||||
|
HashItem *item = malloc(sizeof(HashItem));
|
||||||
|
if (!item) {
|
||||||
|
fprintf(stderr, "Failed to allocate memory for a new item.\n");
|
||||||
|
pthread_mutex_unlock(&table->lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
strcpy(item->key, key);
|
||||||
|
item->value = value;
|
||||||
|
item->is_deleted = 0;
|
||||||
|
|
||||||
|
while (table->items[index] != NULL && !table->items[index]->is_deleted && strcmp(table->items[index]->key, key) != 0) {
|
||||||
|
index = (index + 1) % TABLE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(table->items[index]); // Free the existing item if overwriting
|
||||||
|
table->items[index] = item;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&table->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
remove_item(HashTable *table, const char *key) {
|
||||||
|
assert(table != NULL);
|
||||||
|
assert(key != NULL);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&table->lock);
|
||||||
|
|
||||||
|
unsigned long index = hash_function(key);
|
||||||
|
while (table->items[index] != NULL && strcmp(table->items[index]->key, key) != 0) {
|
||||||
|
index = (index + 1) % TABLE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table->items[index] != NULL) {
|
||||||
|
table->items[index]->is_deleted = 1; // Mark as deleted
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&table->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
*find_value(HashTable *table, const char *key) {
|
||||||
|
assert(table != NULL);
|
||||||
|
assert(key != NULL);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&table->lock);
|
||||||
|
|
||||||
|
unsigned long index = hash_function(key);
|
||||||
|
int count = 0;
|
||||||
|
while (table->items[index] != NULL && count < TABLE_SIZE && (table->items[index]->is_deleted || strcmp(table->items[index]->key, key) != 0)) {
|
||||||
|
index = (index + 1) % TABLE_SIZE;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table->items[index] == NULL || table->items[index]->is_deleted)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&table->lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pthread_mutex_unlock(&table->lock);
|
||||||
|
return table->items[index]->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
free_table(HashTable *table) {
|
||||||
|
assert(table != NULL);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&table->lock);
|
||||||
|
|
||||||
|
for (int i = 0; i < TABLE_SIZE; i++) {
|
||||||
|
if (table->items[i] != NULL) {
|
||||||
|
free(table->items[i]); // Free each item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(table->items);
|
||||||
|
free(table);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&table->lock);
|
||||||
|
pthread_mutex_destroy(&table->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in new issue