diff --git a/HISTORY b/HISTORY index a49c79b..5528cc9 100644 --- a/HISTORY +++ b/HISTORY @@ -1,5 +1,5 @@ -Version 1.38 2018-05-29 +Version 1.38 2018-05-30 * connection_pool.c: set err_no to 0 when success * shared_func.h: add functions float2buff / buff2float, double2buff / buff2double * logger.h: add function log_get_level_caption diff --git a/src/fast_mblock.c b/src/fast_mblock.c index 1fa3a22..4194787 100644 --- a/src/fast_mblock.c +++ b/src/fast_mblock.c @@ -181,7 +181,7 @@ int fast_mblock_manager_stat(struct fast_mblock_info *stats, } //desc order -static int fast_mblock_info_cmp(const void *p1, const void *p2) +static int fast_mblock_info_cmp_by_alloc_bytes(const void *p1, const void *p2) { struct fast_mblock_info *pStat1; struct fast_mblock_info *pStat2; @@ -192,7 +192,18 @@ static int fast_mblock_info_cmp(const void *p1, const void *p2) pStat1->trunk_size * pStat1->trunk_total_count; } -int fast_mblock_manager_stat_print(const bool hide_empty) +//desc order +static int fast_mblock_info_cmp_by_element_size(const void *p1, const void *p2) +{ + struct fast_mblock_info *pStat1; + struct fast_mblock_info *pStat2; + + pStat1 = (struct fast_mblock_info *)p1; + pStat2 = (struct fast_mblock_info *)p2; + return pStat2->element_size - pStat1->element_size; +} + +int fast_mblock_manager_stat_print_ex(const bool hide_empty, const int order_by) { int result; int count; @@ -225,7 +236,16 @@ int fast_mblock_manager_stat_print(const bool hide_empty) char alloc_mem_str[32]; char used_mem_str[32]; - qsort(stats, count, sizeof(struct fast_mblock_info), fast_mblock_info_cmp); + if (order_by == FAST_MBLOCK_ORDER_BY_ALLOC_BYTES) + { + qsort(stats, count, sizeof(struct fast_mblock_info), + fast_mblock_info_cmp_by_alloc_bytes); + } + else + { + qsort(stats, count, sizeof(struct fast_mblock_info), + fast_mblock_info_cmp_by_element_size); + } alloc_mem = 0; used_mem = 0; diff --git a/src/fast_mblock.h b/src/fast_mblock.h index 319ccea..4a304b6 100644 --- a/src/fast_mblock.h +++ b/src/fast_mblock.h @@ -20,6 +20,9 @@ #define FAST_MBLOCK_NAME_SIZE 32 +#define FAST_MBLOCK_ORDER_BY_ALLOC_BYTES 1 +#define FAST_MBLOCK_ORDER_BY_ELEMENT_SIZE 2 + /* free node chain */ struct fast_mblock_node { @@ -282,9 +285,13 @@ int fast_mblock_manager_stat(struct fast_mblock_info *stats, print mblock manager stat parameters: hide_empty: if hide empty + order_by: order by which field return error no, 0 for success, != 0 fail */ -int fast_mblock_manager_stat_print(const bool hide_empty); +int fast_mblock_manager_stat_print_ex(const bool hide_empty, const int order_by); + +#define fast_mblock_manager_stat_print(hide_empty) \ + fast_mblock_manager_stat_print_ex(hide_empty, FAST_MBLOCK_ORDER_BY_ALLOC_BYTES) typedef void (*fast_mblock_free_trunks_func)(struct fast_mblock_man *mblock, struct fast_mblock_malloc *freelist); diff --git a/src/flat_skiplist.c b/src/flat_skiplist.c index 9227512..49b6d7d 100644 --- a/src/flat_skiplist.c +++ b/src/flat_skiplist.c @@ -76,7 +76,7 @@ int flat_skiplist_init_ex(FlatSkiplist *sl, const int level_count, { return result; } - if (alloc_elements_once < 1024 * 1024) { + if (i % 2 == 0 && alloc_elements_once < 64 * 1024) { alloc_elements_once *= 2; } } diff --git a/src/flat_skiplist.h b/src/flat_skiplist.h index bdf6b96..d0fe064 100644 --- a/src/flat_skiplist.h +++ b/src/flat_skiplist.h @@ -6,7 +6,9 @@ * Please visit the FastDFS Home Page http://www.csource.org/ for more detail. **/ -//flat_skiplist.h, support stable sort :) +//flat_skiplist.h, support duplicated entries, and support stable sort :) +//you should use multi_skiplist with too many duplicated entries + #ifndef _FLAT_SKIPLIST_H #define _FLAT_SKIPLIST_H diff --git a/src/multi_skiplist.c b/src/multi_skiplist.c index 8f0a4e2..b40fe5e 100644 --- a/src/multi_skiplist.c +++ b/src/multi_skiplist.c @@ -77,7 +77,7 @@ int multi_skiplist_init_ex(MultiSkiplist *sl, const int level_count, { return result; } - if (alloc_elements_once < 1024 * 1024) { + if (i % 2 == 0 && alloc_elements_once < 64 * 1024) { alloc_elements_once *= 2; } } diff --git a/src/multi_skiplist.h b/src/multi_skiplist.h index 2849b76..6eb5054 100644 --- a/src/multi_skiplist.h +++ b/src/multi_skiplist.h @@ -6,7 +6,8 @@ * Please visit the FastDFS Home Page http://www.csource.org/ for more detail. **/ -//multi_skiplist.h, support stable sort :) +//multi_skiplist.h, support duplicated entries, and support stable sort :) + #ifndef _MULTI_SKIPLIST_H #define _MULTI_SKIPLIST_H @@ -138,4 +139,3 @@ static inline void multi_skiplist_print(MultiSkiplist *sl, multi_skiplist_tostri #endif #endif - diff --git a/src/skiplist.h b/src/skiplist.h index 91e8686..7d077a9 100644 --- a/src/skiplist.h +++ b/src/skiplist.h @@ -7,6 +7,7 @@ **/ //skiplist.h, support stable sort :) + #ifndef _SKIPLIST_H #define _SKIPLIST_H @@ -19,9 +20,9 @@ #include "multi_skiplist.h" #include "skiplist_set.h" -#define SKIPLIST_TYPE_FLAT 0 -#define SKIPLIST_TYPE_MULTI 1 -#define SKIPLIST_TYPE_SET 2 +#define SKIPLIST_TYPE_FLAT 0 //best for small duplicated entries +#define SKIPLIST_TYPE_MULTI 1 //best for large duplicated entries +#define SKIPLIST_TYPE_SET 2 //NO duplicated entries typedef struct skiplist { @@ -155,7 +156,7 @@ static inline int skiplist_find_all(Skiplist *sl, void *data, SkiplistIterator * case SKIPLIST_TYPE_MULTI: return multi_skiplist_find_all(&sl->u.multi, data, &iterator->u.multi); case SKIPLIST_TYPE_SET: - return EOPNOTSUPP; + return skiplist_set_find_all(&sl->u.set, data, &iterator->u.set); default: return EINVAL; } diff --git a/src/skiplist_set.c b/src/skiplist_set.c index 12444f2..dc3f26a 100644 --- a/src/skiplist_set.c +++ b/src/skiplist_set.c @@ -76,7 +76,7 @@ int skiplist_set_init_ex(SkiplistSet *sl, const int level_count, { return result; } - if (alloc_elements_once < 1024 * 1024) { + if (i % 2 == 0 && alloc_elements_once < 64 * 1024) { alloc_elements_once *= 2; } } @@ -268,3 +268,20 @@ void *skiplist_set_find(SkiplistSet *sl, void *data) previous = skiplist_set_get_previous(sl, data, &level_index); return (previous != NULL) ? previous->links[level_index]->data : NULL; } + +int skiplist_set_find_all(SkiplistSet *sl, void *data, SkiplistSetIterator *iterator) +{ + int level_index; + SkiplistSetNode *previous; + + previous = skiplist_set_get_previous(sl, data, &level_index); + if (previous == NULL) { + iterator->tail = sl->tail; + iterator->current = sl->tail; + return ENOENT; + } + + iterator->current = previous->links[level_index]; + iterator->tail = iterator->current->links[0]; + return 0; +} diff --git a/src/skiplist_set.h b/src/skiplist_set.h index 32e3005..a77d859 100644 --- a/src/skiplist_set.h +++ b/src/skiplist_set.h @@ -6,7 +6,8 @@ * Please visit the FastDFS Home Page http://www.csource.org/ for more detail. **/ -//skiplist_set.h, support stable sort :) +//a set implemented by skiplist, the entry can occur only once + #ifndef _SKIPLIST_SET_H #define _SKIPLIST_SET_H @@ -57,6 +58,7 @@ void skiplist_set_destroy(SkiplistSet *sl); int skiplist_set_insert(SkiplistSet *sl, void *data); int skiplist_set_delete(SkiplistSet *sl, void *data); void *skiplist_set_find(SkiplistSet *sl, void *data); +int skiplist_set_find_all(SkiplistSet *sl, void *data, SkiplistSetIterator *iterator); static inline void skiplist_set_iterator(SkiplistSet *sl, SkiplistSetIterator *iterator) { @@ -87,4 +89,3 @@ static inline bool skiplist_set_empty(SkiplistSet *sl) #endif #endif - diff --git a/src/tests/test_skiplist.c b/src/tests/test_skiplist.c index 41d1026..94f0d98 100644 --- a/src/tests/test_skiplist.c +++ b/src/tests/test_skiplist.c @@ -218,22 +218,16 @@ static int test_stable_sort() target.key = max_occur_key; target.line = 0; - if (skiplist_type == SKIPLIST_TYPE_SET) { - record = (Record *)skiplist_find(&sl, &target); - assert(record != NULL && record->key == target.key); + if (skiplist_find_all(&sl, &target, &iterator) == 0) { + printf("found key: %d\n", target.key); } - else { - if (skiplist_find_all(&sl, &target, &iterator) == 0) { - printf("found key: %d\n", target.key); - } - i = 0; - while ((value=skiplist_next(&iterator)) != NULL) { - i++; - record = (Record *)value; - printf("%d => #%d\n", record->key, record->line); - } - printf("found record count: %d\n", i); + i = 0; + while ((value=skiplist_next(&iterator)) != NULL) { + i++; + record = (Record *)value; + printf("%d => #%d\n", record->key, record->line); } + printf("found record count: %d\n", i); /* if (skiplist_type == SKIPLIST_TYPE_FLAT) { @@ -246,17 +240,11 @@ static int test_stable_sort() total_delete_count = 0; for (i=0; i 0) || - (result != 0 && delete_count == 0)); - - } while (result == 0); + if ((result=skiplist_delete_all(&sl, records + i, &delete_count)) == 0) { + total_delete_count += delete_count; + } + assert((result == 0 && delete_count > 0) || + (result != 0 && delete_count == 0)); } assert(total_delete_count == RECORDS); @@ -332,7 +320,7 @@ int main(int argc, char *argv[]) test_insert(); printf("\n"); - fast_mblock_manager_stat_print(false); + fast_mblock_manager_stat_print_ex(false, FAST_MBLOCK_ORDER_BY_ELEMENT_SIZE); test_delete(); printf("\n");