Skip to content

Commit

Permalink
Merge pull request #2 from olapiv/mikaelFixes
Browse files Browse the repository at this point in the history
INCR modifications
  • Loading branch information
mronstro authored Nov 8, 2024
2 parents fa82c40 + 67ffec5 commit 27fbeda
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 127 deletions.
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"
}
}
2 changes: 1 addition & 1 deletion .github/workflows/build_test_push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
needs: [build-pink-macos]
runs-on: ubuntu-latest
env:
RONDB_TARBALL_URI: https://repo.hops.works/master/rondb-22.10.5-linux-glibc2.28-x86_64.tar.gz
RONDB_TARBALL_URI: https://repo.hops.works/master/rondb-24.10.0-linux-glibc2.28-x86_64.tar.gz
RONDB_PATH: /tmp/rondb
IMAGE_NAME: rondis:latest
CONTAINER_NAME: rondis
Expand Down
160 changes: 36 additions & 124 deletions pink/rondis/string/db_operations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,27 @@
#include "../common.h"
#include "db_operations.h"
#include "table_definitions.h"
#include "interpreted_code.h"

NdbRecord *pk_key_record = nullptr;
NdbRecord *entire_key_record = nullptr;
NdbRecord *pk_value_record = nullptr;
NdbRecord *entire_value_record = nullptr;

void set_length(char *buf, Uint32 key_len) {
Uint8 *ptr = (Uint8*)buf;
ptr[0] = (Uint8)(key_len & 255);
ptr[1] = (Uint8)(key_len >> 8);
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;
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;
}

int create_key_row(std::string *response,
Expand Down Expand Up @@ -520,7 +523,7 @@ int read_batched_value_rows(std::string *response,
for (Uint32 i = 0; i < num_rows_to_read; i++)
{
// Transfer char pointer to response's string
Uint32 row_value_len = get_length((char*)&value_rows->value[0]);
Uint32 row_value_len = get_length((char *)&value_rows->value[0]);
response->append((const char *)&value_rows[i].value[2], row_value_len);
}
return 0;
Expand Down Expand Up @@ -582,7 +585,7 @@ int get_complex_key_row(std::string *response,
response->append(header_buf);

// Append inline value to response
Uint32 inline_value_len = get_length((char*)&key_row->value_start[0]);
Uint32 inline_value_len = get_length((char *)&key_row->value_start[0]);
response->append((const char *)&key_row->value_start[2], inline_value_len);

int ret_code = get_value_rows(response,
Expand Down Expand Up @@ -615,44 +618,12 @@ int rondb_get_rondb_key(const NdbDictionary::Table *tab,
return 0;
}

#define RONDB_INSERT 2
#define RONDB_UPDATE 1
#define REG0 0
#define REG1 1
#define REG2 2
#define REG3 3
#define REG4 4
#define REG5 5
#define REG6 6
#define REG7 7
#define LABEL0 0
#define LABEL1 1

#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,
NdbTransaction *trans,
struct key_table *key_row) {

const NdbDictionary::Column *value_start_col = tab->getColumn(KEY_TABLE_COL_value_start);
const NdbDictionary::Column *tot_value_len_col = tab->getColumn(KEY_TABLE_COL_tot_value_len);
const NdbDictionary::Column *rondb_key_col = tab->getColumn(KEY_TABLE_COL_rondb_key);

NdbOperation::OperationOptions opts;
std::memset(&opts, 0, sizeof(opts));
struct key_table *key_row)
{
/**
* The mask specifies which columns is to be updated after the interpreter
* has finished. The values are set in the key_row.
Expand All @@ -672,75 +643,14 @@ void incr_key_row(std::string *response,
key_row->value_data_type = 0;
key_row->expiry_date = 0;

/* Define the interpreted program */
Uint32 code_buffer[128];
NdbInterpretedCode code(tab, &code_buffer[0], sizeof(code_buffer));
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

/**
* The first 4 bytes of the memory must be kept for the Attribute header
* REG0 Memory offset == 4
* REG1 Memory offset == 6
* REG2 Size of value_start
* REG3 Size of value_start without length bytes
* REG4 Old integer value after conversion
* REG5 New integer value after increment
* REG6 Memory offset == 0
* REG7 Value of rondb_key (should be NULL)
*/
/* UPDATE code */
code.read_attr(REG7, rondb_key_col);
code.branch_eq_null(REG7, LABEL0);
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, 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, 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 */
code.def_label(LABEL1);
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] = INITIAL_INT_STRING; //Inserts a string '1'
insert_value_ptr[3] = 0;

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 */
int ret_code = code.finalise();
if (ret_code != 0) {
assign_ndb_err_to_response(response,
"Failed to create Interpreted code",
code.getNdbError());
if (initNdbCodeIncr(response, &code, tab) != 0)
return;
}

/* Prepare the interpreted program to be part of the write */
// Prepare the interpreted program to be part of the write
NdbOperation::OperationOptions opts;
std::memset(&opts, 0, sizeof(opts));
opts.optionsPresent |= NdbOperation::OperationOptions::OO_INTERPRETED;
opts.optionsPresent |= NdbOperation::OperationOptions::OO_INTERPRETED_INSERT;
opts.interpretedCode = &code;
Expand All @@ -759,18 +669,19 @@ void incr_key_row(std::string *response,
opts.extraGetFinalValues = getvals;

if (1)
opts.optionsPresent |= NdbOperation::OperationOptions::OO_DIRTY_FLAG;
opts.optionsPresent |= NdbOperation::OperationOptions::OO_DIRTY_FLAG;

/* Define the actual operation to be sent to RonDB data node. */
const NdbOperation *op = trans->writeTuple(
pk_key_record,
(const char*)key_row,
entire_key_record,
(char*)key_row,
mask_ptr,
&opts,
sizeof(opts));
if (op == nullptr) {
pk_key_record,
(const char *)key_row,
entire_key_record,
(char *)key_row,
mask_ptr,
&opts,
sizeof(opts));
if (op == nullptr)
{
assign_ndb_err_to_response(response,
"Failed to create NdbOperation",
trans->getNdbError());
Expand All @@ -782,10 +693,11 @@ 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());
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,
Expand Down
82 changes: 82 additions & 0 deletions pink/rondis/string/interpreted_code.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#include <ndbapi/NdbApi.hpp>
#include <ndbapi/Ndb.hpp>

#include "../common.h"
#include "interpreted_code.h"
#include "table_definitions.h"

// Define the interpreted program for the INCR operation
int initNdbCodeIncr(std::string *response,
NdbInterpretedCode *code,
const NdbDictionary::Table *tab)
{
const NdbDictionary::Column *value_start_col = tab->getColumn(KEY_TABLE_COL_value_start);
const NdbDictionary::Column *tot_value_len_col = tab->getColumn(KEY_TABLE_COL_tot_value_len);
const NdbDictionary::Column *rondb_key_col = tab->getColumn(KEY_TABLE_COL_rondb_key);

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

/**
* The first 4 bytes of the memory must be kept for the Attribute header
* REG0 Memory offset == 4
* REG1 Memory offset == 6
* REG2 Size of value_start
* REG3 Size of value_start without length bytes
* REG4 Old integer value after conversion
* REG5 New integer value after increment
* REG6 Memory offset == 0
* REG7 Value of rondb_key (should be NULL)
*/
/* UPDATE code */
code->read_attr(REG7, rondb_key_col);
code->branch_eq_null(REG7, LABEL0);
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, 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, 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 */
code->def_label(LABEL1);
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] = INITIAL_INT_STRING; // Inserts a string '1'
insert_value_ptr[3] = 0;

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
int ret_code = code->finalise();
if (ret_code != 0)
{
assign_ndb_err_to_response(response,
"Failed to create Interpreted code",
code->getNdbError());
return;
}
}
36 changes: 36 additions & 0 deletions pink/rondis/string/interpreted_code.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include <ndbapi/NdbApi.hpp>

#ifndef STRING_INTERPRETED_CODE_H
#define STRING_INTERPRETED_CODE_H

#define RONDB_INSERT 2
#define RONDB_UPDATE 1
#define REG0 0
#define REG1 1
#define REG2 2
#define REG3 3
#define REG4 4
#define REG5 5
#define REG6 6
#define REG7 7
#define LABEL0 0
#define LABEL1 1

#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

#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

int initNdbCodeIncr(std::string *response,
NdbInterpretedCode *code,
const NdbDictionary::Table *tab);

#endif
Loading

0 comments on commit 27fbeda

Please sign in to comment.