add hash/kvs-client

This commit is contained in:
King
2024-05-25 14:23:43 +00:00
parent ea5291f3fe
commit 480bccfa04
16 changed files with 1100 additions and 28 deletions

285
kvs_hash.c Executable file
View File

@@ -0,0 +1,285 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include "kvstore.h"
// Key, Value -->
// Modify
kvs_hash_t global_hash;
//Connection
// 'C' + 'o' + 'n'
static int _hash(char *key, int size) {
if (!key) return -1;
int sum = 0;
int i = 0;
while (key[i] != 0) {
sum += key[i];
i ++;
}
return sum % size;
}
hashnode_t *_create_node(char *key, char *value) {
hashnode_t *node = (hashnode_t*)kvs_malloc(sizeof(hashnode_t));
if (!node) return NULL;
#if ENABLE_KEY_POINTER
char *kcopy = kvs_malloc(strlen(key) + 1);
if (kcopy == NULL) return NULL;
memset(kcopy, 0, strlen(key) + 1);
strncpy(kcopy, key, strlen(key));
node->key = kcopy;
char *kvalue = kvs_malloc(strlen(value) + 1);
if (kvalue == NULL) {
kvs_free(kvalue);
return NULL;
}
memset(kvalue, 0, strlen(value) + 1);
strncpy(kvalue, value, strlen(value));
node->value = kvalue;
#else
strncpy(node->key, key, MAX_KEY_LEN);
strncpy(node->value, value, MAX_VALUE_LEN);
#endif
node->next = NULL;
return node;
}
//
int kvs_hash_create(kvs_hash_t *hash) {
if (!hash) return -1;
hash->nodes = (hashnode_t**)kvs_malloc(sizeof(hashnode_t*) * MAX_TABLE_SIZE);
if (!hash->nodes) return -1;
hash->max_slots = MAX_TABLE_SIZE;
hash->count = 0;
return 0;
}
//
void kvs_hash_destory(kvs_hash_t *hash) {
if (!hash) return;
int i = 0;
for (i = 0;i < hash->max_slots;i ++) {
hashnode_t *node = hash->nodes[i];
while (node != NULL) { // error
hashnode_t *tmp = node;
node = node->next;
hash->nodes[i] = node;
kvs_free(tmp);
}
}
kvs_free(hash->nodes);
}
// 5 + 2
// mp
int kvs_hash_set(kvs_hash_t *hash, char *key, char *value) {
if (!hash || !key || !value) return -1;
int idx = _hash(key, MAX_TABLE_SIZE);
hashnode_t *node = hash->nodes[idx];
#if 1
while (node != NULL) {
if (strcmp(node->key, key) == 0) { // exist
return 1;
}
node = node->next;
}
#endif
hashnode_t *new_node = _create_node(key, value);
new_node->next = hash->nodes[idx];
hash->nodes[idx] = new_node;
hash->count ++;
return 0;
}
char * kvs_hash_get(kvs_hash_t *hash, char *key) {
if (!hash || !key) return NULL;
int idx = _hash(key, MAX_TABLE_SIZE);
hashnode_t *node = hash->nodes[idx];
while (node != NULL) {
if (strcmp(node->key, key) == 0) {
return node->value;
}
node = node->next;
}
return NULL;
}
int kvs_hash_mod(kvs_hash_t *hash, char *key, char *value) {
if (!hash || !key) return -1;
int idx = _hash(key, MAX_TABLE_SIZE);
hashnode_t *node = hash->nodes[idx];
while (node != NULL) {
if (strcmp(node->key, key) == 0) {
break;
}
node = node->next;
}
if (node == NULL) {
return 1;
}
// node -->
kvs_free(node->value);
char *kvalue = kvs_malloc(strlen(value) + 1);
if (kvalue == NULL) return -2;
memset(kvalue, 0, strlen(value) + 1);
strncpy(kvalue, value, strlen(value));
node->value = kvalue;
return 0;
}
int kvs_hash_count(kvs_hash_t *hash) {
return hash->count;
}
int kvs_hash_del(kvs_hash_t *hash, char *key) {
if (!hash || !key) return -2;
int idx = _hash(key, MAX_TABLE_SIZE);
hashnode_t *head = hash->nodes[idx];
if (head == NULL) return -1; // noexist
// head node
if (strcmp(head->key, key) == 0) {
hashnode_t *tmp = head->next;
hash->nodes[idx] = tmp;
kvs_free(head);
hash->count --;
return 0;
}
hashnode_t *cur = head;
while (cur->next != NULL) {
if (strcmp(cur->next->key, key) == 0) break; // search node
cur = cur->next;
}
if (cur->next == NULL) {
return -1;
}
hashnode_t *tmp = cur->next;
cur->next = tmp->next;
#if ENABLE_KEY_POINTER
kvs_free(tmp->key);
kvs_free(tmp->value);
#endif
kvs_free(tmp);
hash->count --;
return 0;
}
int kvs_hash_exist(kvs_hash_t *hash, char *key) {
char *value = kvs_hash_get(hash, key);
if (!value) return 1;
return 0;
}
#if 0
int main() {
kvs_hash_create(&hash);
kvs_hash_set(&hash, "Teacher1", "King");
kvs_hash_set(&hash, "Teacher2", "Darren");
kvs_hash_set(&hash, "Teacher3", "Mark");
kvs_hash_set(&hash, "Teacher4", "Vico");
kvs_hash_set(&hash, "Teacher5", "Nick");
char *value1 = kvs_hash_get(&hash, "Teacher1");
printf("Teacher1 : %s\n", value1);
int ret = kvs_hash_mod(&hash, "Teacher1", "King1");
printf("mode Teacher1 ret : %d\n", ret);
char *value2 = kvs_hash_get(&hash, "Teacher1");
printf("Teacher2 : %s\n", value1);
ret = kvs_hash_del(&hash, "Teacher1");
printf("delete Teacher1 ret : %d\n", ret);
ret = kvs_hash_exist(&hash, "Teacher1");
printf("Exist Teacher1 ret : %d\n", ret);
kvs_hash_destory(&hash);
return 0;
}
#endif