Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HSET, HGET and HINCR and improvement of SET, removed FOREIGN KEY #23

Merged
merged 21 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
}
},
"containerEnv": {
"RONDB_PATH": "/usr/src/app/rondb-22.10.5-linux-glibc2.28-arm64_v8",
"RONDB_PATH": "/usr/src/app/rondb-24.10.0-linux-glibc2.28-arm64_v8",
// This assumes that the RonDB tarball is placed the root of the workspace folder
"LD_LIBRARY_PATH": "/usr/src/app/rondb-22.10.5-linux-glibc2.28-arm64_v8/lib"
"LD_LIBRARY_PATH": "/usr/src/app/rondb-24.10.0-linux-glibc2.28-arm64_v8/lib"
}
}
10 changes: 7 additions & 3 deletions .github/workflows/build_test_push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ jobs:
needs: [build-pink-macos]
runs-on: ubuntu-latest
env:
RONDB_VERSION: 22.10.5
RONDB_TARBALL_URI: https://repo.hops.works/master/rondb-22.10.5-linux-glibc2.28-x86_64.tar.gz
RONDB_VERSION: 24.10.0
RONDB_TARBALL_URI: https://repo.hops.works/master/rondb-24.10.0-linux-glibc2.28-x86_64.tar.gz
RONDB_DOCKER_DIR: /tmp/rondb-docker
RONDB_TARBALL_FILE: rondb.tar.gz
RONDB_PATH: /tmp/rondb
Expand Down Expand Up @@ -84,7 +84,7 @@ jobs:
run: |
docker exec -i mysqld_1 bash -c "mysql -uroot -e 'CREATE DATABASE redis;'"
for sql_file in pink/rondis/sql/*.sql; do
cat "$sql_file" | docker exec -i mysqld_1 mysql -uroot
cat "$sql_file" | docker exec -i mysqld_1 mysql -uroot --database=redis
done

- name: Connect Docker network
Expand All @@ -98,6 +98,10 @@ jobs:
docker exec -w $DOCKER_WORK_DIR -e LD_LIBRARY_PATH=/tmp/rondb/lib \
-t $CONTAINER_NAME pink/rondis/rondis 6379 mgmd_1:1186 2 > $LOCAL_RONDIS_LOG &

# Takes a few seconds before all connections are setup and started properly
- name: Wait for Rondis server to start properly
run: sleep 5

# Running this multiple times to check for memory leaks and that overwrites/updates/deletes work
- name: Run tests multiple times
run: |
Expand Down
6 changes: 1 addition & 5 deletions pink/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,7 @@ ifeq ($(NO_PB),1)
$(filter-out $(VERSION_CC) $(wildcard $(SRC_DIR)/pb_*), $(wildcard $(SRC_DIR)/*.cc))
endif


ifndef SLASH_PATH
$(warning Warning: missing slash path, using default)
SLASH_PATH=$(CURDIR)/third/slash
endif
SLASH_PATH=$(CURDIR)/third/slash
SLASH_INCLUDE_DIR=$(SLASH_PATH)
SLASH_LIBRARY=$(SLASH_PATH)/slash/lib/libslash.a

Expand Down
6 changes: 3 additions & 3 deletions pink/include/redis_conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ class RedisConn: public PinkConn {
const int rbuf_max_len = REDIS_MAX_MESSAGE);
virtual ~RedisConn();

virtual ReadStatus GetRequest();
virtual WriteStatus SendReply();
virtual int WriteResp(const std::string& resp);
virtual ReadStatus GetRequest() override;
virtual WriteStatus SendReply() override;
virtual int WriteResp(const std::string& resp) override;

void TryResizeBuffer() override;
void SetHandleType(const HandleType& handle_type);
Expand Down
7 changes: 2 additions & 5 deletions pink/rondis/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ endif

all: rondis

ifndef PINK_PATH
$(warning Warning: missing pink path, using default)
PINK_PATH=$(CURDIR)/../..
endif
PINK_PATH=$(CURDIR)/../..
PINK_INCLUDE_DIR=$(PINK_PATH)
PINK_LIBRARY=$(PINK_PATH)/pink/lib/libpink.a

Expand Down Expand Up @@ -48,7 +45,7 @@ endif
LDFLAGS := $(DEP_LIBS) $(LDFLAGS)

# Use find to locate all .cc files in subdirectories
SOURCES = $(CURDIR)/rondis.cc $(CURDIR)/rondb.cc $(CURDIR)/common.cc $(CURDIR)/string/table_definitions.cc $(CURDIR)/string/commands.cc $(CURDIR)/string/db_operations.cc
SOURCES = $(CURDIR)/rondis.cc $(CURDIR)/rondb.cc $(CURDIR)/common.cc $(CURDIR)/string/table_definitions.cc $(CURDIR)/string/commands.cc $(CURDIR)/string/db_operations.cc $(CURDIR)/string/interpreted_code.cc
OBJECTS = $(SOURCES:.cc=.o)

# Target to build the executable "rondis"
Expand Down
46 changes: 18 additions & 28 deletions pink/rondis/common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,13 @@

#include "common.h"

/**
* @brief Writes formatted data to a buffer.
*
* This function writes formatted data to the provided buffer using a format string
* and a variable number of arguments, similar to printf. It ensures that the
* formatted string does not exceed the specified buffer size.
*
* @param buffer A pointer to the buffer where the formatted string will be written.
* @param bufferSize The size of the buffer.
* @param format A format string that specifies how subsequent arguments are converted for output.
* @param ... Additional arguments specifying the data to be formatted.
* @return The number of characters written, excluding the null terminator. If the output
* is truncated due to the buffer size limit, the return value is the number of
* characters (excluding the null terminator) which would have been written if
* enough space had been available.
*/
int write_formatted(char *buffer, int bufferSize, const char *format, ...)
{
int len = 0;
va_list arguments;
va_start(arguments, format);
len = vsnprintf(buffer, bufferSize, format, arguments);
va_end(arguments);
return len;
}

void assign_ndb_err_to_response(
std::string *response,
const char *app_str,
NdbError error)
{
char buf[512];
write_formatted(buf, sizeof(buf), "-ERR %s; NDB(%u) %s\r\n", app_str, error.code, error.message);
snprintf(buf, sizeof(buf), "-ERR %s; NDB(%u) %s\r\n", app_str, error.code, error.message);
std::cout << buf;
response->assign(buf);
}
Expand All @@ -47,7 +21,23 @@ void assign_generic_err_to_response(
const char *app_str)
{
char buf[512];
write_formatted(buf, sizeof(buf), "-ERR %s\r\n", app_str);
snprintf(buf, sizeof(buf), "-ERR %s\r\n", app_str);
std::cout << buf;
response->assign(buf);
}

void set_length(char *buf, Uint32 key_len)
{
Uint8 *ptr = (Uint8 *)buf;
ptr[0] = (Uint8)(key_len & 255);
ptr[1] = (Uint8)(key_len >> 8);
}

Uint32 get_length(char *buf)
{
Uint8 *ptr = (Uint8 *)buf;
Uint8 low = ptr[0];
Uint8 high = ptr[1];
Uint32 len32 = Uint32(low) + Uint32(256) * Uint32(high);
return len32;
}
11 changes: 10 additions & 1 deletion pink/rondis/common.h
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
#include <ndbapi/NdbApi.hpp>
#include <ndbapi/Ndb.hpp>

#ifndef RONDIS_COMMON_H
#define RONDIS_COMMON_H

#define MAX_CONNECTIONS 2

#define REDIS_DB_NAME "redis"

#define FOREIGN_KEY_RESTRICT_ERROR 256
#define RESTRICT_VALUE_ROWS_ERROR 6000

#define RONDB_INTERNAL_ERROR 2
#define READ_ERROR 626

int write_formatted(char *buffer, int bufferSize, const char *format, ...);
void assign_ndb_err_to_response(std::string *response, const char *app_str, NdbError error);
void assign_generic_err_to_response(std::string *response, const char *app_str);
void set_length(char* buf, Uint32 key_len);
Uint32 get_length(char* buf);

// NDB API error messages
#define FAILED_GET_DICT "Failed to get NdbDict"
#define FAILED_CREATE_TABLE_OBJECT "Failed to create table object"
#define FAILED_CREATE_TXN_OBJECT "Failed to create transaction object"
#define FAILED_EXEC_TXN "Failed to execute transaction"
#define FAILED_READ_KEY "Failed to read key"
#define FAILED_INCR_KEY "Failed to increment key"
#define FAILED_HSET_KEY "Failed to find key"
#define FAILED_INCR_KEY_MULTI_ROW "Failed to increment key, multi-row value"
#define FAILED_GET_OP "Failed to get NdbOperation object"
#define FAILED_DEFINE_OP "Failed to define RonDB operation"

Expand All @@ -28,3 +36,4 @@ void assign_generic_err_to_response(std::string *response, const char *app_str);
#define REDIS_WRONG_NUMBER_OF_ARGS "wrong number of arguments for '%s' command"
#define REDIS_NO_SUCH_KEY "$-1\r\n"
#define REDIS_KEY_TOO_LARGE "key is too large (3000 bytes max)"
#endif
63 changes: 59 additions & 4 deletions pink/rondis/rondb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "common.h"
#include "string/table_definitions.h"
#include "string/commands.h"
#include <strings.h>

/*
Ndb objects are not thread-safe. Hence, each worker thread / RonDB connection should
Expand Down Expand Up @@ -109,7 +110,8 @@ int rondb_redis_handler(const pink::RedisCmdArgsType &argv,
int worker_id)
{
// First check non-ndb commands
if (argv[0] == "ping")
const char *command = argv[0].c_str();
if (strcasecmp(command, "ping") == 0)
{
if (argv.size() != 1)
{
Expand Down Expand Up @@ -156,7 +158,7 @@ int rondb_redis_handler(const pink::RedisCmdArgsType &argv,
else
{
Ndb *ndb = ndb_objects[worker_id];
if (argv[0] == "GET")
if (strcasecmp(command, "GET") == 0)
{
if (argv.size() == 2)
{
Expand All @@ -169,7 +171,7 @@ int rondb_redis_handler(const pink::RedisCmdArgsType &argv,
assign_generic_err_to_response(response, error_message);
}
}
else if (argv[0] == "SET")
else if (strcasecmp(command, "SET") == 0)
{
if (argv.size() == 3)
{
Expand All @@ -182,6 +184,58 @@ int rondb_redis_handler(const pink::RedisCmdArgsType &argv,
assign_generic_err_to_response(response, error_message);
}
}
else if (strcasecmp(command, "INCR") == 0)
{
if (argv.size() == 2)
{
rondb_incr_command(ndb, argv, response);
}
else
{
char error_message[256];
snprintf(error_message, sizeof(error_message), REDIS_WRONG_NUMBER_OF_ARGS, argv[0].c_str());
assign_generic_err_to_response(response, error_message);
}
}
else if (strcasecmp(command, "HGET") == 0)
{
if (argv.size() == 3)
{
rondb_hget_command(ndb, argv, response);
}
else
{
char error_message[256];
snprintf(error_message, sizeof(error_message), REDIS_WRONG_NUMBER_OF_ARGS, argv[0].c_str());
assign_generic_err_to_response(response, error_message);
}
}
else if (strcasecmp(command, "HSET") == 0)
{
if (argv.size() == 4)
{
rondb_hset_command(ndb, argv, response);
}
else
{
char error_message[256];
snprintf(error_message, sizeof(error_message), REDIS_WRONG_NUMBER_OF_ARGS, argv[0].c_str());
assign_generic_err_to_response(response, error_message);
}
}
else if (strcasecmp(command, "HINCR") == 0)
{
if (argv.size() == 3)
{
rondb_hincr_command(ndb, argv, response);
}
else
{
char error_message[256];
snprintf(error_message, sizeof(error_message), REDIS_WRONG_NUMBER_OF_ARGS, argv[0].c_str());
assign_generic_err_to_response(response, error_message);
}
}
else
{
unsupported_command(argv, response);
Expand All @@ -194,7 +248,8 @@ int rondb_redis_handler(const pink::RedisCmdArgsType &argv,
If this limit is reached, the Ndb object will not create any new ones.
Hence, better to catch these cases early.
*/
print_args(argv);
printf("Failed to stop transaction\n");
//print_args(argv);
printf("Number of transactions started: %lld\n", ndb->getClientStat(ndb->TransStartCount));
printf("Number of transactions closed: %lld\n", ndb->getClientStat(ndb->TransCloseCount));
exit(1);
Expand Down
4 changes: 4 additions & 0 deletions pink/rondis/rondb.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#include <ndbapi/NdbApi.hpp>
#include <ndbapi/Ndb.hpp>

#ifndef RONDIS_RONDB_H
#define RONDIS_RONDB_H

extern std::vector<Ndb *> ndb_objects;

int initialize_ndb_objects(const char *connect_string, int num_ndb_objects);
Expand All @@ -14,3 +17,4 @@ void rondb_end();
int rondb_redis_handler(const pink::RedisCmdArgsType &argv,
std::string *response,
int fd);
#endif
2 changes: 1 addition & 1 deletion pink/rondis/rondis.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ static void SignalSetup()
int main(int argc, char *argv[])
{
int port = 6379;
char *connect_string = "localhost:13000";
const char *connect_string = "localhost:13000";
int worker_threads = 2;
if (argc != 4)
{
Expand Down
7 changes: 7 additions & 0 deletions pink/rondis/sql/HSET_key.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE hset_keys(
redis_key VARBINARY(3000) NOT NULL,
redis_key_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (redis_key) USING HASH,
UNIQUE KEY (redis_key_id) USING HASH
) ENGINE NDB,
COMMENT = "NDB_TABLE=PARTITION_BALANCE=RP_BY_LDM_X_8";
7 changes: 4 additions & 3 deletions pink/rondis/sql/STRING_key.sql
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
CREATE TABLE redis.string_keys(
CREATE TABLE string_keys(
-- Redis actually supports a max key size of 512MiB,
-- but we choose not to support that here
redis_key_id BIGINT UNSIGNED NOT NULL,
redis_key VARBINARY(3000) NOT NULL,
-- This is to save space when referencing the key in the value table
rondb_key BIGINT UNSIGNED AUTO_INCREMENT NULL,
Expand All @@ -14,10 +15,10 @@ CREATE TABLE redis.string_keys(
num_rows INT UNSIGNED NOT NULL,
value_start VARBINARY(26500) NOT NULL,
-- Redis supports get/set of seconds/milliseconds
expiry_date INT UNSIGNED,
expiry_date INT UNSIGNED NOT NULL,
-- Easier to sort and delete keys this way
KEY expiry_index(expiry_date),
PRIMARY KEY (redis_key) USING HASH,
PRIMARY KEY (redis_key_id, redis_key) USING HASH,
UNIQUE KEY (rondb_key) USING HASH
) ENGINE NDB -- Each CHAR will use 1 byte
CHARSET = latin1 COMMENT = "NDB_TABLE=PARTITION_BALANCE=FOR_RP_BY_LDM_X_8";
7 changes: 3 additions & 4 deletions pink/rondis/sql/STRING_value.sql
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
CREATE TABLE redis.string_values(
CREATE TABLE string_values(
rondb_key BIGINT UNSIGNED NOT NULL,
ordinal INT UNSIGNED NOT NULL,
value VARBINARY(29500) NOT NULL,
PRIMARY KEY (rondb_key, ordinal),
FOREIGN KEY (rondb_key) REFERENCES redis.string_keys(rondb_key) ON UPDATE RESTRICT ON DELETE CASCADE
PRIMARY KEY (rondb_key, ordinal)
) ENGINE NDB,
COMMENT = "NDB_TABLE=PARTITION_BALANCE=RP_BY_LDM_X_8" PARTITION BY KEY (rondb_key);
COMMENT = "NDB_TABLE=PARTITION_BALANCE=RP_BY_LDM_X_8";
Loading