add files: sorted_array.[hc]
parent
81950ac246
commit
2993b34e80
3
HISTORY
3
HISTORY
|
|
@ -1,11 +1,12 @@
|
||||||
|
|
||||||
Version 1.54 2021-09-10
|
Version 1.54 2021-09-13
|
||||||
* fast_allocator.[hc]: correct reclaim_interval logic
|
* fast_allocator.[hc]: correct reclaim_interval logic
|
||||||
* shared_func.[hc]: add functions getFileContentEx1 and getFileContent1
|
* shared_func.[hc]: add functions getFileContentEx1 and getFileContent1
|
||||||
* fc_queue.[hc]: add function fc_queue_timedpeek
|
* fc_queue.[hc]: add function fc_queue_timedpeek
|
||||||
* pthread_func.[hc]: add function init_pthread_rwlock
|
* pthread_func.[hc]: add function init_pthread_rwlock
|
||||||
* add files: sorted_queue.[hc]
|
* add files: sorted_queue.[hc]
|
||||||
* add files: array_allocator.[hc]
|
* add files: array_allocator.[hc]
|
||||||
|
* add files: sorted_array.[hc]
|
||||||
|
|
||||||
Version 1.53 2021-06-30
|
Version 1.53 2021-06-30
|
||||||
* process_action support action status
|
* process_action support action status
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ FAST_SHARED_OBJS = hash.lo chain.lo shared_func.lo ini_file_reader.lo \
|
||||||
multi_socket_client.lo skiplist_set.lo uniq_skiplist.lo \
|
multi_socket_client.lo skiplist_set.lo uniq_skiplist.lo \
|
||||||
json_parser.lo buffered_file_writer.lo server_id_func.lo \
|
json_parser.lo buffered_file_writer.lo server_id_func.lo \
|
||||||
fc_queue.lo sorted_queue.lo fc_memory.lo shared_buffer.lo \
|
fc_queue.lo sorted_queue.lo fc_memory.lo shared_buffer.lo \
|
||||||
thread_pool.lo array_allocator.lo
|
thread_pool.lo array_allocator.lo sorted_array.lo
|
||||||
|
|
||||||
FAST_STATIC_OBJS = hash.o chain.o shared_func.o ini_file_reader.o \
|
FAST_STATIC_OBJS = hash.o chain.o shared_func.o ini_file_reader.o \
|
||||||
logger.o sockopt.o base64.o sched_thread.o \
|
logger.o sockopt.o base64.o sched_thread.o \
|
||||||
|
|
@ -31,7 +31,7 @@ FAST_STATIC_OBJS = hash.o chain.o shared_func.o ini_file_reader.o \
|
||||||
multi_socket_client.o skiplist_set.o uniq_skiplist.o \
|
multi_socket_client.o skiplist_set.o uniq_skiplist.o \
|
||||||
json_parser.o buffered_file_writer.o server_id_func.o \
|
json_parser.o buffered_file_writer.o server_id_func.o \
|
||||||
fc_queue.o sorted_queue.o fc_memory.o shared_buffer.o \
|
fc_queue.o sorted_queue.o fc_memory.o shared_buffer.o \
|
||||||
thread_pool.o array_allocator.o
|
thread_pool.o array_allocator.o sorted_array.o
|
||||||
|
|
||||||
HEADER_FILES = common_define.h hash.h chain.h logger.h base64.h \
|
HEADER_FILES = common_define.h hash.h chain.h logger.h base64.h \
|
||||||
shared_func.h pthread_func.h ini_file_reader.h _os_define.h \
|
shared_func.h pthread_func.h ini_file_reader.h _os_define.h \
|
||||||
|
|
@ -46,7 +46,8 @@ HEADER_FILES = common_define.h hash.h chain.h logger.h base64.h \
|
||||||
multi_socket_client.h skiplist_set.h uniq_skiplist.h \
|
multi_socket_client.h skiplist_set.h uniq_skiplist.h \
|
||||||
fc_list.h locked_list.h json_parser.h buffered_file_writer.h \
|
fc_list.h locked_list.h json_parser.h buffered_file_writer.h \
|
||||||
server_id_func.h fc_queue.h sorted_queue.h fc_memory.h \
|
server_id_func.h fc_queue.h sorted_queue.h fc_memory.h \
|
||||||
shared_buffer.h thread_pool.h fc_atomic.h array_allocator.h
|
shared_buffer.h thread_pool.h fc_atomic.h array_allocator.h \
|
||||||
|
sorted_array.h
|
||||||
|
|
||||||
ALL_OBJS = $(FAST_STATIC_OBJS) $(FAST_SHARED_OBJS)
|
ALL_OBJS = $(FAST_STATIC_OBJS) $(FAST_SHARED_OBJS)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,3 +71,46 @@ VoidArray *array_allocator_alloc(ArrayAllocatorContext *ctx,
|
||||||
bytes = sizeof(VoidArray) + alloc * ctx->element_size;
|
bytes = sizeof(VoidArray) + alloc * ctx->element_size;
|
||||||
return (VoidArray *)fast_allocator_alloc(&ctx->allocator, bytes);
|
return (VoidArray *)fast_allocator_alloc(&ctx->allocator, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VoidArray *array_allocator_realloc(ArrayAllocatorContext *ctx,
|
||||||
|
VoidArray *old_array, const int target_count)
|
||||||
|
{
|
||||||
|
VoidArray *new_array;
|
||||||
|
|
||||||
|
if (old_array == NULL) {
|
||||||
|
return array_allocator_alloc(ctx, target_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_array->alloc >= target_count) {
|
||||||
|
return old_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((new_array=array_allocator_alloc(ctx, target_count)) != NULL) {
|
||||||
|
if (old_array->count > 0) {
|
||||||
|
memcpy(new_array->elts, old_array->elts, ctx->
|
||||||
|
element_size * old_array->count);
|
||||||
|
}
|
||||||
|
new_array->count = old_array->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_allocator_free(ctx, old_array);
|
||||||
|
return new_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
int array_compare_element_int64(const int64_t *n1, const int64_t *n2)
|
||||||
|
{
|
||||||
|
int64_t sub;
|
||||||
|
sub = *n1 - *n2;
|
||||||
|
if (sub < 0) {
|
||||||
|
return -1;
|
||||||
|
} else if (sub > 0) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int array_compare_element_int32(const int32_t *n1, const int32_t *n2)
|
||||||
|
{
|
||||||
|
return *n1 - *n2;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ typedef struct
|
||||||
int32_t elts[0];
|
int32_t elts[0];
|
||||||
} I32Array;
|
} I32Array;
|
||||||
|
|
||||||
typedef struct
|
typedef struct array_allocator_context
|
||||||
{
|
{
|
||||||
struct fast_allocator_context allocator;
|
struct fast_allocator_context allocator;
|
||||||
int element_size;
|
int element_size;
|
||||||
|
|
@ -57,6 +57,9 @@ extern "C" {
|
||||||
VoidArray *array_allocator_alloc(ArrayAllocatorContext *ctx,
|
VoidArray *array_allocator_alloc(ArrayAllocatorContext *ctx,
|
||||||
const int target_count);
|
const int target_count);
|
||||||
|
|
||||||
|
VoidArray *array_allocator_realloc(ArrayAllocatorContext *ctx,
|
||||||
|
VoidArray *old_array, const int target_count);
|
||||||
|
|
||||||
static inline void array_allocator_free(ArrayAllocatorContext *ctx,
|
static inline void array_allocator_free(ArrayAllocatorContext *ctx,
|
||||||
VoidArray *array)
|
VoidArray *array)
|
||||||
{
|
{
|
||||||
|
|
@ -64,6 +67,9 @@ extern "C" {
|
||||||
fast_allocator_free(&ctx->allocator, array);
|
fast_allocator_free(&ctx->allocator, array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int array_compare_element_int64(const int64_t *n1, const int64_t *n2);
|
||||||
|
|
||||||
|
int array_compare_element_int32(const int32_t *n1, const int32_t *n2);
|
||||||
|
|
||||||
#define i64_array_allocator_init(ctx, min_bits, max_bits) \
|
#define i64_array_allocator_init(ctx, min_bits, max_bits) \
|
||||||
array_allocator_init(ctx, "i64", sizeof(int64_t), min_bits, max_bits)
|
array_allocator_init(ctx, "i64", sizeof(int64_t), min_bits, max_bits)
|
||||||
|
|
@ -71,6 +77,9 @@ extern "C" {
|
||||||
#define i64_array_allocator_alloc(ctx, target_count) \
|
#define i64_array_allocator_alloc(ctx, target_count) \
|
||||||
(I64Array *)array_allocator_alloc(ctx, target_count)
|
(I64Array *)array_allocator_alloc(ctx, target_count)
|
||||||
|
|
||||||
|
#define i64_array_allocator_realloc(ctx, old_array, target_count) \
|
||||||
|
(I64Array *)array_allocator_realloc(ctx, (VoidArray *)old_array, target_count)
|
||||||
|
|
||||||
#define i64_array_allocator_free(ctx, array) \
|
#define i64_array_allocator_free(ctx, array) \
|
||||||
array_allocator_free(ctx, (VoidArray *)array)
|
array_allocator_free(ctx, (VoidArray *)array)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 YuQing <384681@qq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "sorted_array.h"
|
||||||
|
|
||||||
|
void sorted_array_init(SortedArrayContext *ctx,
|
||||||
|
const int element_size, const bool allow_duplicate,
|
||||||
|
int (*compare_func)(const void *, const void *))
|
||||||
|
{
|
||||||
|
ctx->element_size = element_size;
|
||||||
|
ctx->allow_duplicate = allow_duplicate;
|
||||||
|
ctx->compare_func = compare_func;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *sorted_array_bsearch(SortedArrayContext *ctx, void *base,
|
||||||
|
const int count, const void *element, int *insert_pos)
|
||||||
|
{
|
||||||
|
int low;
|
||||||
|
int high;
|
||||||
|
int mid;
|
||||||
|
int compr;
|
||||||
|
|
||||||
|
*insert_pos = 0;
|
||||||
|
low = 0;
|
||||||
|
high = count - 1;
|
||||||
|
while (low <= high) {
|
||||||
|
mid = (low + high) / 2;
|
||||||
|
compr = ctx->compare_func(base + mid, element);
|
||||||
|
if (compr < 0) {
|
||||||
|
low = mid + 1;
|
||||||
|
*insert_pos = low;
|
||||||
|
} else if (compr == 0) {
|
||||||
|
return base + mid;
|
||||||
|
} else {
|
||||||
|
high = mid - 1;
|
||||||
|
*insert_pos = mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sorted_array_insert(SortedArrayContext *ctx,
|
||||||
|
void *base, int *count, const void *element)
|
||||||
|
{
|
||||||
|
int insert_pos;
|
||||||
|
int move_count;
|
||||||
|
void *found;
|
||||||
|
void *end;
|
||||||
|
|
||||||
|
found = sorted_array_bsearch(ctx, base, *count, element, &insert_pos);
|
||||||
|
if (found != NULL) {
|
||||||
|
if (!ctx->allow_duplicate) {
|
||||||
|
return EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
found++;
|
||||||
|
end = base + *count;
|
||||||
|
while (found < end && ctx->compare_func(found, element) == 0) {
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
insert_pos = found - base;
|
||||||
|
}
|
||||||
|
|
||||||
|
move_count = *count - insert_pos;
|
||||||
|
if (move_count > 0) {
|
||||||
|
memmove(base + insert_pos + 1, base + insert_pos,
|
||||||
|
ctx->element_size * move_count);
|
||||||
|
}
|
||||||
|
memcpy(base + insert_pos, element, ctx->element_size);
|
||||||
|
(*count)++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sorted_array_delete(SortedArrayContext *ctx,
|
||||||
|
void *base, int *count, const void *element)
|
||||||
|
{
|
||||||
|
int move_count;
|
||||||
|
struct {
|
||||||
|
void *current;
|
||||||
|
void *start;
|
||||||
|
void *end;
|
||||||
|
} found;
|
||||||
|
void *array_end;
|
||||||
|
|
||||||
|
if ((found.current=bsearch(element, base, *count, ctx->element_size,
|
||||||
|
ctx->compare_func)) == NULL)
|
||||||
|
{
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_end = base + *count;
|
||||||
|
if (ctx->allow_duplicate) {
|
||||||
|
found.start = found.current;
|
||||||
|
while (found.start > base && ctx->compare_func(
|
||||||
|
found.start - 1, element) == 0)
|
||||||
|
{
|
||||||
|
found.start--;
|
||||||
|
}
|
||||||
|
|
||||||
|
found.end = ++found.current;
|
||||||
|
while (found.end < array_end && ctx->compare_func(
|
||||||
|
found.end, element) == 0)
|
||||||
|
{
|
||||||
|
found.end++;
|
||||||
|
}
|
||||||
|
*count -= found.end - found.start;
|
||||||
|
} else {
|
||||||
|
found.start = found.current;
|
||||||
|
found.end = found.start + 1;
|
||||||
|
(*count)--;
|
||||||
|
}
|
||||||
|
|
||||||
|
move_count = array_end - found.end;
|
||||||
|
if (move_count > 0) {
|
||||||
|
memmove(found.start, found.end, ctx->
|
||||||
|
element_size * move_count);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sorted_array_compare_int64(const int64_t *n1, const int64_t *n2)
|
||||||
|
{
|
||||||
|
int64_t sub;
|
||||||
|
sub = *n1 - *n2;
|
||||||
|
if (sub < 0) {
|
||||||
|
return -1;
|
||||||
|
} else if (sub > 0) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int sorted_array_compare_int32(const int32_t *n1, const int32_t *n2)
|
||||||
|
{
|
||||||
|
return *n1 - *n2;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 YuQing <384681@qq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SORTED_ARRAY_H
|
||||||
|
#define SORTED_ARRAY_H
|
||||||
|
|
||||||
|
#include "common_define.h"
|
||||||
|
|
||||||
|
typedef struct sorted_array_context
|
||||||
|
{
|
||||||
|
int element_size;
|
||||||
|
bool allow_duplicate;
|
||||||
|
int (*compare_func)(const void *, const void *);
|
||||||
|
} SortedArrayContext;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void sorted_array_init(SortedArrayContext *ctx,
|
||||||
|
const int element_size, const bool allow_duplicate,
|
||||||
|
int (*compare_func)(const void *, const void *));
|
||||||
|
|
||||||
|
int sorted_array_insert(SortedArrayContext *ctx,
|
||||||
|
void *base, int *count, const void *element);
|
||||||
|
|
||||||
|
int sorted_array_delete(SortedArrayContext *ctx,
|
||||||
|
void *base, int *count, const void *element);
|
||||||
|
|
||||||
|
int sorted_array_compare_int64(const int64_t *n1, const int64_t *n2);
|
||||||
|
|
||||||
|
int sorted_array_compare_int32(const int32_t *n1, const int32_t *n2);
|
||||||
|
|
||||||
|
|
||||||
|
#define sorted_i64_array_init(ctx, allow_duplicate) \
|
||||||
|
sorted_array_init(ctx, sizeof(int64_t), allow_duplicate, \
|
||||||
|
(int (*)(const void *, const void *))sorted_array_compare_int64)
|
||||||
|
|
||||||
|
#define sorted_i32_array_init(ctx, allow_duplicate) \
|
||||||
|
sorted_array_init(ctx, sizeof(int32_t), allow_duplicate, \
|
||||||
|
(int (*)(const void *, const void *))sorted_array_compare_int32)
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Reference in New Issue