summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlijia <[email protected]>2024-06-07 02:07:14 +0800
committeryangwei <[email protected]>2024-06-07 02:07:14 +0800
commitf82a8875043eaa55dd11cc41308d99b024bde706 (patch)
treeca2d1f2f8fe987f8f443295c812696b7e596c0dc
parentd735864a21bec48f8e8083b5ba6c36a389c57bca (diff)
add bloom fs4 statistics, add gtest user args.
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--include/private/sapp_pkt_stat.h8
-rw-r--r--module_test/src/CMakeLists.txt17
-rw-r--r--module_test/src/gtest_main.cpp13
-rw-r--r--module_test/src/gtest_sapp_bloom.cpp180
-rw-r--r--module_test/src/gtest_sapp_fun.h2
-rw-r--r--src/common/sapp_mem.c4
-rw-r--r--src/dealpkt/duplicate_pkt_distinguish.c113
-rw-r--r--src/extensions/sapp_metrics.cpp18
-rw-r--r--src/support/ap_bloom/src/ap_bloom.c175
-rw-r--r--src/support/ap_bloom/src/ap_bloom.h7
-rwxr-xr-xsrc/support/dablooms/src/dablooms.c91
-rwxr-xr-xsrc/support/dablooms/src/dablooms.h13
13 files changed, 548 insertions, 95 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4b78e5e..aca925c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -8,7 +8,7 @@ variables:
libMESA_handle_logger-devel libbreakpad_mini-devel
libMESA_jump_layer-devel libfieldstat3-devel
libMESA_htable libMESA_prof_load libMESA_field_stat2 libMESA_handle_logger
- libcjson libbreakpad_mini libMESA_jump_layer libfieldstat3
+ libcjson libbreakpad_mini libMESA_jump_layer libfieldstat3 libfieldstat4 libfieldstat4-devel
mrzcpd-corei7 hasp-tools libuuid-devel
SYMBOL_TARGET: sapp
TEST_NAME: gtest_sapp_v4
diff --git a/include/private/sapp_pkt_stat.h b/include/private/sapp_pkt_stat.h
index 358d0a8..417ab66 100644
--- a/include/private/sapp_pkt_stat.h
+++ b/include/private/sapp_pkt_stat.h
@@ -202,6 +202,14 @@ typedef enum __sapp_sys_stat_type{
/************* memory stat *******************/
+ /************* bloom filter stat *******************/
+ SAPP_STAT_BM_HASH_NUM,
+ SAPP_STAT_BM_EXPAND_NUM,
+ SAPP_STAT_BM_SLICE_NUM_NEW,
+ SAPP_STAT_BM_SLICE_NUM_FREE,
+ SAPP_STAT_BM_CUR_SLICE_NUM,
+ SAPP_STAT_APBM_EXPAND_MAX_MULTIPLE,
+ SAPP_STAT_DABM_RESIZE_MAX_RATIO,
/************** Maximum Value Definition *******/
SAPP_STAT_NUM_MAX,
}sapp_sys_stat_type_t;
diff --git a/module_test/src/CMakeLists.txt b/module_test/src/CMakeLists.txt
index d041dad..6918cd0 100644
--- a/module_test/src/CMakeLists.txt
+++ b/module_test/src/CMakeLists.txt
@@ -13,12 +13,27 @@ include_directories(${PROJECT_SOURCE_DIR}/src/support/ap_bloom/src)
add_definitions(-DSAPP_V4=1)
add_definitions(-fPIC)
+if(MEM_POOL STREQUAL "TCMALLOC_MINI")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ltcmalloc_minimal -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free")
+ add_definitions(-DUSE_TCMALLOC=1)
+elseif(MEM_POOL STREQUAL "TCMALLOC")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ltcmalloc -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free")
+ add_definitions(-DUSE_TCMALLOC=1)
+elseif(MEM_POOL STREQUAL "JEMALLOC")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ljemalloc -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free")
+ add_definitions(-DUSE_JEMALLOC=1)
+elseif(MEM_POOL STREQUAL "JEMALLOC_STATIC")
+ add_definitions(-DUSE_JEMALLOC=1)
+elseif(MEM_POOL STREQUAL "MIMALLOC")
+ add_definitions(-DUSE_MIMALLOC=1)
+endif()
+
add_executable(gtest_sapp_v4 gtest_main.cpp gtest_sapp_ipv4.cpp gtest_sapp_ipv6.cpp gtest_sapp_tcp.cpp gtest_sapp_udp.cpp gtest_sapp_comm.cpp gtest_sapp_support.cpp gtest_sapp_plug_ctrl.cpp gtest_sapp_tunnel.cpp
gtest_transparent_run.cpp gtest_sapp_jump_layer.cpp gtest_inline_run.cpp gtest_sapp_asymmetric.cpp gtest_sapp_inject.cpp gtest_sapp_app_state.cpp
gtest_mpls.cpp gtest_vlan.cpp gtest_fake_marsio_run.cpp gtest_sapp_proxy.cpp gtest_sapp_pkt_dump.cpp
../test_case/auto_gen_test_functions.cpp ../test_case/test_function_common.cpp gtest_sapp_bloom.cpp)
-target_link_libraries(gtest_sapp_v4 gtest-static ${SAPP_DEPEND_DYN_LIB} sapp_benchmark sapp_devel libdabloom)
+target_link_libraries(gtest_sapp_v4 gtest-static ${SAPP_DEPEND_DYN_LIB} sapp_benchmark sapp_devel libdabloom fieldstat4)
add_executable(transparent_test_sapp_v4 gtest_transparent_env.cpp gtest_sapp_comm.cpp)
target_link_libraries(transparent_test_sapp_v4 pthread pcap m dl MESA_jump_layer MESA_handle_logger)
diff --git a/module_test/src/gtest_main.cpp b/module_test/src/gtest_main.cpp
index 6c0e475..bea1365 100644
--- a/module_test/src/gtest_main.cpp
+++ b/module_test/src/gtest_main.cpp
@@ -21,6 +21,7 @@
void *g_sapp_test_log_handle;
int g_slient_mode = 0;
+const char *user_define_args;
const char *for_test_sapp_version = "4.2.68_c9193fe";
@@ -2215,15 +2216,15 @@ TEST(performance, simple)
TEST(dabloom, simple)
{
- ASSERT_EQ(0, sapp_bloom_filter_test_run(BLOOM_LIBRARY_DABLOOM));
+ ASSERT_EQ(0, sapp_bloom_filter_test_run(BLOOM_LIBRARY_DABLOOM, user_define_args));
}
TEST(apbloom, simple)
{
- ASSERT_EQ(0, sapp_bloom_filter_test_run(BLOOM_LIBRARY_APBLOOM));
+ ASSERT_EQ(0, sapp_bloom_filter_test_run(BLOOM_LIBRARY_APBLOOM, user_define_args));
}
-static const char *gtest_cla_short_options = "hvLsf:l:";
+static const char *gtest_cla_short_options = "hvLsf:l:u:";
static const struct option gtest_cla_long_options[] =
{
@@ -2233,6 +2234,7 @@ static const struct option gtest_cla_long_options[] =
{"gtest_list_tests", no_argument, NULL, 'L'},
{"gtest_filter", required_argument, NULL, 'f'},
{"slient", no_argument, NULL, 's'},
+ {"user-define", required_argument, NULL, 'u'},
{NULL, 0, NULL, 0}
};
@@ -2247,6 +2249,7 @@ static void usage(int argc, char *argv[])
printf("\t%s -s \t--slient\n", argv[0]);
printf("\t%s -f \t--gtest_filter=tcp.simple\n", argv[0]);
printf("\t%s -f \t--gtest_filter=tcp*\n", argv[0]);
+ printf("\t%s -f \t--gtest_filter=apbloom.simple -u \"capacity=2500000,error_rate=0.000001\"\n", argv[0]);
exit(0);
}
@@ -2296,6 +2299,10 @@ int main(int argc, char *argv[])
g_slient_mode = 1;
break;
+ case 'u':
+ user_define_args = optarg;
+ break;
+
case '?': /* invalid or unknown option */
return -1;
break;
diff --git a/module_test/src/gtest_sapp_bloom.cpp b/module_test/src/gtest_sapp_bloom.cpp
index 4c4da87..4416eb9 100644
--- a/module_test/src/gtest_sapp_bloom.cpp
+++ b/module_test/src/gtest_sapp_bloom.cpp
@@ -24,8 +24,9 @@
#include <time.h>
#include <pthread.h>
#include "dablooms.h"
+#include "ap_bloom.h"
#include "sapp_global_val.h"
-
+#include "fieldstat/fieldstat_easy.h"
#ifdef __cplusplus
extern "C"
{
@@ -34,18 +35,21 @@ extern "C"
void *bloom_new(const sapp_dup_pkt_t *dup_conf, struct timeval now, long now_ms);
int bloom_check(void *bloom_filter, const char *key, int key_len, const sapp_dup_pkt_t *dup_conf, struct timeval now, long now_ms);
void bloom_add(void *bloom_filter, const char *key, int key_len, const sapp_dup_pkt_t *dup_conf, struct timeval now, long now_ms);
+ int DA_bloomfilter_get_stat(const struct expiry_dablooms_handle *bloom, sapp_sys_stat_type_t type, long long *count);
+ int AP_bloomfilter_get_stat(const struct AP_bloom *bloom, sapp_sys_stat_type_t type, long long *count);
#ifdef __cplusplus
}
#endif
-static const unsigned int BM_CAPACITY = 200000;
-static const double BM_ERROR_RATE = 0.000001;
-static const int BM_TIMEOUT = 10 * 1000; // ms
-static const int BM_PARTITION_NUM = 64;
-static const long BM_TRANSITION_TIME = 2 * 1000;
-
-static const int MAX_ITEM_NUM = 10000000;
-static const int ITEM_BATCH_NUM = 1000;
+static int BM_LIBRARY = BLOOM_LIBRARY_DABLOOM;
+static unsigned int BM_CAPACITY = 10000000;
+static double BM_ERROR_RATE = 0.000001;
+static int BM_TIMEOUT = 10 * 1000; // ms
+static int BM_PARTITION_NUM = 1;
+static long BM_TRANSITION_TIME = 2 * 1000;
+static int MAX_ITEM_NUM = 10000000;
+static int ITEM_BATCH_NUM = 1000;
+static int APBM_SLICE_NUM = 0;
#define TUPLE4_ADDR_LEN (12 + 1) // sizeof(tuple4) add begin char 'Y' or 'N'
#define BM_TEST_MAX_THREAD (1)
static pthread_t bm_test_thread_id[BM_TEST_MAX_THREAD];
@@ -60,6 +64,11 @@ static const unsigned int INIT_DIP = 0x87654321;
static const unsigned short INIT_SPORT = 0x1234;
static const unsigned short INIT_DPORT = 0x4321;
+static struct fieldstat_easy *fs4_instance;
+static struct fieldstat_tag FS4_HISGRAM_TAG = {"bm_test", TAG_INTEGER , 0};
+static int fs4_add_metric_id, fs4_check_true_metric_id, fs4_check_false_metric_id;
+static int fs4_expand_num_metric_id, fs4_slice_new_metric_id, fs4_slice_free_metric_id;
+
static inline void bm_update_key(char *tuple4_buf, unsigned int index)
{
unsigned int *p_sip = (unsigned int *)&tuple4_buf[1];
@@ -81,14 +90,14 @@ static unsigned long long total_search_time = 0; // us
// for test, only support one thread
static struct timespec start_time, end_time;
-// return us
+// return ns
static inline unsigned long long bm_time_diff(const struct timespec *start_time, const struct timespec *end_time)
{
if (start_time->tv_sec == end_time->tv_sec)
{
- return (unsigned long long)(end_time->tv_nsec - start_time->tv_nsec) / 1000;
+ return (unsigned long long)(end_time->tv_nsec - start_time->tv_nsec);
}
- return ((unsigned long long)end_time->tv_sec * 1000000 + end_time->tv_nsec / 1000) - ((unsigned long long)start_time->tv_sec * 1000000 + start_time->tv_nsec / 1000);
+ return ((unsigned long long)end_time->tv_sec * 1000 * 1000 * 1000 + end_time->tv_nsec) - ((unsigned long long)start_time->tv_sec * 1000 *1000 *1000 + start_time->tv_nsec);
}
static void bm_add_item(void *bloom_filter, char *tuple4_buf, unsigned int index, const sapp_dup_pkt_t *dup_conf)
@@ -106,9 +115,10 @@ static void bm_add_item(void *bloom_filter, char *tuple4_buf, unsigned int index
max_add_time = time_diff;
}
total_add_time += (unsigned long long)time_diff;
+ fieldstat_easy_histogram_record(fs4_instance, 0, fs4_add_metric_id, &FS4_HISGRAM_TAG, 1, time_diff);
}
-static int bm_search_item(void *bloom_filter, char *tuple4_buf, unsigned int index, const sapp_dup_pkt_t *dup_conf)
+static int bm_search_item(void *bloom_filter, char *tuple4_buf, unsigned int index, const sapp_dup_pkt_t *dup_conf, int fs4_metric_id)
{
bm_update_key(tuple4_buf, index);
clock_gettime(CLOCK_REALTIME, &start_time);
@@ -122,16 +132,39 @@ static int bm_search_item(void *bloom_filter, char *tuple4_buf, unsigned int ind
max_search_time = time_diff;
}
total_search_time += (unsigned long long)time_diff;
+ fieldstat_easy_histogram_record(fs4_instance, 0, fs4_metric_id, &FS4_HISGRAM_TAG, 1, time_diff);
return ret;
}
-static int bm_test(int bloom_type)
+static void fieldstat_update(void *bm_handle)
+{
+ static long long history_expand_num = 0, history_slice_new_num = 0, history_slice_free_num = 0;
+ long long expand_num = 0, slice_new_num = 0, slice_free_num = 0;
+ if(BM_LIBRARY == BLOOM_LIBRARY_DABLOOM){
+ DA_bloomfilter_get_stat((const expiry_dablooms_handle *)bm_handle, SAPP_STAT_BM_EXPAND_NUM, &expand_num);
+ DA_bloomfilter_get_stat((const expiry_dablooms_handle *)bm_handle, SAPP_STAT_BM_SLICE_NUM_NEW, &slice_new_num);
+ DA_bloomfilter_get_stat((const expiry_dablooms_handle *)bm_handle, SAPP_STAT_BM_SLICE_NUM_FREE, &slice_free_num);
+
+ }else{
+ AP_bloomfilter_get_stat((const AP_bloom*)bm_handle, SAPP_STAT_BM_EXPAND_NUM, &expand_num);
+ AP_bloomfilter_get_stat((const AP_bloom *)bm_handle, SAPP_STAT_BM_SLICE_NUM_NEW, &slice_new_num);
+ AP_bloomfilter_get_stat((const AP_bloom *)bm_handle, SAPP_STAT_BM_SLICE_NUM_FREE, &slice_free_num);
+ }
+ fieldstat_easy_counter_incrby(fs4_instance, 0, fs4_expand_num_metric_id, &FS4_HISGRAM_TAG, 1, expand_num-history_expand_num);
+ fieldstat_easy_counter_incrby(fs4_instance, 0, fs4_slice_new_metric_id, &FS4_HISGRAM_TAG, 1, slice_new_num-history_slice_new_num);
+ fieldstat_easy_counter_incrby(fs4_instance, 0, fs4_slice_free_metric_id, &FS4_HISGRAM_TAG, 1, slice_free_num-history_slice_free_num);
+ history_expand_num = expand_num;
+ history_slice_new_num = slice_new_num;
+ history_slice_free_num = slice_free_num;
+}
+
+static int bm_test()
{
sapp_dup_pkt_t dup_conf = {};
dup_conf.bloom_capacity = BM_CAPACITY;
dup_conf.bloom_error_rate = BM_ERROR_RATE;
dup_conf.bloom_timeout_ms = BM_TIMEOUT;
- dup_conf.bloom_library = (enum bloom_library)bloom_type;
+ dup_conf.bloom_library = (enum bloom_library)BM_LIBRARY;
dup_conf.kickout_udp_stream_enabled = 1;
dup_conf.dup_pkt_distinguish_all_inject = 1;
dup_conf.dup_pkt_distinguish_ipv4_tcp = 1;
@@ -139,6 +172,16 @@ static int bm_test(int bloom_type)
dup_conf.bloom_partition_num = BM_PARTITION_NUM;
dup_conf.transition_time_ms = BM_TRANSITION_TIME;
+ fs4_instance = fieldstat_easy_new(1, "bm-test", NULL, 0);
+ fieldstat_easy_enable_auto_output(fs4_instance, "./bm_gtest_fs4.json", 1);
+ // fieldstat_easy_enable_delta_in_active_output(fs4_instance);
+ fs4_add_metric_id = fieldstat_easy_register_histogram(fs4_instance, "add", 1, 99999999, 5);
+ fs4_check_true_metric_id = fieldstat_easy_register_histogram(fs4_instance, "chk_true", 1, 99999999, 5);
+ fs4_check_false_metric_id = fieldstat_easy_register_histogram(fs4_instance, "chk_false", 1, 99999999, 5);
+ fs4_expand_num_metric_id = fieldstat_easy_register_counter(fs4_instance, "bm_expand_num");
+ fs4_slice_new_metric_id = fieldstat_easy_register_counter(fs4_instance, "bm_slice_new");
+ fs4_slice_free_metric_id = fieldstat_easy_register_counter(fs4_instance, "bm_slice_free");
+
void *dabm_handle = bloom_new(&dup_conf, g_current_time_tv, g_current_time_in_ms);
assert(dabm_handle);
char tuple4_buf[1024] = {};
@@ -159,8 +202,8 @@ static int bm_test(int bloom_type)
return -1;
}
- printf("starting test, capacity:%u, timeout:%dms, partition:%d, batch_num:%d, max-items:%d\n",
- BM_CAPACITY, BM_TIMEOUT, BM_PARTITION_NUM, ITEM_BATCH_NUM, MAX_ITEM_NUM);
+ printf("starting test, capacity:%u, timeout:%dms, partition:%d, slice_num:%d, batch_num:%d, max-items:%d\n",
+ BM_CAPACITY, BM_TIMEOUT, BM_PARTITION_NUM, APBM_SLICE_NUM, ITEM_BATCH_NUM, MAX_ITEM_NUM);
int ret;
int add_index = 0, search_index_y = 0, search_index_n = 0;
while (add_index < MAX_ITEM_NUM || search_index_y < MAX_ITEM_NUM || search_index_n < MAX_ITEM_NUM)
@@ -174,7 +217,7 @@ static int bm_test(int bloom_type)
tuple4_buf[0] = 'Y';
for (int b = 0; b < ITEM_BATCH_NUM && search_index_y < MAX_ITEM_NUM; b++, search_index_y++)
{
- ret = bm_search_item(dabm_handle, tuple4_buf, search_index_y, &dup_conf);
+ ret = bm_search_item(dabm_handle, tuple4_buf, search_index_y, &dup_conf, fs4_check_true_metric_id);
if (ret <= 0) // expect exist
{
search_y_error_num++;
@@ -184,18 +227,20 @@ static int bm_test(int bloom_type)
tuple4_buf[0] = 'N';
for (int b = 0; b < ITEM_BATCH_NUM && search_index_n < MAX_ITEM_NUM; b++, search_index_n++)
{
- ret = bm_search_item(dabm_handle, tuple4_buf, search_index_n, &dup_conf);
+ ret = bm_search_item(dabm_handle, tuple4_buf, search_index_n, &dup_conf, fs4_check_false_metric_id);
if (ret > 0) // expect not exist
{
search_n_error_num++;
}
}
+
+ fieldstat_update(dabm_handle);
}
- printf("add %lld items success, avg-time:%.3fus, max:%lluus\n",
+ printf("add %lld items success, avg-time:%.3fns, max:%lluns\n",
(long long)MAX_ITEM_NUM, (double)total_add_time / (double)MAX_ITEM_NUM, max_add_time);
- printf("search %lld items , avg-time:%.3fus, max:%lluus\n",
+ printf("search %lld items , avg-time:%.3fns, max:%lluns\n",
(long long)MAX_ITEM_NUM, (double)total_search_time / (double)MAX_ITEM_NUM, max_search_time);
double err_rate = (double)search_n_error_num / (double)MAX_ITEM_NUM;
@@ -203,14 +248,15 @@ static int bm_test(int bloom_type)
search_y_error_num, search_n_error_num, err_rate);
bloom_free(dabm_handle, &dup_conf);
+ sleep(2); //wait fs4 output
+ fieldstat_easy_free(fs4_instance);
return search_y_error_num + (err_rate > (double)BM_ERROR_RATE);
}
static void *bm_test_thread(void *arg)
{
- int bloom = (int)(long)arg;
- if (bm_test(bloom) != 0)
+ if (bm_test() != 0)
{
return (void *)"error";
}
@@ -241,21 +287,103 @@ static void *timer_thread(void *arg)
return NULL;
}
-int sapp_bloom_filter_test_run(int bloom)
+static void bm_test_usage(void)
+{
+ printf("BM test usage:\n");
+ printf("\tlibrary=[dabloom,apbloom]\n");
+ printf("\tcapacity=2500000\n");
+ printf("\terror_rate=0.000001\n");
+ printf("\ttimeout=10000\n");
+ printf("\tmax_item_num=10000000\n");
+ printf("\titem_batch_num=1000\n");
+ printf("\tpartition=1\n");
+ printf("\tslice_num=1\n");
+ printf("\texample: ./gtest_sapp -f=apbloom.simple -u=\"capacity=100000,error_rate=0.000001,partition=1,timeout=10000,slice_num=3,max_item_num=100000,item_batch_num=1000\"\n");
+ printf("\n");
+}
+
+static int convert_user_args(const char *user_args)
+{
+ if (user_args == NULL)
+ {
+ return 0;
+ }
+ if(strstr(user_args, "-h") ){
+ bm_test_usage();
+ exit(0);
+ }
+ if(strstr(user_args, "--help") ){
+ bm_test_usage();
+ exit(0);
+ }
+
+ char *tmp_args = strdup(user_args);
+ char *saveptr = NULL;
+ char *token = strtok_r(tmp_args, ",", &saveptr);
+ while (token)
+ {
+ char *key = strtok(token, "=");
+ char *value = strtok(NULL, "=");
+ if (key && value)
+ {
+ if (strcmp(key, "capacity") == 0)
+ {
+ BM_CAPACITY = (unsigned int )strtoull(value, NULL, 10);
+ }
+ else if (strcmp(key, "error_rate") == 0)
+ {
+ BM_ERROR_RATE = strtod(value, NULL);
+ }
+ else if (strcmp(key, "partition") == 0)
+ {
+ BM_PARTITION_NUM = atoi(value);
+ }
+ else if (strcmp(key, "timeout") == 0)
+ {
+ BM_TIMEOUT = atoi(value);
+ }
+ else if (strcmp(key, "max_item_num") == 0)
+ {
+ MAX_ITEM_NUM = (unsigned int )strtoull(value, NULL, 10);
+ }
+ else if (strcmp(key, "item_batch_num") == 0)
+ {
+ ITEM_BATCH_NUM = atoi(value);
+ }
+ else if (strcmp(key, "slice_num") == 0)
+ {
+ APBM_SLICE_NUM = atoi(value);
+ }
+ else{
+ fprintf(stderr, "unknown args: %s=%s\n", key, value);
+ }
+ }
+ token = strtok_r(NULL, ",", &saveptr);
+ }
+ free(tmp_args);
+
+ return 0;
+}
+
+int sapp_bloom_filter_test_run(int bm_liarary, const char *user_define_args)
{
int ret = 0;
+
+ BM_LIBRARY = bm_liarary;
+ convert_user_args(user_define_args);
+
pthread_create(&timer_thread_id, NULL, timer_thread, NULL);
for (int i = 0; i < BM_TEST_MAX_THREAD; i++)
{
- pthread_create(&bm_test_thread_id[i], NULL, bm_test_thread, (void *)(long)bloom);
+ pthread_create(&bm_test_thread_id[i], NULL, bm_test_thread, NULL);
}
void *thread_result;
for (int i = 0; i < BM_TEST_MAX_THREAD; i++)
{
pthread_join(bm_test_thread_id[i], &thread_result);
- if (thread_result != "success")
+ if (strcmp((char *)thread_result, "success") != 0)
{
printf("thread %d test failed\n", i);
ret = -1;
diff --git a/module_test/src/gtest_sapp_fun.h b/module_test/src/gtest_sapp_fun.h
index b40932c..473eb6d 100644
--- a/module_test/src/gtest_sapp_fun.h
+++ b/module_test/src/gtest_sapp_fun.h
@@ -569,7 +569,7 @@ void sapp_deal_proxy_kill_tcp_run(void);
/**************************** pkt_dump *************************************/
int test_pkt_dump_run(void);
-int sapp_bloom_filter_test_run(int);
+int sapp_bloom_filter_test_run(int bm_lib, const char *args);
void append_entry_list(const char *entryname);
int check_sapp_version(void);
diff --git a/src/common/sapp_mem.c b/src/common/sapp_mem.c
index aeb6b36..0b1395b 100644
--- a/src/common/sapp_mem.c
+++ b/src/common/sapp_mem.c
@@ -288,7 +288,7 @@ void sapp_mem_stat_output(void)
fclose(fp);
}
-char bloomfilter_mem_stat_polling_entry(struct streaminfo *nouse1, void **nouse2, int thread_seq, void *nouse3)
+char bloomfilter_stat_polling_entry(struct streaminfo *nouse1, void **nouse2, int thread_seq, void *nouse3)
{
static time_t last_get_time[SAPP_MAX_THREADS] = {};
@@ -314,7 +314,7 @@ int sapp_mem_init(void)
|| sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_ipv4_udp
|| sapp_global_val->config.packet_io.dup_pkt_para.dup_pkt_distinguish_all_inject)
{
- stream_register_fun(FUN_TYPE_POLLING, (char (*)(void))bloomfilter_mem_stat_polling_entry, 0);
+ stream_register_fun(FUN_TYPE_POLLING, (char (*)(void))bloomfilter_stat_polling_entry, 0);
}
return 0;
}
diff --git a/src/dealpkt/duplicate_pkt_distinguish.c b/src/dealpkt/duplicate_pkt_distinguish.c
index 820642d..1b93f99 100644
--- a/src/dealpkt/duplicate_pkt_distinguish.c
+++ b/src/dealpkt/duplicate_pkt_distinguish.c
@@ -86,6 +86,110 @@ void bloom_add(void *bloom_filter, const char *key, int key_len, const sapp_dup_
return;
}
+int AP_bloomfilter_get_stat(const struct AP_bloom *bloom, sapp_sys_stat_type_t type, long long *count)
+{
+ switch(type){
+ case SAPP_STAT_BM_HASH_NUM:
+ *count = (long long)AP_bloom_stat_get_hash_num(bloom);
+ break;
+ case SAPP_STAT_BM_SLICE_NUM_NEW:
+ *count = (long long)AP_bloom_stat_get_new_num(bloom);
+ break;
+ case SAPP_STAT_BM_SLICE_NUM_FREE:
+ *count = (long long)AP_bloom_stat_get_free_num(bloom);
+ break;
+ case SAPP_STAT_BM_EXPAND_NUM:
+ *count = (long long)AP_bloom_stat_get_expand_num(bloom);
+ break;
+ case SAPP_STAT_BM_CUR_SLICE_NUM:
+ *count = (long long)AP_bloom_stat_get_cur_slice_num(bloom);
+ break;
+ case SAPP_STAT_APBM_EXPAND_MAX_MULTIPLE:
+ *count = (long long)AP_bloom_stat_get_expand_max_multiple(bloom);
+ break;
+
+ default:
+ *count = 0;
+ break;
+ }
+ return 0;
+}
+
+int DA_bloomfilter_get_stat(const struct expiry_dablooms_handle *bloom, sapp_sys_stat_type_t type, long long *count)
+{
+ switch(type){
+ case SAPP_STAT_BM_HASH_NUM:
+ *count = (long long)DA_bloom_stat_get_hash_num(bloom);
+ break;
+ case SAPP_STAT_BM_SLICE_NUM_NEW:
+ *count = (long long)DA_bloom_stat_get_slice_new_num(bloom);
+ break;
+ case SAPP_STAT_BM_SLICE_NUM_FREE:
+ *count = (long long)DA_bloom_stat_get_slice_free_num(bloom);
+ break;
+ case SAPP_STAT_BM_EXPAND_NUM:
+ *count = (long long)DA_bloom_stat_get_expand_num(bloom);
+ break;
+ case SAPP_STAT_BM_CUR_SLICE_NUM:
+ *count = (long long)DA_bloom_stat_get_cur_slice_num(bloom);
+ break;
+ case SAPP_STAT_DABM_RESIZE_MAX_RATIO:
+ *count = (long long)DA_bloom_stat_get_resize_ratio(bloom);
+ break;
+
+ default:
+ *count = 0;
+ break;
+ }
+ return 0;
+}
+
+int bloomfilter_get_stat_by_type(void *bm_handle, sapp_sys_stat_type_t type, long long *count)
+{
+
+ switch (sapp_global_val->config.packet_io.dup_pkt_para.bloom_library)
+ {
+ case BLOOM_LIBRARY_APBLOOM:
+ AP_bloomfilter_get_stat((const struct AP_bloom *)bm_handle, type, count);
+ break;
+
+ case BLOOM_LIBRARY_DABLOOM:
+ DA_bloomfilter_get_stat((struct expiry_dablooms_handle *)bm_handle, type, count);
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int bloomfilter_get_stat(void *bm_handle)
+{
+ long long count = 0;
+ bloomfilter_get_stat_by_type(bm_handle, SAPP_STAT_BM_HASH_NUM, &count);
+ sapp_fs3_metric_set(0, SAPP_STAT_BM_HASH_NUM, count);
+ count = 0;
+ bloomfilter_get_stat_by_type(bm_handle, SAPP_STAT_BM_EXPAND_NUM, &count);
+ sapp_fs3_metric_set(0, SAPP_STAT_BM_EXPAND_NUM, count);
+ count = 0;
+ bloomfilter_get_stat_by_type(bm_handle, SAPP_STAT_BM_SLICE_NUM_NEW, &count);
+ sapp_fs3_metric_set(0, SAPP_STAT_BM_SLICE_NUM_NEW, count);
+ count = 0;
+ bloomfilter_get_stat_by_type(bm_handle, SAPP_STAT_BM_SLICE_NUM_FREE, &count);
+ sapp_fs3_metric_set(0, SAPP_STAT_BM_SLICE_NUM_FREE, count);
+ count = 0;
+ bloomfilter_get_stat_by_type(bm_handle, SAPP_STAT_BM_CUR_SLICE_NUM, &count);
+ sapp_fs3_metric_set(0, SAPP_STAT_BM_CUR_SLICE_NUM, count);
+ count = 0;
+ bloomfilter_get_stat_by_type(bm_handle, SAPP_STAT_APBM_EXPAND_MAX_MULTIPLE, &count);
+ sapp_fs3_metric_set(0, SAPP_STAT_APBM_EXPAND_MAX_MULTIPLE, count);
+ count = 0;
+ bloomfilter_get_stat_by_type(bm_handle, SAPP_STAT_DABM_RESIZE_MAX_RATIO, &count);
+ sapp_fs3_metric_set(0, SAPP_STAT_DABM_RESIZE_MAX_RATIO, count);
+ return 0;
+}
+
int bloomfilter_get_mem_stat(int tseq, long long *mem_blocks, long long *mem_bytes)
{
void *bm_handle = (struct bloom_partition *)sapp_global_val->mthread_volatile[tseq]->dup_pkt_distinguish_handle;
@@ -99,11 +203,10 @@ int bloomfilter_get_mem_stat(int tseq, long long *mem_blocks, long long *mem_byt
switch (sapp_global_val->config.packet_io.dup_pkt_para.bloom_library)
{
case BLOOM_LIBRARY_APBLOOM:
- // todo,
- *mem_blocks = 0;
- *mem_bytes = 0;
- return -1;
+ *mem_blocks = (long long)AP_bloom_mem_blocks((const struct AP_bloom *)bm_handle);
+ *mem_bytes = (long long)AP_bloom_mem_size((const struct AP_bloom *)bm_handle);
break;
+
case BLOOM_LIBRARY_DABLOOM:
expiry_dablooms_get_mem_stat((struct expiry_dablooms_handle *)bm_handle, mem_blocks, mem_bytes);
break;
@@ -112,6 +215,8 @@ int bloomfilter_get_mem_stat(int tseq, long long *mem_blocks, long long *mem_byt
break;
}
+ bloomfilter_get_stat(bm_handle);
+
return 0;
}
diff --git a/src/extensions/sapp_metrics.cpp b/src/extensions/sapp_metrics.cpp
index 30e8dd6..d8239fe 100644
--- a/src/extensions/sapp_metrics.cpp
+++ b/src/extensions/sapp_metrics.cpp
@@ -630,7 +630,23 @@ static int sapp_fs3_init(sapp_global_t *global_paramters)
fs3_rt->metrics_ids[0][SAPP_STAT_TCP_TRY_TIMEOUTS] = fieldstat_register(fs3_handle, FIELD_TYPE_COUNTER, "Tcp_TRY_TIMED",
NULL, 0);
fs3_rt->metrics_ids[0][SAPP_STAT_UDP_TRY_TIMEOUTS] = fieldstat_register(fs3_handle, FIELD_TYPE_COUNTER, "Udp_TRY_TIMED",
- NULL, 0);
+ NULL, 0);
+
+ const sapp_dup_pkt_t *dup_cfg = &global_paramters->config.packet_io.dup_pkt_para;
+ if (dup_cfg->kickout_udp_stream_enabled
+ || dup_cfg->dup_pkt_distinguish_ipv4_tcp
+ || dup_cfg->dup_pkt_distinguish_ipv4_udp
+ || dup_cfg->dup_pkt_distinguish_all_inject)
+ {
+ fs3_rt->metrics_ids[0][SAPP_STAT_BM_HASH_NUM] = fieldstat_register(fs3_handle, FIELD_TYPE_GAUGE, "BM_HASH_NUM", NULL, 0);
+ fs3_rt->metrics_ids[0][SAPP_STAT_BM_EXPAND_NUM] = fieldstat_register(fs3_handle, FIELD_TYPE_GAUGE, "BM_EXPAND_NUM", NULL, 0);
+ fs3_rt->metrics_ids[0][SAPP_STAT_BM_SLICE_NUM_NEW] = fieldstat_register(fs3_handle, FIELD_TYPE_COUNTER, "BM_SLICE_NEW", NULL, 0);
+ fs3_rt->metrics_ids[0][SAPP_STAT_BM_SLICE_NUM_FREE] = fieldstat_register(fs3_handle, FIELD_TYPE_COUNTER, "BM_SLICE_FREE", NULL, 0);
+ fs3_rt->metrics_ids[0][SAPP_STAT_BM_CUR_SLICE_NUM] = fieldstat_register(fs3_handle, FIELD_TYPE_GAUGE, "BM_CUR_SLICE_NUM", NULL, 0);
+ fs3_rt->metrics_ids[0][SAPP_STAT_APBM_EXPAND_MAX_MULTIPLE] = fieldstat_register(fs3_handle, FIELD_TYPE_GAUGE, "APBM_EXPAND_MULTIPLE", NULL, 0);
+ fs3_rt->metrics_ids[0][SAPP_STAT_DABM_RESIZE_MAX_RATIO] = fieldstat_register(fs3_handle, FIELD_TYPE_GAUGE, "DABM_MAX_RESIZE_RATIO", NULL, 0);
+ }
+
return 0;
}
diff --git a/src/support/ap_bloom/src/ap_bloom.c b/src/support/ap_bloom/src/ap_bloom.c
index a0f82a1..9cd1f9f 100644
--- a/src/support/ap_bloom/src/ap_bloom.c
+++ b/src/support/ap_bloom/src/ap_bloom.c
@@ -25,6 +25,39 @@
#define MODE_READ 0
#define MODE_WRITE 1
+struct AP_bloom_stat{
+ size_t slice_new_num_acc;
+ size_t slice_free_num_acc;
+ size_t expand_num_acc;
+ size_t expand_max_multiple_rt;
+ size_t slice_num_rt;
+};
+struct AP_configuration
+{
+ double error;
+ long long capacity;
+ long long time_window_ms;
+ long long time_slice_num;
+ struct timeval last_cfg;
+};
+struct AP_bloom
+{
+ //high level variables determined by caller
+ struct AP_configuration cfg;
+
+ //low level variables caculated by the call configure
+ int hash_num; //k
+ int chain_num; //hash_num+time_slice_num
+ int default_slice_size; // in bytes
+
+ //runtime variables
+ int cursor;
+ struct timeval last_slide;
+ struct ap_slice **heads; //hash_num+timeframe_num
+
+ struct AP_bloom_stat stat;
+};
+
//return 1 if the bit is already set, 0 if it was not set
inline static int test_bit_set_bit(unsigned char *buf, uint64_t x, int mode) {
uint64_t byte = x >> 3;
@@ -51,22 +84,29 @@ struct ap_slice
unsigned char * data;
struct ap_slice * next;
};
-static struct ap_slice *ap_slice_new(int slice_size, int hash_index)
+static struct ap_slice *ap_slice_new(struct AP_bloom *bloom, int slice_size, int hash_index)
{
struct ap_slice *slice = ALLOC(struct ap_slice, 1);
slice->slice_size = slice_size;
assert(slice_size % sizeof(unsigned long long) == 0);
//ap_slice_chain_deserialize may alloc slice_size=0
- if(slice_size > 0) slice->data = ALLOC(unsigned char, slice_size);
+ if(slice_size > 0){
+ slice->data = ALLOC(unsigned char, slice_size);
+ }
slice->hash_index = hash_index;
slice->popcount = 0;
+
+ bloom->stat.slice_new_num_acc++;
+ bloom->stat.slice_num_rt++;
return slice;
}
-static void ap_slice_free(struct ap_slice *slice)
+static void ap_slice_free(struct AP_bloom *bloom, struct ap_slice *slice)
{
free(slice->data);
slice->data = NULL;
free(slice);
+ bloom->stat.slice_free_num_acc++;
+ bloom->stat.slice_num_rt--;
}
void ap_slice_chain_info(const struct ap_slice *head, double *fill_ratio, int *slice_num)
{
@@ -105,9 +145,9 @@ static int ap_slice_cmp(const struct ap_slice *a, const struct ap_slice *b)
//bigger size first
return b->slice_size - a->slice_size;
}
-static struct ap_slice * ap_slice_duplicate(const struct ap_slice *slice)
+static struct ap_slice * ap_slice_duplicate(struct AP_bloom *bloom, const struct ap_slice *slice)
{
- struct ap_slice *new_slice = ap_slice_new(slice->slice_size, slice->hash_index);
+ struct ap_slice *new_slice = ap_slice_new(bloom, slice->slice_size, slice->hash_index);
memcpy(new_slice, slice, offsetof(struct ap_slice, data));
memcpy(new_slice->data, slice->data, slice->slice_size);
return new_slice;
@@ -242,13 +282,17 @@ static void ap_slice_chain_check_hash(const struct ap_slice *head, const struct
* 0 - element was not present and was added
* 1 - element (or a collision) had already been added previously
*/
-static void ap_slice_chain_add_hash(struct ap_slice **head, const struct double_hash *hash, struct timeval now)
+static void ap_slice_chain_add_hash(struct AP_bloom *bloom, struct ap_slice **head, const struct double_hash *hash, struct timeval now)
{
//add new slice if the current slice is full
if(unlikely( (double) (*head)->popcount / ((*head)->slice_size<<3) > FILL_RATIO_THRESHOLD))
{
- struct ap_slice *new_slice = ap_slice_new((*head)->slice_size * SLICE_EXPANSION, (*head)->hash_index);
+ struct ap_slice *new_slice = ap_slice_new(bloom, (*head)->slice_size * SLICE_EXPANSION, (*head)->hash_index);
LL_PREPEND((*head), new_slice);
+ bloom->stat.expand_num_acc++;
+ if(new_slice->slice_size/bloom->default_slice_size > bloom->stat.expand_max_multiple_rt){
+ bloom->stat.expand_max_multiple_rt = new_slice->slice_size/bloom->default_slice_size;
+ }
}
//Add it to the current (head) slice.
ap_slice_add_hash(*head, hash, now);
@@ -267,22 +311,22 @@ void ap_slice_chain_first_insert_time(const struct ap_slice *head, struct timeva
}
return;
}
-static void ap_slice_chain_free(struct ap_slice *head)
+static void ap_slice_chain_free(struct AP_bloom *bloom, struct ap_slice *head)
{
struct ap_slice *slice=NULL, *tmp=NULL;
LL_FOREACH_SAFE(head, slice, tmp)
{
LL_DELETE(head, slice);
- ap_slice_free(slice);
+ ap_slice_free(bloom, slice);
}
}
-static struct ap_slice *ap_slice_chain_duplicate(const struct ap_slice *src)
+static struct ap_slice *ap_slice_chain_duplicate(struct AP_bloom *bloom, const struct ap_slice *src)
{
struct ap_slice *new_head=NULL;
const struct ap_slice *slice=NULL;
LL_FOREACH(src, slice)
{
- struct ap_slice * new_slice=ap_slice_duplicate(slice);
+ struct ap_slice * new_slice=ap_slice_duplicate(bloom, slice);
LL_APPEND(new_head, new_slice);
}
return new_head;
@@ -298,6 +342,16 @@ static size_t ap_slice_chain_mem_size(const struct ap_slice *head)
}
return sz;
}
+static size_t ap_slice_chain_mem_blocks(const struct ap_slice *head)
+{
+ size_t blocks=0;
+ const struct ap_slice *slice=NULL;
+ LL_FOREACH(head, slice)
+ {
+ blocks += 2;
+ }
+ return blocks;
+}
struct slice_chain_header
{
int chain_sequence;
@@ -343,14 +397,14 @@ static size_t ap_slice_chain_serialize(const struct ap_slice *head, int chain_se
assert(offset<=buffer_sz);
return offset;
}
-static struct ap_slice *ap_slice_chain_deserialize(const char *buffer, size_t buffer_sz)
+static struct ap_slice *ap_slice_chain_deserialize(struct AP_bloom *bloom, const char *buffer, size_t buffer_sz)
{
struct slice_chain_header *header=(struct slice_chain_header*)buffer;
size_t offset=sizeof(struct slice_chain_header);
struct ap_slice *head=NULL;
for(size_t i=0; i<header->slice_number; i++)
{
- struct ap_slice *slice = ap_slice_new(0, 0);
+ struct ap_slice *slice = ap_slice_new(bloom, 0, 0);
memcpy(slice, buffer+offset, offsetof(struct ap_slice, data));
offset += offsetof(struct ap_slice, data);
slice->data = (unsigned char*) malloc(slice->slice_size);
@@ -364,7 +418,7 @@ static struct ap_slice *ap_slice_chain_deserialize(const char *buffer, size_t bu
}
return head;
}
-static void ap_slice_merge(struct ap_slice *dst, const struct ap_slice *src)
+static void ap_slice_merge(struct AP_bloom *bloom, struct ap_slice *dst, const struct ap_slice *src)
{
assert(dst->hash_index == src->hash_index);
assert(dst->slice_size == src->slice_size);
@@ -395,7 +449,7 @@ static void ap_slice_merge(struct ap_slice *dst, const struct ap_slice *src)
}
return;
}
-static void ap_slice_chain_merge(struct ap_slice **dst_head, const struct ap_slice *src_head)
+static void ap_slice_chain_merge(struct AP_bloom *bloom, struct ap_slice **dst_head, const struct ap_slice *src_head)
{
const struct ap_slice *src_slice=NULL;
int merged=0;
@@ -411,43 +465,20 @@ static void ap_slice_chain_merge(struct ap_slice **dst_head, const struct ap_sli
{
if(src_slice->slice_size == dst_slice->slice_size)
{
- ap_slice_merge(dst_slice, src_slice);
+ ap_slice_merge(bloom, dst_slice, src_slice);
merged=1;
break;
}
}
if(!merged)
{
- struct ap_slice *new_slice = ap_slice_duplicate(src_slice);
+ struct ap_slice *new_slice = ap_slice_duplicate(bloom, src_slice);
LL_APPEND(*dst_head, new_slice);
}
}
LL_SORT(*dst_head, ap_slice_cmp);
ap_slice_sanity(*dst_head);
}
-struct AP_configuration
-{
- double error;
- long long capacity;
- long long time_window_ms;
- long long time_slice_num;
- struct timeval last_cfg;
-};
-struct AP_bloom
-{
- //high level variables determined by caller
- struct AP_configuration cfg;
-
- //low level variables caculated by the call configure
- int hash_num; //k
- int chain_num; //hash_num+time_slice_num
- int default_slice_size; // in bytes
-
- //runtime variables
- int cursor;
- struct timeval last_slide;
- struct ap_slice **heads; //hash_num+timeframe_num
-};
#define DBL_EPSILON 2.2204460492503131e-16
bool definitelyLessThan(float a, float b)
{
@@ -481,8 +512,10 @@ struct AP_bloom *AP_bloom_new(struct timeval now, double error_rate, long long c
bloom->heads = ALLOC(struct ap_slice*, bloom->chain_num);
for(int i=0; i<bloom->chain_num; i++)
{
- bloom->heads[i] = ap_slice_new(bloom->default_slice_size, i % bloom->chain_num);
+ bloom->heads[i] = ap_slice_new(bloom, bloom->default_slice_size, i % bloom->chain_num);
}
+ bloom->stat.expand_max_multiple_rt = 1;
+ bloom->stat.slice_num_rt = bloom->chain_num;
return bloom;
}
@@ -507,8 +540,8 @@ static void slide_time(struct AP_bloom *bloom, struct timeval now)
for(int i=0; i<n_slide; i++)
{
int reset_idx = (bloom->cursor + bloom->hash_num) % chain_num;
- struct ap_slice *slice = ap_slice_new(bloom->default_slice_size, bloom->heads[reset_idx]->hash_index);
- ap_slice_chain_free(bloom->heads[reset_idx]);
+ struct ap_slice *slice = ap_slice_new(bloom, bloom->default_slice_size, bloom->heads[reset_idx]->hash_index);
+ ap_slice_chain_free(bloom, bloom->heads[reset_idx]);
bloom->heads[reset_idx] = slice;
bloom->cursor = (bloom->cursor + 1) % chain_num;
}
@@ -517,8 +550,8 @@ static void slide_time(struct AP_bloom *bloom, struct timeval now)
{
for(int i=0; i<chain_num; i++)
{
- struct ap_slice *new_slice=ap_slice_new(bloom->default_slice_size, bloom->heads[i]->hash_index);
- ap_slice_chain_free(bloom->heads[i]);
+ struct ap_slice *new_slice=ap_slice_new(bloom, bloom->default_slice_size, bloom->heads[i]->hash_index);
+ ap_slice_chain_free(bloom, bloom->heads[i]);
bloom->heads[i] = new_slice;
}
bloom->cursor = (bloom->cursor + n_slide) % chain_num;
@@ -543,7 +576,7 @@ void AP_bloom_add(struct AP_bloom *bloom, struct timeval now, const char *buffer
for(int i=0; i<bloom->hash_num; i++)
{
int idx=(bloom->cursor+i) % (bloom->chain_num);
- ap_slice_chain_add_hash(&(bloom->heads[idx]), &hash, now);
+ ap_slice_chain_add_hash(bloom,&(bloom->heads[idx]), &hash, now);
}
return;
}
@@ -560,8 +593,8 @@ int AP_bloom_check(const struct AP_bloom *bloom, struct timeval now, const char
struct ap_state state;
ap_state_init(&state, bloom->hash_num);
- int max_num = bloom->hash_num+chain_num;
- for(int i = 0; i < max_num; i++)
+ // int max_num = bloom->hash_num+chain_num;
+ for(int i = 0; i < chain_num; i++)
{
long long delta_us = timeval_delta_us(bloom->heads[i%chain_num]->last_insert, now);
if(unlikely((delta_us > bloom->cfg.time_window_ms*1000) && bloom->cfg.time_window_ms))
@@ -583,7 +616,7 @@ void AP_bloom_free(struct AP_bloom *bloom)
{
for(int i=0; i<bloom->chain_num; i++)
{
- ap_slice_chain_free(bloom->heads[i]);
+ ap_slice_chain_free(bloom, bloom->heads[i]);
bloom->heads[i]=NULL;
}
free(bloom->heads);
@@ -601,6 +634,17 @@ size_t AP_bloom_mem_size(const struct AP_bloom *bloom)
}
return sz;
}
+size_t AP_bloom_mem_blocks(const struct AP_bloom *bloom)
+{
+ size_t blocks=0;
+ blocks++;
+ blocks += bloom->chain_num;
+ for(int i=0; i<bloom->chain_num; i++)
+ {
+ blocks += ap_slice_chain_mem_blocks(bloom->heads[i]);
+ }
+ return blocks;
+}
size_t AP_bloom_serialize_size(const struct AP_bloom *bloom)
{
size_t sz=0;
@@ -635,7 +679,7 @@ struct AP_bloom * AP_bloom_deserialize(const char *blob, size_t blob_sz)
bloom->heads=ALLOC(struct ap_slice*, bloom->chain_num);
for(int i=0; i<bloom->chain_num; i++)
{
- bloom->heads[i]=ap_slice_chain_deserialize(blob+offset, blob_sz-offset);
+ bloom->heads[i]=ap_slice_chain_deserialize(bloom, blob+offset, blob_sz-offset);
offset += ap_slice_chain_serialize_size(bloom->heads[i]);
}
assert(offset==blob_sz);
@@ -654,7 +698,7 @@ void AP_bloom_merge(struct AP_bloom *dst, const struct AP_bloom *src)
{
for(int i=0; i<dst->chain_num; i++)
{
- ap_slice_chain_free(dst->heads[i]);
+ ap_slice_chain_free(dst, dst->heads[i]);
}
memcpy(dst, src, offsetof(struct AP_bloom, heads));
@@ -662,7 +706,7 @@ void AP_bloom_merge(struct AP_bloom *dst, const struct AP_bloom *src)
dst->heads = ALLOC(struct ap_slice*, dst->chain_num);
for(int i=0; i<dst->chain_num; i++)
{
- dst->heads[i] = ap_slice_chain_duplicate(src->heads[i]);
+ dst->heads[i] = ap_slice_chain_duplicate(dst, src->heads[i]);
}
}
return;
@@ -683,7 +727,7 @@ void AP_bloom_merge(struct AP_bloom *dst, const struct AP_bloom *src)
{
continue;
}
- ap_slice_chain_merge(&(dst->heads[i]), src->heads[i]);
+ ap_slice_chain_merge(dst,&(dst->heads[i]), src->heads[i]);
}
return;
}
@@ -769,4 +813,29 @@ void AP_bloom_info(const struct AP_bloom *bloom, struct AP_bloom_info *info)
info->approximate_item_num = approximate_item_num(bloom);
info->oldest_item_time = oldest_item;
return;
+}
+
+size_t AP_bloom_stat_get_hash_num(const struct AP_bloom *bloom)
+{
+ return bloom->hash_num;
+}
+size_t AP_bloom_stat_get_new_num(const struct AP_bloom *bloom)
+{
+ return bloom->stat.slice_new_num_acc;
+}
+size_t AP_bloom_stat_get_free_num(const struct AP_bloom *bloom)
+{
+ return bloom->stat.slice_free_num_acc;
+}
+size_t AP_bloom_stat_get_expand_num(const struct AP_bloom *bloom)
+{
+ return bloom->stat.expand_num_acc;
+}
+size_t AP_bloom_stat_get_cur_slice_num(const struct AP_bloom *bloom)
+{
+ return bloom->stat.slice_num_rt;
+}
+size_t AP_bloom_stat_get_expand_max_multiple(const struct AP_bloom *bloom)
+{
+ return bloom->stat.expand_max_multiple_rt;
} \ No newline at end of file
diff --git a/src/support/ap_bloom/src/ap_bloom.h b/src/support/ap_bloom/src/ap_bloom.h
index c40b5b9..672a75b 100644
--- a/src/support/ap_bloom/src/ap_bloom.h
+++ b/src/support/ap_bloom/src/ap_bloom.h
@@ -72,6 +72,13 @@ void AP_bloom_merge_blob(struct AP_bloom *dst, const char *blob, size_t blob_sz)
struct AP_bloom *AP_bloom_replicate(uuid_t uuid, const char *blob, size_t blob_sz);
size_t AP_bloom_serialized_size(const struct AP_bloom *bloom);
size_t AP_bloom_mem_size(const struct AP_bloom *bloom);
+size_t AP_bloom_stat_get_hash_num(const struct AP_bloom *bloom);
+size_t AP_bloom_mem_blocks(const struct AP_bloom *bloom);
+size_t AP_bloom_stat_get_new_num(const struct AP_bloom *bloom);
+size_t AP_bloom_stat_get_free_num(const struct AP_bloom *bloom);
+size_t AP_bloom_stat_get_expand_num(const struct AP_bloom *bloom);
+size_t AP_bloom_stat_get_cur_slice_num(const struct AP_bloom *bloom);
+size_t AP_bloom_stat_get_expand_max_multiple(const struct AP_bloom *bloom);
#ifdef __cplusplus
}
diff --git a/src/support/dablooms/src/dablooms.c b/src/support/dablooms/src/dablooms.c
index 2c563da..7ecbe4d 100755
--- a/src/support/dablooms/src/dablooms.c
+++ b/src/support/dablooms/src/dablooms.c
@@ -337,12 +337,18 @@ counting_bloom_t *new_counting_bloom_from_scale(scaling_bloom_t *bloom, struct d
bloom->blooms[bloom->num_blooms] = cur_bloom;
bloom->bitmap = bitmap_resize(bloom->bitmap, bloom->num_bytes, bloom->num_bytes + cur_bloom->num_bytes, mstat);
+
+ if(bloom->num_bytes > sizeof(scaling_bloom_header_t)){
+ bloom->stat.expand_num_acc++;
+ bloom->stat.expand_size_ratio_rt *= (double)(bloom->num_bytes + cur_bloom->num_bytes) / bloom->num_bytes;
+ }
/* reset header pointer, as mmap may have moved */
bloom->header = (scaling_bloom_header_t *) bloom->bitmap->array;
/* Set the pointers for these header structs to the right location since mmap may have moved */
bloom->num_blooms++;
+ bloom->stat.slice_num_rt = bloom->num_blooms;
for (unsigned int i = 0; i < bloom->num_blooms; i++) {
offset = bloom->blooms[i]->offset - sizeof(counting_bloom_header_t);
bloom->blooms[i]->header = (counting_bloom_header_t *) (bloom->bitmap->array + offset);
@@ -479,7 +485,6 @@ scaling_bloom_t *scaling_bloom_init(unsigned int capacity, double error_rate,str
static scaling_bloom_t *new_scaling_bloom(unsigned int capacity, double error_rate, struct dabm_mem_stat *mstat)
{
-
scaling_bloom_t *bloom;
counting_bloom_t *cur_bloom;
@@ -495,6 +500,7 @@ static scaling_bloom_t *new_scaling_bloom(unsigned int capacity, double error_ra
cur_bloom->header->id = 0;
bloom->header->mem_seqnum = 1;
+ bloom->stat.expand_size_ratio_rt = 1.0;
return bloom;
}
@@ -512,6 +518,8 @@ struct expiry_dablooms_handle_entity{
long transition_time_ms;
double error_rate;
struct dabm_mem_stat mstat;
+ size_t bloom_new_num;
+ size_t bloom_free_num;
};
/* 24.05, split bloomfilter into multiple partition to avoid blocking caused by memset large memory */
@@ -566,6 +574,7 @@ static struct expiry_dablooms_handle_entity* expiry_dablooms_init_entity(unsigne
handle->expiry_time_ms = expiry_time_ms;
handle->cur_time_ms = cur_time_ms;
handle->transition_time_ms = transition_time_ms;
+ handle->bloom_new_num++;
return handle;
error_out:
@@ -633,6 +642,7 @@ static int bloom_expired_check(struct expiry_dablooms_handle_entity *handle, lon
handle->cur_time_ms=cur_time_ms;
if(unlikely(delta_time_ms >= handle->expiry_time_ms)){
free_scaling_bloom(handle->cur_bloom, mstat);
+ handle->bloom_free_num++;
if(handle->next_bloom != NULL){
handle->cur_bloom = handle->next_bloom;
handle->cur_bloom_start_ms = handle->next_bloom_start_ms;
@@ -645,10 +655,11 @@ static int bloom_expired_check(struct expiry_dablooms_handle_entity *handle, lon
if(unlikely(cur_bloom == NULL)){
return EXPIRY_DABLOOMS_ERRNO_NEW_BLOOM_FAIL;
}
+ handle->bloom_new_num++;
handle->cur_bloom = cur_bloom;
handle->cur_bloom_inc_id = 0;
handle->cur_bloom_start_ms=cur_time_ms;
- handle->last_bloom_check_ms=0;
+ handle->last_bloom_check_ms=0;
}
}
else
@@ -678,6 +689,7 @@ static int expiry_dablooms_add_entity(struct expiry_dablooms_handle_entity *hand
if(next_bloom == NULL){
return EXPIRY_DABLOOMS_ERRNO_NEW_BLOOM_FAIL;
}
+ handle->bloom_new_num++;
handle->next_bloom = next_bloom;
handle->next_bloom_inc_id = 0;
handle->next_bloom_start_ms=cur_time_ms;
@@ -752,4 +764,79 @@ int expiry_dablooms_get_mem_stat(struct expiry_dablooms_handle *handle, long lon
*blocks = tot_blocks;
*bytes = tot_bytes;
return 0;
+}
+
+size_t DA_bloom_stat_get_slice_new_num(const struct expiry_dablooms_handle *bloom)
+{
+ size_t tot_num = 0;
+ for(int i = 0; i < bloom->bm_partition_num; i++){
+ const struct expiry_dablooms_handle_entity *bm_entity = bloom->bm_handle[i];
+ tot_num += bm_entity->bloom_new_num;
+ }
+ return tot_num;
+}
+
+size_t DA_bloom_stat_get_slice_free_num(const struct expiry_dablooms_handle *bloom)
+{
+ size_t tot_num = 0;
+ for(int i = 0; i < bloom->bm_partition_num; i++){
+ const struct expiry_dablooms_handle_entity *bm_entity = bloom->bm_handle[i];
+ tot_num += bm_entity->bloom_free_num;
+ }
+ return tot_num;
+}
+
+size_t DA_bloom_stat_get_hash_num(const struct expiry_dablooms_handle *bloom)
+{
+ if(bloom->bm_handle != NULL && bloom->bm_handle[0] != NULL){
+ const struct expiry_dablooms_handle_entity *bm_entity = bloom->bm_handle[0];
+ return ceil(log(1 / bm_entity->error_rate ) / log(2));
+ }
+ return 0;
+}
+size_t DA_bloom_stat_get_expand_num(const struct expiry_dablooms_handle *bloom)
+{
+ size_t tot_num = 0;
+ for(int i = 0; i < bloom->bm_partition_num; i++){
+ const struct expiry_dablooms_handle_entity *bm_entity = bloom->bm_handle[i];
+ if(bm_entity->cur_bloom){
+ tot_num += bm_entity->cur_bloom->stat.expand_num_acc;
+ }
+ if(bm_entity->next_bloom){
+ tot_num += bm_entity->next_bloom->stat.expand_num_acc;
+ }
+ }
+ return tot_num;
+}
+size_t DA_bloom_stat_get_cur_slice_num(const struct expiry_dablooms_handle *bloom)
+{
+ size_t tot_num = 0;
+ for(int i = 0; i < bloom->bm_partition_num; i++){
+ const struct expiry_dablooms_handle_entity *bm_entity = bloom->bm_handle[i];
+ if(bm_entity->cur_bloom){
+ tot_num += bm_entity->cur_bloom->stat.slice_num_rt;
+ }
+ if(bm_entity->next_bloom){
+ tot_num += bm_entity->next_bloom->stat.slice_num_rt;
+ }
+ }
+ return tot_num;
+}
+size_t DA_bloom_stat_get_resize_ratio(const struct expiry_dablooms_handle *bloom)
+{
+ double max_ratio = 1.000;
+ for(int i = 0; i < bloom->bm_partition_num; i++){
+ const struct expiry_dablooms_handle_entity *bm_entity = bloom->bm_handle[i];
+ if(bm_entity->cur_bloom){
+ if(bm_entity->cur_bloom->stat.expand_size_ratio_rt > max_ratio){
+ max_ratio = bm_entity->cur_bloom->stat.expand_size_ratio_rt;
+ }
+ }
+ if(bm_entity->next_bloom){
+ if(bm_entity->next_bloom->stat.expand_size_ratio_rt > max_ratio){
+ max_ratio = bm_entity->next_bloom->stat.expand_size_ratio_rt;
+ }
+ }
+ }
+ return (size_t)(max_ratio * 100.0);
} \ No newline at end of file
diff --git a/src/support/dablooms/src/dablooms.h b/src/support/dablooms/src/dablooms.h
index 85886b4..1c5a342 100755
--- a/src/support/dablooms/src/dablooms.h
+++ b/src/support/dablooms/src/dablooms.h
@@ -41,7 +41,11 @@ typedef struct {
uint32_t _pad;
} counting_bloom_header_t;
-
+struct DA_bloom_stat{
+ size_t expand_num_acc;
+ double expand_size_ratio_rt; //current bitmap size / defalut bitmap size * 100
+ size_t slice_num_rt;
+};
typedef struct {
counting_bloom_header_t *header;
unsigned int capacity;
@@ -75,6 +79,7 @@ typedef struct {
double error_rate;
counting_bloom_t **blooms;
bitmap_t *bitmap;
+ struct DA_bloom_stat stat;
} scaling_bloom_t;
// scaling_bloom_t *new_scaling_bloom(unsigned int capacity, double error_rate);
@@ -98,6 +103,12 @@ int expiry_dablooms_element_count_get(struct expiry_dablooms_handle *handle, uin
int expiry_dablooms_add(struct expiry_dablooms_handle *handle, const char *key, size_t len, time_t cur_time);
int expiry_dablooms_search(struct expiry_dablooms_handle *handle, const char *key, size_t len, time_t cur_time);
int expiry_dablooms_get_mem_stat(struct expiry_dablooms_handle *handle, long long *blocks, long long *bytes);
+size_t DA_bloom_stat_get_slice_new_num(const struct expiry_dablooms_handle *bloom);
+size_t DA_bloom_stat_get_slice_free_num(const struct expiry_dablooms_handle *bloom);
+size_t DA_bloom_stat_get_hash_num(const struct expiry_dablooms_handle *bloom);
+size_t DA_bloom_stat_get_expand_num(const struct expiry_dablooms_handle *bloom);
+size_t DA_bloom_stat_get_cur_slice_num(const struct expiry_dablooms_handle *bloom);
+size_t DA_bloom_stat_get_resize_ratio(const struct expiry_dablooms_handle *bloom);
#ifdef __cplusplus
}
#endif