add files: sorted_array.[hc]

pull/37/merge
YuQing 2021-09-13 11:18:45 +08:00
parent 81950ac246
commit 2993b34e80
6 changed files with 270 additions and 5 deletions

View File

@ -1,11 +1,12 @@
Version 1.54 2021-09-10
Version 1.54 2021-09-13
* fast_allocator.[hc]: correct reclaim_interval logic
* shared_func.[hc]: add functions getFileContentEx1 and getFileContent1
* fc_queue.[hc]: add function fc_queue_timedpeek
* pthread_func.[hc]: add function init_pthread_rwlock
* add files: sorted_queue.[hc]
* add files: array_allocator.[hc]
* add files: sorted_array.[hc]
Version 1.53 2021-06-30
* process_action support action status

View File

@ -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 \
json_parser.lo buffered_file_writer.lo server_id_func.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 \
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 \
json_parser.o buffered_file_writer.o server_id_func.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 \
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 \
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 \
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)

View File

@ -71,3 +71,46 @@ VoidArray *array_allocator_alloc(ArrayAllocatorContext *ctx,
bytes = sizeof(VoidArray) + alloc * ctx->element_size;
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;
}

View File

@ -39,7 +39,7 @@ typedef struct
int32_t elts[0];
} I32Array;
typedef struct
typedef struct array_allocator_context
{
struct fast_allocator_context allocator;
int element_size;
@ -57,6 +57,9 @@ extern "C" {
VoidArray *array_allocator_alloc(ArrayAllocatorContext *ctx,
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,
VoidArray *array)
{
@ -64,6 +67,9 @@ extern "C" {
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) \
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) \
(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) \
array_allocator_free(ctx, (VoidArray *)array)

151
src/sorted_array.c Normal file
View File

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

60
src/sorted_array.h Normal file
View File

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