2 +--------------------------------------------------------------------+
3 | libmemcached-awesome - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020-2021 Michael Wallner https://awesome.co/ |
13 +--------------------------------------------------------------------+
16 #include "libmemcached/common.h"
18 static void calc_largest_consumption(memcached_analysis_st
*result
, const uint32_t server_num
,
19 const uint64_t nbytes
) {
20 if (result
->most_used_bytes
< nbytes
) {
21 result
->most_used_bytes
= nbytes
;
22 result
->most_consumed_server
= server_num
;
26 static void calc_oldest_node(memcached_analysis_st
*result
, const uint32_t server_num
,
27 const uint32_t uptime
) {
28 if (result
->longest_uptime
< uptime
) {
29 result
->longest_uptime
= uptime
;
30 result
->oldest_server
= server_num
;
34 static void calc_least_free_node(memcached_analysis_st
*result
, const uint32_t server_num
,
35 const uint64_t max_allowed_bytes
, const uint64_t used_bytes
) {
36 uint64_t remaining_bytes
= max_allowed_bytes
- used_bytes
;
38 if (result
->least_remaining_bytes
== 0 || remaining_bytes
< result
->least_remaining_bytes
) {
39 result
->least_remaining_bytes
= remaining_bytes
;
40 result
->least_free_server
= server_num
;
44 static void calc_average_item_size(memcached_analysis_st
*result
, const uint64_t total_items
,
45 const uint64_t total_bytes
) {
46 if (total_items
> 0 && total_bytes
> 0) {
47 result
->average_item_size
= (uint32_t)(total_bytes
/ total_items
);
51 static void calc_hit_ratio(memcached_analysis_st
*result
, const uint64_t total_get_hits
,
52 const uint64_t total_get_cmds
) {
53 if (total_get_hits
== 0 || total_get_cmds
== 0) {
54 result
->pool_hit_ratio
= 0;
58 double temp
= double(total_get_hits
) / total_get_cmds
;
59 result
->pool_hit_ratio
= temp
* 100;
62 memcached_analysis_st
*memcached_analyze(memcached_st
*shell
, memcached_stat_st
*memc_stat
,
63 memcached_return_t
*error
) {
64 Memcached
*memc
= memcached2Memcached(shell
);
65 uint64_t total_items
= 0, total_bytes
= 0;
66 uint64_t total_get_cmds
= 0, total_get_hits
= 0;
68 if (memc
== NULL
or memc_stat
== NULL
) {
72 memcached_return_t not_used
;
77 *error
= MEMCACHED_SUCCESS
;
78 uint32_t server_count
= memcached_server_count(memc
);
79 memcached_analysis_st
*result
= (memcached_analysis_st
*) libmemcached_xcalloc(
80 memc
, memcached_server_count(memc
), memcached_analysis_st
);
83 *error
= MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
89 for (uint32_t x
= 0; x
< server_count
; x
++) {
90 calc_largest_consumption(result
, x
, memc_stat
[x
].bytes
);
91 calc_oldest_node(result
, x
, uint32_t(memc_stat
[x
].uptime
));
92 calc_least_free_node(result
, x
, memc_stat
[x
].limit_maxbytes
, memc_stat
[x
].bytes
);
94 total_get_hits
+= memc_stat
[x
].get_hits
;
95 total_get_cmds
+= memc_stat
[x
].cmd_get
;
96 total_items
+= memc_stat
[x
].curr_items
;
97 total_bytes
+= memc_stat
[x
].bytes
;
100 calc_average_item_size(result
, total_items
, total_bytes
);
101 calc_hit_ratio(result
, total_get_hits
, total_get_cmds
);
106 void memcached_analyze_free(memcached_analysis_st
*ptr
) {
107 libmemcached_free(ptr
->root
, ptr
);