diff options
| author | lijia <[email protected]> | 2024-06-07 02:07:14 +0800 |
|---|---|---|
| committer | yangwei <[email protected]> | 2024-06-07 02:07:14 +0800 |
| commit | f82a8875043eaa55dd11cc41308d99b024bde706 (patch) | |
| tree | ca2d1f2f8fe987f8f443295c812696b7e596c0dc | |
| parent | d735864a21bec48f8e8083b5ba6c36a389c57bca (diff) | |
add bloom fs4 statistics, add gtest user args.
| -rw-r--r-- | .gitlab-ci.yml | 2 | ||||
| -rw-r--r-- | include/private/sapp_pkt_stat.h | 8 | ||||
| -rw-r--r-- | module_test/src/CMakeLists.txt | 17 | ||||
| -rw-r--r-- | module_test/src/gtest_main.cpp | 13 | ||||
| -rw-r--r-- | module_test/src/gtest_sapp_bloom.cpp | 180 | ||||
| -rw-r--r-- | module_test/src/gtest_sapp_fun.h | 2 | ||||
| -rw-r--r-- | src/common/sapp_mem.c | 4 | ||||
| -rw-r--r-- | src/dealpkt/duplicate_pkt_distinguish.c | 113 | ||||
| -rw-r--r-- | src/extensions/sapp_metrics.cpp | 18 | ||||
| -rw-r--r-- | src/support/ap_bloom/src/ap_bloom.c | 175 | ||||
| -rw-r--r-- | src/support/ap_bloom/src/ap_bloom.h | 7 | ||||
| -rwxr-xr-x | src/support/dablooms/src/dablooms.c | 91 | ||||
| -rwxr-xr-x | src/support/dablooms/src/dablooms.h | 13 |
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 |
