skiplist optimization
parent
fd894d810b
commit
beb0c77ebb
2
HISTORY
2
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Reference in New Issue