skiplist optimization

pull/37/head
yuqing 2018-05-30 13:49:27 +08:00
parent fd894d810b
commit beb0c77ebb
11 changed files with 79 additions and 43 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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<RECORDS; i++) {
do {
delete_count = 0;
if ((result=skiplist_delete(&sl, records + i)) == 0)
{
delete_count = 1;
total_delete_count += delete_count;
}
assert((result == 0 && delete_count > 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");