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
|
* connection_pool.c: set err_no to 0 when success
|
||||||
* shared_func.h: add functions float2buff / buff2float, double2buff / buff2double
|
* shared_func.h: add functions float2buff / buff2float, double2buff / buff2double
|
||||||
* logger.h: add function log_get_level_caption
|
* logger.h: add function log_get_level_caption
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ int fast_mblock_manager_stat(struct fast_mblock_info *stats,
|
||||||
}
|
}
|
||||||
|
|
||||||
//desc order
|
//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 *pStat1;
|
||||||
struct fast_mblock_info *pStat2;
|
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;
|
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 result;
|
||||||
int count;
|
int count;
|
||||||
|
|
@ -225,7 +236,16 @@ int fast_mblock_manager_stat_print(const bool hide_empty)
|
||||||
char alloc_mem_str[32];
|
char alloc_mem_str[32];
|
||||||
char used_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;
|
alloc_mem = 0;
|
||||||
used_mem = 0;
|
used_mem = 0;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,9 @@
|
||||||
|
|
||||||
#define FAST_MBLOCK_NAME_SIZE 32
|
#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 */
|
/* free node chain */
|
||||||
struct fast_mblock_node
|
struct fast_mblock_node
|
||||||
{
|
{
|
||||||
|
|
@ -282,9 +285,13 @@ int fast_mblock_manager_stat(struct fast_mblock_info *stats,
|
||||||
print mblock manager stat
|
print mblock manager stat
|
||||||
parameters:
|
parameters:
|
||||||
hide_empty: if hide empty
|
hide_empty: if hide empty
|
||||||
|
order_by: order by which field
|
||||||
return error no, 0 for success, != 0 fail
|
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,
|
typedef void (*fast_mblock_free_trunks_func)(struct fast_mblock_man *mblock,
|
||||||
struct fast_mblock_malloc *freelist);
|
struct fast_mblock_malloc *freelist);
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ int flat_skiplist_init_ex(FlatSkiplist *sl, const int level_count,
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (alloc_elements_once < 1024 * 1024) {
|
if (i % 2 == 0 && alloc_elements_once < 64 * 1024) {
|
||||||
alloc_elements_once *= 2;
|
alloc_elements_once *= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@
|
||||||
* Please visit the FastDFS Home Page http://www.csource.org/ for more detail.
|
* 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
|
#ifndef _FLAT_SKIPLIST_H
|
||||||
#define _FLAT_SKIPLIST_H
|
#define _FLAT_SKIPLIST_H
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ int multi_skiplist_init_ex(MultiSkiplist *sl, const int level_count,
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (alloc_elements_once < 1024 * 1024) {
|
if (i % 2 == 0 && alloc_elements_once < 64 * 1024) {
|
||||||
alloc_elements_once *= 2;
|
alloc_elements_once *= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@
|
||||||
* Please visit the FastDFS Home Page http://www.csource.org/ for more detail.
|
* 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
|
#ifndef _MULTI_SKIPLIST_H
|
||||||
#define _MULTI_SKIPLIST_H
|
#define _MULTI_SKIPLIST_H
|
||||||
|
|
||||||
|
|
@ -138,4 +139,3 @@ static inline void multi_skiplist_print(MultiSkiplist *sl, multi_skiplist_tostri
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
**/
|
**/
|
||||||
|
|
||||||
//skiplist.h, support stable sort :)
|
//skiplist.h, support stable sort :)
|
||||||
|
|
||||||
#ifndef _SKIPLIST_H
|
#ifndef _SKIPLIST_H
|
||||||
#define _SKIPLIST_H
|
#define _SKIPLIST_H
|
||||||
|
|
||||||
|
|
@ -19,9 +20,9 @@
|
||||||
#include "multi_skiplist.h"
|
#include "multi_skiplist.h"
|
||||||
#include "skiplist_set.h"
|
#include "skiplist_set.h"
|
||||||
|
|
||||||
#define SKIPLIST_TYPE_FLAT 0
|
#define SKIPLIST_TYPE_FLAT 0 //best for small duplicated entries
|
||||||
#define SKIPLIST_TYPE_MULTI 1
|
#define SKIPLIST_TYPE_MULTI 1 //best for large duplicated entries
|
||||||
#define SKIPLIST_TYPE_SET 2
|
#define SKIPLIST_TYPE_SET 2 //NO duplicated entries
|
||||||
|
|
||||||
typedef struct skiplist
|
typedef struct skiplist
|
||||||
{
|
{
|
||||||
|
|
@ -155,7 +156,7 @@ static inline int skiplist_find_all(Skiplist *sl, void *data, SkiplistIterator *
|
||||||
case SKIPLIST_TYPE_MULTI:
|
case SKIPLIST_TYPE_MULTI:
|
||||||
return multi_skiplist_find_all(&sl->u.multi, data, &iterator->u.multi);
|
return multi_skiplist_find_all(&sl->u.multi, data, &iterator->u.multi);
|
||||||
case SKIPLIST_TYPE_SET:
|
case SKIPLIST_TYPE_SET:
|
||||||
return EOPNOTSUPP;
|
return skiplist_set_find_all(&sl->u.set, data, &iterator->u.set);
|
||||||
default:
|
default:
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ int skiplist_set_init_ex(SkiplistSet *sl, const int level_count,
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (alloc_elements_once < 1024 * 1024) {
|
if (i % 2 == 0 && alloc_elements_once < 64 * 1024) {
|
||||||
alloc_elements_once *= 2;
|
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);
|
previous = skiplist_set_get_previous(sl, data, &level_index);
|
||||||
return (previous != NULL) ? previous->links[level_index]->data : NULL;
|
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.
|
* 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
|
#ifndef _SKIPLIST_SET_H
|
||||||
#define _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_insert(SkiplistSet *sl, void *data);
|
||||||
int skiplist_set_delete(SkiplistSet *sl, void *data);
|
int skiplist_set_delete(SkiplistSet *sl, void *data);
|
||||||
void *skiplist_set_find(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)
|
static inline void skiplist_set_iterator(SkiplistSet *sl, SkiplistSetIterator *iterator)
|
||||||
{
|
{
|
||||||
|
|
@ -87,4 +89,3 @@ static inline bool skiplist_set_empty(SkiplistSet *sl)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -218,22 +218,16 @@ static int test_stable_sort()
|
||||||
|
|
||||||
target.key = max_occur_key;
|
target.key = max_occur_key;
|
||||||
target.line = 0;
|
target.line = 0;
|
||||||
if (skiplist_type == SKIPLIST_TYPE_SET) {
|
if (skiplist_find_all(&sl, &target, &iterator) == 0) {
|
||||||
record = (Record *)skiplist_find(&sl, &target);
|
printf("found key: %d\n", target.key);
|
||||||
assert(record != NULL && record->key == target.key);
|
|
||||||
}
|
}
|
||||||
else {
|
i = 0;
|
||||||
if (skiplist_find_all(&sl, &target, &iterator) == 0) {
|
while ((value=skiplist_next(&iterator)) != NULL) {
|
||||||
printf("found key: %d\n", target.key);
|
i++;
|
||||||
}
|
record = (Record *)value;
|
||||||
i = 0;
|
printf("%d => #%d\n", record->key, record->line);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
printf("found record count: %d\n", i);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (skiplist_type == SKIPLIST_TYPE_FLAT) {
|
if (skiplist_type == SKIPLIST_TYPE_FLAT) {
|
||||||
|
|
@ -246,17 +240,11 @@ static int test_stable_sort()
|
||||||
|
|
||||||
total_delete_count = 0;
|
total_delete_count = 0;
|
||||||
for (i=0; i<RECORDS; i++) {
|
for (i=0; i<RECORDS; i++) {
|
||||||
do {
|
if ((result=skiplist_delete_all(&sl, records + i, &delete_count)) == 0) {
|
||||||
delete_count = 0;
|
total_delete_count += delete_count;
|
||||||
if ((result=skiplist_delete(&sl, records + i)) == 0)
|
}
|
||||||
{
|
assert((result == 0 && delete_count > 0) ||
|
||||||
delete_count = 1;
|
(result != 0 && delete_count == 0));
|
||||||
total_delete_count += delete_count;
|
|
||||||
}
|
|
||||||
assert((result == 0 && delete_count > 0) ||
|
|
||||||
(result != 0 && delete_count == 0));
|
|
||||||
|
|
||||||
} while (result == 0);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
assert(total_delete_count == RECORDS);
|
assert(total_delete_count == RECORDS);
|
||||||
|
|
@ -332,7 +320,7 @@ int main(int argc, char *argv[])
|
||||||
test_insert();
|
test_insert();
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
fast_mblock_manager_stat_print(false);
|
fast_mblock_manager_stat_print_ex(false, FAST_MBLOCK_ORDER_BY_ELEMENT_SIZE);
|
||||||
|
|
||||||
test_delete();
|
test_delete();
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue