diff --git a/dap_chain_global_db.c b/dap_chain_global_db.c index f114cd5725751fb472a3e50d16ebb69f3f84dfc2..5ad48e0d5a9db2cd7986fff60ecc2bb57c1a48af 100755 --- a/dap_chain_global_db.c +++ b/dap_chain_global_db.c @@ -203,14 +203,16 @@ uint8_t * dap_chain_global_db_gr_get(const char *a_key, size_t *a_data_len_out, { uint8_t *l_ret_value = NULL; // read several items, 0 - no limits + size_t l_data_len_out = 0; if(a_data_len_out) - *a_data_len_out = 0; - dap_store_obj_t *l_store_data = dap_chain_global_db_driver_read(a_group, a_key, a_data_len_out); + l_data_len_out = *a_data_len_out; + dap_store_obj_t *l_store_data = dap_chain_global_db_driver_read(a_group, a_key, &l_data_len_out); if(l_store_data) { l_ret_value = (l_store_data->value) ? DAP_NEW_SIZE(uint8_t, l_store_data->value_len) : NULL; //ret_value = (store_data->value) ? strdup(store_data->value) : NULL; memcpy(l_ret_value, l_store_data->value, l_store_data->value_len); if(a_data_len_out) *a_data_len_out = l_store_data->value_len; + dap_store_obj_free(l_store_data, l_data_len_out); } return l_ret_value; diff --git a/dap_chain_global_db.h b/dap_chain_global_db.h index 17a9aae76976d9e63ec4e63ad74dc89e060fa155..30f5095af9ac42563ff98925ae76e8a7e03e2a4c 100755 --- a/dap_chain_global_db.h +++ b/dap_chain_global_db.h @@ -11,10 +11,11 @@ #define GROUP_LOCAL_HISTORY "global.history" -#define GROUP_LOCAL_NODE_LAST_TS "local.node.last_ts" +#define GROUP_LOCAL_NODE_LAST_ID "local.node.last_id" #define GROUP_LOCAL_GENERAL "local.general" typedef struct dap_global_db_obj { + uint64_t id; char *key; uint8_t *value; size_t value_len; @@ -104,10 +105,10 @@ void* dap_db_log_unpack(const void *a_data, size_t a_data_size, size_t *a_store_ // Get timestamp from dap_db_log_pack() //time_t dap_db_log_unpack_get_timestamp(uint8_t *a_data, size_t a_data_size); -// Get last timestamp in log -time_t dap_db_log_get_last_timestamp(void); +// Get last id in log +uint64_t dap_db_log_get_last_id(void); // Get log diff as list -dap_list_t* dap_db_log_get_list(time_t first_timestamp); +dap_list_t* dap_db_log_get_list(uint64_t first_id); // Free list getting from dap_db_log_get_list() void dap_db_log_del_list(dap_list_t *a_list); // Get log diff as string diff --git a/dap_chain_global_db_driver.c b/dap_chain_global_db_driver.c index d0e7961544553be56a1f1b8cbcdf21bbab62755d..f3fffbd6fb8b0547811144007af8b87c3b2d6b13 100755 --- a/dap_chain_global_db_driver.c +++ b/dap_chain_global_db_driver.c @@ -178,7 +178,7 @@ void dap_store_obj_free(dap_store_obj_t *a_store_obj, size_t a_store_count) static size_t dap_db_get_size_pdap_store_obj_t(pdap_store_obj_t store_obj) { size_t size = sizeof(uint32_t) + 2 * sizeof(uint16_t) + sizeof(size_t) + sizeof(time_t) - + dap_strlen(store_obj->group) + + + sizeof(uint64_t) + dap_strlen(store_obj->group) + dap_strlen(store_obj->key) + store_obj->value_len; return size; } @@ -222,6 +222,8 @@ dap_store_obj_pkt_t *dap_store_packet_multiple(pdap_store_obj_t a_store_obj, tim l_offset += sizeof(uint16_t); memcpy(l_pkt->data + l_offset, obj.group, group_size); l_offset += group_size; + memcpy(l_pkt->data + l_offset, &obj.id, sizeof(uint64_t)); + l_offset += sizeof(uint64_t); memcpy(l_pkt->data + l_offset, &obj.timestamp, sizeof(time_t)); l_offset += sizeof(time_t); memcpy(l_pkt->data + l_offset, &key_size, sizeof(uint16_t)); @@ -269,6 +271,9 @@ dap_store_obj_t *dap_store_unpacket_multiple(const dap_store_obj_pkt_t *pkt, siz memcpy(obj->group, pkt->data + offset, str_size); offset += str_size; + memcpy(&obj->id, pkt->data + offset, sizeof(uint64_t)); + offset += sizeof(uint64_t); + memcpy(&obj->timestamp, pkt->data + offset, sizeof(time_t)); offset += sizeof(time_t); diff --git a/dap_chain_global_db_driver_cdb.c b/dap_chain_global_db_driver_cdb.c index 8c88814a2a034afd05d3d9e4d09b55f48549ef52..5ea100809c587408e86d118830105fe2cc508552 100644 --- a/dap_chain_global_db_driver_cdb.c +++ b/dap_chain_global_db_driver_cdb.c @@ -35,8 +35,6 @@ #define LOG_TAG "db_cdb" -#define uint64_size sizeof(uint64_t) - typedef struct _obj_arg { pdap_store_obj_t o; uint64_t q; @@ -82,8 +80,8 @@ static void cdb_serialize_val_to_dap_store_obj(pdap_store_obj_t a_obj, char *key } int offset = 0; a_obj->key = dap_strdup(key); - a_obj->id = dap_cdb_hex_to_uint((unsigned char*)val, uint64_size); - offset += uint64_size; + // a_obj->id = dap_cdb_hex_to_uint((unsigned char*)val, uint64_size); + offset += sizeof(uint64_t); a_obj->value_len = dap_cdb_hex_to_uint((unsigned char*)val + offset, sizeof(unsigned long)); offset += sizeof(unsigned long); a_obj->value = DAP_NEW_SIZE(uint8_t, a_obj->value_len); @@ -249,6 +247,7 @@ dap_store_obj_t *dap_db_driver_cdb_read_last_store_obj(const char* a_group) { cdb_iterate(l_cdb, dap_cdb_get_last_obj_iter_callback, (void*)&l_arg, l_iter); cdb_iterate_destroy(l_cdb, l_iter); l_arg.o->group = dap_strdup(a_group); + l_arg.o->id = l_cdb_stat.rnum; return l_arg.o; } @@ -272,6 +271,9 @@ dap_store_obj_t *dap_db_driver_cdb_read_store_obj(const char *a_group, const cha cdb_serialize_val_to_dap_store_obj(l_obj, (char*)a_key, l_value); l_obj->group = dap_strdup(a_group); cdb_free_val((void**)&l_value); + if(a_count_out) { + *a_count_out = 1; + } } else { uint64_t l_count_out = 0; if(a_count_out) { @@ -294,6 +296,7 @@ dap_store_obj_t *dap_db_driver_cdb_read_store_obj(const char *a_group, const cha } for (ulong i = 0; i < l_count_out; ++i) { l_arg.o[i].group = dap_strdup(a_group); + l_arg.o[i].id = l_cdb_stat.rnum - l_count_out + i + 1; } l_obj = l_arg.o; } @@ -308,14 +311,22 @@ dap_store_obj_t* dap_db_driver_cdb_read_cond_store_obj(const char *a_group, uint if (!l_cdb) { return NULL; } - dap_store_obj_t *l_obj = NULL; uint64_t l_count_out = 0; if(a_count_out) { l_count_out = *a_count_out; } CDBSTAT l_cdb_stat; cdb_stat(l_cdb, &l_cdb_stat); - if ((l_count_out == 0) || (l_count_out > l_cdb_stat.rnum - a_id)) { + if (a_id + l_count_out > l_cdb_stat.rnum) { + *a_count_out = 0; + return NULL; + } + if (a_id + l_count_out == 0) { + a_id = 0; + l_count_out = l_cdb_stat.rnum; + } else if (a_id == 0) { + a_id = l_cdb_stat.rnum - l_count_out; + } else if (l_count_out == 0) { l_count_out = l_cdb_stat.rnum - a_id; } obj_arg l_arg; @@ -330,18 +341,23 @@ dap_store_obj_t* dap_db_driver_cdb_read_cond_store_obj(const char *a_group, uint } for (ulong i = 0; i < l_count_out; ++i) { l_arg.o[i].group = dap_strdup(a_group); + l_arg.o[i].id = a_id + i + 1; } - l_obj = l_arg.o; + return l_arg.o; } int dap_db_driver_cdb_apply_store_obj(pdap_store_obj_t a_store_obj) { if(!a_store_obj || !a_store_obj->group) { return -1; } + int ret = 0; CDB *l_cdb = dap_cdb_get_db_by_group(a_store_obj->group); if (!l_cdb) { dap_cdb_add_group(a_store_obj->group); pcdb_instance l_cdb_i = dap_cdb_init_group(a_store_obj->group, CDB_CREAT | CDB_PAGEWARMUP); + if (!l_cdb_i) { + return -1; + } l_cdb = l_cdb_i->cdb; } if(a_store_obj->type == 'a') { @@ -349,9 +365,9 @@ int dap_db_driver_cdb_apply_store_obj(pdap_store_obj_t a_store_obj) { cdb_record l_rec; l_rec.key = dap_strdup(a_store_obj->key); int offset = 0; - char *l_val = DAP_NEW_Z_SIZE(char, uint64_size + sizeof(unsigned long) + a_store_obj->value_len + sizeof(time_t)); - dap_cdb_uint_to_hex(l_val, a_store_obj->id, uint64_size); - offset += uint64_size; + char *l_val = DAP_NEW_Z_SIZE(char, sizeof(uint64_t) + sizeof(unsigned long) + a_store_obj->value_len + sizeof(time_t)); + // dap_cdb_uint_to_hex(l_val, a_store_obj->id, uint64_size); + offset += sizeof(uint64_t); dap_cdb_uint_to_hex(l_val + offset, a_store_obj->value_len, sizeof(unsigned long)); offset += sizeof(unsigned long); memcpy(l_val + offset, a_store_obj->value, a_store_obj->value_len); @@ -360,8 +376,9 @@ int dap_db_driver_cdb_apply_store_obj(pdap_store_obj_t a_store_obj) { dap_cdb_uint_to_hex(l_val + offset, l_time, sizeof(time_t)); offset += sizeof(time_t); l_rec.val = l_val; - if (cdb_set2(l_cdb, l_rec.key, strlen(l_rec.key), l_rec.val, offset, CDB_INSERTCACHE | CDB_INSERTIFNOEXIST, 0) < 0) { + if (cdb_set2(l_cdb, l_rec.key, strlen(l_rec.key), l_rec.val, offset, CDB_INSERTCACHE | CDB_OVERWRITE, 0) != CDB_SUCCESS) { log_it(L_ERROR, "Couldn't add record with key [%s] to CDB: \"%s\"", l_rec.key, cdb_errmsg(cdb_errno(l_cdb))); + ret = -1; } DAP_DELETE(l_rec.key); DAP_DELETE(l_rec.val); @@ -370,8 +387,10 @@ int dap_db_driver_cdb_apply_store_obj(pdap_store_obj_t a_store_obj) { cdb_del(l_cdb, a_store_obj->key, strlen(a_store_obj->key)); } else { cdb_destroy(l_cdb); - dap_cdb_init_group(a_store_obj->group, CDB_TRUNC | CDB_PAGEWARMUP); + if (!dap_cdb_init_group(a_store_obj->group, CDB_TRUNC | CDB_PAGEWARMUP)) { + ret = -1; + } } } - return 0; + return ret; } diff --git a/dap_chain_global_db_driver_sqlite.c b/dap_chain_global_db_driver_sqlite.c index d9f7251a4d3b3d74a315577dc2d9014832abface..626506289758ac959151d7686477679c8abdb25f 100755 --- a/dap_chain_global_db_driver_sqlite.c +++ b/dap_chain_global_db_driver_sqlite.c @@ -451,16 +451,16 @@ int dap_db_driver_sqlite_apply_store_obj(dap_store_obj_t *a_store_obj) char *l_error_message = NULL; if(a_store_obj->type == 'a') { if(!a_store_obj->key || !a_store_obj->value || !a_store_obj->value_len) - return -1; - dap_chain_hash_fast_t l_hash; - dap_hash_fast(a_store_obj->value, a_store_obj->value_len, &l_hash); + return -1; + //dap_chain_hash_fast_t l_hash; + //dap_hash_fast(a_store_obj->value, a_store_obj->value_len, &l_hash); - char *l_blob_hash = dap_db_driver_get_string_from_blob((uint8_t*) &l_hash, sizeof(dap_chain_hash_fast_t)); + char *l_blob_hash = ""; //dap_db_driver_get_string_from_blob((uint8_t*) &l_hash, sizeof(dap_chain_hash_fast_t)); char *l_blob_value = dap_db_driver_get_string_from_blob(a_store_obj->value, a_store_obj->value_len); //add one record l_query = sqlite3_mprintf("insert into '%s' values(NULL, '%s', x'%s', '%lld', x'%s')", a_store_obj->group, a_store_obj->key, l_blob_hash, a_store_obj->timestamp, l_blob_value); - dap_db_driver_sqlite_free(l_blob_hash); + //dap_db_driver_sqlite_free(l_blob_hash); dap_db_driver_sqlite_free(l_blob_value); } else if(a_store_obj->type == 'd') { @@ -476,27 +476,41 @@ int dap_db_driver_sqlite_apply_store_obj(dap_store_obj_t *a_store_obj) log_it(L_ERROR, "Unknown store_obj type '0x%x'", a_store_obj->type); return -1; } - int l_ret = dap_db_driver_sqlite_exec(s_db, l_query, NULL); - // missing database + // execute request + int l_ret = dap_db_driver_sqlite_exec(s_db, l_query, &l_error_message); if(l_ret == SQLITE_ERROR) { + dap_db_driver_sqlite_free(l_error_message); + l_error_message = NULL; // create table dap_db_driver_sqlite_create_group_table(a_store_obj->group); + // repeat request l_ret = dap_db_driver_sqlite_exec(s_db, l_query, &l_error_message); + } - dap_db_driver_sqlite_free(l_query); // entry with the same hash is already present if(l_ret == SQLITE_CONSTRAINT) { - log_it(L_INFO, "Entry with the same key is already present, %s", l_error_message); dap_db_driver_sqlite_free(l_error_message); - return 0; + l_error_message = NULL; + //delete exist record + char *l_query_del = sqlite3_mprintf("delete from '%s' where key = '%s'", a_store_obj->group, a_store_obj->key); + l_ret = dap_db_driver_sqlite_exec(s_db, l_query_del, &l_error_message); + dap_db_driver_sqlite_free(l_query_del); + if(l_ret != SQLITE_OK) { + log_it(L_INFO, "Entry with the same key is already present and can't delete, %s", l_error_message); + dap_db_driver_sqlite_free(l_error_message); + l_error_message = NULL; + } + // repeat request + l_ret = dap_db_driver_sqlite_exec(s_db, l_query, &l_error_message); } - if(l_ret != SQLITE_OK) - { + // missing database + if(l_ret != SQLITE_OK) { log_it(L_ERROR, "sqlite apply error: %s", l_error_message); dap_db_driver_sqlite_free(l_error_message); - return -1; + l_ret = -1; } - return 0; + dap_db_driver_sqlite_free(l_query); + return l_ret; } static void fill_one_item(const char *a_group, dap_store_obj_t *a_obj, SQLITE_ROW_VALUE *a_row) diff --git a/dap_chain_global_db_hist.c b/dap_chain_global_db_hist.c index b3704aa2c6f29b8ddeb944bf9e0afa5d79823b27..1b3062b558d0e90d76d2a1239a6179fbcf83bab7 100755 --- a/dap_chain_global_db_hist.c +++ b/dap_chain_global_db_hist.c @@ -73,11 +73,16 @@ uint8_t* dap_db_log_pack(dap_global_db_obj_t *a_obj, size_t *a_data_size_out) while(l_keys[i]) { dap_store_obj_t *l_obj = NULL; // add record - read record - if(l_rec.type == 'a') + if(l_rec.type == 'a'){ l_obj = (dap_store_obj_t*) dap_chain_global_db_obj_get(l_keys[i], l_rec.group); + // l_obj may be NULL, if this record has been deleted but it is present in history + if(l_obj) + l_obj->id = a_obj->id; + } // delete record - save only key for record else if(l_rec.type == 'd') { // //section=strdup("kelvin_nodes"); l_obj = (dap_store_obj_t*) DAP_NEW_Z(dap_store_obj_t); + l_obj->id = a_obj->id; l_obj->group = dap_strdup(l_rec.group); l_obj->key = dap_strdup(l_keys[i]); } @@ -167,7 +172,7 @@ bool dap_db_history_truncate(void) /** * Get last timestamp in log */ -time_t dap_db_log_get_last_timestamp(void) +uint64_t dap_db_log_get_last_id(void) { //dap_store_obj_t *l_last_obj = dap_chain_global_db_driver_read_last( dap_store_obj_t *l_last_obj = dap_chain_global_db_get_last(GROUP_LOCAL_HISTORY); @@ -192,26 +197,27 @@ time_t dap_db_log_get_last_timestamp(void) return l_ret_time;*/ } -static int compare_items(const void * l_a, const void * l_b) +/*static int compare_items(const void * l_a, const void * l_b) { const dap_global_db_obj_t *l_item_a = (const dap_global_db_obj_t*) l_a; const dap_global_db_obj_t *l_item_b = (const dap_global_db_obj_t*) l_b; int l_ret = strcmp(l_item_a->key, l_item_b->key); return l_ret; -} +}*/ /** * Get log diff as list */ -dap_list_t* dap_db_log_get_list(time_t first_timestamp) +dap_list_t* dap_db_log_get_list(uint64_t first_id) { dap_list_t *l_list = NULL; size_t l_data_size_out = 0; - dap_store_obj_t *l_objs = dap_chain_global_db_cond_load(GROUP_LOCAL_HISTORY, first_timestamp, &l_data_size_out); + dap_store_obj_t *l_objs = dap_chain_global_db_cond_load(GROUP_LOCAL_HISTORY, first_id, &l_data_size_out); //dap_global_db_obj_t **l_objs = dap_chain_global_db_gr_load(GROUP_LOCAL_HISTORY, first_timestamp, &l_data_size_out); for(size_t i = 0; i < l_data_size_out; i++) { dap_store_obj_t *l_obj_cur = l_objs + i; dap_global_db_obj_t *l_item = DAP_NEW(dap_global_db_obj_t); + l_item->id = l_obj_cur->id; l_item->key = dap_strdup(l_obj_cur->key); l_item->value = (uint8_t*) dap_strdup((char*) l_obj_cur->value); l_list = dap_list_append(l_list, l_item); diff --git a/dap_chain_global_db_remote.c b/dap_chain_global_db_remote.c index 605ddcf8f07402973658bb2a32e6bc196aa9e674..34e3de72f1ff8a854ec2ecdee689fb4b32cff50c 100755 --- a/dap_chain_global_db_remote.c +++ b/dap_chain_global_db_remote.c @@ -32,31 +32,31 @@ uint64_t dap_db_get_cur_node_addr(void) } /** - * Set last timestamp for remote node + * Set last id for remote node */ -bool dap_db_log_set_last_timestamp_remote(uint64_t a_node_addr, time_t a_timestamp) +bool dap_db_log_set_last_id_remote(uint64_t a_node_addr, uint64_t a_id) { dap_global_db_obj_t l_objs; l_objs.key = dap_strdup_printf("%lld", a_node_addr); - l_objs.value = (uint8_t*) &a_timestamp; - l_objs.value_len = sizeof(time_t); - bool l_ret = dap_chain_global_db_gr_save(&l_objs, 1, GROUP_LOCAL_NODE_LAST_TS); + l_objs.value = (uint8_t*) &a_id; + l_objs.value_len = sizeof(uint64_t); + bool l_ret = dap_chain_global_db_gr_save(&l_objs, 1, GROUP_LOCAL_NODE_LAST_ID); DAP_DELETE(l_objs.key); - log_it( L_NOTICE, "Node 0x%016X set last synced timestamp %llu",a_timestamp); + log_it( L_NOTICE, "Node 0x%016X set last synced timestamp %llu",a_id); return l_ret; } /** - * Get last timestamp for remote node + * Get last id for remote node */ -time_t dap_db_log_get_last_timestamp_remote(uint64_t a_node_addr) +uint64_t dap_db_log_get_last_id_remote(uint64_t a_node_addr) { char *l_node_addr_str = dap_strdup_printf("%lld", a_node_addr); size_t l_timestamp_len = 0; uint8_t *l_timestamp = dap_chain_global_db_gr_get((const char*) l_node_addr_str, &l_timestamp_len, - GROUP_LOCAL_NODE_LAST_TS); - time_t l_ret_timestamp = 0; - if(l_timestamp && l_timestamp_len == sizeof(time_t)) + GROUP_LOCAL_NODE_LAST_ID); + uint64_t l_ret_timestamp = 0; + if(l_timestamp && l_timestamp_len == sizeof(uint64_t)) memcpy(&l_ret_timestamp, l_timestamp, l_timestamp_len); DAP_DELETE(l_node_addr_str); DAP_DELETE(l_timestamp); diff --git a/dap_chain_global_db_remote.h b/dap_chain_global_db_remote.h index 0a0f3b6fa89a867866e3cc5ac2b167dba4c83fd3..2453611dc84e875cf38d5c01f75911e67a935891 100755 --- a/dap_chain_global_db_remote.h +++ b/dap_chain_global_db_remote.h @@ -9,8 +9,8 @@ bool dap_db_set_cur_node_addr(uint64_t a_address); // Get addr for current node uint64_t dap_db_get_cur_node_addr(void); -// Set last timestamp for remote node -bool dap_db_log_set_last_timestamp_remote(uint64_t a_node_addr, time_t a_timestamp); -// Get last timestamp for remote node -time_t dap_db_log_get_last_timestamp_remote(uint64_t a_node_addr); +// Set last id for remote node +bool dap_db_log_set_last_id_remote(uint64_t a_node_addr, uint64_t a_id); +// Get last id for remote node +uint64_t dap_db_log_get_last_id_remote(uint64_t a_node_addr);