Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 81 additions & 6 deletions docs/cn/mbvar_c++.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,13 @@ size_t mbvar_list_exposed(std::vector<std::string>* names) {

多维度统计的实现,主要提供bvar的获取、列举等功能。

为了兼容旧的用法,KeyType默认类型是std::list<std::string>。KeyType必须是(STL或者自定义)容器,value_type必须是std::string。

## constructor

有三个构造函数:
```c++
template <typename T>
template <typename T, typename KeyType = std::list<std::string>>
class MultiDimension : public MVariable {
public:
// 不建议使用
Expand Down Expand Up @@ -398,7 +400,7 @@ bvar::MultiDimension<bvar::Adder<int> > g_request_count("foo_bar", "request_coun

## stats
```c++
template <typename T>
template <typename T, typename KeyType = std::list<std::string>>
class MultiDimension : public MVariable {
public:
...
Expand All @@ -410,7 +412,15 @@ public:
```

### get_stats
根据指定label获取对应的单维度统计项bvar
根据指定label获取对应的单维度统计项bvar。

get_stats除了支持(默认)std::list<std::string>参数类型,也支持自定义参数类型,满足以下条件:
1. (STL或者自定义)容器。
2. K::value_type支持通过operator std::string()转换为std::string和通过operator butil::StringPiece()转换为butil::StringPiece。
3. K::value_type支持和std::string进行比较。

推荐使用不需要分配内存的容器(例如,std::array、absl::InlinedVector)和不需要拷贝字符串的数据结构(例如,const char*、std::string_view、butil::StringPieces),可以提高性能。

```c++
#include <bvar/bvar.h>
#include <bvar/multi_dimension.h>
Expand All @@ -420,7 +430,8 @@ namespace bar {
// 定义一个全局的多维度mbvar变量
bvar::MultiDimension<bvar::Adder<int> > g_request_count("request_count", {"idc", "method", "status"});

int get_request_count(const std::list<std::string>& request_label) {
template <typename K>
int get_request_count(const K& request_label) {
// 获取request_label对应的单维度bvar指针,比如:request_label = {"tc", "get", "200"}
bvar::Adder<int> *request_adder = g_request_count.get_stats(request_label);
// 判断指针非空
Expand All @@ -433,6 +444,70 @@ int get_request_count(const std::list<std::string>& request_label) {
return request_adder->get_value();
}

std::list<std::string> request_label_list = {"tc", "get", "200"};
int request_count = get_request_count(request_label_list);

std::vector<std::string_view> request_label_list = {"tc", "get", "200"};
int request_count = get_request_count(request_label_list);

std::vector<butil::StringPiece> request_label_list = {"tc", "get", "200"};
int request_count = get_request_count(request_label_list);

class MyStringView {
public:
MyStringView() : _ptr(NULL), _len(0) {}
MyStringView(const char* str)
: _ptr(str),
_len(str == NULL ? 0 : strlen(str)) {}
#if __cplusplus >= 201703L
MyStringView(const std::string_view& str)
: _ptr(str.data()), _len(str.size()) {}
#endif // __cplusplus >= 201703L
MyStringView(const std::string& str)
: _ptr(str.data()), _len(str.size()) {}
MyStringView(const char* offset, size_t len)
: _ptr(offset), _len(len) {}

const char* data() const { return _ptr; }
size_t size() const { return _len; }

// Converts to `std::basic_string`.
explicit operator std::string() const {
if (NULL == _ptr) {
return {};
}
return {_ptr, size()};
}

// Converts to butil::StringPiece.
explicit operator butil::StringPiece() const {
if (NULL == _ptr) {
return {};
}
return {_ptr, size()};
}

private:
const char* _ptr;
size_t _len;
};

bool operator==(const MyStringView& x, const std::string& y) {
if (x.size() != y.size()) {
return false;
}
return butil::StringPiece::wordmemcmp(x.data(), y.data(), x.size()) == 0;
}
bool operator==(const std::string& x, const MyStringView& y) {
if (x.size() != y.size()) {
return false;
}
return butil::StringPiece::wordmemcmp(x.data(), y.data(), x.size()) == 0;
}

std::vector<MyStringView> request_label_list = {"tc", "get", "200"};
int request_count = get_request_count(request_label_list);

} // namespace bar
} // namespace foo
```
Expand Down Expand Up @@ -462,7 +537,7 @@ public:
size_t count_labels() const;
};

template <typename T>
template <typename T, typename KeyType = std::list<std::string>>
class MultiDimension : public MVariable {
public:
...
Expand Down Expand Up @@ -536,7 +611,7 @@ size_t count_stats() {

## list
```c++
template <typename T>
template <typename T, typename KeyType = std::list<std::string>>
class MultiDimension : public MVariable {
public:
...
Expand Down
2 changes: 1 addition & 1 deletion src/brpc/builtin/prometheus_metrics_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ int DumpPrometheusMetricsToIOBuf(butil::IOBuf* output) {

if (bvar::FLAGS_bvar_max_dump_multi_dimension_metric_number > 0) {
PrometheusMetricsDumper dumper_md(&os, g_server_info_prefix);
const int ndump_md = bvar::MVariable::dump_exposed(&dumper_md, NULL);
const int ndump_md = bvar::MVariableBase::dump_exposed(&dumper_md, NULL);
if (ndump_md < 0) {
return -1;
}
Expand Down
4 changes: 2 additions & 2 deletions src/butil/containers/flat_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,12 @@ class FlatMap {
// Remove |key| and all associated value
// Returns: 1 on erased, 0 otherwise.
template <typename K2, bool Multi = _Multi>
typename std::enable_if<!Multi, size_t >::type
typename std::enable_if<!Multi, size_t>::type
erase(const K2& key, mapped_type* old_value = NULL);
// For `_Multi=true'.
// Returns: num of value on erased, 0 otherwise.
template <typename K2, bool Multi = _Multi>
typename std::enable_if<Multi, size_t >::type
typename std::enable_if<Multi, size_t>::type
erase(const K2& key, std::vector<mapped_type>* old_values = NULL);

// Remove all items. Allocated spaces are NOT returned by system.
Expand Down
1 change: 0 additions & 1 deletion src/butil/containers/flat_map_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,6 @@ typename std::enable_if<!Multi, _T&>::type
FlatMap<_K, _T, _H, _E, _S, _A, _M>::operator[](const key_type& key) {
const size_t index = flatmap_mod(_hashfn(key), _nbucket);
Bucket& first_node = _buckets[index];
// LOG(INFO) << "index=" << index;
if (!first_node.is_valid()) {
++_size;
if (_S) {
Expand Down
16 changes: 16 additions & 0 deletions src/butil/strings/string_piece.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@

#include <iosfwd>
#include <string>
#if __cplusplus >= 201703L
#include <string_view>
#endif // __cplusplus >= 201703L

#include "butil/base_export.h"
#include "butil/basictypes.h"
Expand Down Expand Up @@ -182,6 +185,11 @@ template <typename STRING_TYPE> class BasicStringPiece {
BasicStringPiece(const value_type* str)
: ptr_(str),
length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {}
#if __cplusplus >= 201703L
BasicStringPiece(
const std::basic_string_view<value_type, typename STRING_TYPE::traits_type>& str)
: ptr_(str.data()), length_(str.size()) {}
#endif // __cplusplus >= 201703L
BasicStringPiece(const STRING_TYPE& str)
: ptr_(str.data()), length_(str.size()) {}
BasicStringPiece(const value_type* offset, size_type len)
Expand Down Expand Up @@ -370,6 +378,14 @@ template <typename STRING_TYPE> class BasicStringPiece {
return internal::substr(*this, pos, n);
}

// Converts to `std::basic_string`.
explicit operator STRING_TYPE() const {
if (NULL == data()) {
return {};
}
return STRING_TYPE(data(), size());
}

protected:
const value_type* ptr_;
size_type length_;
Expand Down
Loading
Loading