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

View File

@@ -1,15 +1,33 @@
CC = gcc
FLAGS = -I ./NtyCo/core/ -L ./NtyCo/ -lntyco -lpthread -luring -ldl
SRCS = kvstore.c ntyco.c proactor.c kvs_array.c kvs_rbtree.c kvs_hash.c
TESTCASE_SRCS = testcase.c
TARGET = kvstore
SRCS = kvstore.c ntyco.c proactor.c kvs_array.c kvs_rbtree.c
INC = -I ./NtyCo/core/
LIBS = -L ./NtyCo/ -lntyco -luring
SUBDIR = ./NtyCo/
TESTCASE = testcase
OBJS = $(SRCS:.c=.o)
all:
$(CC) -o $(TARGET) $(SRCS) $(INC) $(LIBS)
all: $(SUBDIR) $(TARGET) $(TESTCASE)
$(SUBDIR): ECHO
make -C $@
ECHO:
@echo $(SUBDIR)
$(TARGET): $(OBJS)
$(CC) -o $@ $^ $(FLAGS)
$(TESTCASE): $(TESTCASE_SRCS)
$(CC) -o $@ $^
%.o: %.c
$(CC) $(FLAGS) -c $^ -o $@
clean:
rm -rf kvstore
rm -rf $(OBJS) $(TARGET) $(TESTCASE)

29
Makefile.default Normal file
View File

@@ -0,0 +1,29 @@
CC = gcc
FLAGS = -I ./NtyCo/core/ -L ./NtyCo/ -lntyco -luring
TARGET = kvstore
SRCS = kvstore.c ntyco.c proactor.c kvs_array.c kvs_rbtree.c
# INC = -I ./NtyCo/core/
# LIBS = -L ./NtyCo/ -lntyco -luring
# FLAGS = -I ./NtyCo/core/ -L ./NtyCo/ -lntyco -luring
OBJS = $(SRCS:.c=.o)
TESTCASE = testcase
SUBDIR = ./NtyCo/
all: $(SUBDIR) $(TARGET) # $(TESTCASE)
$(SUBDIR): ECHO
make -C $@
ECHO:
@echo $(SUBDIR)
$(TARGET): $(OBJS)
$(CC) -o $@ $^ $(FLAGS)
clean:
rm -rf kvstore *.o

228
hash.c Executable file
View File

@@ -0,0 +1,228 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#define MAX_KEY_LEN 128
#define MAX_VALUE_LEN 512
#define MAX_TABLE_SIZE 1024
typedef struct hashnode_s {
char key[MAX_KEY_LEN];
char value[MAX_VALUE_LEN];
struct hashnode_s *next;
} hashnode_t;
typedef struct hashtable_s {
hashnode_t **nodes; //* change **,
int max_slots;
int count;
pthread_mutex_t lock;
} hashtable_t;
hashtable_t 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*)malloc(sizeof(hashnode_t));
if (!node) return NULL;
strncpy(node->key, key, MAX_KEY_LEN);
strncpy(node->value, value, MAX_VALUE_LEN);
node->next = NULL;
return node;
}
//
int init_hashtable(hashtable_t *hash) {
if (!hash) return -1;
hash->nodes = (hashnode_t**)malloc(sizeof(hashnode_t*) * MAX_TABLE_SIZE);
if (!hash->nodes) return -1;
hash->max_slots = MAX_TABLE_SIZE;
hash->count = 0;
pthread_mutex_init(&hash->lock, NULL);
return 0;
}
//
void dest_hashtable(hashtable_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;
free(tmp);
}
}
free(hash->nodes);
}
// mp
int put_kv_hashtable(hashtable_t *hash, char *key, char *value) {
if (!hash || !key || !value) return -1;
int idx = _hash(key, MAX_TABLE_SIZE);
pthread_mutex_lock(&hash->lock);
hashnode_t *node = hash->nodes[idx];
#if 1
while (node != NULL) {
if (strcmp(node->key, key) == 0) { // exist
pthread_mutex_unlock(&hash->lock);
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 ++;
pthread_mutex_unlock(&hash->lock);
return 0;
}
char * get_kv_hashtable(hashtable_t *hash, char *key) {
if (!hash || !key) return NULL;
int idx = _hash(key, MAX_TABLE_SIZE);
pthread_mutex_lock(&hash->lock);
hashnode_t *node = hash->nodes[idx];
while (node != NULL) {
if (strcmp(node->key, key) == 0) {
pthread_mutex_unlock(&hash->lock);
return node->value;
}
node = node->next;
}
pthread_mutex_unlock(&hash->lock);
return NULL;
}
int count_kv_hashtable(hashtable_t *hash) {
return hash->count;
}
int delete_kv_hashtable(hashtable_t *hash, char *key) {
if (!hash || !key) return -2;
int idx = _hash(key, MAX_TABLE_SIZE);
pthread_mutex_lock(&hash->lock);
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;
free(head);
hash->count --;
pthread_mutex_unlock(&hash->lock);
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) {
pthread_mutex_unlock(&hash->lock);
return -1;
}
hashnode_t *tmp = cur->next;
cur->next = tmp->next;
free(tmp);
hash->count --;
pthread_mutex_unlock(&hash->lock);
return 0;
}
int exist_kv_hashtable(hashtable_t *hash, char *key) {
char *value = get_kv_hashtable(hash, key);
if (value) return 1;
else return 0;
}

42
kvs-client/go-kvstore.go Executable file
View File

@@ -0,0 +1,42 @@
package main
import (
"fmt"
"net"
"os"
)
func main() {
conn, err := net.Dial("tcp", "192.168.243.131:2000")
if err != nil {
fmt.Println("connect failed: ", err)
os.Exit(1)
}
defer conn.Close()
message := "SET Teacher King"
_, err = conn.Write([]byte(message))
if err != nil {
fmt.Println("send failed: ", err)
os.Exit(1)
}
fmt.Printf("send msg: %s\n", message)
buffer := make([]byte, 1024)
length, err := conn.Read(buffer)
if err != nil {
fmt.Println("recv failed: ", err)
os.Exit(1)
}
response := string(buffer[:length])
fmt.Printf("recv msg: %s\n", response)
}

37
kvs-client/javakvstore.java Executable file
View File

@@ -0,0 +1,37 @@
import java.io.*;
import java.net.*;
public class javakvstore {
public static void main(String[] args) {
String serverAddress = "192.168.243.131";
int serverPort = 2000;
try {
Socket socket = new Socket(serverAddress, serverPort);
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
String message = "SET T1 KING";
outputStream.write(message.getBytes());
byte[] buffer = new byte[1024];
int bytesRead = inputStream.read(buffer);
if (bytesRead > 0) {
String response = new String(buffer, 0, bytesRead);
System.out.println("recv: " + response);
}
inputStream.close();
outputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

26
kvs-client/js-kvstore.js Executable file
View File

@@ -0,0 +1,26 @@
const net = require('net');
const client = net.createConnection({ port: 2000, host: '192.168.243.131' }, () => {
console.log('connect kvstore');
client.write('GET Teacher');
});
client.on('data', (data) => {
console.log(`recv${data.toString()}`);
client.end();
});
client.on('error', (err) => {
console.error('connect failed', err);
});
client.on('close', () => {
console.log('close connection');
});

30
kvs-client/py-kvstore.py Executable file
View File

@@ -0,0 +1,30 @@
import socket
def main():
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('192.168.243.131', 2000)
try:
client_socket.connect(server_address)
message = "GET Teacher"
client_socket.sendall(message.encode())
response = client_socket.recv(1024)
print("recv:", response.decode())
except Exception as e:
print("发生异常:", str(e))
finally:
client_socket.close()
if __name__ == '__main__':
main()

18
kvs-client/rust-kvstore.rs Executable file
View File

@@ -0,0 +1,18 @@
use std::io::{self, Read, Write};
use std::net::TcpStream;
fn main() -> io::Result<()> {
let server_address = "192.168.243.131:2000";
let mut stream = TcpStream::connect(server_address)?;
stream.write_all(b"GET Teacher")?;
let mut buffer = [0; 1024];
let bytes_read = stream.read(&mut buffer)?;
println!("Received: {}", String::from_utf8_lossy(&buffer[..bytes_read]));
Ok(())
}

View File

@@ -118,8 +118,11 @@ int kvs_array_del(kvs_array_t *inst, char *key) {
kvs_free(inst->table[i].value);
inst->table[i].value = NULL;
// error: > 1024
if (inst->total-1 == i) {
inst->total --;
}
inst->idx = i;
return 0;
}
@@ -136,6 +139,11 @@ int kvs_array_del(kvs_array_t *inst, char *key) {
int kvs_array_mod(kvs_array_t *inst, char *key, char *value) {
if (inst == NULL || key == NULL || value == NULL) return -1;
// error: > 1024
if (inst->total == 0) {
return KVS_ARRAY_SIZE;
}
int i = 0;
for (i = 0;i < inst->total;i ++) {

BIN
kvs_hash Executable file

Binary file not shown.

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

View File

@@ -498,8 +498,9 @@ int kvs_rbtree_set(kvs_rbtree_t *inst, char *key, char *value) {
char* kvs_rbtree_get(kvs_rbtree_t *inst, char *key) {
if (!inst || !key) return NULL;
rbtree_node *node = rbtree_search(inst, key);
if (!node) return NULL; // no exist
if (node == inst->nil) return NULL;
return node->value;
@@ -524,6 +525,7 @@ int kvs_rbtree_mod(kvs_rbtree_t *inst, char *key, char *value) {
rbtree_node *node = rbtree_search(inst, key);
if (!node) return 1; // no exist
if (node == inst->nil) return 1;
kvs_free(node->value);
@@ -543,6 +545,7 @@ int kvs_rbtree_exist(kvs_rbtree_t *inst, char *key) {
rbtree_node *node = rbtree_search(inst, key);
if (!node) return 1; // no exist
if (node == inst->nil) return 1;
return 0;
}

140
kvs_skiptable.c Executable file
View File

@@ -0,0 +1,140 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_LEVEL 6
typedef struct Node {
int key;
int value;
struct Node** forward;
} Node;
typedef struct SkipList {
int level;
Node* header;
} SkipList;
Node* createNode(int level, int key, int value) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->key = key;
newNode->value = value;
newNode->forward = (Node**)malloc((level + 1) * sizeof(Node*));
return newNode;
}
SkipList* createSkipList() {
SkipList* skipList = (SkipList*)malloc(sizeof(SkipList));
skipList->level = 0;
skipList->header = createNode(MAX_LEVEL, -1, -1);
for (int i = 0; i <= MAX_LEVEL; ++i) {
skipList->header->forward[i] = NULL;
}
return skipList;
}
int randomLevel() {
int level = 0;
while (rand() < RAND_MAX / 2 && level < MAX_LEVEL)
level++;
return level;
}
bool insert(SkipList* skipList, int key, int value) {
Node* update[MAX_LEVEL + 1];
Node* current = skipList->header;
for (int i = skipList->level; i >= 0; --i) {
while (current->forward[i] != NULL && current->forward[i]->key < key)
current = current->forward[i];
update[i] = current;
}
current = current->forward[0];
if (current == NULL || current->key != key) {
int level = randomLevel();
if (level > skipList->level) {
for (int i = skipList->level + 1; i <= level; ++i)
update[i] = skipList->header;
skipList->level = level;
}
Node* newNode = createNode(level, key, value);
for (int i = 0; i <= level; ++i) {
newNode->forward[i] = update[i]->forward[i];
update[i]->forward[i] = newNode;
}
printf("Inserted key %d\n", key);
return true;
} else {
printf("Key %d already exists\n", key);
return false;
}
}
void display(SkipList* skipList) {
printf("Skip List:\n");
for (int i = 0; i <= skipList->level; ++i) {
Node* node = skipList->header->forward[i];
printf("Level %d: ", i);
while (node != NULL) {
printf("%d ", node->key);
node = node->forward[i];
}
printf("\n");
}
}
bool search(SkipList* skipList, int key) {
Node* current = skipList->header;
for (int i = skipList->level; i >= 0; --i) {
while (current->forward[i] != NULL && current->forward[i]->key < key)
current = current->forward[i];
}
current = current -> forward[0];
if(current && current -> key == key){
printf("Key %d found with value %d\n", key, current->value);
return true;
}else{
printf("Key %d not found\n", key);
return false;
}
}
int main() {
SkipList* skipList = createSkipList();
insert(skipList, 3, 30);
insert(skipList, 6, 60);
insert(skipList, 2, 20);
insert(skipList, 4, 40);
display(skipList);
search(skipList, 3);
search(skipList, 7);
return 0;
}

View File

@@ -13,7 +13,9 @@ extern kvs_array_t global_array;
extern kvs_rbtree_t global_rbtree;
#endif
#if ENABLE_HASH
extern kvs_hash_t global_hash;
#endif
void *kvs_malloc(size_t size) {
return malloc(size);
@@ -26,7 +28,8 @@ void kvs_free(void *ptr) {
const char *command[] = {
"SET", "GET", "DEL", "MOD", "EXIST",
"RSET", "RGET", "RDEL", "RMOD", "REXIST"
"RSET", "RGET", "RDEL", "RMOD", "REXIST",
"HSET", "HGET", "HDEL", "HMOD", "HEXIST"
};
enum {
@@ -43,6 +46,12 @@ enum {
KVS_CMD_RDEL,
KVS_CMD_RMOD,
KVS_CMD_REXIST,
// hash
KVS_CMD_HSET,
KVS_CMD_HGET,
KVS_CMD_HDEL,
KVS_CMD_HMOD,
KVS_CMD_HEXIST,
KVS_CMD_COUNT,
};
@@ -195,6 +204,56 @@ int kvs_filter_protocol(char **tokens, int count, char *response) {
}
break;
#endif
#if ENABLE_HASH
case KVS_CMD_HSET:
ret = kvs_hash_set(&global_hash ,key, value);
if (ret < 0) {
length = sprintf(response, "ERROR\r\n");
} else if (ret == 0) {
length = sprintf(response, "OK\r\n");
} else {
length = sprintf(response, "EXIST\r\n");
}
break;
case KVS_CMD_HGET: {
char *result = kvs_hash_get(&global_hash, key);
if (result == NULL) {
length = sprintf(response, "NO EXIST\r\n");
} else {
length = sprintf(response, "%s\r\n", result);
}
break;
}
case KVS_CMD_HDEL:
ret = kvs_hash_del(&global_hash ,key);
if (ret < 0) {
length = sprintf(response, "ERROR\r\n");
} else if (ret == 0) {
length = sprintf(response, "OK\r\n");
} else {
length = sprintf(response, "NO EXIST\r\n");
}
break;
case KVS_CMD_HMOD:
ret = kvs_hash_mod(&global_hash ,key, value);
if (ret < 0) {
length = sprintf(response, "ERROR\r\n");
} else if (ret == 0) {
length = sprintf(response, "OK\r\n");
} else {
length = sprintf(response, "NO EXIST\r\n");
}
break;
case KVS_CMD_HEXIST:
ret = kvs_hash_exist(&global_hash ,key);
if (ret == 0) {
length = sprintf(response, "EXIST\r\n");
} else {
length = sprintf(response, "NO EXIST\r\n");
}
break;
#endif
default:
assert(0);
@@ -243,6 +302,11 @@ int init_kvengine(void) {
kvs_rbtree_create(&global_rbtree);
#endif
#if ENABLE_HASH
memset(&global_hash, 0, sizeof(kvs_hash_t));
kvs_hash_create(&global_hash);
#endif
return 0;
}
@@ -253,6 +317,9 @@ void dest_kvengine(void) {
#if ENABLE_RBTREE
kvs_rbtree_destory(&global_rbtree);
#endif
#if ENABLE_HASH
kvs_hash_destory(&global_hash);
#endif
}

View File

@@ -24,7 +24,7 @@
#define ENABLE_ARRAY 1
#define ENABLE_RBTREE 1
#define ENABLE_HASH 1
typedef int (*msg_handler)(char *msg, int length, char *response);
@@ -104,6 +104,52 @@ int kvs_rbtree_exist(kvs_rbtree_t *inst, char *key);
#endif
#if ENABLE_HASH
#define MAX_KEY_LEN 128
#define MAX_VALUE_LEN 512
#define MAX_TABLE_SIZE 1024
#define ENABLE_KEY_POINTER 1
typedef struct hashnode_s {
#if ENABLE_KEY_POINTER
char *key;
char *value;
#else
char key[MAX_KEY_LEN];
char value[MAX_VALUE_LEN];
#endif
struct hashnode_s *next;
} hashnode_t;
typedef struct hashtable_s {
hashnode_t **nodes; //* change **,
int max_slots;
int count;
} hashtable_t;
typedef struct hashtable_s kvs_hash_t;
int kvs_hash_create(kvs_hash_t *hash);
void kvs_hash_destory(kvs_hash_t *hash);
int kvs_hash_set(hashtable_t *hash, char *key, char *value);
char * kvs_hash_get(kvs_hash_t *hash, char *key);
int kvs_hash_mod(kvs_hash_t *hash, char *key, char *value);
int kvs_hash_del(kvs_hash_t *hash, char *key);
int kvs_hash_exist(kvs_hash_t *hash, char *key);
#endif

View File

@@ -90,9 +90,9 @@ void array_testcase(int connfd) {
}
void array_testcase_10w(int connfd) {
void array_testcase_1w(int connfd) {
int count = 1000;
int count = 10000;
int i = 0;
struct timeval tv_begin;
@@ -117,7 +117,7 @@ void array_testcase_10w(int connfd) {
int time_used = TIME_SUB_MS(tv_end, tv_begin); // ms
printf("array testcase --> time_used: %d, qps: %d\n", time_used, 9000 * 1000 / time_used);
printf("array testcase --> time_used: %d, qps: %d\n", time_used, 90000 * 1000 / time_used);
}
@@ -125,34 +125,129 @@ void array_testcase_10w(int connfd) {
void rbtree_testcase(int connfd) {
testcase(connfd, "RSET Teacher King", "OK\r\n", "RSET-Teacher");
testcase(connfd, "RGET Teacher", "King\r\n", "RGET-Teacher");
testcase(connfd, "RMOD Teacher Darren", "OK\r\n", "RMOD-Teacher");
testcase(connfd, "RGET Teacher", "Darren\r\n", "RGET-Teacher");
testcase(connfd, "REXIST Teacher", "EXIST\r\n", "RGET-Teacher");
testcase(connfd, "RGET Teacher", "King\r\n", "RGET-King-Teacher");
testcase(connfd, "RMOD Teacher Darren", "OK\r\n", "RMOD-D-Teacher");
testcase(connfd, "RGET Teacher", "Darren\r\n", "RGET-Darren-Teacher");
testcase(connfd, "REXIST Teacher", "EXIST\r\n", "REXIST-Teacher");
testcase(connfd, "RDEL Teacher", "OK\r\n", "RDEL-Teacher");
testcase(connfd, "RGET Teacher", "NO EXIST\r\n", "RGET-Teacher");
testcase(connfd, "RMOD Teacher KING", "NO EXIST\r\n", "RMOD-Teacher");
testcase(connfd, "REXIST Teacher", "NO EXIST\r\n", "RGET-Teacher");
testcase(connfd, "RGET Teacher", "NO EXIST\r\n", "RGET-K-Teacher");
testcase(connfd, "RMOD Teacher KING", "NO EXIST\r\n", "RMOD-K-Teacher");
testcase(connfd, "REXIST Teacher", "NO EXIST\r\n", "REXIST-Teacher");
}
void rbtree_testcase_1w(int connfd) {
int count = 10000;
int i = 0;
struct timeval tv_begin;
gettimeofday(&tv_begin, NULL);
for (i = 0;i < count;i ++) {
testcase(connfd, "RSET Teacher King", "OK\r\n", "RSET-Teacher");
testcase(connfd, "RGET Teacher", "King\r\n", "RGET-King-Teacher");
testcase(connfd, "RMOD Teacher Darren", "OK\r\n", "RMOD-D-Teacher");
testcase(connfd, "RGET Teacher", "Darren\r\n", "RGET-Darren-Teacher");
testcase(connfd, "REXIST Teacher", "EXIST\r\n", "REXIST-Teacher");
testcase(connfd, "RDEL Teacher", "OK\r\n", "RDEL-Teacher");
testcase(connfd, "RGET Teacher", "NO EXIST\r\n", "RGET-K-Teacher");
testcase(connfd, "RMOD Teacher KING", "NO EXIST\r\n", "RMOD-K-Teacher");
testcase(connfd, "REXIST Teacher", "NO EXIST\r\n", "REXIST-Teacher");
}
struct timeval tv_end;
gettimeofday(&tv_end, NULL);
int time_used = TIME_SUB_MS(tv_end, tv_begin); // ms
printf("rbtree testcase --> time_used: %d, qps: %d\n", time_used, 90000 * 1000 / time_used);
}
void rbtree_testcase_3w(int connfd) {
int count = 10000;
int i = 0;
struct timeval tv_begin;
gettimeofday(&tv_begin, NULL);
for (i = 0;i < count;i ++) {
char cmd[128] = {0};
snprintf(cmd, 128, "RSET Teacher%d King%d", i, i);
testcase(connfd, cmd, "OK\r\n", "RSET-Teacher");
}
for (i = 0;i < count;i ++) {
char cmd[128] = {0};
snprintf(cmd, 128, "RGET Teacher%d", i);
char result[128] = {0};
snprintf(result, 128, "King%d\r\n", i);
testcase(connfd, cmd, result, "RGET-King-Teacher");
}
for (i = 0;i < count;i ++) {
char cmd[128] = {0};
snprintf(cmd, 128, "RMOD Teacher%d King%d", i, i);
testcase(connfd, cmd, "OK\r\n", "RGET-King-Teacher");
}
struct timeval tv_end;
gettimeofday(&tv_end, NULL);
int time_used = TIME_SUB_MS(tv_end, tv_begin); // ms
printf("rbtree testcase --> time_used: %d, qps: %d\n", time_used, 30000 * 1000 / time_used);
}
void hash_testcase(int connfd) {
testcase(connfd, "HSET Teacher King", "OK\r\n", "HSET-Teacher");
testcase(connfd, "HGET Teacher", "King\r\n", "HGET-King-Teacher");
testcase(connfd, "HMOD Teacher Darren", "OK\r\n", "HMOD-D-Teacher");
testcase(connfd, "HGET Teacher", "Darren\r\n", "HGET-Darren-Teacher");
testcase(connfd, "HEXIST Teacher", "EXIST\r\n", "HEXIST-Teacher");
testcase(connfd, "HDEL Teacher", "OK\r\n", "HDEL-Teacher");
testcase(connfd, "HGET Teacher", "NO EXIST\r\n", "HGET-K-Teacher");
testcase(connfd, "HMOD Teacher KING", "NO EXIST\r\n", "HMOD-K-Teacher");
testcase(connfd, "HEXIST Teacher", "NO EXIST\r\n", "HEXIST-Teacher");
}
// testcase 192.168.243.131 2000
int main(int argc, char *argv[]) {
if (argc != 3) {
if (argc != 4) {
printf("arg error\n");
return -1;
}
char *ip = argv[1];
int port = atoi(argv[2]);
int mode = atoi(argv[3]);
int connfd = connect_tcpserver(ip, port);
rbtree_testcase(connfd);
//array_testcase_10w(connfd);
if (mode == 0) {
rbtree_testcase_1w(connfd);
} else if (mode == 1) {
rbtree_testcase_3w(connfd);
} else if (mode == 2) {
array_testcase_1w(connfd);
} else if (mode == 3) {
hash_testcase(connfd);
}
return 0;