diff --git a/HISTORY b/HISTORY
index ccf2fdb..e915ad3 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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
diff --git a/src/Makefile.in b/src/Makefile.in
index 0565c30..74a09fc 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -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)
diff --git a/src/array_allocator.c b/src/array_allocator.c
index 57dc2b7..9af926f 100644
--- a/src/array_allocator.c
+++ b/src/array_allocator.c
@@ -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;
+}
diff --git a/src/array_allocator.h b/src/array_allocator.h
index cc4946a..de6ff3a 100644
--- a/src/array_allocator.h
+++ b/src/array_allocator.h
@@ -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)
diff --git a/src/sorted_array.c b/src/sorted_array.c
new file mode 100644
index 0000000..bde4822
--- /dev/null
+++ b/src/sorted_array.c
@@ -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 .
+ */
+
+#include
+#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;
+}
diff --git a/src/sorted_array.h b/src/sorted_array.h
new file mode 100644
index 0000000..a2bb9e7
--- /dev/null
+++ b/src/sorted_array.h
@@ -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 .
+ */
+
+#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