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

First functional INCR command #20

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
128a6fa
Merge pull request #1 from olapiv/mikaelMultiP
mronstro Nov 4, 2024
d968646
RONDB-765: First step to implementing INCR command
mikaelronstrom Nov 5, 2024
e0f9c05
RONDB-766: Fix compiler warnings
mikaelronstrom Nov 5, 2024
a265c5d
RONDB-761: First functional INCR command
mikaelronstrom Nov 6, 2024
4f768a4
RONDB-761: Improvements to INCR key
mikaelronstrom Nov 7, 2024
bf9c8fb
RONDB-761: Review comments
mikaelronstrom Nov 8, 2024
fa82c40
RONDB-761: Fixed mistake
mikaelronstrom Nov 8, 2024
8ad0fe3
Autoformatting
olapiv Nov 8, 2024
7fffcde
Bumped RonDB version
olapiv Nov 8, 2024
8a8c34e
Added INCR to Bash tests
olapiv Nov 8, 2024
816ebac
Moved interpreted code to separate file
olapiv Nov 8, 2024
67ffec5
Removed redundant headers
olapiv Nov 8, 2024
27fbeda
Merge pull request #2 from olapiv/mikaelFixes
mronstro Nov 8, 2024
a21b3fb
RONDB-761: Fixed breakout of interpreter code, case insensitive comma…
mikaelronstrom Nov 8, 2024
e7f0dea
Slash compiler warnings
olapiv Nov 11, 2024
c8c449d
Slash compiler warnings
olapiv Nov 11, 2024
0660f9d
Added command ECHO
olapiv Nov 11, 2024
2aac8d2
Added piped_key command in tests
olapiv Nov 12, 2024
e3886c7
Redis-benchmark: multiple clients, random keyspace, batched requests
olapiv Nov 12, 2024
b3265ff
Added $KEY to batched test
olapiv Nov 12, 2024
812495d
Added log
olapiv Nov 12, 2024
6b22057
FIX: Set "close_" to false by default
olapiv Nov 12, 2024
b9d77c2
Fix compiler warning
olapiv Nov 12, 2024
b536240
Added CONFIG parameter
olapiv Nov 12, 2024
3585961
Added comments/logs
olapiv Nov 12, 2024
e4be12f
Removed commented-out code
olapiv Nov 12, 2024
eec0e23
Run tests multi-threaded
olapiv Nov 12, 2024
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
30 changes: 2 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,7 @@ 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);
}
3 changes: 2 additions & 1 deletion pink/rondis/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ void assign_generic_err_to_response(std::string *response, const char *app_str);
#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_INCR_KEY "Failed to increment key, multi-row value"
olapiv marked this conversation as resolved.
Show resolved Hide resolved
#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 Down
83 changes: 53 additions & 30 deletions pink/rondis/string/db_operations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -418,10 +418,10 @@ int get_simple_key_row(std::string *response,
return 0;
}
char header_buf[20];
int header_len = write_formatted(header_buf,
sizeof(header_buf),
"$%u\r\n",
key_row->tot_value_len);
int header_len = snprintf(header_buf,
sizeof(header_buf),
"$%u\r\n",
key_row->tot_value_len);

// The total length of the expected response
response->reserve(header_len + key_row->tot_value_len + 2);
Expand Down Expand Up @@ -574,10 +574,10 @@ int get_complex_key_row(std::string *response,

// Writing the Redis header to the response (indicating value length)
char header_buf[20];
int header_len = write_formatted(header_buf,
sizeof(header_buf),
"$%u\r\n",
key_row->tot_value_len);
int header_len = snprintf(header_buf,
sizeof(header_buf),
"$%u\r\n",
key_row->tot_value_len);
response->reserve(header_len + key_row->tot_value_len + 2);
response->append(header_buf);

Expand Down Expand Up @@ -627,6 +627,20 @@ int rondb_get_rondb_key(const NdbDictionary::Table *tab,
#define REG7 7
#define LABEL0 0
#define LABEL1 1
olapiv marked this conversation as resolved.
Show resolved Hide resolved

#define INITIAL_INT_VALUE 1
#define INITIAL_INT_STRING '1'
#define INITIAL_INT_STRING_LEN 1
#define INITIAL_INT_STRING_LEN_WITH_LEN_BYTES 3

#define MEMORY_OFFSET_START 0
#define MEMORY_OFFSET_LEN_BYTES 4
#define MEMORY_OFFSET_STRING 6
#define NUM_LEN_BYTES 2
#define INCREMENT_VALUE 1
#define OUTPUT_INDEX 0
#define RONDB_KEY_NOT_NULL_ERROR 6000

void incr_key_row(std::string *response,
Ndb *ndb,
const NdbDictionary::Table *tab,
Expand Down Expand Up @@ -661,9 +675,9 @@ void incr_key_row(std::string *response,
/* Define the interpreted program */
Uint32 code_buffer[128];
NdbInterpretedCode code(tab, &code_buffer[0], sizeof(code_buffer));
code.load_const_u16(REG0, 4); //Memory offset 0
code.load_const_u16(REG6, 0); //Memory offset 0
int ret_code = code.load_op_type(REG1); // Read operation type into register 1
code.load_const_u16(REG0, MEMORY_OFFSET_LEN_BYTES);
code.load_const_u16(REG6, MEMORY_OFFSET_START);
code.load_op_type(REG1); // Read operation type into register 1
code.branch_eq_const(REG1, RONDB_INSERT, LABEL1); //Inserts go to label 1

/**
Expand All @@ -680,42 +694,45 @@ void incr_key_row(std::string *response,
/* UPDATE code */
code.read_attr(REG7, rondb_key_col);
code.branch_eq_null(REG7, LABEL0);
code.interpret_exit_nok();
code.interpret_exit_nok(RONDB_KEY_NOT_NULL_ERROR);
code.def_label(LABEL0);
code.read_full(value_start_col, REG6, REG2); // Read value_start column
code.load_const_u16(REG1, 6);//Memory offset 2
code.sub_const_reg(REG3, REG2, 2);//Subtract 2 from length
code.str_to_int64(REG4, REG1, REG3);//Convert string to number into register 6
code.add_const_reg(REG5, REG4, 1); //New integer value in register 6
code.int64_to_str(REG3, REG1, REG5);//Convert to string
code.add_const_reg(REG2, REG3, 2); //New value_start length
code.read_full(value_start_col, REG6, REG2);// Read value_start column
code.load_const_u16(REG1, MEMORY_OFFSET_STRING);
code.sub_const_reg(REG3, REG2, NUM_LEN_BYTES);
code.str_to_int64(REG4, REG1, REG3);//Convert string to number
code.add_const_reg(REG5, REG4, INCREMENT_VALUE);
code.int64_to_str(REG3, REG1, REG5);//Convert number to string
code.add_const_reg(REG2, REG3, NUM_LEN_BYTES); //New value_start length
code.convert_size(REG3, REG0); //Write back length bytes in memory

code.write_interpreter_output(REG5, 0); //Write into output index 0
code.write_interpreter_output(REG5, OUTPUT_INDEX); //Write into output index 0
code.write_from_mem(value_start_col, REG6, REG2); // Write to column
code.write_attr(tot_value_len_col, REG3);
code.interpret_exit_ok();

/* INSERT code */
olapiv marked this conversation as resolved.
Show resolved Hide resolved
code.def_label(LABEL1);
code.load_const_u16(REG5, 1);
code.load_const_u16(REG3, 1);
code.write_interpreter_output(REG5, 0); //Write into output index 0
code.load_const_u16(REG5, INITIAL_INT_VALUE);
code.load_const_u16(REG3, INITIAL_INT_STRING_LEN);
code.write_interpreter_output(REG5, OUTPUT_INDEX); //Write into output index 0

Uint32 insert_value;
Uint8 *insert_value_ptr = (Uint8*)&insert_value;
insert_value_ptr[0] = 1; // Length is 1
insert_value_ptr[1] = 0; // Second length byte is 0
insert_value_ptr[2] = '1'; //Inserts a string '1'
insert_value_ptr[2] = INITIAL_INT_STRING; //Inserts a string '1'
insert_value_ptr[3] = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or is this the 1 we will add to the value?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the bytes we will write into value_start, the string '1' with 2 length bytes representing a length of 1.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used in an INSERT


code.load_const_mem(REG0, REG2, 3, &insert_value);// Load to memory
code.load_const_mem(REG0,
REG2,
INITIAL_INT_STRING_LEN_WITH_LEN_BYTES,
&insert_value);
code.write_from_mem(value_start_col, REG6, REG2); // Write to column
code.write_attr(tot_value_len_col, REG3);
code.interpret_exit_ok();

/* Program end, now compile code */
ret_code = code.finalise();
int ret_code = code.finalise();
if (ret_code != 0) {
assign_ndb_err_to_response(response,
"Failed to create Interpreted code",
Expand Down Expand Up @@ -765,6 +782,12 @@ void incr_key_row(std::string *response,
NdbOperation::AbortOnError) != 0 ||
trans->getNdbError().code != 0)
{
if (trans->getNdbError().code == RONDB_KEY_NOT_NULL_ERROR) {
assign_ndb_err_to_response(response,
FAILED_INCR_KEY_MULTI_ROW,
trans->getNdbError());
return;
}
assign_ndb_err_to_response(response,
FAILED_INCR_KEY,
trans->getNdbError());
Expand All @@ -777,10 +800,10 @@ void incr_key_row(std::string *response,

/* Send the return message to Redis client */
char header_buf[20];
int header_len = write_formatted(header_buf,
sizeof(header_buf),
":%lld\r\n",
new_incremented_value);
int header_len = snprintf(header_buf,
sizeof(header_buf),
":%lld\r\n",
new_incremented_value);
response->assign(header_buf);
return;
olapiv marked this conversation as resolved.
Show resolved Hide resolved
}
Loading