From f5fa33611ff8159c6855460a9fd41b3a5faa2d04 Mon Sep 17 00:00:00 2001
From: YuQing <384681@qq.com>
Date: Fri, 10 Sep 2021 16:36:14 +0800
Subject: [PATCH] add files: array_allocator.[hc]
---
HISTORY | 3 +-
src/Makefile.in | 6 ++--
src/array_allocator.c | 73 ++++++++++++++++++++++++++++++++++++++
src/array_allocator.h | 82 +++++++++++++++++++++++++++++++++++++++++++
src/sorted_queue.h | 15 ++++++++
5 files changed, 175 insertions(+), 4 deletions(-)
create mode 100644 src/array_allocator.c
create mode 100644 src/array_allocator.h
diff --git a/HISTORY b/HISTORY
index fd1d280..ccf2fdb 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,10 +1,11 @@
-Version 1.54 2021-09-09
+Version 1.54 2021-09-10
* 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]
Version 1.53 2021-06-30
* process_action support action status
diff --git a/src/Makefile.in b/src/Makefile.in
index b651b44..0565c30 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
+ thread_pool.lo array_allocator.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
+ thread_pool.o array_allocator.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,7 @@ 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
+ shared_buffer.h thread_pool.h fc_atomic.h array_allocator.h
ALL_OBJS = $(FAST_STATIC_OBJS) $(FAST_SHARED_OBJS)
diff --git a/src/array_allocator.c b/src/array_allocator.c
new file mode 100644
index 0000000..57dc2b7
--- /dev/null
+++ b/src/array_allocator.c
@@ -0,0 +1,73 @@
+/*
+ * 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 "shared_func.h"
+#include "array_allocator.h"
+
+int array_allocator_init(ArrayAllocatorContext *ctx,
+ const char *name_prefix, const int element_size,
+ const int min_bits, const int max_bits)
+{
+ const int reclaim_interval = 0;
+ char name[32];
+ struct fast_region_info regions[32];
+ struct fast_region_info *region;
+ int bit;
+ int start;
+ int end;
+ int alloc_elements_once;
+ int step;
+
+ ctx->element_size = element_size;
+ ctx->min_count = (1 << min_bits);
+ start = 0;
+ alloc_elements_once = (1 << (max_bits - min_bits + 2));
+ for (bit=min_bits, region=regions;
+ bit<=max_bits; bit++, region++)
+ {
+ end = sizeof(VoidArray) + (1 << bit) * ctx->element_size;
+ step = end - start;
+ FAST_ALLOCATOR_INIT_REGION(*region, start,
+ end, step, alloc_elements_once);
+ alloc_elements_once /= 2;
+ start = end;
+ }
+
+ snprintf(name, sizeof(name), "%s-array", name_prefix);
+ return fast_allocator_init_ex(&ctx->allocator,
+ name, regions, region - regions, 0,
+ 0.9999, reclaim_interval, true);
+}
+
+VoidArray *array_allocator_alloc(ArrayAllocatorContext *ctx,
+ const int target_count)
+{
+ int alloc;
+ int bytes;
+
+ if (target_count <= ctx->min_count) {
+ alloc = ctx->min_count;
+ } else if (is_power2(target_count)) {
+ alloc = target_count;
+ } else {
+ alloc = ctx->min_count;
+ while (alloc < target_count) {
+ alloc *= 2;
+ }
+ }
+
+ bytes = sizeof(VoidArray) + alloc * ctx->element_size;
+ return (VoidArray *)fast_allocator_alloc(&ctx->allocator, bytes);
+}
diff --git a/src/array_allocator.h b/src/array_allocator.h
new file mode 100644
index 0000000..cc4946a
--- /dev/null
+++ b/src/array_allocator.h
@@ -0,0 +1,82 @@
+/*
+ * 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 ARRAY_ALLOCATOR_H
+#define ARRAY_ALLOCATOR_H
+
+#include "fast_allocator.h"
+
+typedef struct
+{
+ int alloc;
+ int count;
+ char elts[0];
+} VoidArray;
+
+typedef struct
+{
+ int alloc;
+ int count;
+ int64_t elts[0];
+} I64Array;
+
+typedef struct
+{
+ int alloc;
+ int count;
+ int32_t elts[0];
+} I32Array;
+
+typedef struct
+{
+ struct fast_allocator_context allocator;
+ int element_size;
+ int min_count;
+} ArrayAllocatorContext;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ int array_allocator_init(ArrayAllocatorContext *ctx,
+ const char *name_prefix, const int element_size,
+ const int min_bits, const int max_bits);
+
+ VoidArray *array_allocator_alloc(ArrayAllocatorContext *ctx,
+ const int target_count);
+
+ static inline void array_allocator_free(ArrayAllocatorContext *ctx,
+ VoidArray *array)
+ {
+ array->count = 0;
+ fast_allocator_free(&ctx->allocator, array);
+ }
+
+
+#define i64_array_allocator_init(ctx, min_bits, max_bits) \
+ array_allocator_init(ctx, "i64", sizeof(int64_t), min_bits, max_bits)
+
+#define i64_array_allocator_alloc(ctx, target_count) \
+ (I64Array *)array_allocator_alloc(ctx, target_count)
+
+#define i64_array_allocator_free(ctx, array) \
+ array_allocator_free(ctx, (VoidArray *)array)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/sorted_queue.h b/src/sorted_queue.h
index 5f997dc..f9e1e88 100644
--- a/src/sorted_queue.h
+++ b/src/sorted_queue.h
@@ -89,6 +89,21 @@ static inline bool sorted_queue_empty(struct sorted_queue *sq)
return fc_queue_empty(&sq->queue);
}
+static inline void *sorted_queue_timedpeek(struct sorted_queue *sq,
+ const int timeout, const int time_unit)
+{
+ return fc_queue_timedpeek(&sq->queue, timeout, time_unit);
+}
+
+#define sorted_queue_timedpeek_sec(sq, timeout) \
+ sorted_queue_timedpeek(sq, timeout, FC_TIME_UNIT_SECOND)
+
+#define sorted_queue_timedpeek_ms(sq, timeout_ms) \
+ sorted_queue_timedpeek(sq, timeout_ms, FC_TIME_UNIT_MSECOND)
+
+#define sorted_queue_timedpeek_us(sq, timeout_us) \
+ sorted_queue_timedpeek(sq, timeout_us, FC_TIME_UNIT_USECOND)
+
#ifdef __cplusplus
}
#endif