From a9a10e6d13c3848e7f2feb67f0eab2872512b0c8 Mon Sep 17 00:00:00 2001 From: "Dmitriy A. Gerasimov" <dmitriy.gerasimov@demlabs.net> Date: Mon, 9 Nov 2020 00:54:37 +0700 Subject: [PATCH] [*] Chunks treshold now sorted with bubble --- modules/type/blocks/dap_chain_block_chunk.c | 109 +++++++++++++++--- .../blocks/include/dap_chain_block_chunk.h | 26 ++++- 2 files changed, 114 insertions(+), 21 deletions(-) diff --git a/modules/type/blocks/dap_chain_block_chunk.c b/modules/type/blocks/dap_chain_block_chunk.c index 97ecedb452..5e40fe835e 100644 --- a/modules/type/blocks/dap_chain_block_chunk.c +++ b/modules/type/blocks/dap_chain_block_chunk.c @@ -56,7 +56,7 @@ dap_chain_block_chunks_t * dap_chain_block_chunks_create(dap_chain_cs_blocks_t * */ void dap_chain_block_chunks_delete(dap_chain_block_chunks_t * a_chunks) { - dap_chain_block_chunk_t * l_chunk = a_chunks->chunks_first; + dap_chain_block_chunk_t * l_chunk = a_chunks->chunks_last; while(l_chunk){ dap_chain_block_cache_hash_t* l_block_cache_hash = NULL, *l_tmp = NULL; @@ -98,40 +98,111 @@ dap_chain_block_cache_t * dap_chain_block_chunks_add(dap_chain_block_chunks_t * // Save to GDB dap_chain_global_db_gr_set(dap_strdup(l_block_cache->block_hash_str),a_block,a_block_size, a_chunks->gdb_group); - // Init cache-hash object - l_chunk_cache_hash = DAP_NEW_Z(dap_chain_block_cache_hash_t); - l_chunk_cache_hash->block_cache=l_block_cache; - l_chunk_cache_hash->ts_created = time(NULL); - memcpy(&l_chunk_cache_hash->block_hash, &l_block_cache->block_hash,sizeof (l_block_cache->block_hash)); // And here we select chunk for the new block cache - for (dap_chain_block_chunk_t * l_chunk = a_chunks->chunks_first; l_chunk; l_chunk = l_chunk->prev ){ - if(dap_hash_fast_compare(&l_chunk->block_cache_first->block_hash, &l_block_cache->prev_hash ) ){ + bool l_is_chunk_found = false; + for (dap_chain_block_chunk_t * l_chunk = a_chunks->chunks_last; l_chunk; l_chunk = l_chunk->prev ){ + if(dap_hash_fast_compare(&l_chunk->block_cache_top->block_hash, &l_block_cache->prev_hash ) ){ + // Init cache-hash object + l_chunk_cache_hash = DAP_NEW_Z(dap_chain_block_cache_hash_t); + l_chunk_cache_hash->block_cache=l_block_cache; + l_chunk_cache_hash->ts_created = time(NULL); + memcpy(&l_chunk_cache_hash->block_hash, &l_block_cache->block_hash,sizeof (l_block_cache->block_hash)); l_chunk_cache_hash->chunk = l_chunk; - break; + + // Update first block cache from the head + l_chunk->block_cache_top = l_block_cache; + // Add to selected chunk its hash object + HASH_ADD(hh,l_chunk->block_cache_hash , block_hash, sizeof (l_chunk_cache_hash->block_hash), l_chunk_cache_hash); + + // Update chunk id to make it unique + dap_chain_hash_fast_t l_hash_new_data[2]={l_block_cache->block_hash,l_chunk->chunk_id }; + dap_hash_fast(l_hash_new_data,sizeof (l_hash_new_data),&l_chunk->chunk_id); + l_is_chunk_found = true; } } - if ( ! l_chunk_cache_hash->chunk) { // Don't found anything suitable - if so we create our own chunk + if ( ! l_is_chunk_found ) { // Don't found anything suitable - if so we create our own chunk dap_chain_block_chunk_t * l_chunk = DAP_NEW_Z(dap_chain_block_chunk_t); - l_chunk->block_cache_first = l_block_cache; // Add in tail - l_chunk->prev = a_chunks->chunks_last; - if (a_chunks->chunks_last){ - l_chunk->next = a_chunks->chunks_last->next; + l_chunk->prev = a_chunks->chunks_first; + if (a_chunks->chunks_first){ + l_chunk->next = a_chunks->chunks_first->next; if (! l_chunk->next) - a_chunks->chunks_first = l_chunk; + a_chunks->chunks_last = l_chunk; else l_chunk->next->prev = l_chunk; }else - a_chunks->chunks_first = l_chunk; - a_chunks->chunks_last = l_chunk; + a_chunks->chunks_last = l_chunk; + a_chunks->chunks_first = l_chunk; + + // Init cache-hash object + l_chunk_cache_hash = DAP_NEW_Z(dap_chain_block_cache_hash_t); + l_chunk_cache_hash->block_cache=l_block_cache; + l_chunk_cache_hash->ts_created = time(NULL); + memcpy(&l_chunk_cache_hash->block_hash, &l_block_cache->block_hash,sizeof (l_block_cache->block_hash)); + l_chunk_cache_hash->chunk = l_chunk; + + // Update first block cache from the head + l_chunk->block_cache_top = l_block_cache; + // Add to selected chunk its hash object + HASH_ADD(hh,l_chunk->block_cache_hash , block_hash, sizeof (l_chunk_cache_hash->block_hash), l_chunk_cache_hash); + + // Update chunk id to make it unique + dap_chain_hash_fast_t l_hash_new_data[2]={l_block_cache->block_hash,l_chunk->chunk_id }; + dap_hash_fast(l_hash_new_data,sizeof (l_hash_new_data),&l_chunk->chunk_id); } - // Add to selected chunk its hash object - HASH_ADD(hh,l_chunk_cache_hash->chunk->block_cache_hash , block_hash, sizeof (l_chunk_cache_hash->block_hash), l_chunk_cache_hash); + + // Add object itself to all-chunks cache HASH_ADD(hh,a_chunks->cache ,block_hash ,sizeof (l_block_cache->block_hash), l_block_cache); + // Sort chunk list beginning from the new one and bubble up the longest one on the top + size_t l_chunk_length_max=0; + //dap_chain_block_chunk_t * l_chunk_max = NULL; + for (dap_chain_block_chunk_t * l_chunk = a_chunks->chunks_first ; l_chunk; l_chunk = l_chunk->next ){ + size_t l_chunk_length = HASH_COUNT(l_chunk->block_cache_hash); + if (! l_chunk_length){ + log_it(L_WARNING,"Chunk can't be empty, it must be deleted from chunks treshold"); + } + if (l_chunk_length > l_chunk_length_max ){ + //l_chunk_max = l_chunk; + l_chunk_length_max = l_chunk_length; + }else if (l_chunk_length == l_chunk_length_max ){ + continue; + }else{ + // Prev store + dap_chain_block_chunk_t * l_chunk_prev = l_chunk->prev; + + // Link next with prev + if (l_chunk->next ) + l_chunk->next->prev = l_chunk->prev; + + dap_chain_block_chunk_t * l_chunk_prev_prev = NULL; + + if (l_chunk_prev){ + // Link prev with next + l_chunk_prev->next = l_chunk->next; + l_chunk_prev_prev = l_chunk_prev->prev; + // Link prev with current + l_chunk_prev->prev = l_chunk; + // Update first chunks + if ( ! l_chunk_prev_prev) + a_chunks->chunks_first = l_chunk; + } + + // Link current with prev + l_chunk->next = l_chunk->prev ; + l_chunk->prev = l_chunk_prev_prev; + + // Replace previous with current + l_chunk = l_chunk_prev; + + // Its the last chunk + if ( ! l_chunk->next) + a_chunks->chunks_last = l_chunk; + } + } return l_block_cache; } diff --git a/modules/type/blocks/include/dap_chain_block_chunk.h b/modules/type/blocks/include/dap_chain_block_chunk.h index 18a9e8e9ee..cd7a90ecda 100644 --- a/modules/type/blocks/include/dap_chain_block_chunk.h +++ b/modules/type/blocks/include/dap_chain_block_chunk.h @@ -35,8 +35,9 @@ typedef struct dap_chain_block_cache_hash{ typedef struct dap_chain_block_chunk{ + dap_chain_hash_fast_t chunk_id; dap_chain_block_cache_hash_t *block_cache_hash; - dap_chain_block_cache_t *block_cache_first; + dap_chain_block_cache_t *block_cache_top; struct dap_chain_block_chunk * prev; struct dap_chain_block_chunk * next; } dap_chain_block_chunk_t; @@ -47,8 +48,8 @@ typedef struct dap_chain_block_chunks{ dap_chain_block_cache_t *cache; - dap_chain_block_chunk_t * chunks_first; dap_chain_block_chunk_t * chunks_last; + dap_chain_block_chunk_t * chunks_first; char * gdb_group; } dap_chain_block_chunks_t; @@ -56,3 +57,24 @@ dap_chain_block_chunks_t * dap_chain_block_chunks_create(dap_chain_cs_blocks_t * void dap_chain_block_chunks_delete(dap_chain_block_chunks_t * a_chunks); dap_chain_block_cache_t * dap_chain_block_chunks_add(dap_chain_block_chunks_t * a_chunks, dap_chain_block_t *a_block ,size_t a_block_size); + +/** + * @brief dap_chain_block_chunks_get_longest_count + * @param a_chunks + */ +static inline size_t dap_chain_block_chunks_get_longest_count(dap_chain_block_chunks_t * a_chunks) +{ + assert(a_chunks); + return a_chunks->chunks_last? HASH_COUNT(a_chunks->chunks_last->block_cache_hash):0; +} + +/** + * @brief dap_chain_block_chunks_get_longest_top + * @param a_chunks + * @return + */ +static inline dap_chain_block_cache_t* dap_chain_block_chunks_get_longest_top(dap_chain_block_chunks_t * a_chunks) +{ + assert(a_chunks); + return a_chunks->chunks_last?a_chunks->chunks_last->block_cache_top:NULL; +} -- GitLab