Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Implement triple i64 record functions #182

Merged
merged 3 commits into from
Aug 16, 2017
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
84 changes: 79 additions & 5 deletions contracts/eoslib/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,25 +149,22 @@ int32_t remove_i64( AccountName scope, TableName table, void* data );
* @{
*/

int32_t load_primary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t front_primary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t back_primary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t next_primary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t previous_primary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );

int32_t load_primary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );

int32_t upper_bound_primary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t lower_bound_primary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );

int32_t load_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t front_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t back_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t next_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t previous_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );

int32_t upper_bound_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t lower_bound_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );

int32_t load_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );

/**
* @param data - must point to at lest 32 bytes containing {primary,secondary}
Expand All @@ -186,4 +183,81 @@ int32_t store_i128i128( AccountName scope, TableName table, const void* data, ui
int32_t update_i128i128( AccountName scope, TableName table, const void* data, uint32_t len );

///@} dbi128i128

/**
* @defgroup dbi64i64i64 Triple 64 bit Index Table
* @brief Interface to a database table with 64 bit primary, secondary and tertiary keys and arbitary binary data value.
* @ingroup databaseC
*
* @param scope - the account where table data will be found
* @param code - the code which owns the table
* @param table - the name of the table where record is stored
* @param data - a pointer to memory that is at least 32 bytes long
* @param len - the length of data, must be greater than or equal to 32 bytes
*
* @return the total number of bytes read or -1 for "not found" or "end" where bytes
* read includes 24 bytes of the key
*
* These methods assume a database table with records of the form:
*
* ```
* struct Record {
* uint64 primary;
* uint64 secondary;
* uint64 tertiary;
* ... arbitrary data ...
* };
*
* ```
*
* You can iterate over these indicies with primary index sorting records by { primary, secondary, tertiary },
* the secondary index sorting records by { secondary, tertiary } and the tertiary index sorting records by
* { tertiary }.
*
* @see Table class in C++ API
*
* @{
*/

int32_t load_primary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t front_primary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t back_primary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t next_primary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t previous_primary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t upper_bound_primary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t lower_bound_primary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );

int32_t load_secondary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t front_secondary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t back_secondary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t next_secondary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t previous_secondary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t upper_bound_secondary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t lower_bound_secondary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );

int32_t load_tertiary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t front_tertiary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t back_tertiary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t next_tertiary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t previous_tertiary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t upper_bound_tertiary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t lower_bound_tertiary_i64i64i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );

/**
* @param data - must point to at lest 24 bytes containing {primary,secondary,tertiary}
*
* @return 1 if a record was removed, and 0 if no record with key was found
*/
int32_t remove_i64i64i64( AccountName scope, TableName table, const void* data );
/**
* @return 1 if a new record was created, 0 if an existing record was updated
*/
int32_t store_i64i64i64( AccountName scope, TableName table, const void* data, uint32_t len );

/**
* @return 1 if the record was updated, 0 if no record with key was found
*/
int32_t update_i64i64i64( AccountName scope, TableName table, const void* data, uint32_t len );

///@} dbi64i64i64
}
2 changes: 1 addition & 1 deletion contracts/test_api/test_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ extern "C" {
WASM_TEST_HANDLER(test_db, key_i64_remove_scope);
WASM_TEST_HANDLER(test_db, key_i64_not_found);
WASM_TEST_HANDLER(test_db, key_i64_front_back);

WASM_TEST_HANDLER(test_db, key_i64i64i64_general);
WASM_TEST_HANDLER(test_db, key_i128i128_general);

//test crypto
Expand Down
1 change: 1 addition & 0 deletions contracts/test_api/test_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ struct test_db {
static unsigned int key_i64_front_back();

static unsigned int key_i128i128_general();
static unsigned int key_i64i64i64_general();
};

struct test_crypto {
Expand Down
220 changes: 219 additions & 1 deletion contracts/test_api/test_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@

#include "test_api.hpp"

int primary[11] = {0,1,2,3,4,5,6,7,8,9,10};
int secondary[11] = {7,0,1,3,6,9,2,4,5,10,8};
int tertiary[11] = {0,1,2,3,4,5,6,7,8,9,10};

int primary_lb[11] = {0,0,0,3,3,3,6,7,7,9,9};
int secondary_lb[11] = {0,0,2,0,2,2,0,7,8,0,2};
int tertiary_lb[11] = {0,1,2,3,4,5,6,7,8,9,10};

int primary_ub[11] = {3,3,3,6,6,6,7,9,9,-1,-1};
int secondary_ub[11] = {2,2,8,2,8,8,2,0,-1,2,8};
int tertiary_ub[11] = {1,2,3,4,5,6,7,8,9,10,-1};

#pragma pack(push, 1)
struct TestModel {
AccountName name;
Expand All @@ -30,6 +42,18 @@ struct TestModel128x2 {
struct TestModel128x2_V2 : TestModel128x2 {
uint64_t new_field;
};

struct TestModel3xi64 {
uint64_t a;
uint64_t b;
uint64_t c;
uint64_t table;
};

struct TestModel3xi64_V2 : TestModel3xi64 {
uint64_t new_field;
};

#pragma pack(pop)

extern "C" {
Expand Down Expand Up @@ -481,6 +505,200 @@ unsigned int store_set_in_table(uint64_t table_name)
return WASM_TEST_PASS;
}

unsigned int store_set_in_table(TestModel3xi64* records, int len, uint64_t table_name) {
uint32_t res = 0;
for( int i = 0; i < len; ++i ) {
TestModel3xi64 *tmp = records+i;
tmp->table = table_name;
res = store_i64i64i64(currentCode(), table_name, tmp, sizeof(TestModel3xi64));
WASM_ASSERT(res == 1, "store_set_in_table" );
}
return res;
}

unsigned int test_db::key_i64i64i64_general() {

uint32_t res = 0;

TestModel3xi64 records[] = {
{1, 1, 0, N()}, // 0
{1, 1, 1, N()}, // 1
{1, 2, 2, N()}, // 2
{2, 1, 3, N()}, // 3
{2, 2, 4, N()}, // 4
{2, 2, 5, N()}, // 5
{3, 1, 6, N()}, // 6
{4, 0, 7, N()}, // 7
{4, 5, 8, N()}, // 8
{5, 1, 9, N()}, // 9
{5, 2, 10, N()}, //10
};

store_set_in_table(records, sizeof(records)/sizeof(records[0]), N(table0));
store_set_in_table(records, sizeof(records)/sizeof(records[0]), N(table1));
store_set_in_table(records, sizeof(records)/sizeof(records[0]), N(table2));

#define CALL(F, O, I, T, V) F##_##I##_##O(currentCode(), currentCode(), T, &V, sizeof(V))

#define LOAD(I, O, T, V) CALL(load, O, I, T, V)
#define FRONT(I, O, T, V) CALL(front, O, I, T, V)
#define BACK(I, O, T, V) CALL(back, O, I, T, V)
#define NEXT(I, O, T, V) CALL(next, O, I, T, V)
#define PREV(I, O, T, V) CALL(previous, O, I, T, V)
#define UPPER(I, O, T, V) CALL(upper_bound, O, I, T, V)
#define LOWER(I, O, T, V) CALL(lower_bound, O, I, T, V)

#define LOGME 0
#define BS(X) ((X) ? "true" : "false")
#define TABLE1_ASSERT(I, V, msg) \
if(LOGME) {\
eos::print(msg, " : ", res, " a:", V.a, " b:", V.b, " c:", V.c, " t:", V.table, " ("); \
eos::print(BS(res == sizeof(V)), " ", BS(records[I].a == V.a), " ", BS(records[I].b == V.b), " ", BS(records[I].c == V.c), " => ", N(table1), ")\n"); \
} \
WASM_ASSERT( res == sizeof(V) && records[I].a == V.a && records[I].b == V.b && \
records[I].c == V.c /*&& records[I].table == uint64_t(N(table1))*/, msg);

#define LOAD_OK(I, O, T, INX, MSG) \
{eos::remove_reference<decltype(V)>::type tmp; my_memset(&tmp, 0, sizeof(tmp));tmp = V; \
res = LOAD(I, O, T, tmp); \
TABLE1_ASSERT(INX, tmp, MSG)}

#define LOAD_ER(I, O, T, MSG) \
{eos::remove_reference<decltype(V)>::type tmp; my_memset(&tmp, 0, sizeof(tmp));tmp = V; \
res = LOAD(I, O, T, tmp); \
WASM_ASSERT(res == -1, MSG)}

#define FRONT_OK(I, O, T, INX, MSG) \
{eos::remove_reference<decltype(V)>::type tmp; my_memset(&tmp, 0, sizeof(tmp));tmp = V; \
res = FRONT(I, O, T, tmp); \
TABLE1_ASSERT(INX, tmp, MSG)}

#define BACK_OK(I, O, T, INX, MSG) \
{eos::remove_reference<decltype(V)>::type tmp; my_memset(&tmp, 0, sizeof(tmp));tmp = V; \
res = BACK(I, O, T, tmp); \
TABLE1_ASSERT(INX, tmp, MSG)}

TestModel3xi64 V;

V={0}; LOAD_ER(primary, i64i64i64, N(table1), "i64x3 LOAD primary fail 0");
V={1}; LOAD_OK(primary, i64i64i64, N(table1), 0, "i64x3 LOAD primary 1");
V={2}; LOAD_OK(primary, i64i64i64, N(table1), 3, "i64x3 LOAD primary 2");
V={3}; LOAD_OK(primary, i64i64i64, N(table1), 6, "i64x3 LOAD primary 3");
V={4}; LOAD_OK(primary, i64i64i64, N(table1), 7, "i64x3 LOAD primary 4");
V={5}; LOAD_OK(primary, i64i64i64, N(table1), 9, "i64x3 LOAD primary 5");
V={6}; LOAD_ER(primary, i64i64i64, N(table1), "i64x3 LOAD primary fail 6");

V={11,0}; LOAD_OK(secondary, i64i64i64, N(table1), 7, "i64x3 LOAD secondary 0");
V={11,1}; LOAD_OK(secondary, i64i64i64, N(table1), 0, "i64x3 LOAD secondary 1");
V={11,2}; LOAD_OK(secondary, i64i64i64, N(table1), 2, "i64x3 LOAD secondary 2");
V={11,3}; LOAD_ER(secondary, i64i64i64, N(table1), "i64x3 LOAD secondary fail 3");
V={11,4}; LOAD_ER(secondary, i64i64i64, N(table1), "i64x3 LOAD secondary fail 4");
V={11,5}; LOAD_OK(secondary, i64i64i64, N(table1), 8, "i64x3 LOAD secondary 5");
V={11,6}; LOAD_ER(secondary, i64i64i64, N(table1), "i64x3 LOAD secondary fail 6");

V={11,12,0}; LOAD_OK(tertiary, i64i64i64, N(table1), 0, "i64x3 LOAD tertiary 0");
V={11,12,1}; LOAD_OK(tertiary, i64i64i64, N(table1), 1, "i64x3 LOAD tertiary 1");
V={11,12,2}; LOAD_OK(tertiary, i64i64i64, N(table1), 2, "i64x3 LOAD tertiary 2");
V={11,12,3}; LOAD_OK(tertiary, i64i64i64, N(table1), 3, "i64x3 LOAD tertiary 3");
V={11,12,4}; LOAD_OK(tertiary, i64i64i64, N(table1), 4, "i64x3 LOAD tertiary 4");
V={11,12,5}; LOAD_OK(tertiary, i64i64i64, N(table1), 5, "i64x3 LOAD tertiary 5");
V={11,12,6}; LOAD_OK(tertiary, i64i64i64, N(table1), 6, "i64x3 LOAD tertiary 6");
V={11,12,7}; LOAD_OK(tertiary, i64i64i64, N(table1), 7, "i64x3 LOAD tertiary 7");
V={11,12,8}; LOAD_OK(tertiary, i64i64i64, N(table1), 8, "i64x3 LOAD tertiary 8");
V={11,12,9}; LOAD_OK(tertiary, i64i64i64, N(table1), 9, "i64x3 LOAD tertiary 9");
V={11,12,10}; LOAD_OK(tertiary, i64i64i64, N(table1), 10, "i64x3 LOAD tertiary 10");
V={11,12,11}; LOAD_ER(tertiary, i64i64i64, N(table1), "i64x3 LOAD tertiary fail 11");

#define NEXT_ALL(I, O, T) \
{ \
auto n = sizeof(I)/sizeof(I[0]); \
auto j = 0; \
do { \
eos::remove_reference<decltype(records[0])>::type tmp = records[I[j]]; \
res = NEXT(I, i64i64i64, N(table1), tmp);\
if(j+1<n){ TABLE1_ASSERT(I[j+1], tmp, "i64x3 NEXT " #I " ok "); } \
else { WASM_ASSERT(res == -1, "i64x3 NEXT " #I " fail "); }\
} while(++j<n); \
}

#define PREV_ALL(I, O, T) \
{ \
auto n = sizeof(I)/sizeof(I[0]); \
auto j = n-1; \
do { \
eos::remove_reference<decltype(records[0])>::type tmp = records[I[j]]; \
res = PREV(I, i64i64i64, N(table1), tmp);\
if(j>0){ TABLE1_ASSERT(I[j-1], tmp, "i64x3 PREV " #I " ok "); } \
else { WASM_ASSERT(res == -1, "i64x3 PREV " #I " fail "); }\
} while(--j>0); \
}

PREV_ALL(primary, i64i64i64, N(table1));
PREV_ALL(secondary, i64i64i64, N(table1));
PREV_ALL(tertiary, i64i64i64, N(table1));

FRONT_OK(primary, i64i64i64, N(table1), primary[0], "i64x3 FRONT primary");
FRONT_OK(secondary, i64i64i64, N(table1), secondary[0], "i64x3 FRONT secondary");
FRONT_OK(tertiary, i64i64i64, N(table1), tertiary[0], "i64x3 FRONT tertiary");

BACK_OK(primary, i64i64i64, N(table1), primary[10], "i64x3 BACK primary");
BACK_OK(secondary, i64i64i64, N(table1), secondary[10], "i64x3 BACK secondary");
BACK_OK(tertiary, i64i64i64, N(table1), tertiary[10], "i64x3 BACK tertiary");

#define LOWER_ALL(I, O, T) \
{ \
auto n = sizeof(I##_lb)/sizeof(I##_lb[0]); \
auto j = 0; \
do { \
eos::remove_reference<decltype(records[0])>::type tmp = records[j]; \
res = LOWER(I, i64i64i64, N(table1), tmp);\
TABLE1_ASSERT(I##_lb[j], tmp, "i64x3 LOWER " #I " ok ");\
} while(++j<n); \
}

LOWER_ALL(primary, i64i64i64, N(table1));
LOWER_ALL(secondary, i64i64i64, N(table1));
LOWER_ALL(tertiary, i64i64i64, N(table1));

#define UPPER_ALL(I, O, T) \
{ \
auto n = sizeof(I##_ub)/sizeof(I##_ub[0]); \
auto j = 0; \
do { \
eos::remove_reference<decltype(records[0])>::type tmp = records[j]; \
res = UPPER(I, i64i64i64, N(table1), tmp);\
if(res == -1) { WASM_ASSERT(I##_ub[j]==-1,"i64x3 UPPER " #I " fail ") } \
else { TABLE1_ASSERT(I##_ub[j], tmp, "i64x3 UPPER " #I " ok "); } \
} while(++j<n); \
}

UPPER_ALL(primary, i64i64i64, N(table1));
UPPER_ALL(secondary, i64i64i64, N(table1));
UPPER_ALL(tertiary, i64i64i64, N(table1));

TestModel3xi64_V2 v2;
v2.a = records[6].a;

res = LOAD(primary, i64i64i64, N(table1), v2);
WASM_ASSERT(res == sizeof(TestModel3xi64), "load v2");

v2.new_field = 555;

res = update_i64i64i64(currentCode(), N(table1), &v2, sizeof(TestModel3xi64_V2));
WASM_ASSERT(res == 1, "store v2");

res = LOAD(primary, i64i64i64, N(table1), v2);
WASM_ASSERT(res == sizeof(TestModel3xi64_V2), "load v2 updated");

res = remove_i64i64i64(currentCode(), N(table1), &v2);
WASM_ASSERT(res == 1, "load v2 updated");

res = LOAD(primary, i64i64i64, N(table1), v2);
WASM_ASSERT(res == -1, "load not found");

return WASM_TEST_PASS;
}

unsigned int test_db::key_i128i128_general() {

uint32_t res = 0;
Expand Down Expand Up @@ -665,4 +883,4 @@ unsigned int test_db::key_i128i128_general() {
return WASM_TEST_PASS;
}

//eos::print("xxxx ", res, " ", tmp2.name, " ", uint64_t(tmp2.age), " ", tmp2.phone, " ", tmp2.new_field, "\n");
//eos::print("xxxx ", res, " ", tmp2.name, " ", uint64_t(tmp2.age), " ", tmp2.phone, " ", tmp2.new_field, "\n");
1 change: 1 addition & 0 deletions libraries/chain/chain_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,7 @@ void chain_controller::initialize_indexes() {
_db.add_index<action_permission_index>();
_db.add_index<key_value_index>();
_db.add_index<key128x128_value_index>();
_db.add_index<key64x64x64_value_index>();

_db.add_index<global_property_multi_index>();
_db.add_index<dynamic_global_property_multi_index>();
Expand Down
Loading