├── OSSMETADATA ├── bundle ├── pcre.sh ├── libcurl-linux.a ├── libcurl-osx.a ├── libpcre-linux.a ├── libpcre-osx.a └── curl.sh ├── 3rd-party ├── benchmark │ ├── .clang-format │ ├── cmake │ │ ├── Config.cmake.in │ │ ├── thread_safety_attributes.cpp │ │ ├── steady_clock.cpp │ │ ├── std_regex.cpp │ │ ├── gnu_posix_regex.cpp │ │ ├── posix_regex.cpp │ │ ├── GetGitVersion.cmake │ │ └── CXXFeatureCheck.cmake │ ├── tools │ │ └── gbench │ │ │ ├── __init__.py │ │ │ └── Inputs │ │ │ └── test2_run.json │ ├── src │ │ ├── sysinfo.h │ │ ├── sleep.h │ │ ├── colorprint.h │ │ ├── counter.h │ │ ├── string_util.h │ │ ├── arraysize.h │ │ ├── timers.h │ │ ├── benchmark_api_internal.h │ │ ├── statistics.h │ │ ├── internal_macros.h │ │ ├── log.h │ │ ├── sleep.cc │ │ ├── counter.cc │ │ └── complexity.h │ ├── test │ │ ├── templated_fixture_test.cc │ │ ├── fixture_test.cc │ │ ├── donotoptimize_test.cc │ │ ├── map_test.cc │ │ ├── cxx03_test.cc │ │ ├── options_test.cc │ │ └── diagnostics_test.cc │ ├── .gitignore │ ├── releasing.md │ ├── .travis-libcxx-setup.sh │ ├── appveyor.yml │ └── AUTHORS ├── spdlog │ ├── version.h │ ├── fmt │ │ ├── ostr.h │ │ ├── fmt.h │ │ └── bundled │ │ │ └── LICENSE.rst │ ├── formatter.h │ ├── sinks │ │ ├── null_sink.h │ │ ├── msvc_sink.h │ │ ├── ostream_sink.h │ │ ├── sink.h │ │ ├── stdout_color_sinks.h │ │ ├── basic_file_sink.h │ │ └── base_sink.h │ └── details │ │ ├── null_mutex.h │ │ ├── log_msg.h │ │ ├── console_globals.h │ │ ├── circular_q.h │ │ └── periodic_worker.h ├── fmt │ ├── printf.cc │ ├── ostream.cc │ └── container.h ├── curl │ ├── stdcheaders.h │ └── mprintf.h ├── rapidjson │ └── internal │ │ ├── swap.h │ │ └── strfunc.h ├── src │ └── gtest │ │ ├── gtest_main.cc │ │ └── gtest-all.cc └── gtest │ └── internal │ └── custom │ ├── gtest.h │ └── gtest-printers.h ├── test ├── environment_test.cc ├── runtests.cc ├── resources │ ├── config.json │ ├── subs1.json │ └── metadata.json ├── config_manager_test.cc ├── gauge_test.cc ├── steplong_test.cc ├── system_clock_test.cc ├── test_registry.h ├── collections_test.cc ├── bucket_counter_test.cc ├── percentile_timer_test.cc ├── test_utils.h ├── percentile_dist_summary_test.cc ├── default_max_gauge_test.cc ├── function_gauge_test.cc ├── http_server.h ├── expression_test.cc └── query_utils.h ├── .gitignore ├── util ├── memory.h ├── gzip.h ├── intern.cc ├── buffer.h ├── json.h ├── environment.h ├── string_pool.cc ├── buffer.cc ├── string_pool.h ├── intern.h ├── collections.h ├── http.h ├── config_manager.h ├── logger.h └── optional.h ├── interpreter ├── word.h ├── evaluator.h ├── multiple_results.h ├── interpreter.h ├── all.h ├── singleton_value_expr.cc ├── multiple_results.cc ├── vocabulary.h ├── singleton_value_expr.h ├── keep_drop_tags.h ├── context.h ├── all.cc ├── group_by.h ├── evaluator.cc ├── aggregation.h ├── tags_value.cc └── context.cc ├── bench ├── README.md └── CMakeLists.txt ├── codecov.yml ├── meter ├── gauge.h ├── statistic.h ├── timer.h ├── counter.h ├── distribution_summary.h ├── default_gauge.h ├── percentile_buckets.h ├── monotonic_counter.h ├── tag.h ├── statistic.cc ├── clock.cc ├── default_gauge.cc ├── bucket_timer.h ├── bucket_counter.h ├── validation.h ├── manual_clock.h ├── bucket_distribution_summary.h ├── interval_counter.h ├── subscription.h ├── id_format.h ├── bucket_counter.cc ├── measurement.h ├── subscription_format.h ├── default_timer.h ├── clock.h ├── bucket_distribution_summary.cc ├── publisher.h ├── percentile_timer.h ├── bucket_timer.cc ├── default_long_task_timer.h ├── percentile_dist_summary.h ├── id.cc ├── monotonic_counter.cc ├── percentile_timer.cc ├── function_gauge.h ├── interval_counter.cc ├── percentile_dist_summary.cc ├── long_task_timer.h ├── default_max_gauge.h ├── meter.h ├── consolidation_registry.h └── default_counter.h ├── types.h ├── create-lcov-report.sh ├── atlas_client.h ├── resources └── atlas-config-reference.json ├── README.md ├── gen_perc_bucket_tags.cc ├── main.cc ├── gen_valid_chars.cc ├── run-build.sh ├── .github └── workflows │ ├── pr.yml │ ├── snapshot.yml │ └── release.yml └── gen_perc_bucket_values.cc /OSSMETADATA: -------------------------------------------------------------------------------- 1 | osslifecycle=active 2 | -------------------------------------------------------------------------------- /bundle/pcre.sh: -------------------------------------------------------------------------------- 1 | CFLAGS="-fPIC -O2 -g" ./configure --disable-shared --enable-static --disable-cpp 2 | -------------------------------------------------------------------------------- /3rd-party/benchmark/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | BasedOnStyle: Google 4 | ... 5 | 6 | -------------------------------------------------------------------------------- /3rd-party/benchmark/cmake/Config.cmake.in: -------------------------------------------------------------------------------- 1 | include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake") 2 | -------------------------------------------------------------------------------- /bundle/libcurl-linux.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix-Skunkworks/atlas-native-client/main/bundle/libcurl-linux.a -------------------------------------------------------------------------------- /bundle/libcurl-osx.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix-Skunkworks/atlas-native-client/main/bundle/libcurl-osx.a -------------------------------------------------------------------------------- /bundle/libpcre-linux.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix-Skunkworks/atlas-native-client/main/bundle/libpcre-linux.a -------------------------------------------------------------------------------- /bundle/libpcre-osx.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Netflix-Skunkworks/atlas-native-client/main/bundle/libpcre-osx.a -------------------------------------------------------------------------------- /3rd-party/benchmark/cmake/thread_safety_attributes.cpp: -------------------------------------------------------------------------------- 1 | #define HAVE_THREAD_SAFETY_ATTRIBUTES 2 | #include "../src/mutex.h" 3 | 4 | int main() {} 5 | -------------------------------------------------------------------------------- /3rd-party/benchmark/cmake/steady_clock.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | typedef std::chrono::steady_clock Clock; 5 | Clock::time_point tp = Clock::now(); 6 | ((void)tp); 7 | } 8 | -------------------------------------------------------------------------------- /test/environment_test.cc: -------------------------------------------------------------------------------- 1 | #include "../util/environment.h" 2 | #include 3 | 4 | using namespace atlas::util; 5 | 6 | TEST(Environment, id) { EXPECT_FALSE(env::instance_id().empty()); } 7 | -------------------------------------------------------------------------------- /test/runtests.cc: -------------------------------------------------------------------------------- 1 | #include <../util/logger.h> 2 | #include 3 | 4 | int main(int argc, char** argv) { 5 | atlas::util::UseConsoleLogger(1); 6 | testing::InitGoogleTest(&argc, argv); 7 | return RUN_ALL_TESTS(); 8 | } 9 | -------------------------------------------------------------------------------- /test/resources/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "forceStart": true, 3 | "publishUrl": "http://atlas.example.com/pub", 4 | "evaluateUrl": "http://atlas.example.com/eval", 5 | "subscriptionsUrl": "http://atlas.example.com/subs", 6 | "dumpMetrics": true 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .newt.netflix_environment.sh 3 | .vscode/ 4 | build 5 | build-* 6 | cmake_install.cmake 7 | cmake-build-* 8 | CMakeCache.txt 9 | CMakeFiles/ 10 | CTestTestfile.cmake 11 | logs/ 12 | Makefile 13 | node_modules/ 14 | npm-debug.log 15 | -------------------------------------------------------------------------------- /3rd-party/benchmark/tools/gbench/__init__.py: -------------------------------------------------------------------------------- 1 | """Google Benchmark tooling""" 2 | 3 | __author__ = 'Eric Fiselier' 4 | __email__ = 'eric@efcs.ca' 5 | __versioninfo__ = (0, 5, 0) 6 | __version__ = '.'.join(str(v) for v in __versioninfo__) + 'dev' 7 | 8 | __all__ = [] 9 | -------------------------------------------------------------------------------- /3rd-party/benchmark/src/sysinfo.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_SYSINFO_H_ 2 | #define BENCHMARK_SYSINFO_H_ 3 | 4 | namespace benchmark { 5 | int NumCPUs(); 6 | double CyclesPerSecond(); 7 | bool CpuScalingEnabled(); 8 | } // end namespace benchmark 9 | 10 | #endif // BENCHMARK_SYSINFO_H_ 11 | -------------------------------------------------------------------------------- /util/memory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #if __cplusplus < 201402L 6 | namespace std { 7 | template 8 | unique_ptr make_unique(Args&&... args) { 9 | return unique_ptr(new T(forward(args)...)); 10 | } 11 | } // namespace std 12 | #endif 13 | -------------------------------------------------------------------------------- /interpreter/word.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../util/optional.h" 4 | 5 | namespace atlas { 6 | namespace interpreter { 7 | 8 | class Word { 9 | public: 10 | virtual OptionalString Execute(Context* context) = 0; 11 | virtual ~Word() = default; 12 | }; 13 | } // namespace interpreter 14 | } // namespace atlas 15 | -------------------------------------------------------------------------------- /3rd-party/benchmark/cmake/std_regex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() { 4 | const std::string str = "test0159"; 5 | std::regex re; 6 | re = std::regex("^[a-z]+[0-9]+$", 7 | std::regex_constants::extended | std::regex_constants::nosubs); 8 | return std::regex_search(str, re) ? 0 : -1; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /3rd-party/benchmark/cmake/gnu_posix_regex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() { 4 | std::string str = "test0159"; 5 | regex_t re; 6 | int ec = regcomp(&re, "^[a-z]+[0-9]+$", REG_EXTENDED | REG_NOSUB); 7 | if (ec != 0) { 8 | return ec; 9 | } 10 | return regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /bench/README.md: -------------------------------------------------------------------------------- 1 | To build benchmarks: 2 | 3 | ```sh 4 | # At the top dir 5 | mkdir -p build-bench 6 | cd build-bench 7 | cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_BENCHMARKS=ON .. 8 | make -j8 9 | ``` 10 | 11 | That will build `build-bench/bench/*` binaries. You'll need to symlink some 12 | resources for some benchmarks (`curl -o subs.json .../api/v1/expressions`) 13 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: 2 | layout: "reach, diff, flags, files" 3 | behavior: default 4 | require_changes: false # if true: only post the comment if coverage changes 5 | require_base: no # [yes :: must have a base report to post] 6 | require_head: yes # [yes :: must have a head report to post] 7 | branches: null 8 | ignore: 9 | - "3rd-party/**/*" 10 | -------------------------------------------------------------------------------- /3rd-party/spdlog/version.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2015 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | 8 | #define SPDLOG_VER_MAJOR 1 9 | #define SPDLOG_VER_MINOR 2 10 | #define SPDLOG_VER_PATCH 0 11 | 12 | #define SPDLOG_VERSION (SPDLOG_VER_MAJOR * 10000 + SPDLOG_VER_MINOR * 100 + SPDLOG_VER_PATCH) 13 | -------------------------------------------------------------------------------- /meter/gauge.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "meter.h" 6 | 7 | namespace atlas { 8 | namespace meter { 9 | 10 | template 11 | class Gauge { 12 | public: 13 | virtual ~Gauge() = default; 14 | virtual double Value() const noexcept = 0; 15 | virtual void Update(T d) noexcept = 0; 16 | }; 17 | } // namespace meter 18 | } // namespace atlas 19 | -------------------------------------------------------------------------------- /3rd-party/benchmark/cmake/posix_regex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() { 4 | std::string str = "test0159"; 5 | regex_t re; 6 | int ec = regcomp(&re, "^[a-z]+[0-9]+$", REG_EXTENDED | REG_NOSUB); 7 | if (ec != 0) { 8 | return ec; 9 | } 10 | int ret = regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0; 11 | regfree(&re); 12 | return ret; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /test/resources/subs1.json: -------------------------------------------------------------------------------- 1 | { 2 | "expressions" : [ 3 | { 4 | "expression" : "nf.cluster,skan-test,:eq,name,foometric,:eq,:and,:sum", 5 | "frequency" : 60000, 6 | "id" : "So3yA1c1xN_vzZASUQdORBqd9hM" 7 | }, 8 | { 9 | "expression" : "nf.cluster,skan,:re,name,foometric,:eq,:and,:sum", 10 | "frequency" : 60000, 11 | "id" : "tphgPWqODm0ZUhgUCwj23lpEs1o" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace atlas { 8 | 9 | // maybe switch to fbvector as well 10 | using Strings = std::vector; 11 | } // namespace atlas 12 | 13 | namespace std { 14 | template 15 | unique_ptr make_unique(Args&&... args) { 16 | return unique_ptr(new T(forward(args)...)); 17 | } 18 | } // namespace std 19 | -------------------------------------------------------------------------------- /3rd-party/spdlog/fmt/ostr.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2016 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | // 8 | // include bundled or external copy of fmtlib's ostream support 9 | // 10 | #if !defined(SPDLOG_FMT_EXTERNAL) 11 | #ifndef FMT_HEADER_ONLY 12 | #define FMT_HEADER_ONLY 13 | #endif 14 | #include "bundled/ostream.h" 15 | #include "fmt.h" 16 | #else 17 | #include 18 | #endif 19 | -------------------------------------------------------------------------------- /create-lcov-report.sh: -------------------------------------------------------------------------------- 1 | # Creating report 2 | set -ex 3 | if [ x$TRAVIS_BUILD_DIR != x ]; then 4 | cd $TRAVIS_BUILD_DIR 5 | fi 6 | echo $PWD 7 | # capture coverage info 8 | lcov --directory . --capture --output-file coverage.info 9 | # filter out system, build, tests and 3rd-party code from our test coverage 10 | lcov --remove coverage.info '/usr/*' '*/usr/*' '*/3rd-party/*' '*/build/*' '*/test/*' --output-file coverage.info 11 | # print report to stdout for debugging 12 | lcov --list coverage.info 13 | -------------------------------------------------------------------------------- /meter/statistic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "id.h" 4 | 5 | namespace atlas { 6 | namespace meter { 7 | namespace statistic { 8 | extern const Tag count; 9 | extern const Tag gauge; 10 | extern const Tag totalTime; 11 | extern const Tag totalAmount; 12 | extern const Tag max; 13 | extern const Tag totalOfSquares; 14 | extern const Tag activeTasks; 15 | extern const Tag duration; 16 | extern const Tag percentile; 17 | } // namespace statistic 18 | } // namespace meter 19 | } // namespace atlas 20 | -------------------------------------------------------------------------------- /meter/timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace atlas { 6 | namespace meter { 7 | class Timer { 8 | public: 9 | virtual ~Timer() = default; 10 | 11 | virtual void Record(std::chrono::nanoseconds nanos) = 0; 12 | 13 | virtual void Record(int64_t nanos) { 14 | Record(std::chrono::nanoseconds(nanos)); 15 | } 16 | 17 | virtual int64_t Count() const noexcept = 0; 18 | 19 | virtual int64_t TotalTime() const noexcept = 0; 20 | }; 21 | } // namespace meter 22 | } // namespace atlas 23 | -------------------------------------------------------------------------------- /bundle/curl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ex 4 | 5 | curl https://curl.haxx.se/download/curl-7.53.1.tar.gz | tar zx 6 | cd curl-7.53.1 7 | ./configure --enable-optimize --disable-dict --disable-gopher --disable-ftp --disable-imap --disable-ldap --disable-ldaps --disable-pop3 --disable-proxy --disable-rtsp --disable-smtp --disable-telnet --disable-tftp --disable-zlib --without-ca-bundle --without-gnutls --without-libidn --without-librtmp --without-libssh2 --without-nss --without-ssl --without-zlib --disable-shared --enable-threaded-resolver 8 | make -j4 9 | -------------------------------------------------------------------------------- /3rd-party/spdlog/formatter.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2015 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | 8 | #include "fmt/fmt.h" 9 | #include "spdlog/details/log_msg.h" 10 | 11 | namespace spdlog { 12 | 13 | class formatter 14 | { 15 | public: 16 | virtual ~formatter() = default; 17 | virtual void format(const details::log_msg &msg, fmt::memory_buffer &dest) = 0; 18 | virtual std::unique_ptr clone() const = 0; 19 | }; 20 | } // namespace spdlog 21 | -------------------------------------------------------------------------------- /3rd-party/benchmark/src/sleep.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_SLEEP_H_ 2 | #define BENCHMARK_SLEEP_H_ 3 | 4 | namespace benchmark { 5 | const int kNumMillisPerSecond = 1000; 6 | const int kNumMicrosPerMilli = 1000; 7 | const int kNumMicrosPerSecond = kNumMillisPerSecond * 1000; 8 | const int kNumNanosPerMicro = 1000; 9 | const int kNumNanosPerSecond = kNumNanosPerMicro * kNumMicrosPerSecond; 10 | 11 | void SleepForMilliseconds(int milliseconds); 12 | void SleepForSeconds(double seconds); 13 | } // end namespace benchmark 14 | 15 | #endif // BENCHMARK_SLEEP_H_ 16 | -------------------------------------------------------------------------------- /interpreter/evaluator.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "tags_value.h" 5 | #include "interpreter.h" 6 | 7 | namespace atlas { 8 | namespace interpreter { 9 | class Evaluator { 10 | public: 11 | Evaluator() noexcept; 12 | TagsValuePairs eval(const std::string& expression, 13 | const TagsValuePairs& measurements) const noexcept; 14 | std::shared_ptr get_query(const std::string& expression) const 15 | noexcept; 16 | 17 | private: 18 | Interpreter interpreter_; 19 | }; 20 | 21 | } // namespace interpreter 22 | } // namespace atlas 23 | -------------------------------------------------------------------------------- /meter/counter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "clock.h" 7 | #include "meter.h" 8 | 9 | namespace atlas { 10 | namespace meter { 11 | 12 | template 13 | class CounterNumber { 14 | public: 15 | virtual void Increment() noexcept = 0; 16 | 17 | virtual void Add(T amount) noexcept = 0; 18 | 19 | virtual T Count() const noexcept = 0; 20 | }; 21 | 22 | using Counter = CounterNumber; 23 | using DCounter = CounterNumber; 24 | 25 | } // namespace meter 26 | } // namespace atlas 27 | -------------------------------------------------------------------------------- /util/gzip.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace atlas { 7 | namespace util { 8 | 9 | static constexpr int kGzipHeaderSize = 16; // size of the gzip header 10 | 11 | int gzip_compress(char* dest, size_t* destLen, const char* source, 12 | size_t sourceLen); 13 | int gzip_uncompress(char* dest, size_t* destLen, const char* source, 14 | size_t sourceLen); 15 | 16 | int inflate_string(std::string* dest, const char* source, size_t sourceLen); 17 | 18 | } // namespace util 19 | } // namespace atlas 20 | -------------------------------------------------------------------------------- /util/intern.cc: -------------------------------------------------------------------------------- 1 | #include "intern.h" 2 | #include "string_pool.h" 3 | 4 | namespace atlas { 5 | namespace util { 6 | 7 | const StrRef& intern_str(const char* string) { 8 | const auto& r = the_str_pool().intern(string); 9 | #ifdef DEBUG 10 | if (strcmp(string, r.get()) != 0) { 11 | printf("Unable to intern %s = %s -> %s\n", string, r.data, r.get()); 12 | abort(); 13 | } 14 | #endif 15 | return r; 16 | } 17 | 18 | const StrRef& intern_str(const std::string& string) { 19 | return intern_str(string.c_str()); 20 | } 21 | 22 | } // namespace util 23 | } // namespace atlas 24 | -------------------------------------------------------------------------------- /util/buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | namespace atlas { 6 | namespace util { 7 | 8 | class Buffer { 9 | public: 10 | Buffer() = default; 11 | Buffer(const Buffer&) = delete; 12 | Buffer& operator=(const Buffer&) = delete; 13 | Buffer& operator=(Buffer&&) = delete; 14 | Buffer(Buffer&&) = delete; 15 | void append(void* data, size_t data_size); 16 | void assign(std::string* s); 17 | void uncompress_to(std::string* s); 18 | 19 | private: 20 | std::vector buf; 21 | }; 22 | 23 | } // namespace util 24 | } // namespace atlas 25 | -------------------------------------------------------------------------------- /util/json.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace atlas { 8 | namespace util { 9 | 10 | inline const char* JsonGetString(rapidjson::StringBuffer& buffer, 11 | const rapidjson::Document& document) { 12 | using namespace rapidjson; 13 | Writer, UTF8<>, CrtAllocator, kWriteNanAndInfFlag> 14 | writer(buffer); 15 | document.Accept(writer); 16 | return buffer.GetString(); 17 | } 18 | } // namespace util 19 | } // namespace atlas 20 | -------------------------------------------------------------------------------- /test/config_manager_test.cc: -------------------------------------------------------------------------------- 1 | #include "../util/config_manager.h" 2 | #include 3 | #include 4 | 5 | using atlas::util::ConfigManager; 6 | 7 | TEST(ConfigManager, Init) { 8 | ConfigManager cm("./resources/config.json", 1); 9 | auto cfg = cm.GetConfig(); 10 | EXPECT_TRUE(cfg->ShouldForceStart()); 11 | 12 | const auto& endpoints = cfg->EndpointConfiguration(); 13 | EXPECT_EQ(endpoints.publish, "http://atlas.example.com/pub"); 14 | EXPECT_EQ(endpoints.evaluate, "http://atlas.example.com/eval"); 15 | EXPECT_EQ(endpoints.subscriptions, "http://atlas.example.com/subs"); 16 | } 17 | -------------------------------------------------------------------------------- /meter/distribution_summary.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace atlas { 6 | namespace meter { 7 | 8 | template 9 | class DistributionSummaryNumber { 10 | public: 11 | virtual ~DistributionSummaryNumber() = default; 12 | virtual void Record(T amount) noexcept = 0; 13 | virtual int64_t Count() const noexcept = 0; 14 | virtual T TotalAmount() const noexcept = 0; 15 | }; 16 | 17 | using DistributionSummary = DistributionSummaryNumber; 18 | using DDistributionSummary = DistributionSummaryNumber; 19 | 20 | } // namespace meter 21 | } // namespace atlas 22 | -------------------------------------------------------------------------------- /interpreter/multiple_results.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "context.h" 4 | #include "expression.h" 5 | 6 | namespace atlas { 7 | namespace interpreter { 8 | 9 | class MultipleResults : public Expression { 10 | public: 11 | virtual TagsValuePairs Apply(const TagsValuePairs& measurements) = 0; 12 | virtual std::shared_ptr GetQuery() const noexcept = 0; 13 | 14 | protected: 15 | static OptionalString get_value(const TagsValuePair& tagsValuePair, 16 | util::StrRef k); 17 | static std::string keys_str(StringRefs strings); 18 | }; 19 | } // namespace interpreter 20 | } // namespace atlas 21 | -------------------------------------------------------------------------------- /bench/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(BUILD_BENCHMARKS STREQUAL "ON") 2 | set(BENCHMARK_ENABLE_TESTING "OFF") 3 | set(BENCHMARK_ENABLE_INSTALL "OFF") 4 | set(BENCHMARK_HAS_CXX11 "ON") 5 | add_subdirectory(../3rd-party/benchmark gbench) 6 | file(GLOB bench_files RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/code" "code/*.cc") 7 | foreach(bench_file IN LISTS bench_files) 8 | string(REPLACE ".cc" "" bench_file "${bench_file}") 9 | add_executable(${bench_file} code/${bench_file}.cc) 10 | message("Adding ${bench_file} code/${bench_file}.cc") 11 | target_link_libraries(${bench_file} atlasclient pthread benchmark) 12 | endforeach() 13 | endif() 14 | -------------------------------------------------------------------------------- /3rd-party/benchmark/test/templated_fixture_test.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "benchmark/benchmark.h" 3 | 4 | #include 5 | #include 6 | 7 | template 8 | class MyFixture : public ::benchmark::Fixture { 9 | public: 10 | MyFixture() : data(0) {} 11 | 12 | T data; 13 | }; 14 | 15 | BENCHMARK_TEMPLATE_F(MyFixture, Foo, int)(benchmark::State &st) { 16 | for (auto _ : st) { 17 | data += 1; 18 | } 19 | } 20 | 21 | BENCHMARK_TEMPLATE_DEFINE_F(MyFixture, Bar, double)(benchmark::State& st) { 22 | for (auto _ : st) { 23 | data += 1.0; 24 | } 25 | } 26 | BENCHMARK_REGISTER_F(MyFixture, Bar); 27 | 28 | BENCHMARK_MAIN() 29 | -------------------------------------------------------------------------------- /3rd-party/spdlog/fmt/fmt.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2016-2018 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // Include a bundled header-only copy of fmtlib or an external one. 10 | // By default spdlog include its own copy. 11 | // 12 | 13 | #if !defined(SPDLOG_FMT_EXTERNAL) 14 | #ifndef FMT_HEADER_ONLY 15 | #define FMT_HEADER_ONLY 16 | #endif 17 | #ifndef FMT_USE_WINDOWS_H 18 | #define FMT_USE_WINDOWS_H 0 19 | #endif 20 | #include "bundled/core.h" 21 | #include "bundled/format.h" 22 | #else // external fmtlib 23 | #include 24 | #include 25 | #endif 26 | -------------------------------------------------------------------------------- /meter/default_gauge.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gauge.h" 4 | 5 | namespace atlas { 6 | namespace meter { 7 | 8 | class DefaultGauge : public Meter, public Gauge { 9 | public: 10 | DefaultGauge(const IdPtr& id, const Clock& clock); 11 | 12 | void Update(double d) noexcept override; 13 | double Value() const noexcept override; 14 | 15 | std::ostream& Dump(std::ostream& os) const override; 16 | 17 | Measurements Measure() const override; 18 | 19 | const char* GetClass() const noexcept override { return "DefaultGauge"; } 20 | 21 | private: 22 | std::atomic value_; 23 | }; 24 | } // namespace meter 25 | } // namespace atlas 26 | -------------------------------------------------------------------------------- /util/environment.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../meter/id.h" 4 | 5 | namespace atlas { 6 | namespace util { 7 | 8 | std::string safe_getenv(const char* var) noexcept; 9 | 10 | namespace env { 11 | 12 | std::string ami() noexcept; 13 | std::string app() noexcept; 14 | std::string asg() noexcept; 15 | std::string instance_id() noexcept; 16 | std::string cluster() noexcept; 17 | std::string stack() noexcept; 18 | std::string vmtype() noexcept; 19 | std::string taskid() noexcept; 20 | std::string region() noexcept; 21 | std::string account() noexcept; 22 | std::string zone() noexcept; 23 | 24 | } // namespace env 25 | } // namespace util 26 | } // namespace atlas 27 | -------------------------------------------------------------------------------- /meter/percentile_buckets.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace atlas { 9 | namespace meter { 10 | namespace percentile_buckets { 11 | 12 | size_t IndexOf(int64_t v); 13 | constexpr size_t Length() { return 276; } 14 | int64_t Get(size_t i); 15 | int64_t Bucket(int64_t v); 16 | 17 | void Percentiles(const std::array& counts, 18 | const std::vector& pcts, std::vector* results); 19 | double Percentile(const std::array& counts, double p); 20 | 21 | } // namespace percentile_buckets 22 | } // namespace meter 23 | } // namespace atlas 24 | -------------------------------------------------------------------------------- /3rd-party/benchmark/.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.so 3 | *.so.?* 4 | *.dll 5 | *.exe 6 | *.dylib 7 | *.cmake 8 | !/cmake/*.cmake 9 | *~ 10 | *.pyc 11 | __pycache__ 12 | 13 | # lcov 14 | *.lcov 15 | /lcov 16 | 17 | # cmake files. 18 | /Testing 19 | CMakeCache.txt 20 | CMakeFiles/ 21 | cmake_install.cmake 22 | 23 | # makefiles. 24 | Makefile 25 | 26 | # in-source build. 27 | bin/ 28 | lib/ 29 | /test/*_test 30 | 31 | # exuberant ctags. 32 | tags 33 | 34 | # YouCompleteMe configuration. 35 | .ycm_extra_conf.pyc 36 | 37 | # ninja generated files. 38 | .ninja_deps 39 | .ninja_log 40 | build.ninja 41 | install_manifest.txt 42 | rules.ninja 43 | 44 | # out-of-source build top-level folders. 45 | build/ 46 | _build/ 47 | -------------------------------------------------------------------------------- /3rd-party/spdlog/sinks/null_sink.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2015 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | 8 | #include "spdlog/details/null_mutex.h" 9 | #include "spdlog/sinks/base_sink.h" 10 | 11 | #include 12 | 13 | namespace spdlog { 14 | namespace sinks { 15 | 16 | template 17 | class null_sink : public base_sink 18 | { 19 | protected: 20 | void sink_it_(const details::log_msg &) override {} 21 | void flush_() override {} 22 | }; 23 | 24 | using null_sink_mt = null_sink; 25 | using null_sink_st = null_sink; 26 | 27 | } // namespace sinks 28 | } // namespace spdlog 29 | -------------------------------------------------------------------------------- /interpreter/interpreter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "context.h" 4 | #include "expression.h" 5 | #include "vocabulary.h" 6 | 7 | namespace atlas { 8 | namespace interpreter { 9 | class Interpreter { 10 | public: 11 | explicit Interpreter(std::unique_ptr vocabulary); 12 | 13 | void Execute(Context* context, const std::string& program) const; 14 | 15 | std::shared_ptr GetQuery(const std::string& program) const; 16 | 17 | private: 18 | const std::unique_ptr vocabulary_; 19 | }; 20 | 21 | using Expressions = std::vector>; 22 | 23 | void split(const std::string& s, Expressions* result); 24 | 25 | } // namespace interpreter 26 | } // namespace atlas 27 | -------------------------------------------------------------------------------- /meter/monotonic_counter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "meter.h" 4 | #include "registry.h" 5 | 6 | namespace atlas { 7 | namespace meter { 8 | 9 | class MonotonicCounter : public Meter { 10 | public: 11 | MonotonicCounter(Registry* registry, const IdPtr& id); 12 | Measurements Measure() const override; 13 | std::ostream& Dump(std::ostream& os) const override; 14 | void Set(int64_t amount) noexcept; 15 | int64_t Count() const noexcept; 16 | const char* GetClass() const noexcept override { return "MonotonicCounter"; } 17 | 18 | private: 19 | std::atomic value_; 20 | Registry* registry_; 21 | std::shared_ptr counter_; 22 | }; 23 | 24 | } // namespace meter 25 | } // namespace atlas 26 | -------------------------------------------------------------------------------- /meter/tag.h: -------------------------------------------------------------------------------- 1 | #include "../util/intern.h" 2 | 3 | namespace atlas { 4 | namespace meter { 5 | 6 | struct Tag { 7 | // for backwards compatibility keep the names first and second 8 | // instead of more descriptive key and value 9 | util::StrRef key; 10 | util::StrRef value; 11 | 12 | Tag() noexcept {} 13 | Tag(util::StrRef k, util::StrRef v) noexcept : key{k}, value{v} {} 14 | 15 | static Tag of(const char* k, const char* v) noexcept { 16 | return Tag{util::intern_str(k), util::intern_str(v)}; 17 | } 18 | static Tag of(const std::string& k, const std::string& v) noexcept { 19 | return Tag{util::intern_str(k), util::intern_str(v)}; 20 | } 21 | }; 22 | 23 | } // namespace meter 24 | } // namespace atlas 25 | -------------------------------------------------------------------------------- /3rd-party/benchmark/releasing.md: -------------------------------------------------------------------------------- 1 | # How to release 2 | 3 | * Make sure you're on master and synced to HEAD 4 | * Ensure the project builds and tests run (sanity check only, obviously) 5 | * `parallel -j0 exec ::: test/*_test` can help ensure everything at least 6 | passes 7 | * Prepare release notes 8 | * `git log $(git describe --abbrev=0 --tags)..HEAD` gives you the list of 9 | commits between the last annotated tag and HEAD 10 | * Pick the most interesting. 11 | * Create a release through github's interface 12 | * Note this will create a lightweight tag. 13 | * Update this to an annotated tag: 14 | * `git pull --tags` 15 | * `git tag -a -f ` 16 | * `git push --force origin` 17 | -------------------------------------------------------------------------------- /interpreter/all.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "context.h" 4 | #include "multiple_results.h" 5 | 6 | namespace atlas { 7 | namespace interpreter { 8 | 9 | class All : public MultipleResults { 10 | public: 11 | explicit All(std::shared_ptr query); 12 | 13 | ExpressionType GetType() const noexcept override { 14 | return ExpressionType::MultipleResults; 15 | } 16 | 17 | std::shared_ptr GetQuery() const noexcept override { return query_; } 18 | 19 | TagsValuePairs Apply(const TagsValuePairs& measurements) override; 20 | 21 | std::ostream& Dump(std::ostream& os) const override; 22 | 23 | private: 24 | std::shared_ptr query_; 25 | }; 26 | } // namespace interpreter 27 | } // namespace atlas 28 | -------------------------------------------------------------------------------- /meter/statistic.cc: -------------------------------------------------------------------------------- 1 | #include "statistic.h" 2 | 3 | namespace atlas { 4 | namespace meter { 5 | 6 | namespace statistic { 7 | const Tag count = Tag::of("statistic", "count"); 8 | const Tag gauge = Tag::of("statistic", "gauge"); 9 | const Tag totalTime = Tag::of("statistic", "totalTime"); 10 | const Tag totalAmount = Tag::of("statistic", "totalAmount"); 11 | const Tag max = Tag::of("statistic", "max"); 12 | const Tag totalOfSquares = Tag::of("statistic", "totalOfSquares"); 13 | const Tag duration = Tag::of("statistic", "duration"); 14 | const Tag activeTasks = Tag::of("statistic", "activeTasks"); 15 | const Tag percentile = Tag::of("statistic", "percentile"); 16 | } // namespace statistic 17 | } // namespace meter 18 | } // namespace atlas 19 | -------------------------------------------------------------------------------- /interpreter/singleton_value_expr.cc: -------------------------------------------------------------------------------- 1 | #include "singleton_value_expr.h" 2 | 3 | namespace atlas { 4 | namespace interpreter { 5 | 6 | SingletonValueExpr::SingletonValueExpr(std::shared_ptr expr) 7 | : expr_(std::move(expr)) {} 8 | 9 | TagsValuePairs SingletonValueExpr::Apply(const TagsValuePairs& measurements) { 10 | auto expr_result = expr_->Apply(measurements); 11 | auto v = expr_result->value(); 12 | if (std::isnan(v)) { 13 | return {}; 14 | } 15 | return {TagsValuePair::of(expr_result->all_tags(), v)}; 16 | } 17 | 18 | std::ostream& SingletonValueExpr::Dump(std::ostream& os) const { 19 | os << "SingletonVE{expr=" << *expr_ << "}"; 20 | return os; 21 | } 22 | 23 | } // namespace interpreter 24 | } // namespace atlas -------------------------------------------------------------------------------- /interpreter/multiple_results.cc: -------------------------------------------------------------------------------- 1 | #include "multiple_results.h" 2 | #include "../meter/id.h" 3 | #include 4 | 5 | namespace atlas { 6 | namespace interpreter { 7 | 8 | OptionalString MultipleResults::get_value(const TagsValuePair& tagsValuePair, 9 | const util::StrRef k) { 10 | return tagsValuePair.get_value(k); 11 | } 12 | 13 | std::string MultipleResults::keys_str(StringRefs strings) { 14 | std::ostringstream os; 15 | 16 | auto first = true; 17 | for (const auto& s : strings) { 18 | if (!first) { 19 | os << ','; 20 | } else { 21 | first = false; 22 | } 23 | os << s.get(); 24 | } 25 | return os.str(); 26 | } 27 | } // namespace interpreter 28 | } // namespace atlas 29 | -------------------------------------------------------------------------------- /meter/clock.cc: -------------------------------------------------------------------------------- 1 | #include "clock.h" 2 | #include 3 | 4 | namespace atlas { 5 | namespace meter { 6 | 7 | using std::chrono::duration_cast; 8 | using std::chrono::milliseconds; 9 | using std::chrono::nanoseconds; 10 | using std::chrono::steady_clock; 11 | using std::chrono::system_clock; 12 | 13 | int64_t SystemClock::WallTime() const noexcept { 14 | return static_cast( 15 | duration_cast(system_clock::now().time_since_epoch()) 16 | .count()); 17 | } 18 | 19 | int64_t SystemClock::MonotonicTime() const noexcept { 20 | return static_cast( 21 | duration_cast(steady_clock::now().time_since_epoch()) 22 | .count()); 23 | } 24 | } // namespace meter 25 | } // namespace atlas 26 | -------------------------------------------------------------------------------- /interpreter/vocabulary.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "context.h" 4 | #include "word.h" 5 | 6 | namespace atlas { 7 | namespace interpreter { 8 | class Vocabulary { 9 | public: 10 | virtual OptionalString Execute(Context* context, 11 | const std::string& token) const = 0; 12 | virtual ~Vocabulary() = default; 13 | }; 14 | 15 | class ClientVocabulary : public Vocabulary { 16 | public: 17 | ClientVocabulary(); 18 | ~ClientVocabulary() override = default; 19 | 20 | OptionalString Execute(Context* context, 21 | const std::string& token) const override; 22 | 23 | private: 24 | std::map> words; 25 | }; 26 | } // namespace interpreter 27 | } // namespace atlas 28 | -------------------------------------------------------------------------------- /interpreter/singleton_value_expr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "multiple_results.h" 4 | 5 | namespace atlas { 6 | namespace interpreter { 7 | 8 | class SingletonValueExpr : public MultipleResults { 9 | public: 10 | explicit SingletonValueExpr(std::shared_ptr); 11 | 12 | ExpressionType GetType() const noexcept override { 13 | return ExpressionType::MultipleResults; 14 | } 15 | 16 | std::shared_ptr GetQuery() const noexcept override { 17 | return expr_->GetQuery(); 18 | } 19 | 20 | TagsValuePairs Apply(const TagsValuePairs& measurements) override; 21 | 22 | std::ostream& Dump(std::ostream& os) const override; 23 | 24 | private: 25 | std::shared_ptr expr_; 26 | }; 27 | 28 | } // namespace interpreter 29 | } // namespace atlas 30 | -------------------------------------------------------------------------------- /meter/default_gauge.cc: -------------------------------------------------------------------------------- 1 | #include "default_gauge.h" 2 | 3 | #include 4 | 5 | namespace atlas { 6 | namespace meter { 7 | 8 | DefaultGauge::DefaultGauge(const IdPtr& id, const Clock& clock) 9 | : Meter(WithDefaultGaugeTags(id), clock), value_(myNaN) {} 10 | 11 | double DefaultGauge::Value() const noexcept { return value_; } 12 | 13 | std::ostream& DefaultGauge::Dump(std::ostream& os) const { 14 | os << "Gauge{" << *id_ << ", value=" << Value() << "}"; 15 | return os; 16 | } 17 | 18 | Measurements DefaultGauge::Measure() const { 19 | return Measurements{Measurement{id_, clock_.WallTime(), Value()}}; 20 | } 21 | 22 | void DefaultGauge::Update(double d) noexcept { 23 | value_.store(d, std::memory_order_relaxed); 24 | Updated(); 25 | } 26 | 27 | } // namespace meter 28 | } // namespace atlas 29 | -------------------------------------------------------------------------------- /meter/bucket_timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "bucket_functions.h" 4 | #include "meter.h" 5 | #include "registry.h" 6 | #include "timer.h" 7 | 8 | namespace atlas { 9 | namespace meter { 10 | class BucketTimer : public Meter, public Timer { 11 | public: 12 | BucketTimer(Registry* registry, IdPtr id, BucketFunction bucket_function); 13 | std::ostream& Dump(std::ostream& os) const override; 14 | Measurements Measure() const override; 15 | void Record(std::chrono::nanoseconds duration) override; 16 | int64_t Count() const noexcept override; 17 | int64_t TotalTime() const noexcept override; 18 | const char* GetClass() const noexcept override { return "BucketTimer"; } 19 | 20 | private: 21 | Registry* registry_; 22 | BucketFunction bucket_function_; 23 | }; 24 | } // namespace meter 25 | } // namespace atlas 26 | -------------------------------------------------------------------------------- /atlas_client.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "util/config.h" 4 | #include "meter/measurement.h" 5 | #include "meter/registry.h" 6 | #include 7 | 8 | namespace atlas { 9 | 10 | class Client { 11 | class impl; 12 | std::unique_ptr impl_; 13 | 14 | public: 15 | Client() noexcept; 16 | ~Client() noexcept; 17 | 18 | void Start() noexcept; 19 | 20 | void Stop() noexcept; 21 | 22 | std::shared_ptr GetConfig() noexcept; 23 | 24 | void Push(const meter::Measurements& measurements) noexcept; 25 | 26 | void AddCommonTag(const char* key, const char* value) noexcept; 27 | 28 | void SetLoggingDirs(const std::vector& dirs) noexcept; 29 | void UseConsoleLogger(int level) noexcept; 30 | std::shared_ptr GetRegistry() const noexcept; 31 | }; 32 | 33 | } // namespace atlas 34 | -------------------------------------------------------------------------------- /resources/atlas-config-reference.json: -------------------------------------------------------------------------------- 1 | { 2 | "logVerbosity": 2, 3 | "logMaxSize": 1048576, 4 | "logMaxFiles": 8, 5 | "evaluateUrl": "http://atlas-lwcapi-iep.$EC2_REGION.iep$NETFLIX_ENVIRONMENT.netflix.net/lwc/api/v1/evaluate", 6 | "subscriptionsUrl": "http://atlas-lwcapi-iep.$EC2_REGION.iep$NETFLIX_ENVIRONMENT.netflix.net/lwc/api/v1/$NETFLIX_AUTO_SCALE_GROUP", 7 | "publishUrl": "http://atlas-pub-$EC2_OWNER_ID.$EC2_REGION.$NETFLIX_ACCOUNT.netflix.net/api/v1/publish-fast", 8 | "publishConfig": [ 9 | ":true,:all" 10 | ], 11 | "publishEnabled": true, 12 | "subscriptionsEnabled": false, 13 | "forceStart": false, 14 | "dumpMetrics": false, 15 | "dumpSubscriptions": false, 16 | "subscriptionsRefreshMillis": 10000, 17 | "connectTimeout": 6, 18 | "readTimeout": 20, 19 | "sendInParallel": false, 20 | "batchSize": 10000 21 | } 22 | -------------------------------------------------------------------------------- /meter/bucket_counter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "bucket_functions.h" 4 | #include "counter.h" 5 | #include "meter.h" 6 | #include "registry.h" 7 | 8 | namespace atlas { 9 | namespace meter { 10 | class BucketCounter : public Meter, public DistributionSummary { 11 | public: 12 | BucketCounter(Registry* registry, IdPtr id, BucketFunction bucket_function); 13 | std::ostream& Dump(std::ostream& os) const override; 14 | Measurements Measure() const override; 15 | void Record(int64_t amount) noexcept override; 16 | int64_t Count() const noexcept override { return 0; }; 17 | int64_t TotalAmount() const noexcept override { return 0; }; 18 | const char* GetClass() const noexcept override { return "BucketCounter"; } 19 | 20 | private: 21 | Registry* registry_; 22 | BucketFunction bucket_function_; 23 | }; 24 | } // namespace meter 25 | } // namespace atlas 26 | -------------------------------------------------------------------------------- /meter/validation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "id.h" 5 | 6 | namespace atlas { 7 | namespace meter { 8 | 9 | /// Return whether the given tags will pass validation rules done by our 10 | /// backends. It assumes we will fix invalid characters 11 | bool AreTagsValid(const Tags& tags) noexcept; 12 | 13 | struct ValidationIssue { 14 | enum class Level { WARN, ERROR }; 15 | Level level; 16 | std::string description; 17 | 18 | bool operator<(const ValidationIssue& rhs) const noexcept; 19 | std::string ToString() const noexcept; 20 | static ValidationIssue Err(std::string message) noexcept; 21 | static ValidationIssue Warn(std::string message) noexcept; 22 | }; 23 | 24 | using ValidationIssues = std::set; 25 | ValidationIssues AnalyzeTags(const Tags& tags) noexcept; 26 | 27 | } // namespace meter 28 | } // namespace atlas 29 | -------------------------------------------------------------------------------- /interpreter/keep_drop_tags.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "multiple_results.h" 4 | 5 | namespace atlas { 6 | namespace interpreter { 7 | class KeepOrDropTags : public MultipleResults { 8 | public: 9 | KeepOrDropTags(const List& keys, std::shared_ptr expr, 10 | bool keep); 11 | 12 | ExpressionType GetType() const noexcept override { 13 | return ExpressionType::MultipleResults; 14 | } 15 | 16 | std::shared_ptr GetQuery() const noexcept override { 17 | return expr_->GetQuery(); 18 | } 19 | 20 | TagsValuePairs Apply(const TagsValuePairs& measurements) override; 21 | 22 | std::ostream& Dump(std::ostream& os) const override; 23 | 24 | private: 25 | std::unique_ptr keys_; 26 | std::shared_ptr expr_; 27 | bool keep_; 28 | }; 29 | } // namespace interpreter 30 | } // namespace atlas 31 | -------------------------------------------------------------------------------- /test/gauge_test.cc: -------------------------------------------------------------------------------- 1 | #include "../meter/manual_clock.h" 2 | #include "../meter/default_gauge.h" 3 | #include 4 | #include 5 | 6 | using namespace atlas::meter; 7 | 8 | static ManualClock manual_clock; 9 | 10 | static std::unique_ptr newGauge() { 11 | static auto id = std::make_shared("foo", kEmptyTags); 12 | return std::make_unique(id, manual_clock); 13 | } 14 | 15 | TEST(GaugeTest, Value) { 16 | auto g = newGauge(); 17 | manual_clock.SetWall(1); 18 | EXPECT_TRUE(std::isnan(g->Value())); 19 | g->Update(42.0); 20 | EXPECT_DOUBLE_EQ(g->Value(), 42.0); 21 | } 22 | 23 | TEST(GaugeTest, Expiration) { 24 | auto g = newGauge(); 25 | manual_clock.SetWall(1); 26 | g->Update(42.0); 27 | EXPECT_FALSE(g->HasExpired()); 28 | manual_clock.SetWall(MAX_IDLE_TIME + 1000); 29 | EXPECT_TRUE(g->HasExpired()); 30 | } 31 | -------------------------------------------------------------------------------- /interpreter/context.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "expression.h" 6 | #include "query.h" 7 | 8 | namespace atlas { 9 | namespace interpreter { 10 | class Context { 11 | public: 12 | using Stack = std::vector>; 13 | 14 | Context(); 15 | 16 | util::StrRef PopString(); 17 | 18 | std::shared_ptr PopExpression(); 19 | 20 | void Push(const std::shared_ptr& expression); 21 | 22 | void PushToList(std::shared_ptr expression); 23 | 24 | std::size_t StackSize() const noexcept; 25 | 26 | std::ostream& Dump(std::ostream& os) const; 27 | 28 | private: 29 | Stack stack_; 30 | const std::shared_ptr& TopOfStack(); 31 | }; 32 | 33 | std::ostream& operator<<(std::ostream& os, const Context& context); 34 | } // namespace interpreter 35 | } // namespace atlas 36 | -------------------------------------------------------------------------------- /meter/manual_clock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "clock.h" 5 | 6 | namespace atlas { 7 | namespace meter { 8 | class ManualClock : public Clock { 9 | public: 10 | ManualClock(int64_t wall = 0, int64_t monotonic = 0) noexcept 11 | : wall_(wall), monotonic_(monotonic) {} 12 | 13 | virtual int64_t WallTime() const noexcept override { return wall_.load(); } 14 | 15 | virtual int64_t MonotonicTime() const noexcept override { 16 | return monotonic_.load(); 17 | } 18 | 19 | void SetWall(int64_t n) const noexcept { wall_.store(n); } 20 | 21 | void SetMonotonic(int64_t n) const noexcept { monotonic_.store(n); } 22 | 23 | private: 24 | // the following are marked mutable to help with testing 25 | mutable std::atomic wall_; 26 | mutable std::atomic monotonic_; 27 | }; 28 | } // namespace meter 29 | } // namespace atlas 30 | -------------------------------------------------------------------------------- /3rd-party/fmt/printf.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Formatting library for C++ 3 | 4 | Copyright (c) 2012 - 2016, Victor Zverovich 5 | All rights reserved. 6 | 7 | For the license information refer to format.h. 8 | */ 9 | 10 | #include "format.h" 11 | #include "printf.h" 12 | 13 | namespace fmt { 14 | 15 | template 16 | void printf(BasicWriter &w, BasicCStringRef format, ArgList args); 17 | 18 | FMT_FUNC int fprintf(std::FILE *f, CStringRef format, ArgList args) { 19 | MemoryWriter w; 20 | printf(w, format, args); 21 | std::size_t size = w.size(); 22 | return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast(size); 23 | } 24 | 25 | #ifndef FMT_HEADER_ONLY 26 | 27 | template void PrintfFormatter::format(CStringRef format); 28 | template void PrintfFormatter::format(WCStringRef format); 29 | 30 | #endif // FMT_HEADER_ONLY 31 | 32 | } // namespace fmt 33 | -------------------------------------------------------------------------------- /3rd-party/spdlog/details/null_mutex.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2015 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | // null, no cost dummy "mutex" and dummy "atomic" int 10 | 11 | namespace spdlog { 12 | namespace details { 13 | struct null_mutex 14 | { 15 | void lock() {} 16 | void unlock() {} 17 | bool try_lock() 18 | { 19 | return true; 20 | } 21 | }; 22 | 23 | struct null_atomic_int 24 | { 25 | int value; 26 | null_atomic_int() = default; 27 | 28 | explicit null_atomic_int(int val) 29 | : value(val) 30 | { 31 | } 32 | 33 | int load(std::memory_order) const 34 | { 35 | return value; 36 | } 37 | 38 | void store(int val) 39 | { 40 | value = val; 41 | } 42 | }; 43 | 44 | } // namespace details 45 | } // namespace spdlog 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.com/Netflix-Skunkworks/atlas-native-client.svg?branch=master)](https://travis-ci.com/Netflix-Skunkworks/atlas-native-client) 2 | 3 | # Atlas Client Native Library 4 | 5 | > :warning: This library is deprecated. C++ projects should migrate to 6 | [spectator-cpp](https://github.com/Netflix/spectator-cpp) for publishing Atlas 7 | metrics. 8 | 9 | This is the original C++ client implementation, which was intended to be a fully-featured equivalent 10 | of the Java reference implementation, with on-instance alerts, and other items which were deprecated 11 | from the Spectator clients when we moved to using the Light Weight Client infrastructure. 12 | 13 | This is only used by the [atlas-node-client](https://github.com/Netflix-Skunkworks/atlas-node-client) 14 | library, which is deprecated. 15 | 16 | ## Building 17 | 18 | ``` 19 | ./run-build.sh 20 | ./build/runtests 21 | ``` 22 | -------------------------------------------------------------------------------- /3rd-party/benchmark/src/colorprint.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_COLORPRINT_H_ 2 | #define BENCHMARK_COLORPRINT_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace benchmark { 9 | enum LogColor { 10 | COLOR_DEFAULT, 11 | COLOR_RED, 12 | COLOR_GREEN, 13 | COLOR_YELLOW, 14 | COLOR_BLUE, 15 | COLOR_MAGENTA, 16 | COLOR_CYAN, 17 | COLOR_WHITE 18 | }; 19 | 20 | std::string FormatString(const char* msg, va_list args); 21 | std::string FormatString(const char* msg, ...); 22 | 23 | void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, 24 | va_list args); 25 | void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...); 26 | 27 | // Returns true if stdout appears to be a terminal that supports colored 28 | // output, false otherwise. 29 | bool IsColorTerminal(); 30 | 31 | } // end namespace benchmark 32 | 33 | #endif // BENCHMARK_COLORPRINT_H_ 34 | -------------------------------------------------------------------------------- /util/string_pool.cc: -------------------------------------------------------------------------------- 1 | #include "string_pool.h" 2 | 3 | namespace atlas { 4 | namespace util { 5 | 6 | StringPool& the_str_pool() noexcept { 7 | static auto* the_pool = new StringPool(); 8 | return *the_pool; 9 | } 10 | 11 | StringPool::~StringPool() noexcept { 12 | for (const auto& kv : table) { 13 | auto copy = static_cast(const_cast(kv.first)); 14 | free(copy); 15 | } 16 | } 17 | 18 | const StrRef& StringPool::intern(const char* string) noexcept { 19 | std::lock_guard guard(mutex); 20 | auto it = table.find(string); 21 | if (it != table.end()) { 22 | return it->second; 23 | } 24 | const auto* copy = strdup(string); 25 | StrRef ref; 26 | ref.data = copy; 27 | auto added = table.insert(std::make_pair(copy, ref)); 28 | alloc_size_ += strlen(copy) + 1; // null terminator 29 | return added.first->second; 30 | } 31 | 32 | } // namespace util 33 | } // namespace atlas 34 | -------------------------------------------------------------------------------- /gen_perc_bucket_tags.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Number of positions of base-2 digits to shift when iterating over the long 5 | // space. 6 | void output_array(std::ostream& os, size_t size, char prefix, 7 | const std::string& name) { 8 | os << "const std::array" 9 | << " " << name << " = {{"; 10 | bool first = true; 11 | char tag[64]; 12 | for (size_t i = 0; i < size; ++i) { 13 | if (!first) { 14 | os << ",\n"; 15 | } else { 16 | first = false; 17 | } 18 | sprintf(tag, "\"%c%04zX\"", prefix, i); 19 | os << tag; 20 | } 21 | os << "}};\n"; 22 | } 23 | 24 | int main(int argc, char* argv[]) { 25 | std::ofstream of; 26 | if (argc > 1) { 27 | of.open(argv[1]); 28 | } else { 29 | of.open("/dev/stdout"); 30 | } 31 | 32 | output_array(of, 276, 'T', "kTimerTags"); 33 | output_array(of, 276, 'D', "kDistTags"); 34 | } 35 | -------------------------------------------------------------------------------- /main.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "atlas_client.h" 3 | #include "util/logger.h" 4 | #include 5 | #include 6 | 7 | using namespace atlas::meter; 8 | 9 | int main(int argc, char* argv[]) { 10 | atlas::util::UseConsoleLogger(0); 11 | auto logger = atlas::util::Logger(); 12 | atlas::Client atlas_client; 13 | auto cfg = atlas_client.GetConfig(); 14 | logger->info("Disabled File Name {}", cfg->DisabledFileName()); 15 | 16 | atlas_client.Start(); 17 | auto registry = atlas_client.GetRegistry(); 18 | 19 | std::string name{"test.counter"}; 20 | for (int second = 0; second < 60; ++second) { 21 | registry->counter(name, kEmptyTags)->Increment(); 22 | logger->info("Incrementing test.counter: {} ({})", second + 1, 23 | (second + 1) / 60.0); 24 | std::this_thread::sleep_for(std::chrono::seconds(1)); 25 | } 26 | logger->info("Shutting down"); 27 | 28 | atlas_client.Stop(); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /interpreter/all.cc: -------------------------------------------------------------------------------- 1 | #include "all.h" 2 | #include "../meter/id_format.h" 3 | #include "../util/logger.h" 4 | 5 | namespace atlas { 6 | namespace interpreter { 7 | 8 | All::All(std::shared_ptr query) : query_(std::move(query)) {} 9 | 10 | TagsValuePairs All::Apply(const TagsValuePairs& measurements) { 11 | if (query_->GetQueryType() == QueryType::True) { 12 | // fast path 13 | return measurements; 14 | } 15 | 16 | TagsValuePairs result; 17 | auto q = query_.get(); 18 | std::copy_if(measurements.begin(), measurements.end(), 19 | std::back_inserter(result), 20 | [q](const std::shared_ptr& m) { 21 | return !std::isnan(m->value()) && q->Matches(*m); 22 | }); 23 | return result; 24 | } 25 | 26 | std::ostream& All::Dump(std::ostream& os) const { 27 | os << "All(" << *query_ << ")"; 28 | return os; 29 | } 30 | } // namespace interpreter 31 | } // namespace atlas 32 | -------------------------------------------------------------------------------- /interpreter/group_by.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "all.h" 4 | #include "context.h" 5 | #include "expression.h" 6 | 7 | namespace atlas { 8 | namespace interpreter { 9 | 10 | class GroupBy : public MultipleResults { 11 | public: 12 | GroupBy(const List& keys, std::shared_ptr expr); 13 | 14 | ExpressionType GetType() const noexcept override { 15 | return ExpressionType::MultipleResults; 16 | } 17 | 18 | std::shared_ptr GetQuery() const noexcept override { 19 | return expr_->GetQuery(); 20 | } 21 | 22 | TagsValuePairs Apply(const TagsValuePairs& measurements) override; 23 | 24 | std::ostream& Dump(std::ostream& os) const override; 25 | 26 | private: 27 | std::unique_ptr keys_; 28 | std::shared_ptr expr_; 29 | }; 30 | 31 | std::shared_ptr GetMultipleResultsExpr( 32 | std::shared_ptr e); 33 | 34 | } // namespace interpreter 35 | } // namespace atlas 36 | -------------------------------------------------------------------------------- /meter/bucket_distribution_summary.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "bucket_functions.h" 4 | #include "counter.h" 5 | #include "meter.h" 6 | #include "registry.h" 7 | 8 | namespace atlas { 9 | namespace meter { 10 | class BucketDistributionSummary : public Meter, public DistributionSummary { 11 | public: 12 | BucketDistributionSummary(Registry* registry, IdPtr id, 13 | BucketFunction bucket_function); 14 | std::ostream& Dump(std::ostream& os) const override; 15 | Measurements Measure() const override; 16 | void Record(int64_t amount) noexcept override; 17 | int64_t Count() const noexcept override { return 0; }; 18 | int64_t TotalAmount() const noexcept override { return 0; }; 19 | const char* GetClass() const noexcept override { 20 | return "BucketDistributionSummary"; 21 | } 22 | 23 | private: 24 | Registry* registry_; 25 | BucketFunction bucket_function_; 26 | }; 27 | } // namespace meter 28 | } // namespace atlas 29 | -------------------------------------------------------------------------------- /meter/interval_counter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "counter.h" 4 | #include "function_gauge.h" 5 | #include "registry.h" 6 | 7 | namespace atlas { 8 | namespace meter { 9 | 10 | class IntervalCounter : public Meter, public Counter { 11 | public: 12 | IntervalCounter(Registry* registry, const IdPtr& id); 13 | ~IntervalCounter() override = default; 14 | 15 | void Increment() noexcept override; 16 | void Add(int64_t amount) noexcept override; 17 | int64_t Count() const noexcept override; 18 | double SecondsSinceLastUpdate() const noexcept; 19 | 20 | std::ostream& Dump(std::ostream& os) const override; 21 | Measurements Measure() const override; 22 | const char* GetClass() const noexcept override { return "IntervalCounter"; } 23 | 24 | private: 25 | std::shared_ptr counter_; 26 | std::shared_ptr counter_updated; 27 | std::shared_ptr> gauge_; 28 | }; 29 | 30 | } // namespace meter 31 | } // namespace atlas 32 | -------------------------------------------------------------------------------- /meter/subscription.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../interpreter/tags_value.h" 4 | #include 5 | 6 | namespace atlas { 7 | namespace meter { 8 | 9 | /// A subscription to an expression that needs to be sent to a server 10 | /// at a given interval 11 | struct Subscription { 12 | const std::string id; 13 | const int64_t frequency; 14 | const std::string expression; 15 | }; 16 | 17 | inline bool operator==(const Subscription& lhs, const Subscription& rhs) { 18 | return lhs.frequency == rhs.frequency && lhs.id == rhs.id && 19 | lhs.expression == rhs.expression; 20 | } 21 | 22 | using DataExpressionResults = std::vector; 23 | 24 | struct SubscriptionMetric { 25 | const std::string id; 26 | const Tags tags; 27 | const double value; 28 | }; 29 | 30 | using SubscriptionResults = std::vector; 31 | 32 | using Subscriptions = std::vector; 33 | } // namespace meter 34 | } // namespace atlas 35 | -------------------------------------------------------------------------------- /meter/id_format.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "id.h" 4 | #include 5 | #include 6 | 7 | namespace atlas { 8 | namespace meter { 9 | 10 | inline std::ostream& operator<<(std::ostream& os, const Tags& tags) { 11 | bool first = true; 12 | os << '['; 13 | for (const auto& tag : tags) { 14 | if (first) { 15 | first = false; 16 | } else { 17 | os << ", "; 18 | } 19 | os << tag.first.get() << "->" << tag.second.get(); 20 | } 21 | os << ']'; 22 | return os; 23 | } 24 | 25 | } // namespace meter 26 | } // namespace atlas 27 | 28 | namespace std { 29 | 30 | inline ostream& operator<<(ostream& os, const vector& vs) { 31 | os << '['; 32 | auto it = vs.begin(); 33 | const auto& end = vs.end(); 34 | if (it != end) { 35 | os << *it; 36 | ++it; 37 | } 38 | for (; it != end; ++it) { 39 | os << ','; 40 | os << *it; 41 | } 42 | os << ']'; 43 | return os; 44 | } 45 | 46 | } // namespace std 47 | -------------------------------------------------------------------------------- /meter/bucket_counter.cc: -------------------------------------------------------------------------------- 1 | #include "bucket_counter.h" 2 | 3 | #include 4 | namespace atlas { 5 | namespace meter { 6 | 7 | BucketCounter::BucketCounter(Registry* registry, IdPtr id, 8 | BucketFunction bucket_function) 9 | : Meter{std::move(id), registry->clock()}, 10 | registry_{registry}, 11 | bucket_function_{std::move(bucket_function)} {} 12 | 13 | std::ostream& BucketCounter::Dump(std::ostream& os) const { 14 | os << "BucketCounter{" << *id_ << "}"; 15 | return os; 16 | } 17 | 18 | static const Measurements kEmptyMeasurements; 19 | Measurements BucketCounter::Measure() const { return kEmptyMeasurements; } 20 | 21 | void BucketCounter::Record(int64_t amount) noexcept { 22 | static const std::string kBucket{"bucket"}; 23 | const auto& bucket = bucket_function_(amount); 24 | registry_->counter(id_->WithTag(Tag::of(kBucket, bucket)))->Increment(); 25 | Updated(); 26 | } 27 | 28 | } // namespace meter 29 | } // namespace atlas 30 | -------------------------------------------------------------------------------- /test/steplong_test.cc: -------------------------------------------------------------------------------- 1 | #include "../meter/manual_clock.h" 2 | #include "../meter/stepnumber.h" 3 | #include 4 | 5 | using namespace ::atlas::meter; 6 | 7 | TEST(StepLong, Init) { 8 | ManualClock manual_clock; 9 | StepLong s(0, 10, &manual_clock); 10 | EXPECT_EQ(0, s.Current()); 11 | EXPECT_EQ(0, s.Poll()); 12 | } 13 | 14 | TEST(StepLong, Increment) { 15 | ManualClock manual_clock; 16 | StepLong s(0, 10, &manual_clock); 17 | s.Add(1); 18 | EXPECT_EQ(1, s.Current()); 19 | EXPECT_EQ(0, s.Poll()); 20 | } 21 | 22 | TEST(StepLong, IncrementAndCrossStep) { 23 | ManualClock manual_clock; 24 | StepLong s(0, 10, &manual_clock); 25 | s.Add(1); 26 | manual_clock.SetWall(10); 27 | EXPECT_EQ(0, s.Current()); 28 | EXPECT_EQ(1, s.Poll()); 29 | } 30 | 31 | TEST(StepLong, MissedRead) { 32 | ManualClock manual_clock; 33 | StepLong s(0, 10, &manual_clock); 34 | s.Add(1); 35 | manual_clock.SetWall(20); 36 | EXPECT_EQ(0, s.Current()); 37 | EXPECT_EQ(0, s.Poll()); 38 | } -------------------------------------------------------------------------------- /meter/measurement.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "id.h" 4 | #include 5 | #include 6 | 7 | namespace atlas { 8 | namespace meter { 9 | 10 | struct Measurement { 11 | IdPtr id; 12 | int64_t timestamp; 13 | double value; 14 | 15 | bool operator==(const Measurement& other) const { 16 | return other.timestamp == timestamp && 17 | std::abs(value - other.value) < 1e-9 && *id == *(other.id); 18 | } 19 | }; 20 | 21 | inline std::ostream& operator<<(std::ostream& os, const Measurement& m) { 22 | os << "Measurement{" << *(m.id) << "," << m.timestamp << "," << m.value 23 | << "}"; 24 | return os; 25 | } 26 | 27 | inline Measurement factor_measurement(Measurement measurement, 28 | double conv_factor) { 29 | return Measurement{measurement.id, measurement.timestamp, 30 | measurement.value * conv_factor}; 31 | } 32 | 33 | using Measurements = std::vector; 34 | } // namespace meter 35 | } // namespace atlas 36 | -------------------------------------------------------------------------------- /meter/subscription_format.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "subscription.h" 4 | #include "id_format.h" 5 | #include 6 | 7 | namespace atlas { 8 | namespace meter { 9 | 10 | std::ostream& operator<<(std::ostream& os, const Subscription& subscription) { 11 | os << "Subscription{" << subscription.id << "," << subscription.frequency 12 | << "," << subscription.expression << "}"; 13 | return os; 14 | } 15 | 16 | std::ostream& operator<<(std::ostream& os, 17 | const std::vector& subscriptions) { 18 | os << "Subscriptions:[\n"; 19 | for (const auto& s : subscriptions) { 20 | os << "\t{" << s.id << "," << s.frequency << "," << s.expression << "\n"; 21 | } 22 | os << ']'; 23 | return os; 24 | } 25 | 26 | std::ostream& operator<<(std::ostream& os, const SubscriptionMetric& s) { 27 | os << "SubMetric{id=" << s.id << ",tags=" << s.tags << ",v=" << s.value 28 | << "}"; 29 | return os; 30 | } 31 | 32 | } // namespace meter 33 | } // namespace atlas 34 | -------------------------------------------------------------------------------- /3rd-party/fmt/ostream.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Formatting library for C++ - std::ostream support 3 | 4 | Copyright (c) 2012 - 2016, Victor Zverovich 5 | All rights reserved. 6 | 7 | For the license information refer to format.h. 8 | */ 9 | 10 | #include "ostream.h" 11 | 12 | namespace fmt { 13 | 14 | namespace internal { 15 | FMT_FUNC void write(std::ostream &os, Writer &w) { 16 | const char *data = w.data(); 17 | typedef internal::MakeUnsigned::Type UnsignedStreamSize; 18 | UnsignedStreamSize size = w.size(); 19 | UnsignedStreamSize max_size = 20 | internal::to_unsigned((std::numeric_limits::max)()); 21 | do { 22 | UnsignedStreamSize n = size <= max_size ? size : max_size; 23 | os.write(data, static_cast(n)); 24 | data += n; 25 | size -= n; 26 | } while (size != 0); 27 | } 28 | } 29 | 30 | FMT_FUNC void print(std::ostream &os, CStringRef format_str, ArgList args) { 31 | MemoryWriter w; 32 | w.write(format_str, args); 33 | internal::write(os, w); 34 | } 35 | } // namespace fmt 36 | -------------------------------------------------------------------------------- /meter/default_timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "default_counter.h" 4 | #include "default_max_gauge.h" 5 | #include "timer.h" 6 | 7 | namespace atlas { 8 | namespace meter { 9 | 10 | class DefaultTimer : public Meter, public Timer { 11 | public: 12 | DefaultTimer(const IdPtr& id, const Clock& clock, int64_t freq_millis); 13 | 14 | Measurements Measure() const override; 15 | 16 | std::ostream& Dump(std::ostream& os) const override; 17 | 18 | void Record(std::chrono::nanoseconds nanos) override; 19 | 20 | int64_t Count() const noexcept override; 21 | 22 | int64_t TotalTime() const noexcept override; 23 | 24 | const char* GetClass() const noexcept override { return "DefaultTimer"; } 25 | 26 | private: 27 | // used to conform to the API for timer 28 | std::atomic count_; 29 | std::atomic total_time_; 30 | 31 | DefaultCounter sub_count_; 32 | DefaultDoubleCounter sub_total_sq_; 33 | DefaultCounter sub_total_time_; 34 | DefaultMaxGaugeInt sub_max_; 35 | }; 36 | } // namespace meter 37 | } // namespace atlas 38 | -------------------------------------------------------------------------------- /meter/clock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace atlas { 7 | namespace meter { 8 | class Clock { 9 | public: 10 | virtual int64_t WallTime() const noexcept = 0; 11 | 12 | virtual int64_t MonotonicTime() const noexcept = 0; 13 | 14 | virtual ~Clock() = default; 15 | }; 16 | 17 | class SystemClock : public Clock { 18 | public: 19 | int64_t WallTime() const noexcept override; 20 | 21 | int64_t MonotonicTime() const noexcept override; 22 | }; 23 | 24 | class WrappedClock : public Clock { 25 | public: 26 | explicit WrappedClock(const Clock* clock) : underlying_(clock) {} 27 | void SetOffset(int offset) { offset_ = offset; } 28 | int64_t WallTime() const noexcept override { 29 | return underlying_->WallTime() + offset_; 30 | } 31 | int64_t MonotonicTime() const noexcept override { 32 | return underlying_->MonotonicTime() + offset_ * 1000000; 33 | } 34 | 35 | private: 36 | const Clock* underlying_; 37 | int offset_ = 0; 38 | }; 39 | 40 | } // namespace meter 41 | } // namespace atlas 42 | -------------------------------------------------------------------------------- /test/system_clock_test.cc: -------------------------------------------------------------------------------- 1 | #include "../meter/clock.h" 2 | #include 3 | 4 | using atlas::meter::SystemClock; 5 | using atlas::meter::WrappedClock; 6 | 7 | TEST(SystemClock, WallTime) { 8 | SystemClock clock; 9 | 10 | auto clock_now = clock.WallTime(); 11 | auto secs = time(nullptr); 12 | 13 | auto clock_secs = clock_now / 1000; 14 | EXPECT_LE(std::abs(secs - clock_secs), 1); 15 | } 16 | 17 | TEST(WrappedClock, WallTimeOffset) { 18 | SystemClock sys_clock; 19 | WrappedClock clock{&sys_clock}; 20 | 21 | clock.SetOffset(5000); 22 | auto clock_now = clock.WallTime(); 23 | auto secs = time(nullptr); 24 | 25 | auto clock_secs = clock_now / 1000; 26 | auto delta = std::abs(secs - clock_secs); 27 | EXPECT_TRUE(delta >= 5 && delta <= 6); 28 | } 29 | 30 | TEST(SystemClock, MonotonicTime) { 31 | SystemClock clock; 32 | for (auto j = 0; j < 10; ++j) { 33 | auto prev = clock.MonotonicTime(); 34 | for (auto i = 0; i < 100; ++i) { 35 | auto now = clock.MonotonicTime(); 36 | EXPECT_GE(now - prev, 0); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /meter/bucket_distribution_summary.cc: -------------------------------------------------------------------------------- 1 | #include "bucket_distribution_summary.h" 2 | 3 | #include 4 | 5 | namespace atlas { 6 | namespace meter { 7 | 8 | BucketDistributionSummary::BucketDistributionSummary( 9 | Registry* registry, IdPtr id, BucketFunction bucket_function) 10 | : Meter{std::move(id), registry->clock()}, 11 | registry_{registry}, 12 | bucket_function_{std::move(bucket_function)} {} 13 | 14 | std::ostream& BucketDistributionSummary::Dump(std::ostream& os) const { 15 | os << "BucketDistributionSummary{" << *id_ << "}"; 16 | return os; 17 | } 18 | 19 | static const Measurements kEmptyMeasurements; 20 | Measurements BucketDistributionSummary::Measure() const { 21 | return kEmptyMeasurements; 22 | } 23 | 24 | void BucketDistributionSummary::Record(int64_t amount) noexcept { 25 | static const std::string kBucket{"bucket"}; 26 | const auto& bucket = bucket_function_(amount); 27 | registry_->distribution_summary(id_->WithTag(Tag::of(kBucket, bucket))) 28 | ->Record(amount); 29 | Updated(); 30 | } 31 | 32 | } // namespace meter 33 | } // namespace atlas 34 | -------------------------------------------------------------------------------- /3rd-party/benchmark/src/counter.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "benchmark/benchmark.h" 16 | 17 | namespace benchmark { 18 | 19 | // these counter-related functions are hidden to reduce API surface. 20 | namespace internal { 21 | void Finish(UserCounters *l, double time, double num_threads); 22 | void Increment(UserCounters *l, UserCounters const& r); 23 | bool SameNames(UserCounters const& l, UserCounters const& r); 24 | } // end namespace internal 25 | 26 | } //end namespace benchmark 27 | -------------------------------------------------------------------------------- /util/buffer.cc: -------------------------------------------------------------------------------- 1 | #include "buffer.h" 2 | #include "gzip.h" 3 | #include "logger.h" 4 | 5 | namespace atlas { 6 | namespace util { 7 | 8 | void Buffer::append(void* data, size_t data_size) { 9 | auto* p = static_cast(data); 10 | buf.insert(buf.end(), p, p + data_size); 11 | } 12 | 13 | void Buffer::assign(std::string* s) { s->assign(buf.begin(), buf.end()); } 14 | 15 | void Buffer::uncompress_to(std::string* s) { 16 | auto res = inflate_string(s, buf.data(), buf.size()); 17 | if (res != Z_OK) { 18 | std::string err_msg; 19 | switch (res) { 20 | case Z_MEM_ERROR: 21 | err_msg = "Out of memory"; 22 | break; 23 | case Z_DATA_ERROR: 24 | err_msg = "Invalid or incomplete compressed data"; 25 | break; 26 | case Z_STREAM_ERROR: 27 | err_msg = "Invalid compression level"; 28 | break; 29 | default: 30 | err_msg = std::to_string(res); 31 | } 32 | Logger()->error("Unable to decompress payload (compressed size={}) err={}", 33 | buf.size(), err_msg); 34 | } 35 | } 36 | 37 | } // namespace util 38 | } // namespace atlas 39 | -------------------------------------------------------------------------------- /meter/publisher.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../interpreter/tags_value.h" 4 | #include "../meter/subscription.h" 5 | #include "../util/config.h" 6 | #include "../util/http.h" 7 | #include "registry.h" 8 | 9 | namespace atlas { 10 | namespace meter { 11 | 12 | class Publisher { 13 | public: 14 | explicit Publisher(std::shared_ptr registry) noexcept 15 | : registry_(std::move(registry)) {} 16 | 17 | void PushMeasurements(const util::Config& config, int64_t now_millis, 18 | const interpreter::TagsValuePairs& measurements) const 19 | noexcept; 20 | void SendSubscriptions(const util::Config& config, int64_t freq_millis, 21 | const SubscriptionResults& sub_results) const noexcept; 22 | 23 | private: 24 | std::shared_ptr registry_; 25 | 26 | void batch_to_lwc( 27 | const util::http& client, const util::Config& config, int64_t freq_millis, 28 | const meter::SubscriptionResults::const_iterator& first, 29 | const meter::SubscriptionResults::const_iterator& last) const noexcept; 30 | }; 31 | 32 | } // namespace meter 33 | } // namespace atlas 34 | -------------------------------------------------------------------------------- /meter/percentile_timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "meter.h" 5 | #include "percentile_buckets.h" 6 | #include "registry.h" 7 | #include "timer.h" 8 | 9 | namespace atlas { 10 | namespace meter { 11 | 12 | class PercentileTimer : public Meter, public Timer { 13 | public: 14 | PercentileTimer(Registry* registry, const IdPtr& id); 15 | void Record(std::chrono::nanoseconds nanos) noexcept override; 16 | std::ostream& Dump(std::ostream& os) const override; 17 | Measurements Measure() const override { return Measurements(); }; 18 | int64_t Count() const noexcept override { return timer_->Count(); } 19 | int64_t TotalTime() const noexcept override { return timer_->TotalTime(); } 20 | double Percentile(double p) const noexcept; 21 | const char* GetClass() const noexcept override { return "PercentileTimer"; } 22 | 23 | private: 24 | Registry* registry_; 25 | std::shared_ptr timer_; 26 | mutable std::array, percentile_buckets::Length()> 27 | counters_; 28 | std::shared_ptr CounterFor(size_t i) const noexcept; 29 | }; 30 | 31 | } // namespace meter 32 | } // namespace atlas 33 | -------------------------------------------------------------------------------- /meter/bucket_timer.cc: -------------------------------------------------------------------------------- 1 | #include "bucket_timer.h" 2 | 3 | #include 4 | namespace atlas { 5 | namespace meter { 6 | 7 | BucketTimer::BucketTimer(Registry* registry, IdPtr id, 8 | BucketFunction bucket_function) 9 | : Meter{std::move(id), registry->clock()}, 10 | registry_{registry}, 11 | bucket_function_{std::move(bucket_function)} {} 12 | 13 | std::ostream& BucketTimer::Dump(std::ostream& os) const { 14 | os << "BucketTimer{" << *id_ << "}"; 15 | return os; 16 | } 17 | 18 | static const Measurements kEmptyMeasurements; 19 | Measurements BucketTimer::Measure() const { return kEmptyMeasurements; } 20 | 21 | static const std::string kBucket{"bucket"}; 22 | 23 | void BucketTimer::Record(std::chrono::nanoseconds duration) { 24 | const auto& bucket = bucket_function_(duration.count()); 25 | registry_->timer(id_->WithTag(Tag::of(kBucket, bucket)))->Record(duration); 26 | Updated(); 27 | } 28 | 29 | // not supported 30 | int64_t BucketTimer::Count() const noexcept { return 0; } 31 | 32 | // not supported 33 | int64_t BucketTimer::TotalTime() const noexcept { return 0; } 34 | 35 | } // namespace meter 36 | } // namespace atlas 37 | -------------------------------------------------------------------------------- /meter/default_long_task_timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "long_task_timer.h" 4 | #include 5 | #include 6 | #include 7 | 8 | namespace atlas { 9 | namespace meter { 10 | 11 | class DefaultLongTaskTimer : public Meter, public LongTaskTimer { 12 | public: 13 | DefaultLongTaskTimer(IdPtr id, const Clock& clock); 14 | 15 | Measurements Measure() const override; 16 | 17 | std::ostream& Dump(std::ostream& os) const override; 18 | 19 | int64_t Start() override; 20 | 21 | int64_t Stop(int64_t task) override; 22 | 23 | int64_t Duration(int64_t task) const noexcept override; 24 | 25 | int64_t Duration() const noexcept override; 26 | 27 | int ActiveTasks() const noexcept override; 28 | 29 | // Long task timers don't expire 30 | bool HasExpired() const noexcept override { return false; } 31 | 32 | const char* GetClass() const noexcept override { 33 | return "DefaultLongTaskTimer"; 34 | }; 35 | 36 | private: 37 | static const int EXPECTED_TASKS = 8; 38 | std::atomic next_; 39 | mutable std::mutex tasks_mutex_; 40 | ska::flat_hash_map tasks_; 41 | }; 42 | } // namespace meter 43 | } // namespace atlas 44 | -------------------------------------------------------------------------------- /3rd-party/benchmark/src/string_util.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_STRING_UTIL_H_ 2 | #define BENCHMARK_STRING_UTIL_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "internal_macros.h" 8 | 9 | namespace benchmark { 10 | 11 | void AppendHumanReadable(int n, std::string* str); 12 | 13 | std::string HumanReadableNumber(double n, double one_k = 1024.0); 14 | 15 | std::string StringPrintF(const char* format, ...); 16 | 17 | inline std::ostream& StringCatImp(std::ostream& out) BENCHMARK_NOEXCEPT { 18 | return out; 19 | } 20 | 21 | template 22 | inline std::ostream& StringCatImp(std::ostream& out, First&& f, 23 | Rest&&... rest) { 24 | out << std::forward(f); 25 | return StringCatImp(out, std::forward(rest)...); 26 | } 27 | 28 | template 29 | inline std::string StrCat(Args&&... args) { 30 | std::ostringstream ss; 31 | StringCatImp(ss, std::forward(args)...); 32 | return ss.str(); 33 | } 34 | 35 | void ReplaceAll(std::string* str, const std::string& from, 36 | const std::string& to); 37 | 38 | } // end namespace benchmark 39 | 40 | #endif // BENCHMARK_STRING_UTIL_H_ 41 | -------------------------------------------------------------------------------- /util/string_pool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "intern.h" 4 | #include "xxhash.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace atlas { 11 | namespace util { 12 | 13 | struct CStrHasher { 14 | size_t operator()(const char* str) const { 15 | return XXH64(str, std::strlen(str), 42); 16 | } 17 | }; 18 | 19 | struct CStrComparer { 20 | bool operator()(const char* s1, const char* s2) const { 21 | return std::strcmp(s1, s2) == 0; 22 | } 23 | }; 24 | 25 | class StringPool { 26 | public: 27 | StringPool() noexcept {} 28 | ~StringPool() noexcept; 29 | StringPool(const StringPool& pool) = delete; 30 | StringPool& operator=(const StringPool& pool) = delete; 31 | 32 | const StrRef& intern(const char* string) noexcept; 33 | 34 | size_t pool_size() const noexcept { return table.size(); } 35 | 36 | size_t alloc_size() const noexcept { return alloc_size_; } 37 | 38 | private: 39 | ska::flat_hash_map table; 40 | size_t alloc_size_ = 0; 41 | 42 | std::mutex mutex; 43 | }; 44 | 45 | StringPool& the_str_pool() noexcept; 46 | } // namespace util 47 | } // namespace atlas 48 | -------------------------------------------------------------------------------- /3rd-party/spdlog/sinks/msvc_sink.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2016 Alexander Dalshov. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | 8 | #if defined(_WIN32) 9 | 10 | #include "spdlog/details/null_mutex.h" 11 | #include "spdlog/sinks/base_sink.h" 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace spdlog { 19 | namespace sinks { 20 | /* 21 | * MSVC sink (logging using OutputDebugStringA) 22 | */ 23 | template 24 | class msvc_sink : public base_sink 25 | { 26 | public: 27 | explicit msvc_sink() {} 28 | 29 | protected: 30 | void sink_it_(const details::log_msg &msg) override 31 | { 32 | 33 | fmt::memory_buffer formatted; 34 | sink::formatter_->format(msg, formatted); 35 | OutputDebugStringA(fmt::to_string(formatted).c_str()); 36 | } 37 | 38 | void flush_() override {} 39 | }; 40 | 41 | using msvc_sink_mt = msvc_sink; 42 | using msvc_sink_st = msvc_sink; 43 | 44 | using windebug_sink_mt = msvc_sink_mt; 45 | using windebug_sink_st = msvc_sink_st; 46 | 47 | } // namespace sinks 48 | } // namespace spdlog 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /3rd-party/benchmark/.travis-libcxx-setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Install a newer CMake version 4 | curl -sSL https://cmake.org/files/v3.6/cmake-3.6.1-Linux-x86_64.sh -o install-cmake.sh 5 | chmod +x install-cmake.sh 6 | sudo ./install-cmake.sh --prefix=/usr/local --skip-license 7 | 8 | # Checkout LLVM sources 9 | git clone --depth=1 https://github.com/llvm-mirror/llvm.git llvm-source 10 | git clone --depth=1 https://github.com/llvm-mirror/libcxx.git llvm-source/projects/libcxx 11 | git clone --depth=1 https://github.com/llvm-mirror/libcxxabi.git llvm-source/projects/libcxxabi 12 | 13 | # Setup libc++ options 14 | if [ -z "$BUILD_32_BITS" ]; then 15 | export BUILD_32_BITS=OFF && echo disabling 32 bit build 16 | fi 17 | 18 | # Build and install libc++ (Use unstable ABI for better sanitizer coverage) 19 | mkdir llvm-build && cd llvm-build 20 | cmake -DCMAKE_C_COMPILER=${C_COMPILER} -DCMAKE_CXX_COMPILER=${COMPILER} \ 21 | -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr \ 22 | -DLIBCXX_ABI_UNSTABLE=ON \ 23 | -DLLVM_USE_SANITIZER=${LIBCXX_SANITIZER} \ 24 | -DLLVM_BUILD_32_BITS=${BUILD_32_BITS} \ 25 | ../llvm-source 26 | make cxx -j2 27 | sudo make install-cxxabi install-cxx 28 | cd ../ 29 | -------------------------------------------------------------------------------- /meter/percentile_dist_summary.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "distribution_summary.h" 4 | #include "meter.h" 5 | #include "percentile_buckets.h" 6 | #include "registry.h" 7 | 8 | #include 9 | 10 | namespace atlas { 11 | namespace meter { 12 | 13 | class PercentileDistributionSummary : public Meter, public DistributionSummary { 14 | public: 15 | PercentileDistributionSummary(Registry* registry, const IdPtr& id); 16 | void Record(int64_t amount) noexcept override; 17 | std::ostream& Dump(std::ostream& os) const override; 18 | Measurements Measure() const override { return Measurements(); }; 19 | int64_t Count() const noexcept override { return dist_->Count(); } 20 | int64_t TotalAmount() const noexcept override { return dist_->TotalAmount(); } 21 | double Percentile(double p) const noexcept; 22 | const char* GetClass() const noexcept override { 23 | return "PercentileDistributionSummary"; 24 | } 25 | 26 | private: 27 | Registry* registry_; 28 | std::shared_ptr dist_; 29 | mutable std::array, percentile_buckets::Length()> 30 | counters_; 31 | std::shared_ptr CounterFor(size_t i) const noexcept; 32 | }; 33 | 34 | } // namespace meter 35 | } // namespace atlas 36 | -------------------------------------------------------------------------------- /util/intern.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace atlas { 8 | namespace util { 9 | 10 | class StringPool; 11 | 12 | class StrRef { 13 | public: 14 | StrRef() = default; 15 | bool operator==(const StrRef& rhs) const { return data == rhs.data; } 16 | bool operator!=(const StrRef& rhs) const { return data != rhs.data; } 17 | const char* get() const { return data; } 18 | bool is_null() const { return data == nullptr; } 19 | bool valid() const { return data != nullptr; } 20 | size_t length() const { return std::strlen(data); } 21 | 22 | private: 23 | const char* data = nullptr; 24 | friend std::hash; 25 | friend StringPool; 26 | }; 27 | 28 | const StrRef& intern_str(const char* string); 29 | const StrRef& intern_str(const std::string& string); 30 | } // namespace util 31 | } // namespace atlas 32 | 33 | namespace std { 34 | template <> 35 | struct hash { 36 | size_t operator()(const atlas::util::StrRef& ref) const { 37 | auto pointer_value = reinterpret_cast(ref.data); 38 | // get rid of lower bits since the pointer will usually be 16-byte aligned 39 | return pointer_value >> 4; 40 | } 41 | }; 42 | } // namespace std 43 | -------------------------------------------------------------------------------- /util/collections.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | template 6 | void append_to_set(std::unordered_set* dest, 7 | std::unordered_set&& to_append) { 8 | dest->reserve(dest->size() + to_append.size()); 9 | for (auto&& item : to_append) { 10 | dest->emplace(std::move(item)); 11 | } 12 | } 13 | 14 | template 15 | void append_to_vector(std::vector* dest, std::vector&& to_append) { 16 | dest->reserve(dest->size() + to_append.size()); 17 | for (auto&& item : to_append) { 18 | dest->emplace_back(std::move(item)); 19 | } 20 | } 21 | 22 | template 23 | std::vector vector_concat(std::vector&& v1, std::vector&& v2) { 24 | std::vector result{v1}; 25 | append_to_vector(&result, std::move(v2)); 26 | return result; 27 | } 28 | 29 | template 30 | std::vector vector_cross_product(const std::vector& v1, 31 | const std::vector& v2, Fact factory) { 32 | std::vector result; 33 | result.reserve(v1.size() * v2.size()); 34 | for (auto& i1 : v1) { 35 | for (auto& i2 : v2) { 36 | result.emplace_back(factory(i1, i2)); 37 | } 38 | } 39 | return result; 40 | } -------------------------------------------------------------------------------- /interpreter/evaluator.cc: -------------------------------------------------------------------------------- 1 | #include "evaluator.h" 2 | #include "group_by.h" 3 | 4 | namespace atlas { 5 | namespace interpreter { 6 | 7 | Evaluator::Evaluator() noexcept 8 | : interpreter_(std::make_unique()) {} 9 | 10 | TagsValuePairs Evaluator::eval(const std::string& expression, 11 | const TagsValuePairs& measurements) const 12 | noexcept { 13 | auto results = TagsValuePairs(); 14 | 15 | if (measurements.empty()) { 16 | return results; 17 | } 18 | 19 | interpreter::Context context; 20 | interpreter_.Execute(&context, expression); 21 | 22 | // for each expression on the stack 23 | while (context.StackSize() > 0) { 24 | auto by = interpreter::GetMultipleResultsExpr(context.PopExpression()); 25 | if (by) { 26 | auto expression_result = by->Apply(measurements); 27 | std::move(expression_result.begin(), expression_result.end(), 28 | std::back_inserter(results)); 29 | } 30 | } 31 | 32 | return results; 33 | } 34 | 35 | std::shared_ptr Evaluator::get_query(const std::string& expression) const 36 | noexcept { 37 | return interpreter_.GetQuery(expression); 38 | } 39 | 40 | } // namespace interpreter 41 | } // namespace atlas 42 | -------------------------------------------------------------------------------- /3rd-party/benchmark/src/arraysize.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_ARRAYSIZE_H_ 2 | #define BENCHMARK_ARRAYSIZE_H_ 3 | 4 | #include "internal_macros.h" 5 | 6 | namespace benchmark { 7 | namespace internal { 8 | // The arraysize(arr) macro returns the # of elements in an array arr. 9 | // The expression is a compile-time constant, and therefore can be 10 | // used in defining new arrays, for example. If you use arraysize on 11 | // a pointer by mistake, you will get a compile-time error. 12 | // 13 | 14 | // This template function declaration is used in defining arraysize. 15 | // Note that the function doesn't need an implementation, as we only 16 | // use its type. 17 | template 18 | char (&ArraySizeHelper(T (&array)[N]))[N]; 19 | 20 | // That gcc wants both of these prototypes seems mysterious. VC, for 21 | // its part, can't decide which to use (another mystery). Matching of 22 | // template overloads: the final frontier. 23 | #ifndef COMPILER_MSVC 24 | template 25 | char (&ArraySizeHelper(const T (&array)[N]))[N]; 26 | #endif 27 | 28 | #define arraysize(array) (sizeof(::benchmark::internal::ArraySizeHelper(array))) 29 | 30 | } // end namespace internal 31 | } // end namespace benchmark 32 | 33 | #endif // BENCHMARK_ARRAYSIZE_H_ 34 | -------------------------------------------------------------------------------- /interpreter/aggregation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "expression.h" 4 | #include "query.h" 5 | 6 | namespace atlas { 7 | namespace interpreter { 8 | 9 | enum class Aggregate { COUNT, SUM, MAX, MIN, AVG }; 10 | 11 | class AggregateExpression : public ValueExpression { 12 | public: 13 | AggregateExpression(Aggregate aggregate, std::shared_ptr filter); 14 | 15 | virtual std::ostream& Dump(std::ostream& os) const override; 16 | 17 | virtual std::unique_ptr Apply( 18 | const TagsValuePairs& tagsValuePairs) const override; 19 | 20 | std::shared_ptr GetQuery() const noexcept override { return filter_; } 21 | 22 | private: 23 | Aggregate aggregate_; 24 | std::shared_ptr filter_; 25 | }; 26 | 27 | namespace aggregation { 28 | 29 | std::unique_ptr count(std::shared_ptr filter); 30 | 31 | std::unique_ptr sum(std::shared_ptr filter); 32 | 33 | std::unique_ptr max(std::shared_ptr filter); 34 | 35 | std::unique_ptr min(std::shared_ptr filter); 36 | 37 | std::unique_ptr avg(std::shared_ptr filter); 38 | } // namespace aggregation 39 | } // namespace interpreter 40 | } // namespace atlas 41 | -------------------------------------------------------------------------------- /gen_valid_chars.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void dump_array(std::ostream& os, const std::string& name, 5 | const std::array& chars) { 6 | os << "const std::array " << name << " = {{"; 7 | os.setf(std::ios::boolalpha); 8 | 9 | os << chars[0]; 10 | for (auto i = 1u; i < chars.size(); ++i) { 11 | os << ", " << chars[i]; 12 | } 13 | 14 | os << "}};\n"; 15 | } 16 | 17 | int main(int argc, char* argv[]) { 18 | std::ofstream of; 19 | if (argc > 1) { 20 | of.open(argv[1]); 21 | } else { 22 | of.open("/dev/stdout"); 23 | } 24 | 25 | std::array charsAllowed; 26 | for (int i = 0; i < 128; ++i) { 27 | charsAllowed[i] = false; 28 | } 29 | 30 | charsAllowed['.'] = true; 31 | charsAllowed['-'] = true; 32 | charsAllowed['_'] = true; 33 | 34 | for (auto ch = '0'; ch <= '9'; ++ch) { 35 | charsAllowed[ch] = true; 36 | } 37 | for (auto ch = 'a'; ch <= 'z'; ++ch) { 38 | charsAllowed[ch] = true; 39 | } 40 | for (auto ch = 'A'; ch <= 'Z'; ++ch) { 41 | charsAllowed[ch] = true; 42 | } 43 | 44 | dump_array(of, "kCharsAllowed", charsAllowed); 45 | 46 | charsAllowed['~'] = true; 47 | charsAllowed['^'] = true; 48 | dump_array(of, "kGroupCharsAllowed", charsAllowed); 49 | }; 50 | -------------------------------------------------------------------------------- /run-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | RED='\033[0;31m' # Red 6 | BB='\033[0;34m' # Blue 7 | NC='\033[0m' # No Color 8 | BG='\033[0;32m' # Green 9 | 10 | error() { >&2 echo -e "${RED}$1${NC}"; } 11 | showinfo() { echo -e "${BG}$1${NC}"; } 12 | workingprocess() { echo -e "${BB}$1${NC}"; } 13 | allert () { echo -e "${RED}$1${NC}"; } 14 | 15 | # Building project 16 | mkdir -p build 17 | cd build 18 | 19 | if [ "$CC" = gcc ] ; then 20 | export CC=gcc-5 21 | export CXX=g++-5 22 | fi 23 | 24 | if [ "$CC" = gcc-5 ] ; then 25 | cmake -DCMAKE_BUILD_TYPE=Debug .. 26 | else 27 | cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DASAN=ON .. 28 | fi 29 | 30 | make -j4 31 | # Checks if last comand didn't output 0 32 | # $? checks what last command outputed 33 | # If output is 0 then command is succesfuly executed 34 | # If command fails it outputs number between 0 to 255 35 | if [ $? -ne 0 ]; then 36 | error "Error: there are compile errors!" 37 | # Terminate script and outputs 3 38 | exit 3 39 | fi 40 | 41 | showinfo "Running tests ..." 42 | 43 | if [ "$CC" = gcc-5 ]; then 44 | make -j4 libatlasclient_coverage 45 | fi 46 | 47 | ./runtests 48 | if [ $? -ne 0 ]; then 49 | error "Error: there are failed tests!" 50 | exit 4 51 | fi 52 | 53 | workingprocess "All tests compile and pass." 54 | 55 | -------------------------------------------------------------------------------- /3rd-party/benchmark/test/fixture_test.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "benchmark/benchmark.h" 3 | 4 | #include 5 | #include 6 | 7 | class MyFixture : public ::benchmark::Fixture { 8 | public: 9 | void SetUp(const ::benchmark::State& state) { 10 | if (state.thread_index == 0) { 11 | assert(data.get() == nullptr); 12 | data.reset(new int(42)); 13 | } 14 | } 15 | 16 | void TearDown(const ::benchmark::State& state) { 17 | if (state.thread_index == 0) { 18 | assert(data.get() != nullptr); 19 | data.reset(); 20 | } 21 | } 22 | 23 | ~MyFixture() { assert(data == nullptr); } 24 | 25 | std::unique_ptr data; 26 | }; 27 | 28 | BENCHMARK_F(MyFixture, Foo)(benchmark::State &st) { 29 | assert(data.get() != nullptr); 30 | assert(*data == 42); 31 | for (auto _ : st) { 32 | } 33 | } 34 | 35 | BENCHMARK_DEFINE_F(MyFixture, Bar)(benchmark::State& st) { 36 | if (st.thread_index == 0) { 37 | assert(data.get() != nullptr); 38 | assert(*data == 42); 39 | } 40 | for (auto _ : st) { 41 | assert(data.get() != nullptr); 42 | assert(*data == 42); 43 | } 44 | st.SetItemsProcessed(st.range(0)); 45 | } 46 | BENCHMARK_REGISTER_F(MyFixture, Bar)->Arg(42); 47 | BENCHMARK_REGISTER_F(MyFixture, Bar)->Arg(42)->ThreadPerCpu(); 48 | 49 | BENCHMARK_MAIN() 50 | -------------------------------------------------------------------------------- /3rd-party/spdlog/details/log_msg.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2015 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | 8 | #include "spdlog/common.h" 9 | #include "spdlog/details/os.h" 10 | 11 | #include 12 | #include 13 | 14 | namespace spdlog { 15 | namespace details { 16 | struct log_msg 17 | { 18 | log_msg() = default; 19 | 20 | log_msg(const std::string *loggers_name, level::level_enum lvl) 21 | : logger_name(loggers_name) 22 | , level(lvl) 23 | #ifndef SPDLOG_NO_DATETIME 24 | , time(os::now()) 25 | #endif 26 | 27 | #ifndef SPDLOG_NO_THREAD_ID 28 | , thread_id(os::thread_id()) 29 | #endif 30 | { 31 | } 32 | 33 | log_msg(const log_msg &other) = delete; 34 | log_msg(log_msg &&other) = delete; 35 | log_msg &operator=(log_msg &&other) = delete; 36 | 37 | const std::string *logger_name{nullptr}; 38 | level::level_enum level; 39 | log_clock::time_point time; 40 | size_t thread_id; 41 | fmt::memory_buffer raw; 42 | size_t msg_id; 43 | 44 | // info about wrapping the formatted text with color (updated by pattern_formatter). 45 | mutable size_t color_range_start{0}; 46 | mutable size_t color_range_end{0}; 47 | }; 48 | } // namespace details 49 | } // namespace spdlog 50 | -------------------------------------------------------------------------------- /3rd-party/benchmark/src/timers.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_TIMERS_H 2 | #define BENCHMARK_TIMERS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace benchmark { 8 | 9 | // Return the CPU usage of the current process 10 | double ProcessCPUUsage(); 11 | 12 | // Return the CPU usage of the children of the current process 13 | double ChildrenCPUUsage(); 14 | 15 | // Return the CPU usage of the current thread 16 | double ThreadCPUUsage(); 17 | 18 | #if defined(HAVE_STEADY_CLOCK) 19 | template 20 | struct ChooseSteadyClock { 21 | typedef std::chrono::high_resolution_clock type; 22 | }; 23 | 24 | template <> 25 | struct ChooseSteadyClock { 26 | typedef std::chrono::steady_clock type; 27 | }; 28 | #endif 29 | 30 | struct ChooseClockType { 31 | #if defined(HAVE_STEADY_CLOCK) 32 | typedef ChooseSteadyClock<>::type type; 33 | #else 34 | typedef std::chrono::high_resolution_clock type; 35 | #endif 36 | }; 37 | 38 | inline double ChronoClockNow() { 39 | typedef ChooseClockType::type ClockType; 40 | using FpSeconds = std::chrono::duration; 41 | return FpSeconds(ClockType::now().time_since_epoch()).count(); 42 | } 43 | 44 | std::string LocalDateTimeString(); 45 | 46 | } // end namespace benchmark 47 | 48 | #endif // BENCHMARK_TIMERS_H 49 | -------------------------------------------------------------------------------- /3rd-party/benchmark/src/benchmark_api_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_API_INTERNAL_H 2 | #define BENCHMARK_API_INTERNAL_H 3 | 4 | #include "benchmark/benchmark.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace benchmark { 13 | namespace internal { 14 | 15 | // Information kept per benchmark we may want to run 16 | struct Benchmark::Instance { 17 | std::string name; 18 | Benchmark* benchmark; 19 | ReportMode report_mode; 20 | std::vector arg; 21 | TimeUnit time_unit; 22 | int range_multiplier; 23 | bool use_real_time; 24 | bool use_manual_time; 25 | BigO complexity; 26 | BigOFunc* complexity_lambda; 27 | UserCounters counters; 28 | const std::vector* statistics; 29 | bool last_benchmark_instance; 30 | int repetitions; 31 | double min_time; 32 | size_t iterations; 33 | int threads; // Number of concurrent threads to us 34 | }; 35 | 36 | bool FindBenchmarksInternal(const std::string& re, 37 | std::vector* benchmarks, 38 | std::ostream* Err); 39 | 40 | bool IsZero(double n); 41 | 42 | ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color = false); 43 | 44 | } // end namespace internal 45 | } // end namespace benchmark 46 | 47 | #endif // BENCHMARK_API_INTERNAL_H 48 | -------------------------------------------------------------------------------- /meter/id.cc: -------------------------------------------------------------------------------- 1 | #include "id.h" 2 | 3 | #include "id_format.h" 4 | #include "statistic.h" 5 | #include 6 | 7 | namespace atlas { 8 | namespace meter { 9 | 10 | const Tags kEmptyTags; 11 | 12 | const char* Id::Name() const noexcept { return name_.get(); } 13 | 14 | const Tags& Id::GetTags() const noexcept { return tags_; } 15 | 16 | std::unique_ptr Id::WithTag(const Tag& tag) const { 17 | Tags new_tags(tags_); 18 | new_tags.add(tag); 19 | return std::make_unique(name_, new_tags); 20 | } 21 | 22 | bool Id::operator==(const Id& rhs) const noexcept { 23 | return name_ == rhs.name_ && tags_ == rhs.tags_; 24 | } 25 | 26 | IdPtr WithDefaultTagForId(const IdPtr& id, const Tag& default_tag) { 27 | bool already_has_key = id->GetTags().has(default_tag.key); 28 | return already_has_key ? id : id->WithTag(default_tag); 29 | } 30 | 31 | const Tag kGaugeDsType = Tag::of("atlas.dstype", "gauge"); 32 | 33 | IdPtr WithDefaultGaugeTags(const IdPtr& id) { 34 | return WithDefaultGaugeTags(id, statistic::gauge); 35 | } 36 | 37 | IdPtr WithDefaultGaugeTags(const IdPtr& id, const Tag& stat) { 38 | return WithDefaultTagForId(WithDefaultTagForId(id, stat), kGaugeDsType); 39 | } 40 | 41 | std::ostream& operator<<(std::ostream& os, const Id& id) { 42 | os << "Id(" << id.Name() << ", " << id.GetTags() << ")"; 43 | return os; 44 | } 45 | 46 | } // namespace meter 47 | } // namespace atlas 48 | -------------------------------------------------------------------------------- /3rd-party/spdlog/fmt/bundled/LICENSE.rst: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 - 2016, Victor Zverovich 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /meter/monotonic_counter.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "monotonic_counter.h" 3 | #include "statistic.h" 4 | 5 | namespace atlas { 6 | namespace meter { 7 | 8 | MonotonicCounter::MonotonicCounter(Registry* registry, const IdPtr& id) 9 | : Meter{WithDefaultTagForId(id, statistic::count), registry->clock()}, 10 | value_(0), 11 | registry_(registry), 12 | counter_(std::shared_ptr(nullptr)) {} 13 | 14 | std::ostream& MonotonicCounter::Dump(std::ostream& os) const { 15 | os << "MonotonicCounter(" 16 | << "id=" << *id_ << ", value=" << value_ 17 | << ", last_updated=" << last_updated_ << ")"; 18 | 19 | return os; 20 | } 21 | 22 | Measurements MonotonicCounter::Measure() const { return Measurements(); } 23 | 24 | void MonotonicCounter::Set(int64_t amount) noexcept { 25 | auto prev_updated = last_updated_.load(std::memory_order_relaxed); 26 | 27 | if (prev_updated > 0) { 28 | if (!counter_) { 29 | counter_ = registry_->counter(id_); 30 | } 31 | auto prev_value = value_.load(std::memory_order_relaxed); 32 | auto delta = amount - prev_value; 33 | if (delta >= 0) { 34 | counter_->Add(delta); 35 | } 36 | } 37 | value_.store(amount, std::memory_order_relaxed); 38 | Updated(); 39 | } 40 | 41 | int64_t MonotonicCounter::Count() const noexcept { 42 | return value_.load(std::memory_order_relaxed); 43 | } 44 | 45 | } // namespace meter 46 | } // namespace atlas 47 | -------------------------------------------------------------------------------- /3rd-party/curl/stdcheaders.h: -------------------------------------------------------------------------------- 1 | #ifndef __STDC_HEADERS_H 2 | #define __STDC_HEADERS_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.haxx.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | ***************************************************************************/ 24 | 25 | #include 26 | 27 | size_t fread(void *, size_t, size_t, FILE *); 28 | size_t fwrite(const void *, size_t, size_t, FILE *); 29 | 30 | int strcasecmp(const char *, const char *); 31 | int strncasecmp(const char *, const char *, size_t); 32 | 33 | #endif /* __STDC_HEADERS_H */ 34 | -------------------------------------------------------------------------------- /3rd-party/benchmark/test/donotoptimize_test.cc: -------------------------------------------------------------------------------- 1 | #include "benchmark/benchmark.h" 2 | 3 | #include 4 | 5 | namespace { 6 | #if defined(__GNUC__) 7 | std::uint64_t double_up(const std::uint64_t x) __attribute__((const)); 8 | #endif 9 | std::uint64_t double_up(const std::uint64_t x) { return x * 2; } 10 | } 11 | 12 | // Using DoNotOptimize on types like BitRef seem to cause a lot of problems 13 | // with the inline assembly on both GCC and Clang. 14 | struct BitRef { 15 | int index; 16 | unsigned char &byte; 17 | 18 | public: 19 | static BitRef Make() { 20 | static unsigned char arr[2] = {}; 21 | BitRef b(1, arr[0]); 22 | return b; 23 | } 24 | private: 25 | BitRef(int i, unsigned char& b) : index(i), byte(b) {} 26 | }; 27 | 28 | int main(int, char*[]) { 29 | // this test verifies compilation of DoNotOptimize() for some types 30 | 31 | char buffer8[8]; 32 | benchmark::DoNotOptimize(buffer8); 33 | 34 | char buffer20[20]; 35 | benchmark::DoNotOptimize(buffer20); 36 | 37 | char buffer1024[1024]; 38 | benchmark::DoNotOptimize(buffer1024); 39 | benchmark::DoNotOptimize(&buffer1024[0]); 40 | 41 | int x = 123; 42 | benchmark::DoNotOptimize(x); 43 | benchmark::DoNotOptimize(&x); 44 | benchmark::DoNotOptimize(x += 42); 45 | 46 | benchmark::DoNotOptimize(double_up(x)); 47 | 48 | // These tests are to e 49 | benchmark::DoNotOptimize(BitRef::Make()); 50 | BitRef lval = BitRef::Make(); 51 | benchmark::DoNotOptimize(lval); 52 | } 53 | -------------------------------------------------------------------------------- /3rd-party/spdlog/sinks/ostream_sink.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2015 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | 8 | #include "spdlog/details/null_mutex.h" 9 | #include "spdlog/sinks/base_sink.h" 10 | 11 | #include 12 | #include 13 | 14 | namespace spdlog { 15 | namespace sinks { 16 | template 17 | class ostream_sink final : public base_sink 18 | { 19 | public: 20 | explicit ostream_sink(std::ostream &os, bool force_flush = false) 21 | : ostream_(os) 22 | , force_flush_(force_flush) 23 | { 24 | } 25 | ostream_sink(const ostream_sink &) = delete; 26 | ostream_sink &operator=(const ostream_sink &) = delete; 27 | 28 | protected: 29 | void sink_it_(const details::log_msg &msg) override 30 | { 31 | fmt::memory_buffer formatted; 32 | sink::formatter_->format(msg, formatted); 33 | ostream_.write(formatted.data(), static_cast(formatted.size())); 34 | if (force_flush_) 35 | { 36 | ostream_.flush(); 37 | } 38 | } 39 | 40 | void flush_() override 41 | { 42 | ostream_.flush(); 43 | } 44 | 45 | std::ostream &ostream_; 46 | bool force_flush_; 47 | }; 48 | 49 | using ostream_sink_mt = ostream_sink; 50 | using ostream_sink_st = ostream_sink; 51 | 52 | } // namespace sinks 53 | } // namespace spdlog 54 | -------------------------------------------------------------------------------- /util/http.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "config.h" 4 | #include "../meter/registry.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace atlas { 11 | namespace util { 12 | 13 | class CurlHeaders; 14 | class http { 15 | public: 16 | http(std::shared_ptr registry, const HttpConfig& config) 17 | : registry_(std::move(registry)), 18 | connect_timeout_(config.connect_timeout), 19 | read_timeout_(config.read_timeout) {} 20 | 21 | int conditional_get(const std::string& url, std::string* etag, 22 | std::string* res) const; 23 | 24 | int get(const std::string& url, std::string* res) const; 25 | 26 | int post(const std::string& url, const char* content_type, 27 | const char* payload, size_t size) const; 28 | 29 | int post(const std::string& url, const rapidjson::Document& payload) const; 30 | 31 | std::vector post_batches( 32 | const std::string& url, 33 | const std::vector& batches) const; 34 | static void global_init() noexcept; 35 | static void global_shutdown() noexcept; 36 | 37 | private: 38 | std::shared_ptr registry_; 39 | int connect_timeout_; 40 | int read_timeout_; 41 | 42 | int do_post(const std::string& url, std::unique_ptr headers, 43 | std::unique_ptr payload, size_t size) const; 44 | }; 45 | 46 | } // namespace util 47 | } // namespace atlas 48 | -------------------------------------------------------------------------------- /test/test_registry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../meter/manual_clock.h" 4 | #include "../meter/atlas_registry.h" 5 | 6 | class TestRegistry : public atlas::meter::AtlasRegistry { 7 | public: 8 | TestRegistry(int64_t step_millis, 9 | const atlas::meter::ManualClock* manual_clock) 10 | : atlas::meter::AtlasRegistry(step_millis, manual_clock), 11 | manual_clock_(manual_clock) {} 12 | 13 | void SetWall(int64_t millis) { manual_clock_->SetWall(millis); } 14 | 15 | atlas::meter::Measurements measurements_for_name(const char* name) { 16 | auto ms = measurements(); 17 | auto mine = atlas::meter::Measurements{}; 18 | std::copy_if(ms.begin(), ms.end(), std::back_inserter(mine), 19 | [&name](const atlas::meter::Measurement& m) { 20 | return strcmp(m.id->Name(), name) == 0; 21 | }); 22 | return mine; 23 | } 24 | 25 | Meters my_meters() const { 26 | auto ms = meters(); 27 | auto new_end = std::remove_if( 28 | ms.begin(), ms.end(), 29 | [](const std::shared_ptr& m) { 30 | return atlas::util::StartsWith(m->GetId()->NameRef(), "atlas."); 31 | }); 32 | ms.resize(std::distance(ms.begin(), new_end)); 33 | return ms; 34 | } 35 | 36 | const atlas::meter::ManualClock* manual_clock() const { 37 | return manual_clock_; 38 | } 39 | 40 | void expire() { expire_meters(); } 41 | 42 | private: 43 | const atlas::meter::ManualClock* manual_clock_; 44 | }; 45 | -------------------------------------------------------------------------------- /util/config_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "config.h" 10 | 11 | namespace atlas { 12 | namespace util { 13 | 14 | static constexpr const char* kLocalFileName = "./atlas-config.json"; 15 | static constexpr int kConfigRefreshMillis = 10000; 16 | 17 | class ConfigManager { 18 | public: 19 | explicit ConfigManager(std::string local_file_name = kLocalFileName, 20 | int refresh_ms = kConfigRefreshMillis) noexcept 21 | : local_file_name_{std::move(local_file_name)}, 22 | refresh_ms_{refresh_ms}, 23 | current_config_{std::shared_ptr(get_current_config())} {} 24 | ~ConfigManager() { Stop(); } 25 | std::shared_ptr GetConfig() const noexcept; 26 | 27 | void Start() noexcept; 28 | 29 | void Stop() noexcept; 30 | 31 | void AddCommonTag(const char* key, const char* value) noexcept; 32 | 33 | private: 34 | mutable std::mutex config_mutex; 35 | std::mutex cv_mutex; 36 | std::condition_variable cv; 37 | std::string local_file_name_; 38 | int refresh_ms_; 39 | std::shared_ptr current_config_; 40 | std::atomic should_run_{false}; 41 | meter::Tags extra_tags_; 42 | 43 | void refresher() noexcept; 44 | void refresh_configs() noexcept; 45 | std::unique_ptr get_current_config() noexcept; 46 | std::thread refresher_thread; 47 | }; 48 | } // namespace util 49 | } // namespace atlas 50 | -------------------------------------------------------------------------------- /3rd-party/benchmark/src/statistics.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Ismael Jimenez Martinez. All rights reserved. 2 | // Copyright 2017 Roman Lebedev. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #ifndef STATISTICS_H_ 17 | #define STATISTICS_H_ 18 | 19 | #include 20 | 21 | #include "benchmark/benchmark.h" 22 | 23 | namespace benchmark { 24 | 25 | // Return a vector containing the mean, median and standard devation information 26 | // (and any user-specified info) for the specified list of reports. If 'reports' 27 | // contains less than two non-errored runs an empty vector is returned 28 | std::vector ComputeStats( 29 | const std::vector& reports); 30 | 31 | double StatisticsMean(const std::vector& v); 32 | double StatisticsMedian(const std::vector& v); 33 | double StatisticsStdDev(const std::vector& v); 34 | 35 | } // end namespace benchmark 36 | 37 | #endif // STATISTICS_H_ 38 | -------------------------------------------------------------------------------- /3rd-party/spdlog/details/console_globals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // 3 | // Copyright(c) 2018 Gabi Melman. 4 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 5 | // 6 | 7 | #include "spdlog/details/null_mutex.h" 8 | #include 9 | #include 10 | 11 | #ifdef _WIN32 12 | 13 | #ifndef NOMINMAX 14 | #define NOMINMAX // prevent windows redefining min/max 15 | #endif 16 | 17 | #ifndef WIN32_LEAN_AND_MEAN 18 | #define WIN32_LEAN_AND_MEAN 19 | #endif 20 | 21 | #include 22 | #endif 23 | 24 | namespace spdlog { 25 | namespace details { 26 | struct console_stdout 27 | { 28 | static std::FILE *stream() 29 | { 30 | return stdout; 31 | } 32 | #ifdef _WIN32 33 | static HANDLE handle() 34 | { 35 | return ::GetStdHandle(STD_OUTPUT_HANDLE); 36 | } 37 | #endif 38 | }; 39 | 40 | struct console_stderr 41 | { 42 | static std::FILE *stream() 43 | { 44 | return stderr; 45 | } 46 | #ifdef _WIN32 47 | static HANDLE handle() 48 | { 49 | return ::GetStdHandle(STD_ERROR_HANDLE); 50 | } 51 | #endif 52 | }; 53 | 54 | struct console_mutex 55 | { 56 | using mutex_t = std::mutex; 57 | static mutex_t &mutex() 58 | { 59 | static mutex_t s_mutex; 60 | return s_mutex; 61 | } 62 | }; 63 | 64 | struct console_nullmutex 65 | { 66 | using mutex_t = null_mutex; 67 | static mutex_t &mutex() 68 | { 69 | static mutex_t s_mutex; 70 | return s_mutex; 71 | } 72 | }; 73 | } // namespace details 74 | } // namespace spdlog 75 | -------------------------------------------------------------------------------- /meter/percentile_timer.cc: -------------------------------------------------------------------------------- 1 | #include "percentile_timer.h" 2 | #include "statistic.h" 3 | 4 | namespace atlas { 5 | namespace meter { 6 | 7 | #include "percentile_bucket_tags.inc" 8 | 9 | PercentileTimer::PercentileTimer(Registry* registry, const IdPtr& id) 10 | : Meter{id, registry->clock()}, 11 | registry_{registry}, 12 | timer_{registry->timer(id)} {} 13 | 14 | std::ostream& PercentileTimer::Dump(std::ostream& os) const { 15 | os << "PercentileTimer{" << id_ << "}"; 16 | return os; 17 | } 18 | 19 | void PercentileTimer::Record(std::chrono::nanoseconds nanos) noexcept { 20 | timer_->Record(nanos); 21 | CounterFor(percentile_buckets::IndexOf(nanos.count()))->Increment(); 22 | } 23 | 24 | inline Tag PercentileTag(size_t i) { 25 | static std::string kPercentile{"percentile"}; 26 | return Tag::of(kPercentile, kTimerTags.at(i)); 27 | } 28 | 29 | std::shared_ptr PercentileTimer::CounterFor(size_t i) const noexcept { 30 | auto& c = counters_.at(i); 31 | if (!c) { 32 | c = registry_->counter( 33 | id_->WithTag(statistic::percentile)->WithTag(PercentileTag(i))); 34 | counters_.at(i) = c; 35 | } 36 | return c; 37 | } 38 | 39 | double PercentileTimer::Percentile(double p) const noexcept { 40 | std::array counts; 41 | for (size_t i = 0; i < percentile_buckets::Length(); ++i) { 42 | counts.at(i) = CounterFor(i)->Count(); 43 | } 44 | auto v = percentile_buckets::Percentile(counts, p); 45 | return v / 1e9; 46 | } 47 | 48 | } // namespace meter 49 | } // namespace atlas 50 | -------------------------------------------------------------------------------- /test/resources/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "instanceId" : "i-12345678", 3 | "billingProducts" 4 | : null, 5 | "imageId" : "ami-87654321", 6 | "architecture" 7 | : "x86_64", 8 | "pendingTime" 9 | : "2014-07-15T22:27:08Z", 10 | "instanceType" 11 | : "m2.4xlarge", 12 | "accountId" 13 | : "123456789000", 14 | "kernelId" : "aki-12345678", 15 | "ramdiskId" 16 | : null, 17 | "region" 18 | : "us-east-1", 19 | "version" 20 | : "2010-08-31", 21 | "availabilityZone" 22 | : "us-east-1e", 23 | "devpayProductCodes" 24 | : null, 25 | "privateIp" 26 | : "1.2.3.4" 27 | } 28 | -------------------------------------------------------------------------------- /test/collections_test.cc: -------------------------------------------------------------------------------- 1 | #include "../util/collections.h" 2 | #include 3 | #include 4 | 5 | TEST(Vector, Concat) { 6 | std::vector v1{1, 2, 3}; 7 | std::vector v2{4, 5, 6}; 8 | 9 | auto result = vector_concat(std::move(v1), std::move(v2)); 10 | std::vector expected{1, 2, 3, 4, 5, 6}; 11 | EXPECT_EQ(expected, result); 12 | } 13 | 14 | TEST(Vector, Append_to) { 15 | std::vector v1{1, 2, 3}; 16 | std::vector v2{4, 5, 6}; 17 | std::vector v3{7, 8, 9}; 18 | 19 | std::vector result; 20 | append_to_vector(&result, std::move(v1)); 21 | append_to_vector(&result, std::move(v2)); 22 | append_to_vector(&result, std::move(v3)); 23 | std::vector expected{1, 2, 3, 4, 5, 6, 7, 8, 9}; 24 | EXPECT_EQ(expected, result); 25 | } 26 | 27 | TEST(Vector, Cross) { 28 | std::vector v1{"a", "b"}; 29 | std::vector v2{"c", "d"}; 30 | 31 | auto res = vector_cross_product( 32 | v1, v2, [](const std::string& a, const std::string& b) { return a + b; }); 33 | std::vector expected{"ac", "ad", "bc", "bd"}; 34 | EXPECT_EQ(res, expected); 35 | }; 36 | 37 | TEST(Set, Append_to) { 38 | std::unordered_set v1{1, 2, 3}; 39 | std::unordered_set v2{4, 5, 6}; 40 | std::unordered_set v3{7, 8, 9}; 41 | 42 | std::unordered_set result; 43 | append_to_set(&result, std::move(v1)); 44 | append_to_set(&result, std::move(v2)); 45 | append_to_set(&result, std::move(v3)); 46 | std::unordered_set expected{1, 2, 3, 4, 5, 6, 7, 8, 9}; 47 | EXPECT_EQ(expected, result); 48 | } 49 | -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: PR Build 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-18.04 8 | strategy: 9 | matrix: 10 | include: 11 | - {compiler: gcc} 12 | - {compiler: clang} 13 | env: 14 | LANG: "en_US.UTF-8" 15 | steps: 16 | - uses: actions/checkout@v2 17 | 18 | - name: Install Dependencies (clang) 19 | if: startsWith(matrix.compiler, 'clang') 20 | run: | 21 | sudo apt-get update 22 | sudo apt-get install -y curl software-properties-common 23 | curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - 24 | sudo apt-add-repository -y "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-5.0 main" 25 | sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test 26 | sudo apt-get update 27 | sudo apt-get install -y clang-5.0 cmake 28 | 29 | - name: Build and Test (clang) 30 | if: startsWith(matrix.compiler, 'clang') 31 | env: 32 | CC: "clang-5.0" 33 | CXX: "clang++-5.0" 34 | run: ./run-build.sh 35 | 36 | - name: Install Dependencies (gcc) 37 | if: startsWith(matrix.compiler, 'gcc') 38 | run: | 39 | sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test 40 | sudo apt-get update 41 | sudo apt-get install -y g++-5 lcov 42 | 43 | - name: Build and Test (gcc) 44 | if: startsWith(matrix.compiler, 'gcc') 45 | env: 46 | CC: "gcc-5" 47 | CXX: "g++-5" 48 | run: ./run-build.sh 49 | -------------------------------------------------------------------------------- /interpreter/tags_value.cc: -------------------------------------------------------------------------------- 1 | #include "tags_value.h" 2 | #include "../meter/id_format.h" 3 | 4 | namespace atlas { 5 | namespace interpreter { 6 | 7 | const OptionalString kNone{nullptr}; 8 | 9 | util::StrRef name_ref() { 10 | static util::StrRef name = util::intern_str("name"); 11 | return name; 12 | } 13 | 14 | void IdTagsValuePair::dump(std::ostream& os) const noexcept { 15 | os << "IdTagsValuePair(id=" << *id_ << ",common_tags=" << *common_tags_ 16 | << ",value=" << value_ << ")"; 17 | } 18 | 19 | void SimpleTagsValuePair::dump(std::ostream& os) const noexcept { 20 | os << "SimpleTagsValuePair(tags=" << tags_ << ",value=" << value_ << ")"; 21 | } 22 | 23 | std::ostream& operator<<(std::ostream& os, const TagsValuePair& tagsValuePair) { 24 | tagsValuePair.dump(os); 25 | return os; 26 | } 27 | 28 | std::ostream& operator<<(std::ostream& os, 29 | const std::shared_ptr& tagsValuePair) { 30 | tagsValuePair->dump(os); 31 | return os; 32 | } 33 | 34 | std::unique_ptr TagsValuePair::from( 35 | const meter::Measurement& measurement, 36 | const meter::Tags* common_tags) noexcept { 37 | return std::make_unique(measurement.id, common_tags, 38 | measurement.value); 39 | } 40 | 41 | std::unique_ptr TagsValuePair::of(meter::Tags&& tags, 42 | double value) noexcept { 43 | return std::make_unique(std::move(tags), value); 44 | } 45 | 46 | } // namespace interpreter 47 | } // namespace atlas 48 | -------------------------------------------------------------------------------- /test/bucket_counter_test.cc: -------------------------------------------------------------------------------- 1 | #include "../meter/bucket_counter.h" 2 | #include "../meter/statistic.h" 3 | #include "../util/logger.h" 4 | #include "test_registry.h" 5 | #include 6 | 7 | using atlas::meter::BucketCounter; 8 | using atlas::meter::kEmptyTags; 9 | using atlas::meter::ManualClock; 10 | using atlas::meter::Measurement; 11 | using atlas::meter::Measurements; 12 | using atlas::meter::Registry; 13 | using atlas::meter::Tag; 14 | using atlas::meter::bucket_functions::Age; 15 | using atlas::util::Logger; 16 | using std::chrono::microseconds; 17 | 18 | TEST(BucketCounter, Init) { 19 | ManualClock m; 20 | TestRegistry r{60000, &m}; 21 | auto id = r.CreateId("test", kEmptyTags); 22 | BucketCounter b(&r, id, Age(microseconds{100})); 23 | auto ms = r.measurements_for_name("test"); 24 | EXPECT_EQ(ms.size(), 0); 25 | } 26 | 27 | // micros to nanos 28 | static constexpr int64_t kMicrosToNanos = 1000l; 29 | TEST(BucketCounter, Record) { 30 | ManualClock manual_clock; 31 | TestRegistry r{60000, &manual_clock}; 32 | r.SetWall(1000); 33 | 34 | auto id = r.CreateId("test", kEmptyTags); 35 | BucketCounter b(&r, id, Age(microseconds{100})); 36 | b.Record(30 * kMicrosToNanos); 37 | 38 | r.SetWall(61000); 39 | auto ms = r.measurements_for_name("test"); 40 | EXPECT_EQ(ms.size(), 1); 41 | 42 | auto m = ms.front(); 43 | 44 | auto expected_id = id->WithTag(atlas::meter::statistic::count) 45 | ->WithTag(Tag::of("bucket", "050us")); 46 | auto expected_value = 1 / 60.0; 47 | EXPECT_EQ(*expected_id, *m.id); 48 | EXPECT_DOUBLE_EQ(expected_value, m.value); 49 | } 50 | -------------------------------------------------------------------------------- /3rd-party/benchmark/appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '{build}' 2 | 3 | image: Visual Studio 2017 4 | 5 | configuration: 6 | - Debug 7 | - Release 8 | 9 | environment: 10 | matrix: 11 | - compiler: msvc-15-seh 12 | generator: "Visual Studio 15 2017" 13 | 14 | - compiler: msvc-15-seh 15 | generator: "Visual Studio 15 2017 Win64" 16 | 17 | - compiler: msvc-14-seh 18 | generator: "Visual Studio 14 2015" 19 | 20 | - compiler: msvc-14-seh 21 | generator: "Visual Studio 14 2015 Win64" 22 | 23 | - compiler: msvc-12-seh 24 | generator: "Visual Studio 12 2013" 25 | 26 | - compiler: msvc-12-seh 27 | generator: "Visual Studio 12 2013 Win64" 28 | 29 | - compiler: gcc-5.3.0-posix 30 | generator: "MinGW Makefiles" 31 | cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin' 32 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 33 | 34 | matrix: 35 | fast_finish: true 36 | 37 | install: 38 | # git bash conflicts with MinGW makefiles 39 | - if "%generator%"=="MinGW Makefiles" (set "PATH=%PATH:C:\Program Files\Git\usr\bin;=%") 40 | - if not "%cxx_path%"=="" (set "PATH=%PATH%;%cxx_path%") 41 | 42 | build_script: 43 | - md _build -Force 44 | - cd _build 45 | - echo %configuration% 46 | - cmake -G "%generator%" "-DCMAKE_BUILD_TYPE=%configuration%" .. 47 | - cmake --build . --config %configuration% 48 | 49 | test_script: 50 | - ctest -c %configuration% --timeout 300 --output-on-failure 51 | 52 | artifacts: 53 | - path: '_build/CMakeFiles/*.log' 54 | name: logs 55 | - path: '_build/Testing/**/*.xml' 56 | name: test_results 57 | -------------------------------------------------------------------------------- /3rd-party/benchmark/test/map_test.cc: -------------------------------------------------------------------------------- 1 | #include "benchmark/benchmark.h" 2 | 3 | #include 4 | #include 5 | 6 | namespace { 7 | 8 | std::map ConstructRandomMap(int size) { 9 | std::map m; 10 | for (int i = 0; i < size; ++i) { 11 | m.insert(std::make_pair(rand() % size, rand() % size)); 12 | } 13 | return m; 14 | } 15 | 16 | } // namespace 17 | 18 | // Basic version. 19 | static void BM_MapLookup(benchmark::State& state) { 20 | const int size = state.range(0); 21 | std::map m; 22 | for (auto _ : state) { 23 | state.PauseTiming(); 24 | m = ConstructRandomMap(size); 25 | state.ResumeTiming(); 26 | for (int i = 0; i < size; ++i) { 27 | benchmark::DoNotOptimize(m.find(rand() % size)); 28 | } 29 | } 30 | state.SetItemsProcessed(state.iterations() * size); 31 | } 32 | BENCHMARK(BM_MapLookup)->Range(1 << 3, 1 << 12); 33 | 34 | // Using fixtures. 35 | class MapFixture : public ::benchmark::Fixture { 36 | public: 37 | void SetUp(const ::benchmark::State& st) { 38 | m = ConstructRandomMap(st.range(0)); 39 | } 40 | 41 | void TearDown(const ::benchmark::State&) { m.clear(); } 42 | 43 | std::map m; 44 | }; 45 | 46 | BENCHMARK_DEFINE_F(MapFixture, Lookup)(benchmark::State& state) { 47 | const int size = state.range(0); 48 | for (auto _ : state) { 49 | for (int i = 0; i < size; ++i) { 50 | benchmark::DoNotOptimize(m.find(rand() % size)); 51 | } 52 | } 53 | state.SetItemsProcessed(state.iterations() * size); 54 | } 55 | BENCHMARK_REGISTER_F(MapFixture, Lookup)->Range(1 << 3, 1 << 12); 56 | 57 | BENCHMARK_MAIN() 58 | -------------------------------------------------------------------------------- /3rd-party/rapidjson/internal/swap.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_SWAP_H_ 16 | #define RAPIDJSON_INTERNAL_SWAP_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #if defined(__clang__) 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(c++98-compat) 23 | #endif 24 | 25 | RAPIDJSON_NAMESPACE_BEGIN 26 | namespace internal { 27 | 28 | //! Custom swap() to avoid dependency on C++ header 29 | /*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. 30 | \note This has the same semantics as std::swap(). 31 | */ 32 | template 33 | inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { 34 | T tmp = a; 35 | a = b; 36 | b = tmp; 37 | } 38 | 39 | } // namespace internal 40 | RAPIDJSON_NAMESPACE_END 41 | 42 | #if defined(__clang__) 43 | RAPIDJSON_DIAG_POP 44 | #endif 45 | 46 | #endif // RAPIDJSON_INTERNAL_SWAP_H_ 47 | -------------------------------------------------------------------------------- /meter/function_gauge.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gauge.h" 4 | #include "registry.h" 5 | #include 6 | 7 | namespace atlas { 8 | namespace meter { 9 | 10 | /// A gauge that will compute its value by invoking a function 11 | /// on a given object 12 | template 13 | class FunctionGauge : public UpdateableMeter { 14 | public: 15 | FunctionGauge(IdPtr id, const Clock& clock, std::weak_ptr ptr, 16 | const std::function& f) noexcept 17 | : UpdateableMeter{WithDefaultGaugeTags(id), clock}, 18 | ptr_{ptr}, 19 | f_{f}, 20 | value_{kNAN} {} 21 | 22 | ~FunctionGauge() override = default; 23 | 24 | bool HasExpired() const noexcept override { return ptr_.expired(); } 25 | 26 | double Value() const noexcept { 27 | auto ptr = ptr_.lock(); 28 | return ptr ? f_(*ptr) : kNAN; 29 | } 30 | 31 | std::ostream& Dump(std::ostream& os) const override { 32 | auto ptr = ptr_.lock(); 33 | os << "FunctionGauge{" << *id_ << ",obj=" << *ptr << ",value=" << Value() 34 | << "}"; 35 | return os; 36 | } 37 | 38 | Measurements Measure() const override { 39 | return Measurements{Measurement{id_, clock_.WallTime(), value_}}; 40 | } 41 | 42 | void Update() noexcept override { value_ = Value(); } 43 | 44 | const char* GetClass() const noexcept override { return "FunctionGauge"; } 45 | 46 | private: 47 | static constexpr auto kNAN = std::numeric_limits::quiet_NaN(); 48 | std::weak_ptr ptr_; 49 | std::function f_; 50 | std::atomic value_; 51 | }; 52 | } // namespace meter 53 | } // namespace atlas 54 | -------------------------------------------------------------------------------- /3rd-party/benchmark/src/internal_macros.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_INTERNAL_MACROS_H_ 2 | #define BENCHMARK_INTERNAL_MACROS_H_ 3 | 4 | #include "benchmark/benchmark.h" 5 | 6 | #ifndef __has_feature 7 | #define __has_feature(x) 0 8 | #endif 9 | 10 | #if defined(__clang__) 11 | #define COMPILER_CLANG 12 | #elif defined(_MSC_VER) 13 | #define COMPILER_MSVC 14 | #elif defined(__GNUC__) 15 | #define COMPILER_GCC 16 | #endif 17 | 18 | #if __has_feature(cxx_attributes) 19 | #define BENCHMARK_NORETURN [[noreturn]] 20 | #elif defined(__GNUC__) 21 | #define BENCHMARK_NORETURN __attribute__((noreturn)) 22 | #elif defined(COMPILER_MSVC) 23 | #define BENCHMARK_NORETURN __declspec(noreturn) 24 | #else 25 | #define BENCHMARK_NORETURN 26 | #endif 27 | 28 | #if defined(__CYGWIN__) 29 | #define BENCHMARK_OS_CYGWIN 1 30 | #elif defined(_WIN32) 31 | #define BENCHMARK_OS_WINDOWS 1 32 | #elif defined(__APPLE__) 33 | #include "TargetConditionals.h" 34 | #if defined(TARGET_OS_MAC) 35 | #define BENCHMARK_OS_MACOSX 1 36 | #if defined(TARGET_OS_IPHONE) 37 | #define BENCHMARK_OS_IOS 1 38 | #endif 39 | #endif 40 | #elif defined(__FreeBSD__) 41 | #define BENCHMARK_OS_FREEBSD 1 42 | #elif defined(__linux__) 43 | #define BENCHMARK_OS_LINUX 1 44 | #elif defined(__native_client__) 45 | #define BENCHMARK_OS_NACL 1 46 | #elif defined(EMSCRIPTEN) 47 | #define BENCHMARK_OS_EMSCRIPTEN 1 48 | #elif defined(__rtems__) 49 | #define BENCHMARK_OS_RTEMS 1 50 | #endif 51 | 52 | #if !__has_feature(cxx_exceptions) && !defined(__cpp_exceptions) \ 53 | && !defined(__EXCEPTIONS) 54 | #define BENCHMARK_HAS_NO_EXCEPTIONS 55 | #endif 56 | 57 | #endif // BENCHMARK_INTERNAL_MACROS_H_ 58 | -------------------------------------------------------------------------------- /3rd-party/benchmark/AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of benchmark authors for copyright purposes. 2 | # This file is distinct from the CONTRIBUTORS files. 3 | # See the latter for an explanation. 4 | # 5 | # Names should be added to this file as: 6 | # Name or Organization 7 | # The email address is not required for organizations. 8 | # 9 | # Please keep the list sorted. 10 | 11 | Albert Pretorius 12 | Arne Beer 13 | Carto 14 | Christopher Seymour 15 | David Coeurjolly 16 | Dirac Research 17 | Dominik Czarnota 18 | Eric Fiselier 19 | Eugene Zhuk 20 | Evgeny Safronov 21 | Felix Homann 22 | Google Inc. 23 | International Business Machines Corporation 24 | Ismael Jimenez Martinez 25 | Jern-Kuan Leong 26 | JianXiong Zhou 27 | Joao Paulo Magalhaes 28 | Jussi Knuuttila 29 | Kaito Udagawa 30 | Lei Xu 31 | Matt Clarkson 32 | Maxim Vafin 33 | Nick Hutchinson 34 | Oleksandr Sochka 35 | Paul Redmond 36 | Radoslav Yovchev 37 | Roman Lebedev 38 | Shuo Chen 39 | Yixuan Qiu 40 | Yusuke Suzuki 41 | Zbigniew Skowron 42 | -------------------------------------------------------------------------------- /meter/interval_counter.cc: -------------------------------------------------------------------------------- 1 | #include "interval_counter.h" 2 | #include "statistic.h" 3 | 4 | namespace atlas { 5 | namespace meter { 6 | 7 | static std::function age(const Clock& clock) { 8 | return [&clock](int64_t t) { 9 | return static_cast(clock.WallTime() - t) / 1000.0; 10 | }; 11 | } 12 | 13 | IntervalCounter::IntervalCounter(Registry* registry, const IdPtr& id) 14 | : Meter{id, registry->clock()}, 15 | counter_{registry->counter(id->WithTag(statistic::count))}, 16 | counter_updated{std::make_shared(0)}, 17 | gauge_{std::make_shared>( 18 | id->WithTag(statistic::duration), registry->clock(), counter_updated, 19 | age(registry->clock()))} { 20 | registry->RegisterMonitor(gauge_); 21 | } 22 | 23 | void IntervalCounter::Increment() noexcept { 24 | counter_->Increment(); 25 | *counter_updated = clock_.WallTime(); 26 | } 27 | 28 | void IntervalCounter::Add(int64_t amount) noexcept { 29 | counter_->Add(amount); 30 | *counter_updated = clock_.WallTime(); 31 | } 32 | 33 | int64_t IntervalCounter::Count() const noexcept { return counter_->Count(); } 34 | 35 | Measurements IntervalCounter::Measure() const { return Measurements{}; } 36 | 37 | std::ostream& IntervalCounter::Dump(std::ostream& os) const { 38 | os << "IntervalCounter{" << id_ << ",count=" << counter_->Count() 39 | << ",updated=" << counter_updated << "}"; 40 | return os; 41 | } 42 | 43 | double IntervalCounter::SecondsSinceLastUpdate() const noexcept { 44 | return (clock_.WallTime() - *counter_updated) / 1000.0; 45 | } 46 | 47 | } // namespace meter 48 | } // namespace atlas 49 | -------------------------------------------------------------------------------- /test/percentile_timer_test.cc: -------------------------------------------------------------------------------- 1 | #include "../meter/percentile_timer.h" 2 | #include "test_registry.h" 3 | #include 4 | 5 | using namespace atlas::meter; 6 | using atlas::util::intern_str; 7 | 8 | TEST(PercentileTimer, Percentile) { 9 | ManualClock manual_clock; 10 | TestRegistry r{60000, &manual_clock}; 11 | PercentileTimer t{&r, r.CreateId("foo", kEmptyTags)}; 12 | 13 | for (auto i = 0; i < 100000; ++i) { 14 | t.Record(std::chrono::milliseconds{i}); 15 | } 16 | 17 | for (auto i = 0; i <= 100; ++i) { 18 | auto expected = static_cast(i); 19 | auto threshold = 0.15 * expected; 20 | EXPECT_NEAR(expected, t.Percentile(i), threshold); 21 | } 22 | } 23 | 24 | TEST(PercentileTimer, HasProperStatistic) { 25 | ManualClock manual_clock; 26 | TestRegistry r{60000, &manual_clock}; 27 | PercentileTimer t{&r, r.CreateId("foo", kEmptyTags)}; 28 | 29 | t.Record(std::chrono::milliseconds{42}); 30 | 31 | auto ms = r.meters(); 32 | auto percentileRef = intern_str("percentile"); 33 | auto statisticRef = intern_str("statistic"); 34 | for (const auto& m : ms) { 35 | auto tags = m->GetId()->GetTags(); 36 | if (tags.has(percentileRef)) { 37 | EXPECT_EQ(tags.at(statisticRef), percentileRef); 38 | } 39 | } 40 | } 41 | 42 | TEST(PercentileTimer, CountTotal) { 43 | ManualClock manual_clock; 44 | TestRegistry r{60000, &manual_clock}; 45 | PercentileTimer t{&r, r.CreateId("foo", kEmptyTags)}; 46 | 47 | for (auto i = 0; i < 100; ++i) { 48 | t.Record(std::chrono::nanoseconds(i)); 49 | } 50 | 51 | EXPECT_EQ(t.Count(), 100); 52 | EXPECT_EQ(t.TotalTime(), 100 * 99 / 2); // sum(1,n) = n * (n - 1) / 2 53 | } 54 | -------------------------------------------------------------------------------- /3rd-party/benchmark/cmake/GetGitVersion.cmake: -------------------------------------------------------------------------------- 1 | # - Returns a version string from Git tags 2 | # 3 | # This function inspects the annotated git tags for the project and returns a string 4 | # into a CMake variable 5 | # 6 | # get_git_version() 7 | # 8 | # - Example 9 | # 10 | # include(GetGitVersion) 11 | # get_git_version(GIT_VERSION) 12 | # 13 | # Requires CMake 2.8.11+ 14 | find_package(Git) 15 | 16 | if(__get_git_version) 17 | return() 18 | endif() 19 | set(__get_git_version INCLUDED) 20 | 21 | function(get_git_version var) 22 | if(GIT_EXECUTABLE) 23 | execute_process(COMMAND ${GIT_EXECUTABLE} describe --match "v[0-9]*.[0-9]*.[0-9]*" --abbrev=8 24 | RESULT_VARIABLE status 25 | OUTPUT_VARIABLE GIT_VERSION 26 | ERROR_QUIET) 27 | if(${status}) 28 | set(GIT_VERSION "v0.0.0") 29 | else() 30 | string(STRIP ${GIT_VERSION} GIT_VERSION) 31 | string(REGEX REPLACE "-[0-9]+-g" "-" GIT_VERSION ${GIT_VERSION}) 32 | endif() 33 | 34 | # Work out if the repository is dirty 35 | execute_process(COMMAND ${GIT_EXECUTABLE} update-index -q --refresh 36 | OUTPUT_QUIET 37 | ERROR_QUIET) 38 | execute_process(COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD -- 39 | OUTPUT_VARIABLE GIT_DIFF_INDEX 40 | ERROR_QUIET) 41 | string(COMPARE NOTEQUAL "${GIT_DIFF_INDEX}" "" GIT_DIRTY) 42 | if (${GIT_DIRTY}) 43 | set(GIT_VERSION "${GIT_VERSION}-dirty") 44 | endif() 45 | else() 46 | set(GIT_VERSION "v0.0.0") 47 | endif() 48 | 49 | message("-- git Version: ${GIT_VERSION}") 50 | set(${var} ${GIT_VERSION} PARENT_SCOPE) 51 | endfunction() 52 | -------------------------------------------------------------------------------- /test/test_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../meter/measurement.h" 4 | #include "../interpreter/expression.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | inline std::string string_join(const std::vector& vec, 11 | const char* separator) { 12 | switch (vec.size()) { 13 | case 0: 14 | return ""; 15 | case 1: 16 | return vec.front(); 17 | default: 18 | std::ostringstream os; 19 | std::copy(vec.begin(), vec.end() - 1, 20 | std::ostream_iterator(os, separator)); 21 | os << vec.back(); 22 | return os.str(); 23 | } 24 | } 25 | 26 | inline std::string tags_to_string(const atlas::meter::Tags& tags) { 27 | std::vector a_vec; 28 | for (const auto& tag : tags) { 29 | a_vec.emplace_back(fmt::format("{}={}", tag.first.get(), tag.second.get())); 30 | } 31 | std::sort(a_vec.begin(), a_vec.end()); 32 | return string_join(a_vec, ","); 33 | } 34 | 35 | inline bool operator<(const atlas::meter::Tags& a, 36 | const atlas::meter::Tags& b) { 37 | return tags_to_string(a) < tags_to_string(b); 38 | } 39 | 40 | inline bool operator<(const atlas::meter::Id& a, const atlas::meter::Id& b) { 41 | auto name_cmp = strcmp(a.Name(), b.Name()); 42 | if (name_cmp < 0) { 43 | return true; 44 | } else if (name_cmp > 0) { 45 | return false; 46 | } 47 | 48 | return a.GetTags() < b.GetTags(); 49 | } 50 | 51 | inline std::string to_str(const atlas::interpreter::Expression& expression) { 52 | std::ostringstream os; 53 | expression.Dump(os); 54 | return os.str(); 55 | } 56 | -------------------------------------------------------------------------------- /3rd-party/spdlog/sinks/sink.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2015 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | 8 | #include "spdlog/details/log_msg.h" 9 | #include "spdlog/details/pattern_formatter.h" 10 | #include "spdlog/formatter.h" 11 | 12 | namespace spdlog { 13 | namespace sinks { 14 | class sink 15 | { 16 | public: 17 | sink() 18 | : level_(level::trace) 19 | , formatter_(new pattern_formatter("%+")) 20 | { 21 | } 22 | 23 | explicit sink(std::unique_ptr formatter) 24 | : level_(level::trace) 25 | , formatter_(std::move(formatter)) 26 | { 27 | } 28 | 29 | virtual ~sink() = default; 30 | virtual void log(const details::log_msg &msg) = 0; 31 | virtual void flush() = 0; 32 | virtual void set_pattern(const std::string &pattern) = 0; 33 | virtual void set_formatter(std::unique_ptr sink_formatter) = 0; 34 | 35 | bool should_log(level::level_enum msg_level) const 36 | { 37 | return msg_level >= level_.load(std::memory_order_relaxed); 38 | } 39 | 40 | void set_level(level::level_enum log_level) 41 | { 42 | level_.store(log_level); 43 | } 44 | 45 | level::level_enum level() const 46 | { 47 | return static_cast(level_.load(std::memory_order_relaxed)); 48 | } 49 | 50 | protected: 51 | // sink log level - default is all 52 | level_t level_; 53 | 54 | // sink formatter - default is full format 55 | std::unique_ptr formatter_; 56 | }; 57 | 58 | } // namespace sinks 59 | } // namespace spdlog 60 | -------------------------------------------------------------------------------- /meter/percentile_dist_summary.cc: -------------------------------------------------------------------------------- 1 | #include "percentile_dist_summary.h" 2 | #include "statistic.h" 3 | 4 | namespace atlas { 5 | namespace meter { 6 | 7 | #include "percentile_bucket_tags.inc" 8 | 9 | PercentileDistributionSummary::PercentileDistributionSummary(Registry* registry, 10 | const IdPtr& id) 11 | : Meter{id, registry->clock()}, 12 | registry_{registry}, 13 | dist_{registry->distribution_summary(id)} {} 14 | 15 | std::ostream& PercentileDistributionSummary::Dump(std::ostream& os) const { 16 | os << "PercentileDistributionSummary{" << id_ << "}"; 17 | return os; 18 | } 19 | 20 | void PercentileDistributionSummary::Record(int64_t amount) noexcept { 21 | dist_->Record(amount); 22 | CounterFor(percentile_buckets::IndexOf(amount))->Increment(); 23 | } 24 | 25 | inline Tag PercentileTag(size_t i) { 26 | static std::string kPercentile{"percentile"}; 27 | return Tag::of(kPercentile, kDistTags.at(i)); 28 | } 29 | 30 | std::shared_ptr PercentileDistributionSummary::CounterFor( 31 | size_t i) const noexcept { 32 | auto& c = counters_.at(i); 33 | if (!c) { 34 | c = registry_->counter( 35 | id_->WithTag(statistic::percentile)->WithTag(PercentileTag(i))); 36 | counters_.at(i) = c; 37 | } 38 | return c; 39 | } 40 | 41 | double PercentileDistributionSummary::Percentile(double p) const noexcept { 42 | std::array counts; 43 | for (size_t i = 0; i < percentile_buckets::Length(); ++i) { 44 | counts.at(i) = CounterFor(i)->Count(); 45 | } 46 | return percentile_buckets::Percentile(counts, p); 47 | } 48 | 49 | } // namespace meter 50 | } // namespace atlas 51 | -------------------------------------------------------------------------------- /.github/workflows/snapshot.yml: -------------------------------------------------------------------------------- 1 | name: Snapshot 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | if: ${{ github.repository == 'Netflix-Skunkworks/atlas-native-client' }} 11 | runs-on: ubuntu-18.04 12 | strategy: 13 | matrix: 14 | include: 15 | - {compiler: gcc} 16 | - {compiler: clang} 17 | env: 18 | LANG: "en_US.UTF-8" 19 | steps: 20 | - uses: actions/checkout@v2 21 | 22 | - name: Install Dependencies (clang) 23 | if: startsWith(matrix.compiler, 'clang') 24 | run: | 25 | sudo apt-get update 26 | sudo apt-get install -y curl software-properties-common 27 | curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - 28 | sudo apt-add-repository -y "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-5.0 main" 29 | sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test 30 | sudo apt-get update 31 | sudo apt-get install -y clang-5.0 cmake 32 | 33 | - name: Build and Test (clang) 34 | if: startsWith(matrix.compiler, 'clang') 35 | env: 36 | CC: "clang-5.0" 37 | CXX: "clang++-5.0" 38 | run: ./run-build.sh 39 | 40 | - name: Install Dependencies (gcc) 41 | if: startsWith(matrix.compiler, 'gcc') 42 | run: | 43 | sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test 44 | sudo apt-get update 45 | sudo apt-get install -y g++-5 lcov 46 | 47 | - name: Build and Test (gcc) 48 | if: startsWith(matrix.compiler, 'gcc') 49 | env: 50 | CC: "gcc-5" 51 | CXX: "g++-5" 52 | run: ./run-build.sh 53 | -------------------------------------------------------------------------------- /test/percentile_dist_summary_test.cc: -------------------------------------------------------------------------------- 1 | #include "../interpreter/interpreter.h" 2 | #include "../meter/percentile_dist_summary.h" 3 | #include "test_registry.h" 4 | 5 | #include 6 | 7 | using namespace atlas::meter; 8 | using atlas::util::intern_str; 9 | 10 | TEST(PercentileDistributionSummary, Percentile) { 11 | ManualClock manual_clock; 12 | TestRegistry r{60000, &manual_clock}; 13 | PercentileDistributionSummary d{&r, r.CreateId("foo", kEmptyTags)}; 14 | 15 | for (auto i = 0; i < 100000; ++i) { 16 | d.Record(i); 17 | } 18 | 19 | for (auto i = 0; i <= 100; ++i) { 20 | auto expected = i * 1000.0; 21 | auto threshold = 0.15 * expected; 22 | EXPECT_NEAR(expected, d.Percentile(i), threshold); 23 | } 24 | } 25 | 26 | TEST(PercentileDistributionSummary, HasProperStatistic) { 27 | ManualClock manual_clock; 28 | TestRegistry r{60000, &manual_clock}; 29 | PercentileDistributionSummary t{&r, r.CreateId("foo", kEmptyTags)}; 30 | t.Record(42); 31 | 32 | auto ms = r.meters(); 33 | auto percentileRef = intern_str("percentile"); 34 | auto statisticRef = intern_str("statistic"); 35 | for (const auto& m : ms) { 36 | auto tags = m->GetId()->GetTags(); 37 | if (tags.has(percentileRef)) { 38 | EXPECT_EQ(tags.at(statisticRef), percentileRef); 39 | } 40 | } 41 | } 42 | 43 | TEST(PercentileDistributionSummary, CountTotal) { 44 | ManualClock manual_clock; 45 | TestRegistry r{60000, &manual_clock}; 46 | PercentileDistributionSummary d{&r, r.CreateId("foo", kEmptyTags)}; 47 | 48 | for (auto i = 0; i < 100; ++i) { 49 | d.Record(i); 50 | } 51 | 52 | EXPECT_EQ(d.Count(), 100); 53 | EXPECT_EQ(d.TotalAmount(), 100 * 99 / 2); // sum(1,n) = n * (n - 1) / 2 54 | } 55 | -------------------------------------------------------------------------------- /meter/long_task_timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "meter.h" 4 | 5 | namespace atlas { 6 | namespace meter { 7 | /// 8 | /// Timer intended to track a small number of long running tasks. Example would 9 | /// be something like 10 | /// a batch hadoop job. Though "long running" is a bit subjective the assumption 11 | /// is that anything 12 | /// over a minute is long running. 13 | /// 14 | class LongTaskTimer { 15 | public: 16 | virtual ~LongTaskTimer() = default; 17 | 18 | /// Start keeping time for a task and return a task id that can be used to 19 | /// look up how long 20 | /// it has been running. 21 | virtual int64_t Start() = 0; 22 | 23 | /// Indicates that a given task has completed. 24 | /// 25 | /// @param task 26 | /// Id for the task to stop. This should be the value returned from 27 | /// {@link #start()}. 28 | /// @return 29 | /// Duration for the task in nanoseconds. A -1 value will be returned for 30 | /// an unknown task. 31 | virtual int64_t Stop(int64_t task) = 0; 32 | 33 | /// Returns the current duration for a given active task. 34 | /// 35 | /// @param task 36 | /// Id for the task. This should be the value returned from {@link 37 | /// #start()}. 38 | /// @return 39 | /// Duration for the task in nanoseconds. A -1 value will be returned 40 | /// for an unknown task. 41 | virtual int64_t Duration(int64_t task) const noexcept = 0; 42 | 43 | /// Returns the cumulative duration of all current tasks in nanoseconds. 44 | virtual int64_t Duration() const noexcept = 0; 45 | 46 | /// Returns the current number of tasks being executed. 47 | virtual int ActiveTasks() const noexcept = 0; 48 | }; 49 | } // namespace meter 50 | } // namespace atlas 51 | -------------------------------------------------------------------------------- /util/logger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "config.h" 4 | #include 5 | #include 6 | 7 | namespace atlas { 8 | namespace util { 9 | 10 | class LogManager { 11 | public: 12 | explicit LogManager(std::string name) noexcept; 13 | std::shared_ptr Logger() noexcept; 14 | void UseConsoleLogger(int level) noexcept; 15 | void SetLoggingDirs(const std::vector& dirs) noexcept; 16 | void InitializeLogging(const LogConfig& config) noexcept; 17 | std::string GetLoggingDir() const noexcept; 18 | 19 | private: 20 | std::string name_; 21 | std::mutex logger_mutex; 22 | std::shared_ptr current_logger_; 23 | std::vector logging_directories = {"/logs/atlasd", "./logs"}; 24 | 25 | std::string current_logging_directory; 26 | LogConfig current_log_config; 27 | 28 | std::string get_usable_logging_directory() const noexcept; 29 | void fallback_init_for_logger() noexcept; 30 | void initialize_logger(const std::string& log_dir) noexcept; 31 | void initialize() noexcept; 32 | }; 33 | 34 | LogManager& log_manager() noexcept; 35 | 36 | inline std::shared_ptr Logger() noexcept { 37 | return log_manager().Logger(); 38 | } 39 | 40 | inline void UseConsoleLogger(int level) noexcept { 41 | log_manager().UseConsoleLogger(level); 42 | } 43 | 44 | inline void SetLoggingDirs(const std::vector& dirs) noexcept { 45 | log_manager().SetLoggingDirs(dirs); 46 | } 47 | 48 | inline void InitializeLogging(const LogConfig& config) noexcept { 49 | log_manager().InitializeLogging(config); 50 | } 51 | 52 | inline std::string GetLoggingDir() noexcept { 53 | return log_manager().GetLoggingDir(); 54 | } 55 | 56 | } // namespace util 57 | } // namespace atlas 58 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - v[0-9]+.[0-9]+.[0-9]+ 7 | - v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+ 8 | 9 | jobs: 10 | build: 11 | if: ${{ github.repository == 'Netflix-Skunkworks/atlas-native-client' }} 12 | runs-on: ubuntu-18.04 13 | strategy: 14 | matrix: 15 | include: 16 | - {compiler: gcc} 17 | - {compiler: clang} 18 | env: 19 | LANG: "en_US.UTF-8" 20 | steps: 21 | - uses: actions/checkout@v2 22 | 23 | - name: Install Dependencies (clang) 24 | if: startsWith(matrix.compiler, 'clang') 25 | run: | 26 | sudo apt-get update 27 | sudo apt-get install -y curl software-properties-common 28 | curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - 29 | sudo apt-add-repository -y "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-5.0 main" 30 | sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test 31 | sudo apt-get update 32 | sudo apt-get install -y clang-5.0 cmake 33 | 34 | - name: Build and Test (clang) 35 | if: startsWith(matrix.compiler, 'clang') 36 | env: 37 | CC: "clang-5.0" 38 | CXX: "clang++-5.0" 39 | run: ./run-build.sh 40 | 41 | - name: Install Dependencies (gcc) 42 | if: startsWith(matrix.compiler, 'gcc') 43 | run: | 44 | sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test 45 | sudo apt-get update 46 | sudo apt-get install -y g++-5 lcov 47 | 48 | - name: Build and Test (gcc) 49 | if: startsWith(matrix.compiler, 'gcc') 50 | env: 51 | CC: "gcc-5" 52 | CXX: "g++-5" 53 | run: ./run-build.sh 54 | -------------------------------------------------------------------------------- /util/optional.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "intern.h" 4 | 5 | class OptionalString { 6 | public: 7 | explicit OptionalString(atlas::util::StrRef ref) noexcept : s_ref(ref) {} 8 | 9 | explicit OptionalString(const char* string) noexcept { 10 | if (string != nullptr) { 11 | s_ref = atlas::util::intern_str(string); 12 | } 13 | } 14 | 15 | operator bool() const { return s_ref.valid(); } 16 | 17 | operator const char*() const { return s_ref.get(); }; 18 | 19 | bool operator==(const std::string& other) const { 20 | return s_ref.valid() && std::string(s_ref.get()) == other; 21 | } 22 | 23 | bool operator==(const char* other) const { 24 | return s_ref.valid() && atlas::util::intern_str(other) == s_ref; 25 | } 26 | 27 | bool operator==(atlas::util::StrRef other) const { return s_ref == other; } 28 | 29 | bool operator<(atlas::util::StrRef other) const { 30 | if (s_ref.valid() && other.valid()) { 31 | return strcmp(s_ref.get(), other.get()) < 0; 32 | } 33 | return false; 34 | } 35 | 36 | bool operator<=(atlas::util::StrRef other) const { 37 | if (s_ref.valid() && other.valid()) { 38 | return strcmp(s_ref.get(), other.get()) <= 0; 39 | } 40 | return false; 41 | } 42 | 43 | bool operator>(atlas::util::StrRef other) const { 44 | if (s_ref.valid() && other.valid()) { 45 | return strcmp(s_ref.get(), other.get()) > 0; 46 | } 47 | return false; 48 | } 49 | 50 | bool operator>=(atlas::util::StrRef other) const { 51 | if (s_ref.valid() && other.valid()) { 52 | return strcmp(s_ref.get(), other.get()) >= 0; 53 | } 54 | return false; 55 | } 56 | 57 | const char* get() const { return s_ref.get(); } 58 | 59 | size_t length() const { return s_ref.length(); } 60 | 61 | private: 62 | atlas::util::StrRef s_ref; 63 | }; 64 | -------------------------------------------------------------------------------- /gen_perc_bucket_values.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Number of positions of base-2 digits to shift when iterating over the long 6 | // space. 7 | constexpr int kDigits = 2; 8 | 9 | static std::vector bucketValues; 10 | static std::vector powerOf4Index; 11 | 12 | static void init() { 13 | powerOf4Index.push_back(0); 14 | bucketValues.push_back(1); 15 | bucketValues.push_back(2); 16 | bucketValues.push_back(3); 17 | 18 | auto exp = kDigits; 19 | while (exp < 64) { 20 | auto current = int64_t{1} << exp; 21 | auto delta = current / 3; 22 | auto next = (current << kDigits) - delta; 23 | 24 | powerOf4Index.push_back(bucketValues.size()); 25 | while (current < next) { 26 | bucketValues.push_back(current); 27 | current += delta; 28 | } 29 | exp += kDigits; 30 | } 31 | bucketValues.push_back(std::numeric_limits::max()); 32 | } 33 | 34 | int main(int argc, char* argv[]) { 35 | init(); 36 | std::ofstream of; 37 | if (argc > 1) { 38 | of.open(argv[1]); 39 | } else { 40 | of.open("/dev/stdout"); 41 | } 42 | of << "// Do not modify - auto-generated\n//\n" 43 | << "const std::array kBucketValues = {{"; 45 | bool first = true; 46 | for (auto v : bucketValues) { 47 | if (!first) { 48 | of << ",\n"; 49 | } else { 50 | first = false; 51 | } 52 | of << " " << v << "LL"; 53 | } 54 | of << "}};\n"; 55 | 56 | of << "const std::array kPowerOf4Index = {{\n"; 58 | first = true; 59 | for (auto v : powerOf4Index) { 60 | if (!first) { 61 | of << ",\n"; 62 | } else { 63 | first = false; 64 | } 65 | of << " " << v << "u"; 66 | } 67 | of << "\n}};\n"; 68 | } 69 | -------------------------------------------------------------------------------- /test/default_max_gauge_test.cc: -------------------------------------------------------------------------------- 1 | #include "../meter/default_max_gauge.h" 2 | #include "../meter/manual_clock.h" 3 | #include "test_registry.h" 4 | #include 5 | #include 6 | 7 | using namespace atlas::meter; 8 | using atlas::util::kMainFrequencyMillis; 9 | 10 | static ManualClock manual_clock; 11 | 12 | static std::unique_ptr newMaxGaugeInt() { 13 | manual_clock.SetWall(0); 14 | return std::make_unique( 15 | std::make_shared("foo", kEmptyTags), manual_clock, 16 | kMainFrequencyMillis); 17 | } 18 | 19 | static std::unique_ptr> newMaxGaugeDouble() { 20 | manual_clock.SetWall(0); 21 | return std::make_unique>( 22 | std::make_shared("foo", kEmptyTags), manual_clock, 23 | kMainFrequencyMillis); 24 | } 25 | 26 | TEST(DefaultMaxGaugeInt, Init) { 27 | auto mg = newMaxGaugeInt(); 28 | EXPECT_EQ(mg->Value(), 0); 29 | } 30 | 31 | TEST(DefaultMaxGaugeInt, OnePoller) { 32 | auto mg = newMaxGaugeInt(); 33 | auto ms = mg->Measure(); 34 | EXPECT_EQ(1, ms.size()); 35 | EXPECT_TRUE(std::isnan(ms[0].value)); 36 | 37 | mg->Update(42); 38 | manual_clock.SetWall(60000); 39 | auto one = mg->Measure(); 40 | 41 | EXPECT_EQ(1, one.size()); 42 | EXPECT_DOUBLE_EQ(42.0, one[0].value); 43 | } 44 | 45 | TEST(DefaultMaxGaugeDouble, Init) { 46 | auto mg = newMaxGaugeDouble(); 47 | EXPECT_DOUBLE_EQ(mg->Value(), 0); 48 | } 49 | 50 | TEST(DefaultMaxGaugeDouble, OnePoller) { 51 | auto mg = newMaxGaugeDouble(); 52 | auto ms = mg->Measure(); 53 | EXPECT_DOUBLE_EQ(1, ms.size()); 54 | EXPECT_TRUE(std::isnan(ms[0].value)); 55 | 56 | mg->Update(42.1); 57 | manual_clock.SetWall(60000); 58 | auto one = mg->Measure(); 59 | 60 | EXPECT_EQ(1, one.size()); 61 | EXPECT_DOUBLE_EQ(42.1, one[0].value); 62 | } 63 | -------------------------------------------------------------------------------- /3rd-party/spdlog/details/circular_q.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2018 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | // cirucal q view of std::vector. 7 | #pragma once 8 | 9 | #include 10 | 11 | namespace spdlog { 12 | namespace details { 13 | template 14 | class circular_q 15 | { 16 | public: 17 | using item_type = T; 18 | 19 | explicit circular_q(size_t max_items) 20 | : max_items_(max_items + 1) // one item is reserved as marker for full q 21 | , v_(max_items_) 22 | { 23 | } 24 | 25 | // push back, overrun (oldest) item if no room left 26 | void push_back(T &&item) 27 | { 28 | v_[tail_] = std::move(item); 29 | tail_ = (tail_ + 1) % max_items_; 30 | 31 | if (tail_ == head_) // overrun last item if full 32 | { 33 | head_ = (head_ + 1) % max_items_; 34 | ++overrun_counter_; 35 | } 36 | } 37 | 38 | // Pop item from front. 39 | // If there are no elements in the container, the behavior is undefined. 40 | void pop_front(T &popped_item) 41 | { 42 | popped_item = std::move(v_[head_]); 43 | head_ = (head_ + 1) % max_items_; 44 | } 45 | 46 | bool empty() 47 | { 48 | return tail_ == head_; 49 | } 50 | 51 | bool full() 52 | { 53 | // head is ahead of the tail by 1 54 | return ((tail_ + 1) % max_items_) == head_; 55 | } 56 | 57 | size_t overrun_counter() const 58 | { 59 | return overrun_counter_; 60 | } 61 | 62 | private: 63 | size_t max_items_; 64 | typename std::vector::size_type head_ = 0; 65 | typename std::vector::size_type tail_ = 0; 66 | 67 | std::vector v_; 68 | 69 | size_t overrun_counter_ = 0; 70 | }; 71 | } // namespace details 72 | } // namespace spdlog 73 | -------------------------------------------------------------------------------- /3rd-party/spdlog/sinks/stdout_color_sinks.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2018 spdlog 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | 8 | #include "spdlog/spdlog.h" 9 | #ifdef _WIN32 10 | #include "spdlog/sinks/wincolor_sink.h" 11 | #else 12 | #include "spdlog/sinks/ansicolor_sink.h" 13 | #endif 14 | 15 | namespace spdlog { 16 | namespace sinks { 17 | #ifdef _WIN32 18 | using stdout_color_sink_mt = wincolor_stdout_sink_mt; 19 | using stdout_color_sink_st = wincolor_stdout_sink_st; 20 | using stderr_color_sink_mt = wincolor_stderr_sink_mt; 21 | using stderr_color_sink_st = wincolor_stderr_sink_st; 22 | #else 23 | using stdout_color_sink_mt = ansicolor_stdout_sink_mt; 24 | using stdout_color_sink_st = ansicolor_stdout_sink_st; 25 | using stderr_color_sink_mt = ansicolor_stderr_sink_mt; 26 | using stderr_color_sink_st = ansicolor_stderr_sink_st; 27 | #endif 28 | } // namespace sinks 29 | 30 | template 31 | inline std::shared_ptr stdout_color_mt(const std::string &logger_name) 32 | { 33 | return Factory::template create(logger_name); 34 | } 35 | 36 | template 37 | inline std::shared_ptr stdout_color_st(const std::string &logger_name) 38 | { 39 | return Factory::template create(logger_name); 40 | } 41 | 42 | template 43 | inline std::shared_ptr stderr_color_mt(const std::string &logger_name) 44 | { 45 | return Factory::template create(logger_name); 46 | } 47 | 48 | template 49 | inline std::shared_ptr stderr_color_st(const std::string &logger_name) 50 | { 51 | return Factory::template create(logger_name); 52 | } 53 | } // namespace spdlog 54 | -------------------------------------------------------------------------------- /3rd-party/benchmark/test/cxx03_test.cc: -------------------------------------------------------------------------------- 1 | #undef NDEBUG 2 | #include 3 | #include 4 | 5 | #include "benchmark/benchmark.h" 6 | 7 | #if __cplusplus >= 201103L 8 | #error C++11 or greater detected. Should be C++03. 9 | #endif 10 | 11 | #ifdef BENCHMARK_HAS_CXX11 12 | #error C++11 or greater detected by the library. BENCHMARK_HAS_CXX11 is defined. 13 | #endif 14 | 15 | void BM_empty(benchmark::State& state) { 16 | while (state.KeepRunning()) { 17 | volatile std::size_t x = state.iterations(); 18 | ((void)x); 19 | } 20 | } 21 | BENCHMARK(BM_empty); 22 | 23 | // The new C++11 interface for args/ranges requires initializer list support. 24 | // Therefore we provide the old interface to support C++03. 25 | void BM_old_arg_range_interface(benchmark::State& state) { 26 | assert((state.range(0) == 1 && state.range(1) == 2) || 27 | (state.range(0) == 5 && state.range(1) == 6)); 28 | while (state.KeepRunning()) { 29 | } 30 | } 31 | BENCHMARK(BM_old_arg_range_interface)->ArgPair(1, 2)->RangePair(5, 5, 6, 6); 32 | 33 | template 34 | void BM_template2(benchmark::State& state) { 35 | BM_empty(state); 36 | } 37 | BENCHMARK_TEMPLATE2(BM_template2, int, long); 38 | 39 | template 40 | void BM_template1(benchmark::State& state) { 41 | BM_empty(state); 42 | } 43 | BENCHMARK_TEMPLATE(BM_template1, long); 44 | BENCHMARK_TEMPLATE1(BM_template1, int); 45 | 46 | template 47 | struct BM_Fixture : public ::benchmark::Fixture { 48 | }; 49 | 50 | BENCHMARK_TEMPLATE_F(BM_Fixture, BM_template1, long)(benchmark::State& state) { 51 | BM_empty(state); 52 | } 53 | BENCHMARK_TEMPLATE1_F(BM_Fixture, BM_template2, int)(benchmark::State& state) { 54 | BM_empty(state); 55 | } 56 | 57 | void BM_counters(benchmark::State& state) { 58 | BM_empty(state); 59 | state.counters["Foo"] = 2; 60 | } 61 | BENCHMARK(BM_counters); 62 | 63 | BENCHMARK_MAIN() 64 | -------------------------------------------------------------------------------- /3rd-party/benchmark/src/log.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_LOG_H_ 2 | #define BENCHMARK_LOG_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "benchmark/benchmark.h" 8 | 9 | namespace benchmark { 10 | namespace internal { 11 | 12 | typedef std::basic_ostream&(EndLType)(std::basic_ostream&); 13 | 14 | class LogType { 15 | friend LogType& GetNullLogInstance(); 16 | friend LogType& GetErrorLogInstance(); 17 | 18 | // FIXME: Add locking to output. 19 | template 20 | friend LogType& operator<<(LogType&, Tp const&); 21 | friend LogType& operator<<(LogType&, EndLType*); 22 | 23 | private: 24 | LogType(std::ostream* out) : out_(out) {} 25 | std::ostream* out_; 26 | BENCHMARK_DISALLOW_COPY_AND_ASSIGN(LogType); 27 | }; 28 | 29 | template 30 | LogType& operator<<(LogType& log, Tp const& value) { 31 | if (log.out_) { 32 | *log.out_ << value; 33 | } 34 | return log; 35 | } 36 | 37 | inline LogType& operator<<(LogType& log, EndLType* m) { 38 | if (log.out_) { 39 | *log.out_ << m; 40 | } 41 | return log; 42 | } 43 | 44 | inline int& LogLevel() { 45 | static int log_level = 0; 46 | return log_level; 47 | } 48 | 49 | inline LogType& GetNullLogInstance() { 50 | static LogType log(nullptr); 51 | return log; 52 | } 53 | 54 | inline LogType& GetErrorLogInstance() { 55 | static LogType log(&std::clog); 56 | return log; 57 | } 58 | 59 | inline LogType& GetLogInstanceForLevel(int level) { 60 | if (level <= LogLevel()) { 61 | return GetErrorLogInstance(); 62 | } 63 | return GetNullLogInstance(); 64 | } 65 | 66 | } // end namespace internal 67 | } // end namespace benchmark 68 | 69 | #define VLOG(x) \ 70 | (::benchmark::internal::GetLogInstanceForLevel(x) << "-- LOG(" << x << "):" \ 71 | " ") 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /3rd-party/src/gtest/gtest_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #include 31 | 32 | #include "gtest/gtest.h" 33 | 34 | GTEST_API_ int main(int argc, char** argv) { 35 | printf("Running main() from gtest_main.cc\n"); 36 | testing::InitGoogleTest(&argc, argv); 37 | return RUN_ALL_TESTS(); 38 | } 39 | -------------------------------------------------------------------------------- /test/function_gauge_test.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "../meter/function_gauge.h" 3 | #include "../meter/manual_clock.h" 4 | #include "test_registry.h" 5 | #include 6 | 7 | using atlas::meter::FunctionGauge; 8 | using atlas::meter::Id; 9 | using atlas::meter::kEmptyTags; 10 | using atlas::meter::ManualClock; 11 | using atlas::meter::Meter; 12 | 13 | static ManualClock manual_clock; 14 | static constexpr auto kNAN = std::numeric_limits::quiet_NaN(); 15 | 16 | void expect_gauge_value(const Meter& m, double expected) { 17 | auto measures = m.Measure(); 18 | EXPECT_EQ(measures.size(), 1); 19 | auto value = measures.at(0).value; 20 | if (std::isnan(expected)) { 21 | EXPECT_TRUE(std::isnan(value)); 22 | } else { 23 | EXPECT_DOUBLE_EQ(value, expected); 24 | } 25 | } 26 | 27 | TEST(FunctionGauge, Init) { 28 | auto id = std::make_shared("foo", kEmptyTags); 29 | auto n = std::make_shared(0); 30 | auto f = [](int64_t v) { return v * 2.0; }; 31 | FunctionGauge fg{id, manual_clock, n, f}; 32 | 33 | EXPECT_FALSE(fg.HasExpired()); 34 | auto ms = fg.Measure(); 35 | } 36 | 37 | TEST(FunctionGauge, Value) { 38 | auto id = std::make_shared("foo", kEmptyTags); 39 | auto n = std::make_shared(21); 40 | auto f = [](int64_t v) { return v * 2.0; }; 41 | FunctionGauge fg{id, manual_clock, n, f}; 42 | 43 | fg.Update(); 44 | EXPECT_DOUBLE_EQ(fg.Value(), 42.0); 45 | } 46 | 47 | TEST(FunctionGauge, Expiration) { 48 | auto id = std::make_shared("foo", kEmptyTags); 49 | auto n = std::make_shared(21); 50 | auto f = [](int64_t v) { return v * 2.0; }; 51 | FunctionGauge fg{id, manual_clock, n, f}; 52 | 53 | EXPECT_FALSE(fg.HasExpired()); // valid pointer 54 | fg.Update(); 55 | expect_gauge_value(fg, 42.0); 56 | 57 | n.reset(); 58 | EXPECT_TRUE(fg.HasExpired()); // pointer is gone 59 | 60 | fg.Update(); 61 | expect_gauge_value(fg, kNAN); 62 | } -------------------------------------------------------------------------------- /3rd-party/benchmark/src/sleep.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "sleep.h" 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "internal_macros.h" 22 | 23 | #ifdef BENCHMARK_OS_WINDOWS 24 | #include 25 | #endif 26 | 27 | namespace benchmark { 28 | #ifdef BENCHMARK_OS_WINDOWS 29 | // Window's Sleep takes milliseconds argument. 30 | void SleepForMilliseconds(int milliseconds) { Sleep(milliseconds); } 31 | void SleepForSeconds(double seconds) { 32 | SleepForMilliseconds(static_cast(kNumMillisPerSecond * seconds)); 33 | } 34 | #else // BENCHMARK_OS_WINDOWS 35 | void SleepForMicroseconds(int microseconds) { 36 | struct timespec sleep_time; 37 | sleep_time.tv_sec = microseconds / kNumMicrosPerSecond; 38 | sleep_time.tv_nsec = (microseconds % kNumMicrosPerSecond) * kNumNanosPerMicro; 39 | while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) 40 | ; // Ignore signals and wait for the full interval to elapse. 41 | } 42 | 43 | void SleepForMilliseconds(int milliseconds) { 44 | SleepForMicroseconds(milliseconds * kNumMicrosPerMilli); 45 | } 46 | 47 | void SleepForSeconds(double seconds) { 48 | SleepForMicroseconds(static_cast(seconds * kNumMicrosPerSecond)); 49 | } 50 | #endif // BENCHMARK_OS_WINDOWS 51 | } // end namespace benchmark 52 | -------------------------------------------------------------------------------- /3rd-party/benchmark/tools/gbench/Inputs/test2_run.json: -------------------------------------------------------------------------------- 1 | { 2 | "context": { 3 | "date": "2016-08-02 17:44:46", 4 | "num_cpus": 4, 5 | "mhz_per_cpu": 4228, 6 | "cpu_scaling_enabled": false, 7 | "library_build_type": "release" 8 | }, 9 | "benchmarks": [ 10 | { 11 | "name": "BM_Hi", 12 | "iterations": 1234, 13 | "real_time": 42, 14 | "cpu_time": 24, 15 | "time_unit": "ms" 16 | }, 17 | { 18 | "name": "BM_Zero", 19 | "iterations": 1000, 20 | "real_time": 10, 21 | "cpu_time": 10, 22 | "time_unit": "ns" 23 | }, 24 | { 25 | "name": "BM_Zero/4", 26 | "iterations": 4000, 27 | "real_time": 40, 28 | "cpu_time": 40, 29 | "time_unit": "ns" 30 | }, 31 | { 32 | "name": "Prefix/BM_Zero", 33 | "iterations": 2000, 34 | "real_time": 20, 35 | "cpu_time": 20, 36 | "time_unit": "ns" 37 | }, 38 | { 39 | "name": "Prefix/BM_Zero/3", 40 | "iterations": 3000, 41 | "real_time": 30, 42 | "cpu_time": 30, 43 | "time_unit": "ns" 44 | }, 45 | { 46 | "name": "BM_One", 47 | "iterations": 5000, 48 | "real_time": 5, 49 | "cpu_time": 5, 50 | "time_unit": "ns" 51 | }, 52 | { 53 | "name": "BM_One/4", 54 | "iterations": 2000, 55 | "real_time": 20, 56 | "cpu_time": 20, 57 | "time_unit": "ns" 58 | }, 59 | { 60 | "name": "Prefix/BM_One", 61 | "iterations": 1000, 62 | "real_time": 10, 63 | "cpu_time": 10, 64 | "time_unit": "ns" 65 | }, 66 | { 67 | "name": "Prefix/BM_One/3", 68 | "iterations": 1500, 69 | "real_time": 15, 70 | "cpu_time": 15, 71 | "time_unit": "ns" 72 | }, 73 | { 74 | "name": "BM_Bye", 75 | "iterations": 5321, 76 | "real_time": 11, 77 | "cpu_time": 63, 78 | "time_unit": "ns" 79 | } 80 | ] 81 | } 82 | -------------------------------------------------------------------------------- /meter/default_max_gauge.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "gauge.h" 6 | #include "stepnumber.h" 7 | #include "statistic.h" 8 | 9 | namespace atlas { 10 | namespace meter { 11 | 12 | template 13 | class DefaultMaxGauge : public Meter, public Gauge { 14 | static constexpr auto kMinValue = std::numeric_limits::lowest(); 15 | 16 | public: 17 | DefaultMaxGauge(IdPtr id, const Clock& clock, int64_t freq_millis) 18 | : Meter(WithDefaultGaugeTags(std::move(id), statistic::max), clock), 19 | value_(0), 20 | step_number_(kMinValue, freq_millis, &clock) { 21 | Updated(); 22 | } 23 | 24 | void Update(T v) noexcept override { 25 | step_number_.UpdateCurrentMax(v); 26 | auto current = value_.load(std::memory_order_relaxed); 27 | value_.store(std::max(current, v), std::memory_order_relaxed); 28 | Updated(); 29 | } 30 | 31 | double Value() const noexcept override { 32 | return value_.load(std::memory_order_relaxed); 33 | } 34 | 35 | std::ostream& Dump(std::ostream& os) const override { 36 | auto v = value_.load(std::memory_order_relaxed); 37 | os << "MaxGauge{" << *id_ << ", value=" << v << "}"; 38 | return os; 39 | } 40 | 41 | Measurements Measure() const override { 42 | const auto maybe_max = step_number_.Poll(); 43 | const double max = maybe_max != kMinValue ? maybe_max : myNaN; 44 | auto now = clock_.WallTime(); 45 | auto stepMillis = step_number_.StepMillis(); 46 | auto offset = now % stepMillis; 47 | auto start_step = now - offset; 48 | return Measurements{Measurement{id_, start_step, max}}; 49 | } 50 | 51 | const char* GetClass() const noexcept override { return "DefaultMaxGauge"; } 52 | 53 | private: 54 | std::atomic value_; // to keep the local max 55 | mutable StepNumber step_number_; 56 | }; 57 | 58 | using DefaultMaxGaugeInt = DefaultMaxGauge; 59 | 60 | } // namespace meter 61 | } // namespace atlas 62 | -------------------------------------------------------------------------------- /meter/meter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "clock.h" 8 | #include "id.h" 9 | #include "measurement.h" 10 | 11 | namespace atlas { 12 | namespace meter { 13 | 14 | static constexpr auto myNaN = std::numeric_limits::quiet_NaN(); 15 | static constexpr std::size_t MAX_POLLER_FREQ = 4; 16 | static constexpr int64_t MAX_IDLE_TIME = 17 | 15 * 60 * 1000L; // maximum time to keep monitors with no updates 18 | 19 | using Pollers = std::vector; // { 60000, 10000 } millis 20 | 21 | class Meter { 22 | public: 23 | Meter(IdPtr id, const Clock& clock) noexcept 24 | : id_(std::move(id)), clock_(clock) {} 25 | 26 | virtual IdPtr GetId() const noexcept { return id_; } 27 | 28 | virtual std::ostream& Dump(std::ostream& os) const = 0; 29 | 30 | virtual ~Meter() noexcept = default; 31 | 32 | virtual Measurements Measure() const = 0; 33 | 34 | virtual bool HasExpired() const noexcept { 35 | auto last = last_updated_.load(std::memory_order::memory_order_relaxed); 36 | auto now = clock_.WallTime(); 37 | return (now - last) > MAX_IDLE_TIME; 38 | } 39 | 40 | virtual bool IsUpdateable() const noexcept { return false; } 41 | 42 | virtual const char* GetClass() const noexcept = 0; 43 | 44 | protected: 45 | std::atomic last_updated_{0}; 46 | const IdPtr id_; 47 | const Clock& clock_; 48 | 49 | inline void Updated() { 50 | last_updated_.store(clock_.WallTime(), 51 | std::memory_order::memory_order_relaxed); 52 | } 53 | }; 54 | 55 | class UpdateableMeter : public Meter { 56 | public: 57 | UpdateableMeter(IdPtr id, const Clock& clock) : Meter(id, clock) {} 58 | bool IsUpdateable() const noexcept override { return true; } 59 | virtual void Update() noexcept = 0; 60 | }; 61 | 62 | inline std::ostream& operator<<(std::ostream& os, const Meter& meter) { 63 | return meter.Dump(os); 64 | } 65 | } // namespace meter 66 | } // namespace atlas 67 | -------------------------------------------------------------------------------- /3rd-party/spdlog/sinks/basic_file_sink.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2015-2018 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | #include "spdlog/details/file_helper.h" 8 | #include "spdlog/details/null_mutex.h" 9 | #include "spdlog/sinks/base_sink.h" 10 | #include "spdlog/spdlog.h" 11 | 12 | #include 13 | #include 14 | 15 | namespace spdlog { 16 | namespace sinks { 17 | /* 18 | * Trivial file sink with single file as target 19 | */ 20 | template 21 | class basic_file_sink final : public base_sink 22 | { 23 | public: 24 | explicit basic_file_sink(const filename_t &filename, bool truncate = false) 25 | { 26 | file_helper_.open(filename, truncate); 27 | } 28 | 29 | protected: 30 | void sink_it_(const details::log_msg &msg) override 31 | { 32 | fmt::memory_buffer formatted; 33 | sink::formatter_->format(msg, formatted); 34 | file_helper_.write(formatted); 35 | } 36 | 37 | void flush_() override 38 | { 39 | file_helper_.flush(); 40 | } 41 | 42 | private: 43 | details::file_helper file_helper_; 44 | }; 45 | 46 | using basic_file_sink_mt = basic_file_sink; 47 | using basic_file_sink_st = basic_file_sink; 48 | 49 | } // namespace sinks 50 | 51 | // 52 | // factory functions 53 | // 54 | template 55 | inline std::shared_ptr basic_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate = false) 56 | { 57 | return Factory::template create(logger_name, filename, truncate); 58 | } 59 | 60 | template 61 | inline std::shared_ptr basic_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate = false) 62 | { 63 | return Factory::template create(logger_name, filename, truncate); 64 | } 65 | 66 | } // namespace spdlog 67 | -------------------------------------------------------------------------------- /meter/consolidation_registry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "registry.h" 6 | #include "stepnumber.h" 7 | namespace atlas { 8 | 9 | namespace meter { 10 | 11 | class ConsolidatedValue { 12 | public: 13 | static constexpr auto kMinValue = std::numeric_limits::lowest(); 14 | ConsolidatedValue(bool is_gauge, int update_multiple, int64_t step_ms, 15 | const Clock* clock) 16 | : is_gauge_(is_gauge), 17 | update_multiple_(update_multiple), 18 | v(StepNumber(is_gauge ? kMinValue : 0.0, step_ms, clock)), 19 | marked_{false} {} 20 | bool has_value() const { 21 | auto value = v.Poll(); 22 | return is_gauge_ ? value > kMinValue : value > 0; 23 | } 24 | double value() const { return v.Poll(); } 25 | void update(double value) { 26 | if (is_gauge_) { 27 | v.UpdateCurrentMax(value); 28 | } else { 29 | v.Add(value / update_multiple_); 30 | } 31 | } 32 | bool marked() const noexcept { return marked_; } 33 | void set_marked(bool marked) noexcept { marked_ = marked; } 34 | 35 | private: 36 | bool is_gauge_; 37 | int update_multiple_; 38 | StepNumber v; 39 | bool marked_; 40 | }; 41 | 42 | class ConsolidationRegistry { 43 | public: 44 | ConsolidationRegistry(int64_t update_frequency, int64_t reporting_frequency, 45 | const Clock* clock) noexcept; 46 | void update_from(const Measurements& measurements) noexcept; 47 | Measurements measurements(int64_t timestamp) const noexcept; 48 | size_t size() const noexcept { 49 | std::lock_guard guard{mutex}; 50 | return my_values.size(); 51 | } 52 | 53 | private: 54 | int64_t update_frequency_; 55 | int64_t reporting_frequency_; 56 | WrappedClock clock_; 57 | using values_map = ska::flat_hash_map; 58 | mutable values_map my_values; 59 | mutable std::mutex mutex; 60 | }; 61 | 62 | } // namespace meter 63 | 64 | } // namespace atlas 65 | -------------------------------------------------------------------------------- /3rd-party/spdlog/sinks/base_sink.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2015 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | // 8 | // base sink templated over a mutex (either dummy or real) 9 | // concrete implementation should override the sink_it_() and flush_() methods. 10 | // locking is taken care of in this class - no locking needed by the 11 | // implementers.. 12 | // 13 | 14 | #include "spdlog/common.h" 15 | #include "spdlog/details/log_msg.h" 16 | #include "spdlog/formatter.h" 17 | #include "spdlog/sinks/sink.h" 18 | 19 | namespace spdlog { 20 | namespace sinks { 21 | template 22 | class base_sink : public sink 23 | { 24 | public: 25 | base_sink() = default; 26 | base_sink(const base_sink &) = delete; 27 | base_sink &operator=(const base_sink &) = delete; 28 | 29 | void log(const details::log_msg &msg) final 30 | { 31 | std::lock_guard lock(mutex_); 32 | sink_it_(msg); 33 | } 34 | 35 | void flush() final 36 | { 37 | std::lock_guard lock(mutex_); 38 | flush_(); 39 | } 40 | 41 | void set_pattern(const std::string &pattern) final 42 | { 43 | std::lock_guard lock(mutex_); 44 | set_pattern_(pattern); 45 | } 46 | 47 | void set_formatter(std::unique_ptr sink_formatter) final 48 | { 49 | std::lock_guard lock(mutex_); 50 | set_formatter_(std::move(sink_formatter)); 51 | } 52 | 53 | protected: 54 | virtual void sink_it_(const details::log_msg &msg) = 0; 55 | virtual void flush_() = 0; 56 | 57 | virtual void set_pattern_(const std::string &pattern) 58 | { 59 | set_formatter_(details::make_unique(pattern)); 60 | } 61 | 62 | virtual void set_formatter_(std::unique_ptr sink_formatter) 63 | { 64 | formatter_ = std::move(sink_formatter); 65 | } 66 | Mutex mutex_; 67 | }; 68 | } // namespace sinks 69 | } // namespace spdlog 70 | -------------------------------------------------------------------------------- /3rd-party/spdlog/details/periodic_worker.h: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // Copyright(c) 2018 Gabi Melman. 4 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 5 | // 6 | 7 | #pragma once 8 | 9 | // periodic worker thread - periodically executes the given callback function. 10 | // 11 | // RAII over the owned thread: 12 | // creates the thread on construction. 13 | // stops and joins the thread on destruction. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | namespace spdlog { 21 | namespace details { 22 | 23 | class periodic_worker 24 | { 25 | public: 26 | periodic_worker(const std::function &callback_fun, std::chrono::seconds interval) 27 | { 28 | active_ = (interval > std::chrono::seconds::zero()); 29 | if (!active_) 30 | { 31 | return; 32 | } 33 | 34 | worker_thread_ = std::thread([this, callback_fun, interval]() { 35 | for (;;) 36 | { 37 | std::unique_lock lock(this->mutex_); 38 | if (this->cv_.wait_for(lock, interval, [this] { return !this->active_; })) 39 | { 40 | return; // active_ == false, so exit this thread 41 | } 42 | callback_fun(); 43 | } 44 | }); 45 | } 46 | 47 | periodic_worker(const periodic_worker &) = delete; 48 | periodic_worker &operator=(const periodic_worker &) = delete; 49 | 50 | // stop the worker thread and join it 51 | ~periodic_worker() 52 | { 53 | if (worker_thread_.joinable()) 54 | { 55 | { 56 | std::lock_guard lock(mutex_); 57 | active_ = false; 58 | } 59 | cv_.notify_one(); 60 | worker_thread_.join(); 61 | } 62 | } 63 | 64 | private: 65 | bool active_; 66 | std::thread worker_thread_; 67 | std::mutex mutex_; 68 | std::condition_variable cv_; 69 | }; 70 | } // namespace details 71 | } // namespace spdlog 72 | -------------------------------------------------------------------------------- /3rd-party/benchmark/src/counter.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "counter.h" 16 | 17 | namespace benchmark { 18 | namespace internal { 19 | 20 | double Finish(Counter const& c, double cpu_time, double num_threads) { 21 | double v = c.value; 22 | if (c.flags & Counter::kIsRate) { 23 | v /= cpu_time; 24 | } 25 | if (c.flags & Counter::kAvgThreads) { 26 | v /= num_threads; 27 | } 28 | return v; 29 | } 30 | 31 | void Finish(UserCounters *l, double cpu_time, double num_threads) { 32 | for (auto &c : *l) { 33 | c.second.value = Finish(c.second, cpu_time, num_threads); 34 | } 35 | } 36 | 37 | void Increment(UserCounters *l, UserCounters const& r) { 38 | // add counters present in both or just in *l 39 | for (auto &c : *l) { 40 | auto it = r.find(c.first); 41 | if (it != r.end()) { 42 | c.second.value = c.second + it->second; 43 | } 44 | } 45 | // add counters present in r, but not in *l 46 | for (auto const &tc : r) { 47 | auto it = l->find(tc.first); 48 | if (it == l->end()) { 49 | (*l)[tc.first] = tc.second; 50 | } 51 | } 52 | } 53 | 54 | bool SameNames(UserCounters const& l, UserCounters const& r) { 55 | if (&l == &r) return true; 56 | if (l.size() != r.size()) { 57 | return false; 58 | } 59 | for (auto const& c : l) { 60 | if (r.find(c.first) == r.end()) { 61 | return false; 62 | } 63 | } 64 | return true; 65 | } 66 | 67 | } // end namespace internal 68 | } // end namespace benchmark 69 | -------------------------------------------------------------------------------- /test/http_server.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class http_server { 10 | public: 11 | http_server() noexcept; 12 | http_server(const http_server&) = delete; 13 | http_server(http_server&&) = delete; 14 | http_server& operator=(const http_server&) = delete; 15 | http_server& operator=(http_server&&) = delete; 16 | 17 | ~http_server(); 18 | 19 | void set_read_sleep(int millis) { read_sleep_ = millis; } 20 | 21 | void set_accept_sleep(int millis) { accept_sleep_ = millis; } 22 | 23 | void start() noexcept; 24 | 25 | int get_port() const { return port_; }; 26 | 27 | void stop() { is_done = true; } 28 | 29 | class Request { 30 | public: 31 | Request() : size_(0), body_(nullptr) {} 32 | Request(std::string method, std::string path, 33 | std::map headers, size_t size, 34 | std::unique_ptr&& body) 35 | : method_(std::move(method)), 36 | path_(std::move(path)), 37 | headers_(std::move(headers)), 38 | size_(size), 39 | body_(std::move(body)) {} 40 | 41 | size_t size() const { return size_; } 42 | const char* body() const { return body_.get(); } 43 | std::string get_header(const std::string& name) const; 44 | std::string method() const { return method_; } 45 | std::string path() const { return path_; } 46 | 47 | private: 48 | std::string method_; 49 | std::string path_; 50 | std::map headers_{}; 51 | size_t size_; 52 | std::unique_ptr body_{}; 53 | }; 54 | 55 | const std::vector& get_requests() const; 56 | 57 | private: 58 | volatile int sockfd_ = -1; 59 | volatile int port_ = 0; 60 | volatile int accept_sleep_ = 0; 61 | volatile int read_sleep_ = 0; 62 | 63 | volatile bool is_done{false}; 64 | mutable std::mutex requests_mutex_{}; 65 | std::vector requests_; 66 | 67 | std::map path_response_; 68 | 69 | void accept_request(int client); 70 | void accept_loop(); 71 | }; 72 | -------------------------------------------------------------------------------- /3rd-party/benchmark/test/options_test.cc: -------------------------------------------------------------------------------- 1 | #include "benchmark/benchmark.h" 2 | #include 3 | #include 4 | 5 | #if defined(NDEBUG) 6 | #undef NDEBUG 7 | #endif 8 | #include 9 | 10 | void BM_basic(benchmark::State& state) { 11 | for (auto _ : state) { 12 | } 13 | } 14 | 15 | void BM_basic_slow(benchmark::State& state) { 16 | std::chrono::milliseconds sleep_duration(state.range(0)); 17 | for (auto _ : state) { 18 | std::this_thread::sleep_for( 19 | std::chrono::duration_cast(sleep_duration)); 20 | } 21 | } 22 | 23 | BENCHMARK(BM_basic); 24 | BENCHMARK(BM_basic)->Arg(42); 25 | BENCHMARK(BM_basic_slow)->Arg(10)->Unit(benchmark::kNanosecond); 26 | BENCHMARK(BM_basic_slow)->Arg(100)->Unit(benchmark::kMicrosecond); 27 | BENCHMARK(BM_basic_slow)->Arg(1000)->Unit(benchmark::kMillisecond); 28 | BENCHMARK(BM_basic)->Range(1, 8); 29 | BENCHMARK(BM_basic)->RangeMultiplier(2)->Range(1, 8); 30 | BENCHMARK(BM_basic)->DenseRange(10, 15); 31 | BENCHMARK(BM_basic)->Args({42, 42}); 32 | BENCHMARK(BM_basic)->Ranges({{64, 512}, {64, 512}}); 33 | BENCHMARK(BM_basic)->MinTime(0.7); 34 | BENCHMARK(BM_basic)->UseRealTime(); 35 | BENCHMARK(BM_basic)->ThreadRange(2, 4); 36 | BENCHMARK(BM_basic)->ThreadPerCpu(); 37 | BENCHMARK(BM_basic)->Repetitions(3); 38 | 39 | void CustomArgs(benchmark::internal::Benchmark* b) { 40 | for (int i = 0; i < 10; ++i) { 41 | b->Arg(i); 42 | } 43 | } 44 | 45 | BENCHMARK(BM_basic)->Apply(CustomArgs); 46 | 47 | void BM_explicit_iteration_count(benchmark::State& state) { 48 | // Test that benchmarks specified with an explicit iteration count are 49 | // only run once. 50 | static bool invoked_before = false; 51 | assert(!invoked_before); 52 | invoked_before = true; 53 | 54 | // Test that the requested iteration count is respected. 55 | assert(state.max_iterations == 42); 56 | size_t actual_iterations = 0; 57 | for (auto _ : state) 58 | ++actual_iterations; 59 | assert(state.iterations() == state.max_iterations); 60 | assert(state.iterations() == 42); 61 | 62 | } 63 | BENCHMARK(BM_explicit_iteration_count)->Iterations(42); 64 | 65 | BENCHMARK_MAIN() 66 | -------------------------------------------------------------------------------- /3rd-party/rapidjson/internal/strfunc.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ 16 | #define RAPIDJSON_INTERNAL_STRFUNC_H_ 17 | 18 | #include "../stream.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | //! Custom strlen() which works on different character types. 24 | /*! \tparam Ch Character type (e.g. char, wchar_t, short) 25 | \param s Null-terminated input string. 26 | \return Number of characters in the string. 27 | \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. 28 | */ 29 | template 30 | inline SizeType StrLen(const Ch* s) { 31 | const Ch* p = s; 32 | while (*p) ++p; 33 | return SizeType(p - s); 34 | } 35 | 36 | //! Returns number of code points in a encoded string. 37 | template 38 | bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { 39 | GenericStringStream is(s); 40 | const typename Encoding::Ch* end = s + length; 41 | SizeType count = 0; 42 | while (is.src_ < end) { 43 | unsigned codepoint; 44 | if (!Encoding::Decode(is, &codepoint)) 45 | return false; 46 | count++; 47 | } 48 | *outCount = count; 49 | return true; 50 | } 51 | 52 | } // namespace internal 53 | RAPIDJSON_NAMESPACE_END 54 | 55 | #endif // RAPIDJSON_INTERNAL_STRFUNC_H_ 56 | -------------------------------------------------------------------------------- /3rd-party/benchmark/cmake/CXXFeatureCheck.cmake: -------------------------------------------------------------------------------- 1 | # - Compile and run code to check for C++ features 2 | # 3 | # This functions compiles a source file under the `cmake` folder 4 | # and adds the corresponding `HAVE_[FILENAME]` flag to the CMake 5 | # environment 6 | # 7 | # cxx_feature_check( []) 8 | # 9 | # - Example 10 | # 11 | # include(CXXFeatureCheck) 12 | # cxx_feature_check(STD_REGEX) 13 | # Requires CMake 2.8.12+ 14 | 15 | if(__cxx_feature_check) 16 | return() 17 | endif() 18 | set(__cxx_feature_check INCLUDED) 19 | 20 | function(cxx_feature_check FILE) 21 | string(TOLOWER ${FILE} FILE) 22 | string(TOUPPER ${FILE} VAR) 23 | string(TOUPPER "HAVE_${VAR}" FEATURE) 24 | if (DEFINED HAVE_${VAR}) 25 | set(HAVE_${VAR} 1 PARENT_SCOPE) 26 | add_definitions(-DHAVE_${VAR}) 27 | return() 28 | endif() 29 | 30 | message("-- Performing Test ${FEATURE}") 31 | if(CMAKE_CROSSCOMPILING) 32 | try_compile(COMPILE_${FEATURE} 33 | ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp 34 | CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS} 35 | LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}) 36 | if(COMPILE_${FEATURE}) 37 | message(WARNING 38 | "If you see build failures due to cross compilation, try setting HAVE_${VAR} to 0") 39 | set(RUN_${FEATURE} 0) 40 | else() 41 | set(RUN_${FEATURE} 1) 42 | endif() 43 | else() 44 | message("-- Performing Test ${FEATURE}") 45 | try_run(RUN_${FEATURE} COMPILE_${FEATURE} 46 | ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp 47 | CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS} 48 | LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}) 49 | endif() 50 | 51 | if(RUN_${FEATURE} EQUAL 0) 52 | message("-- Performing Test ${FEATURE} -- success") 53 | set(HAVE_${VAR} 1 PARENT_SCOPE) 54 | add_definitions(-DHAVE_${VAR}) 55 | else() 56 | if(NOT COMPILE_${FEATURE}) 57 | message("-- Performing Test ${FEATURE} -- failed to compile") 58 | else() 59 | message("-- Performing Test ${FEATURE} -- compiled but failed to run") 60 | endif() 61 | endif() 62 | endfunction() 63 | -------------------------------------------------------------------------------- /3rd-party/gtest/internal/custom/gtest.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. 31 | // The following macros can be defined: 32 | // 33 | // GTEST_OS_STACK_TRACE_GETTER_ - The name of an implementation of 34 | // OsStackTraceGetterInterface. 35 | // 36 | // ** Custom implementation starts here ** 37 | 38 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 39 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 40 | 41 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 42 | -------------------------------------------------------------------------------- /interpreter/context.cc: -------------------------------------------------------------------------------- 1 | #include "context.h" 2 | #include "../util/config_manager.h" 3 | 4 | namespace atlas { 5 | namespace interpreter { 6 | 7 | Context::Context() {} 8 | 9 | static void ensure_stack_notempty(const Context::Stack& stack) { 10 | if (stack.empty()) { 11 | throw std::underflow_error( 12 | "Stack underflow: expecting a string on the stack."); 13 | } 14 | } 15 | 16 | std::shared_ptr Context::PopExpression() { 17 | ensure_stack_notempty(stack_); 18 | auto top = stack_.at(stack_.size() - 1); 19 | stack_.pop_back(); 20 | return top; 21 | } 22 | 23 | const std::shared_ptr& Context::TopOfStack() { 24 | ensure_stack_notempty(stack_); 25 | return stack_.at(stack_.size() - 1); 26 | } 27 | 28 | static void ensure(bool b, const std::string& msg) { 29 | if (!b) { 30 | throw std::runtime_error(msg); 31 | } 32 | } 33 | 34 | util::StrRef Context::PopString() { 35 | ensure_stack_notempty(stack_); 36 | auto maybe_str = PopExpression(); 37 | ensure(expression::IsLiteral(*maybe_str), 38 | "Wrong type. Expecting a literal string."); 39 | return std::static_pointer_cast(maybe_str)->AsString(); 40 | } 41 | 42 | void Context::PushToList(std::shared_ptr expression) { 43 | ensure_stack_notempty(stack_); 44 | auto top = TopOfStack().get(); 45 | ensure(expression::IsList(*top), "Wrong type. Expecting a list."); 46 | auto list = static_cast(top); 47 | list->Add(expression); 48 | } 49 | 50 | size_t Context::StackSize() const noexcept { return stack_.size(); } 51 | 52 | std::ostream& Context::Dump(std::ostream& os) const { 53 | os << "Context: {" 54 | << "\n"; 55 | bool first = true; 56 | for (auto& elt : stack_) { 57 | if (!first) { 58 | os << ",\n"; 59 | } else { 60 | first = false; 61 | } 62 | os << *elt; 63 | } 64 | os << "}\n"; 65 | return os; 66 | } 67 | 68 | void Context::Push(const std::shared_ptr& expression) { 69 | stack_.push_back(expression); 70 | } 71 | 72 | std::ostream& operator<<(std::ostream& os, const Context& context) { 73 | return context.Dump(os); 74 | } 75 | } // namespace interpreter 76 | } // namespace atlas 77 | -------------------------------------------------------------------------------- /3rd-party/benchmark/src/complexity.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Ismael Jimenez Martinez. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Source project : https://github.com/ismaelJimenez/cpp.leastsq 16 | // Adapted to be used with google benchmark 17 | 18 | #ifndef COMPLEXITY_H_ 19 | #define COMPLEXITY_H_ 20 | 21 | #include 22 | #include 23 | 24 | #include "benchmark/benchmark.h" 25 | 26 | namespace benchmark { 27 | 28 | // Return a vector containing the bigO and RMS information for the specified 29 | // list of reports. If 'reports.size() < 2' an empty vector is returned. 30 | std::vector ComputeBigO( 31 | const std::vector& reports); 32 | 33 | // This data structure will contain the result returned by MinimalLeastSq 34 | // - coef : Estimated coeficient for the high-order term as 35 | // interpolated from data. 36 | // - rms : Normalized Root Mean Squared Error. 37 | // - complexity : Scalability form (e.g. oN, oNLogN). In case a scalability 38 | // form has been provided to MinimalLeastSq this will return 39 | // the same value. In case BigO::oAuto has been selected, this 40 | // parameter will return the best fitting curve detected. 41 | 42 | struct LeastSq { 43 | LeastSq() : coef(0.0), rms(0.0), complexity(oNone) {} 44 | 45 | double coef; 46 | double rms; 47 | BigO complexity; 48 | }; 49 | 50 | // Function to return an string for the calculated complexity 51 | std::string GetBigOString(BigO complexity); 52 | 53 | } // end namespace benchmark 54 | 55 | #endif // COMPLEXITY_H_ 56 | -------------------------------------------------------------------------------- /3rd-party/benchmark/test/diagnostics_test.cc: -------------------------------------------------------------------------------- 1 | // Testing: 2 | // State::PauseTiming() 3 | // State::ResumeTiming() 4 | // Test that CHECK's within these function diagnose when they are called 5 | // outside of the KeepRunning() loop. 6 | // 7 | // NOTE: Users should NOT include or use src/check.h. This is only done in 8 | // order to test library internals. 9 | 10 | #include 11 | #include 12 | 13 | #include "../src/check.h" 14 | #include "benchmark/benchmark.h" 15 | 16 | #if defined(__GNUC__) && !defined(__EXCEPTIONS) 17 | #define TEST_HAS_NO_EXCEPTIONS 18 | #endif 19 | 20 | void TestHandler() { 21 | #ifndef TEST_HAS_NO_EXCEPTIONS 22 | throw std::logic_error(""); 23 | #else 24 | std::abort(); 25 | #endif 26 | } 27 | 28 | void try_invalid_pause_resume(benchmark::State& state) { 29 | #if !defined(TEST_BENCHMARK_LIBRARY_HAS_NO_ASSERTIONS) && !defined(TEST_HAS_NO_EXCEPTIONS) 30 | try { 31 | state.PauseTiming(); 32 | std::abort(); 33 | } catch (std::logic_error const&) { 34 | } 35 | try { 36 | state.ResumeTiming(); 37 | std::abort(); 38 | } catch (std::logic_error const&) { 39 | } 40 | #else 41 | (void)state; // avoid unused warning 42 | #endif 43 | } 44 | 45 | void BM_diagnostic_test(benchmark::State& state) { 46 | static bool called_once = false; 47 | 48 | if (called_once == false) try_invalid_pause_resume(state); 49 | 50 | for (auto _ : state) { 51 | benchmark::DoNotOptimize(state.iterations()); 52 | } 53 | 54 | if (called_once == false) try_invalid_pause_resume(state); 55 | 56 | called_once = true; 57 | } 58 | BENCHMARK(BM_diagnostic_test); 59 | 60 | 61 | void BM_diagnostic_test_keep_running(benchmark::State& state) { 62 | static bool called_once = false; 63 | 64 | if (called_once == false) try_invalid_pause_resume(state); 65 | 66 | while(state.KeepRunning()) { 67 | benchmark::DoNotOptimize(state.iterations()); 68 | } 69 | 70 | if (called_once == false) try_invalid_pause_resume(state); 71 | 72 | called_once = true; 73 | } 74 | BENCHMARK(BM_diagnostic_test_keep_running); 75 | 76 | int main(int argc, char* argv[]) { 77 | benchmark::internal::GetAbortHandler() = &TestHandler; 78 | benchmark::Initialize(&argc, argv); 79 | benchmark::RunSpecifiedBenchmarks(); 80 | } 81 | -------------------------------------------------------------------------------- /test/expression_test.cc: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "../interpreter/expression.h" 3 | #include "../interpreter/singleton_value_expr.h" 4 | #include "test_utils.h" 5 | 6 | using namespace atlas::interpreter; 7 | using atlas::meter::Tags; 8 | using atlas::util::intern_str; 9 | 10 | TEST(ConstantExpression, Basic) { 11 | ConstantExpression ce{5.0}; 12 | auto res = ce.Apply(TagsValuePairs{}); 13 | auto expected = TagsValuePair::of(Tags{}, 5.0); 14 | EXPECT_EQ(*expected, *res); 15 | EXPECT_EQ("ConstantExpression(5)", to_str(ce)); 16 | EXPECT_EQ(ce.GetType(), ExpressionType::ValueExpression); 17 | EXPECT_TRUE(ce.GetQuery()->IsFalse()); 18 | } 19 | 20 | TEST(SingletonValueExpr, Basic) { 21 | auto ve = std::make_shared(5.0); 22 | auto sve = SingletonValueExpr(ve); 23 | EXPECT_EQ(sve.GetType(), ExpressionType::MultipleResults); 24 | EXPECT_EQ("SingletonVE{expr=ConstantExpression(5)}", to_str(sve)); 25 | auto res = sve.Apply(TagsValuePairs{}); 26 | auto expected = TagsValuePairs{TagsValuePair::of(Tags{}, 5.0)}; 27 | EXPECT_EQ(expected, res); 28 | EXPECT_TRUE(sve.GetQuery()->IsFalse()); 29 | } 30 | 31 | TEST(List, Basic) { 32 | List list; 33 | list.Add(std::make_shared("foo")); 34 | list.Add(std::make_shared("bar")); 35 | EXPECT_TRUE(list.Contains("foo")); 36 | EXPECT_TRUE(list.Contains("bar")); 37 | EXPECT_FALSE(list.Contains("baz")); 38 | auto refs = list.ToStrings(); 39 | EXPECT_EQ(refs->size(), 2); 40 | EXPECT_EQ(refs->front(), intern_str("foo")); 41 | EXPECT_EQ(refs->back(), intern_str("bar")); 42 | EXPECT_EQ(list.Size(), 2); 43 | EXPECT_EQ(list.GetType(), ExpressionType::List); 44 | EXPECT_EQ(to_str(list), "List(Literal(foo),Literal(bar))"); 45 | } 46 | 47 | TEST(Literal, Word) { 48 | Literal word(":foo"); 49 | Literal not_word("b"); 50 | EXPECT_TRUE(word.IsWord()); 51 | EXPECT_EQ(word.GetWord(), "foo"); 52 | EXPECT_FALSE(not_word.IsWord()); 53 | EXPECT_EQ(not_word.GetWord(), "b"); 54 | } 55 | 56 | TEST(Literal, Basic) { 57 | Literal literal("name"); 58 | EXPECT_EQ(strcmp(literal.AsString().get(), "name"), 0); 59 | EXPECT_TRUE(literal.Is("name")); 60 | 61 | EXPECT_EQ(to_str(literal), "Literal(name)"); 62 | EXPECT_EQ(literal.GetType(), ExpressionType::Literal); 63 | } -------------------------------------------------------------------------------- /3rd-party/curl/mprintf.h: -------------------------------------------------------------------------------- 1 | #ifndef __CURL_MPRINTF_H 2 | #define __CURL_MPRINTF_H 3 | /*************************************************************************** 4 | * _ _ ____ _ 5 | * Project ___| | | | _ \| | 6 | * / __| | | | |_) | | 7 | * | (__| |_| | _ <| |___ 8 | * \___|\___/|_| \_\_____| 9 | * 10 | * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. 11 | * 12 | * This software is licensed as described in the file COPYING, which 13 | * you should have received as part of this distribution. The terms 14 | * are also available at https://curl.haxx.se/docs/copyright.html. 15 | * 16 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 | * copies of the Software, and permit persons to whom the Software is 18 | * furnished to do so, under the terms of the COPYING file. 19 | * 20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 | * KIND, either express or implied. 22 | * 23 | ***************************************************************************/ 24 | 25 | #include 26 | #include /* needed for FILE */ 27 | #include "curl.h" /* for CURL_EXTERN */ 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | CURL_EXTERN int curl_mprintf(const char *format, ...); 34 | CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); 35 | CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); 36 | CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, 37 | const char *format, ...); 38 | CURL_EXTERN int curl_mvprintf(const char *format, va_list args); 39 | CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); 40 | CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); 41 | CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, 42 | const char *format, va_list args); 43 | CURL_EXTERN char *curl_maprintf(const char *format, ...); 44 | CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif /* __CURL_MPRINTF_H */ 51 | -------------------------------------------------------------------------------- /3rd-party/gtest/internal/custom/gtest-printers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // This file provides an injection point for custom printers in a local 31 | // installation of gTest. 32 | // It will be included from gtest-printers.h and the overrides in this file 33 | // will be visible to everyone. 34 | // See documentation at gtest/gtest-printers.h for details on how to define a 35 | // custom printer. 36 | // 37 | // ** Custom implementation starts here ** 38 | 39 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 40 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 41 | 42 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 43 | -------------------------------------------------------------------------------- /meter/default_counter.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "counter.h" 4 | #include "stepnumber.h" 5 | #include "statistic.h" 6 | 7 | #pragma once 8 | 9 | namespace atlas { 10 | namespace meter { 11 | 12 | template 13 | class DefaultCounterNumber : public Meter, public CounterNumber { 14 | template 15 | struct type {}; 16 | 17 | public: 18 | DefaultCounterNumber(IdPtr id, const Clock& clock, int64_t freq_millis) 19 | : Meter(WithDefaultTagForId(id, statistic::count), clock), 20 | step_number_(0, freq_millis, &clock), 21 | value_(0) { 22 | Updated(); 23 | } 24 | 25 | std::ostream& Dump(std::ostream& os) const override { 26 | os << "DefaultCounter(id=" << *id_ << ",c=" << step_number_.Current() 27 | << ")"; 28 | return os; 29 | } 30 | 31 | Measurements Measure() const override { 32 | auto stepMillis = step_number_.StepMillis(); 33 | auto poller_freq_secs = stepMillis / 1000.0; 34 | auto rate = step_number_.Poll() / poller_freq_secs; 35 | auto now = clock_.WallTime(); 36 | auto offset = now % stepMillis; 37 | auto start_step = now - offset; 38 | return Measurements{Measurement{id_, start_step, rate}}; 39 | } 40 | 41 | void Increment() noexcept override { Add(1); } 42 | 43 | void Add(T amount) noexcept override { 44 | step_number_.Add(amount); 45 | Add(amount, type()); 46 | Updated(); 47 | } 48 | 49 | T Count() const noexcept override { 50 | return value_.load(std::memory_order_relaxed); 51 | } 52 | 53 | const char* GetClass() const noexcept override { return "DefaultCounter"; } 54 | 55 | private: 56 | mutable StepNumber step_number_; 57 | std::atomic value_; // to keep the total count 58 | 59 | template 60 | void Add(T amount, type) noexcept { 61 | value_ += amount; 62 | } 63 | 64 | void Add(double amount, type) noexcept { 65 | T current; 66 | do { 67 | current = value_.load(std::memory_order_relaxed); 68 | } while (!value_.compare_exchange_weak(current, current + amount)); 69 | } 70 | }; 71 | 72 | using DefaultCounter = DefaultCounterNumber; 73 | using DefaultDoubleCounter = DefaultCounterNumber; 74 | } // namespace meter 75 | } // namespace atlas 76 | -------------------------------------------------------------------------------- /3rd-party/fmt/container.h: -------------------------------------------------------------------------------- 1 | /* 2 | Formatting library for C++ - standard container utilities 3 | 4 | Copyright (c) 2012 - 2016, Victor Zverovich 5 | All rights reserved. 6 | 7 | For the license information refer to format.h. 8 | */ 9 | 10 | #ifndef FMT_CONTAINER_H_ 11 | #define FMT_CONTAINER_H_ 12 | 13 | #include "format.h" 14 | 15 | namespace fmt { 16 | 17 | namespace internal { 18 | 19 | /** 20 | \rst 21 | A "buffer" that appends data to a standard container (e.g. typically a 22 | ``std::vector`` or ``std::basic_string``). 23 | \endrst 24 | */ 25 | template 26 | class ContainerBuffer : public Buffer { 27 | private: 28 | Container& container_; 29 | 30 | protected: 31 | virtual void grow(std::size_t size) FMT_OVERRIDE { 32 | container_.resize(size); 33 | this->ptr_ = &container_[0]; 34 | this->capacity_ = size; 35 | } 36 | 37 | public: 38 | explicit ContainerBuffer(Container& container) : container_(container) { 39 | this->size_ = container_.size(); 40 | if (this->size_ > 0) { 41 | this->ptr_ = &container_[0]; 42 | this->capacity_ = this->size_; 43 | } 44 | } 45 | }; 46 | } // namespace internal 47 | 48 | /** 49 | \rst 50 | This class template provides operations for formatting and appending data 51 | to a standard *container* like ``std::vector`` or ``std::basic_string``. 52 | 53 | **Example**:: 54 | 55 | void vecformat(std::vector& dest, fmt::BasicCStringRef format, 56 | fmt::ArgList args) { 57 | fmt::BasicContainerWriter > appender(dest); 58 | appender.write(format, args); 59 | } 60 | FMT_VARIADIC(void, vecformat, std::vector&, 61 | fmt::BasicCStringRef); 62 | \endrst 63 | */ 64 | template 65 | class BasicContainerWriter 66 | : public BasicWriter { 67 | private: 68 | internal::ContainerBuffer buffer_; 69 | 70 | public: 71 | /** 72 | \rst 73 | Constructs a :class:`fmt::BasicContainerWriter` object. 74 | \endrst 75 | */ 76 | explicit BasicContainerWriter(Container& dest) 77 | : BasicWriter(buffer_), buffer_(dest) {} 78 | }; 79 | 80 | } // namespace fmt 81 | 82 | #endif // FMT_CONTAINER_H_ 83 | -------------------------------------------------------------------------------- /3rd-party/src/gtest/gtest-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // Google C++ Testing Framework (Google Test) 33 | // 34 | // Sometimes it's desirable to build Google Test by compiling a single file. 35 | // This file serves this purpose. 36 | 37 | // This line ensures that gtest.h can be compiled on its own, even 38 | // when it's fused. 39 | #include "gtest/gtest.h" 40 | 41 | // The following lines pull in the real gtest *.cc files. 42 | #include "./gtest-death-test.cc" 43 | #include "./gtest-filepath.cc" 44 | #include "./gtest-port.cc" 45 | #include "./gtest-printers.cc" 46 | #include "./gtest-test-part.cc" 47 | #include "./gtest-typed-test.cc" 48 | #include "./gtest.cc" 49 | -------------------------------------------------------------------------------- /test/query_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "../interpreter/query.h" 7 | 8 | using atlas::interpreter::Query; 9 | using atlas::interpreter::QueryType; 10 | using QueryPtr = std::shared_ptr; 11 | using Queries = std::vector; 12 | 13 | template 14 | inline std::string queries_to_str(const T& qs) { 15 | std::ostringstream os; 16 | os << '['; 17 | auto first = true; 18 | for (const auto& q : qs) { 19 | if (first) { 20 | first = false; 21 | } else { 22 | os << ','; 23 | } 24 | q->Dump(os); 25 | } 26 | os << ']'; 27 | return os.str(); 28 | } 29 | 30 | inline std::string query_to_str(const Query& q) { 31 | std::ostringstream os; 32 | q.Dump(os); 33 | return os.str(); 34 | } 35 | 36 | inline void expect_eq_queries(const char* file, int line, const Queries& lhs, 37 | const Queries& rhs) { 38 | if (lhs.size() != rhs.size()) { 39 | FAIL() << file << ":" << line << ": lhs.size()=" << lhs.size() 40 | << " != rhs.size()=" << rhs.size() << "\n" 41 | << queries_to_str(lhs) << " != " << queries_to_str(rhs); 42 | } 43 | 44 | auto i = 0u; 45 | for (const auto& q1 : lhs) { 46 | auto& q2 = rhs[i++]; 47 | if (!q1->Equals(*q2)) { 48 | FAIL() << query_to_str(*q1) << " != " << query_to_str(*q2) << "\n" 49 | << queries_to_str(lhs) << " !=\n" 50 | << queries_to_str(rhs); 51 | } 52 | } 53 | } 54 | 55 | inline void expect_eq_queries(const char* file, int line, 56 | const std::unordered_set& lhs, 57 | const std::unordered_set& rhs) { 58 | if (lhs.size() != rhs.size()) { 59 | std::cerr << fmt::format("{}:{} lhs.size()={} != rhs.size()={}\n", file, 60 | line, lhs.size(), rhs.size()); 61 | GTEST_FAIL(); 62 | } 63 | 64 | for (const auto& q1 : lhs) { 65 | auto found = rhs.find(q1) != rhs.end(); 66 | if (!found) { 67 | std::cerr << fmt::format("{}:{} {} not found in {}\n", file, line, 68 | query_to_str(*q1), queries_to_str(rhs)); 69 | GTEST_FAIL(); 70 | } 71 | } 72 | } 73 | 74 | #define EXPECT_EQ_QUERIES(a, b) expect_eq_queries(__FILE__, __LINE__, a, b) 75 | --------------------------------------------------------------------------------