From 370a25ea0176183eb49731d9af7bd84f512bf600 Mon Sep 17 00:00:00 2001 From: "Filipe Oliveira (Personal)" Date: Sun, 12 Jan 2025 15:01:01 +0000 Subject: [PATCH 1/9] Bump version to 2.1.3 (#291) --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 15f3d9a..eb0a398 100755 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ dnl You should have received a copy of the GNU General Public License dnl along with this program. If not, see . AC_PREREQ(2.59) -AC_INIT(memtier_benchmark,2.1.2,oss@redis.com) +AC_INIT(memtier_benchmark,2.1.3,oss@redis.com) AC_CONFIG_SRCDIR([memtier_benchmark.cpp]) AC_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE From ae4c12b21e0363b7affffa06c506d6f0c26125ba Mon Sep 17 00:00:00 2001 From: "Filipe Oliveira (Personal)" Date: Mon, 13 Jan 2025 07:56:47 +0000 Subject: [PATCH 2/9] Doing coverage checks on Ubuntu 22.04 instead of latest due to autoconf lcov >= 2.0 issue (#293) --- .github/workflows/ci.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index daf3296..1c4daa4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,10 +48,22 @@ jobs: - name: Build run: autoreconf -ivf && ./configure --disable-tls && make -j + build-ubuntu-latest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo apt-get -qq update + sudo apt-get install lcov autoconf automake pkg-config libevent-dev libpcre3-dev + + - name: Build + run: autoreconf -ivf && ./configure --disable-tls && make -j + build-ubuntu: strategy: matrix: - platform: [ubuntu-latest, ubuntu-20.04] + platform: [ubuntu-22.04, ubuntu-20.04] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 @@ -61,6 +73,8 @@ jobs: sudo apt-get install lcov autoconf automake pkg-config libevent-dev libpcre3-dev libssl-dev - name: Build + # for coverage reports we need to use Ubuntu 22.04 or lower + # (given Ubuntu 24.04 uses lcov >= 2.0 which is not support on autoconf still) run: autoreconf -ivf && ./configure --enable-code-coverage && make -j - name: Setup Python uses: actions/setup-python@v2 From 9095d9831ec8fb09f866216fb91cf95f586c1b98 Mon Sep 17 00:00:00 2001 From: "Filipe Oliveira (Personal)" Date: Wed, 29 Jan 2025 19:42:50 +0000 Subject: [PATCH 3/9] Revert LATENCY_HDR_SEC_SIGDIGTS to 2. Optimize summarize_current_second by using hdr_value_at_percentiles() instead of N x hdr_value_at_percentile(). (#295) --- deps/hdr_histogram/.dirstamp | 0 deps/hdr_histogram/hdr_histogram.c | 59 +++++++++++++++++++++++++----- deps/hdr_histogram/hdr_histogram.h | 12 ++++++ run_stats.cpp | 7 ++-- run_stats.h | 2 +- run_stats_types.cpp | 13 ++++--- run_stats_types.h | 11 +++++- 7 files changed, 83 insertions(+), 21 deletions(-) create mode 100644 deps/hdr_histogram/.dirstamp diff --git a/deps/hdr_histogram/.dirstamp b/deps/hdr_histogram/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/deps/hdr_histogram/hdr_histogram.c b/deps/hdr_histogram/hdr_histogram.c index 7bb6422..b3b48e0 100644 --- a/deps/hdr_histogram/hdr_histogram.c +++ b/deps/hdr_histogram/hdr_histogram.c @@ -643,28 +643,67 @@ int64_t hdr_min(const struct hdr_histogram* h) return non_zero_min(h); } +static int64_t get_value_from_idx_up_to_count(const struct hdr_histogram* h, int64_t count_at_percentile) +{ + int64_t count_to_idx = 0; + + count_at_percentile = 0 < count_at_percentile ? count_at_percentile : 1; + for (int32_t idx = 0; idx < h->counts_len; idx++) + { + count_to_idx += h->counts[idx]; + if (count_to_idx >= count_at_percentile) + { + return hdr_value_at_index(h, idx); + } + } + + return 0; +} + int64_t hdr_value_at_percentile(const struct hdr_histogram* h, double percentile) { - struct hdr_iter iter; - int64_t total = 0; double requested_percentile = percentile < 100.0 ? percentile : 100.0; int64_t count_at_percentile = (int64_t) (((requested_percentile / 100) * h->total_count) + 0.5); - count_at_percentile = count_at_percentile > 1 ? count_at_percentile : 1; + int64_t value_from_idx = get_value_from_idx_up_to_count(h, count_at_percentile); + if (percentile == 0.0) + { + return lowest_equivalent_value(h, value_from_idx); + } + return highest_equivalent_value(h, value_from_idx); +} - hdr_iter_init(&iter, h); +int hdr_value_at_percentiles(const struct hdr_histogram *h, const double *percentiles, int64_t *values, size_t length) +{ + if (NULL == percentiles || NULL == values) + { + return EINVAL; + } - while (hdr_iter_next(&iter)) + struct hdr_iter iter; + const int64_t total_count = h->total_count; + // to avoid allocations we use the values array for intermediate computation + // i.e. to store the expected cumulative count at each percentile + for (size_t i = 0; i < length; i++) { - total += iter.count; + const double requested_percentile = percentiles[i] < 100.0 ? percentiles[i] : 100.0; + const int64_t count_at_percentile = + (int64_t) (((requested_percentile / 100) * total_count) + 0.5); + values[i] = count_at_percentile > 1 ? count_at_percentile : 1; + } - if (total >= count_at_percentile) + hdr_iter_init(&iter, h); + int64_t total = 0; + size_t at_pos = 0; + while (hdr_iter_next(&iter) && at_pos < length) + { + total += iter.count; + while (at_pos < length && total >= values[at_pos]) { - int64_t value_from_index = iter.value; - return highest_equivalent_value(h, value_from_index); + values[at_pos] = highest_equivalent_value(h, iter.value); + at_pos++; } } - return 0; } diff --git a/deps/hdr_histogram/hdr_histogram.h b/deps/hdr_histogram/hdr_histogram.h index dc35416..ad1e3a3 100644 --- a/deps/hdr_histogram/hdr_histogram.h +++ b/deps/hdr_histogram/hdr_histogram.h @@ -284,6 +284,18 @@ int64_t hdr_max(const struct hdr_histogram* h); */ int64_t hdr_value_at_percentile(const struct hdr_histogram* h, double percentile); +/** + * Get the values at the given percentiles. + * + * @param h "This" pointer. + * @param percentiles The ordered percentiles array to get the values for. + * @param length Number of elements in the arrays. + * @param values Destination array containing the values at the given percentiles. + * The values array should be allocated by the caller. + * @return 0 on success, ENOMEM if the provided destination array is null. + */ +int hdr_value_at_percentiles(const struct hdr_histogram *h, const double *percentiles, int64_t *values, size_t length); + /** * Gets the standard deviation for the values in the histogram. * diff --git a/run_stats.cpp b/run_stats.cpp index f945377..a5e38a0 100644 --- a/run_stats.cpp +++ b/run_stats.cpp @@ -117,8 +117,9 @@ run_stats::run_stats(benchmark_config *config) : { memset(&m_start_time, 0, sizeof(m_start_time)); memset(&m_end_time, 0, sizeof(m_end_time)); - quantiles_list = config->print_percentiles.quantile_list; - + std::vector quantiles_list_float = config->print_percentiles.quantile_list; + std::sort(quantiles_list_float.begin(), quantiles_list_float.end()); + quantiles_list = std::vector(quantiles_list_float.begin(), quantiles_list_float.end()); if (config->arbitrary_commands->is_defined()) { setup_arbitrary_commands(config->arbitrary_commands->size()); } @@ -882,7 +883,7 @@ void run_stats::summarize(totals& result) const void result_print_to_json(json_handler * jsonhandler, const char * type, double ops_sec, double hits, double miss, double moved, double ask, double kbs, double kbs_rx, double kbs_tx, double latency, long m_total_latency, long ops, - std::vector quantile_list, struct hdr_histogram* latency_histogram, + std::vector quantile_list, struct hdr_histogram* latency_histogram, std::vector timestamps, std::vector timeserie_stats ) { diff --git a/run_stats.h b/run_stats.h index 580ef1f..14796ea 100644 --- a/run_stats.h +++ b/run_stats.h @@ -97,7 +97,7 @@ class run_stats { totals m_totals; std::list m_stats; - std::vector quantiles_list; + std::vector quantiles_list; // current second stats ( appended to m_stats and reset every second ) one_second_stats m_cur_stats; diff --git a/run_stats_types.cpp b/run_stats_types.cpp index 77068dd..7ae7b0e 100644 --- a/run_stats_types.cpp +++ b/run_stats_types.cpp @@ -72,11 +72,14 @@ void one_sec_cmd_stats::merge(const one_sec_cmd_stats& other) { m_min_latency = other.m_min_latency < m_min_latency ? other.m_min_latency : m_min_latency; } -void one_sec_cmd_stats::summarize_quantiles(safe_hdr_histogram histogram, std::vector quantiles) { - for (std::size_t i = 0; i < quantiles.size(); i++){ - const float quantile = quantiles[i]; - const double value = hdr_value_at_percentile(histogram, quantile)/ (double) LATENCY_HDR_RESULTS_MULTIPLIER; - summarized_quantile_values.push_back(value); +void one_sec_cmd_stats::summarize_quantiles(safe_hdr_histogram histogram, std::vector sorted_quantiles) { + std::vector values(sorted_quantiles.size()); + int result = hdr_value_at_percentiles(histogram, sorted_quantiles.data(), values.data(), sorted_quantiles.size()); + if (result != 0) { + return; + } + for (std::size_t i = 0; i < sorted_quantiles.size(); i++) { + summarized_quantile_values.push_back(values[i] / static_cast(LATENCY_HDR_RESULTS_MULTIPLIER)); } } diff --git a/run_stats_types.h b/run_stats_types.h index 827c86d..2b6e982 100644 --- a/run_stats_types.h +++ b/run_stats_types.h @@ -24,7 +24,7 @@ #define LATENCY_HDR_SIGDIGTS 3 #define LATENCY_HDR_SEC_MIN_VALUE 10 #define LATENCY_HDR_SEC_MAX_VALUE 600000000 ## LL -#define LATENCY_HDR_SEC_SIGDIGTS 3 +#define LATENCY_HDR_SEC_SIGDIGTS 2 #define LATENCY_HDR_RESULTS_MULTIPLIER 1000 #define LATENCY_HDR_GRANULARITY 10 @@ -90,7 +90,14 @@ class one_sec_cmd_stats { one_sec_cmd_stats(); void reset(); void merge(const one_sec_cmd_stats& other); - void summarize_quantiles(safe_hdr_histogram histogram, std::vector quantiles); + /** + * Summarizes quantiles from the given histogram. + * + * @param histogram The histogram from which quantile values are extracted. + * @param sorted_quantiles A sorted (ascending order) vector of quantiles for which values will be computed. + * The caller must ensure the vector is sorted from smallest to largest. + */ + void summarize_quantiles(safe_hdr_histogram histogram, std::vector sorted_quantiles); void update_op(unsigned int bytes_rx, unsigned int bytes_tx, unsigned int latency); void update_op(unsigned int bytes_rx, unsigned int bytes_tx, unsigned int latency, unsigned int hits, unsigned int misses); void update_moved_op(unsigned int bytes_rx, unsigned int bytes_tx, unsigned int latency); From 4b0f5ee8b88498d6cc17fbccff9590f78e047186 Mon Sep 17 00:00:00 2001 From: "Filipe Oliveira (Personal)" Date: Wed, 29 Jan 2025 19:46:05 +0000 Subject: [PATCH 4/9] Bump version to next patch 2.1.4 (#289) --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index eb0a398..185e865 100755 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ dnl You should have received a copy of the GNU General Public License dnl along with this program. If not, see . AC_PREREQ(2.59) -AC_INIT(memtier_benchmark,2.1.3,oss@redis.com) +AC_INIT(memtier_benchmark,2.1.4,oss@redis.com) AC_CONFIG_SRCDIR([memtier_benchmark.cpp]) AC_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE From 2e36027a7b33c84d1686a040fd9979a52442ec57 Mon Sep 17 00:00:00 2001 From: "Filipe Oliveira (Personal)" Date: Thu, 30 Jan 2025 13:36:30 +0000 Subject: [PATCH 5/9] Use libpcre3-dev on apt release flow (#296) --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b30dc80..651ae17 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: run: | sudo apt-get update && \ sudo apt-get install \ - debhelper dput libevent-dev libpcre2-dev libssl-dev pkg-config + debhelper dput libevent-dev libpcre3-dev libssl-dev pkg-config - name: Create changelog env: VERSION: ${{ github.event.inputs.tag_name || github.event.release.tag_name }} From ed30f3ce1da08628957692e2accd71bf7926210c Mon Sep 17 00:00:00 2001 From: "Filipe Oliveira (Personal)" Date: Thu, 30 Jan 2025 13:58:24 +0000 Subject: [PATCH 6/9] Matching CI deps on Release github flow (#297) --- .github/workflows/release.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 651ae17..fcea488 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,9 @@ jobs: run: | sudo apt-get update && \ sudo apt-get install \ - debhelper dput libevent-dev libpcre3-dev libssl-dev pkg-config + build-essential autoconf automake libpcre3-dev libevent-dev \ + pkg-config zlib1g-dev libssl-dev libboost-all-dev cmake flex \ + debhelper dput - name: Create changelog env: VERSION: ${{ github.event.inputs.tag_name || github.event.release.tag_name }} From 80fa7c7c69b395c81385dd56fd2408c0f2564c68 Mon Sep 17 00:00:00 2001 From: "Filipe Oliveira (Personal)" Date: Tue, 11 Feb 2025 14:22:38 +0000 Subject: [PATCH 7/9] Fixed release action steps with minimal changes (#299) --- .github/workflows/release.yml | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fcea488..dcd9e23 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,9 +17,15 @@ on: description: "Docker images for smoke testing (comma-separated, e.g., ubuntu:20.04,ubuntu:22.04,ubuntu:24.04)" required: false default: "ubuntu:20.04,ubuntu:22.04,ubuntu:24.04" + build_runner: + description: "os in which build steps run on" + required: false + default: "ubuntu-22.04" + type: string jobs: build-source-package: - runs-on: ubuntu-latest + runs-on: ${{ inputs.build_runner }} + continue-on-error: true strategy: matrix: dist: ${{ fromJSON(vars.BUILD_DISTS) }} @@ -27,6 +33,24 @@ jobs: - uses: actions/checkout@v4 with: path: sources + - name: Validate configure.ac version matches GitHub Release (only on release) + if: github.event.release.tag_name != '' + env: + VERSION: ${{ github.event.release.tag_name }} + run: | + # Extract the current version from configure.ac + CURRENT_VERSION=$(awk -F'[(),]' '/AC_INIT/ {print $3}' sources/configure.ac | tr -d ' ') + + echo "Current configure.ac version: $CURRENT_VERSION" + echo "GitHub Release version: $VERSION" + + # Check if versions match + if [ "$CURRENT_VERSION" != "$VERSION" ]; then + echo "❌ Version mismatch! configure.ac: $CURRENT_VERSION, GitHub Release: $VERSION" + exit 1 # Fail the build + else + echo "Version match. Proceeding with the build." + fi - name: Install dependencies run: | sudo apt-get update && \ @@ -63,7 +87,8 @@ jobs: memtier-benchmark_*.tar.* build-binary-package: - runs-on: ubuntu-latest + runs-on: ${{ inputs.build_runner }} + continue-on-error: true environment: build strategy: matrix: @@ -121,7 +146,7 @@ jobs: *.deb smoke-test-packages: - runs-on: ubuntu-latest + runs-on: ${{ inputs.build_runner }} needs: build-binary-package env: ARCH: amd64 From cc6cbb7e23115b4b90db472446cbdfcef2d9ba9c Mon Sep 17 00:00:00 2001 From: "Filipe Oliveira (Personal)" Date: Tue, 11 Feb 2025 14:47:03 +0000 Subject: [PATCH 8/9] using ubuntu-22.04 on runner of release (#300) --- .github/workflows/release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dcd9e23..840e1af 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ on: type: string jobs: build-source-package: - runs-on: ${{ inputs.build_runner }} + runs-on: ubuntu-22.04 continue-on-error: true strategy: matrix: @@ -87,7 +87,7 @@ jobs: memtier-benchmark_*.tar.* build-binary-package: - runs-on: ${{ inputs.build_runner }} + runs-on: ubuntu-22.04 continue-on-error: true environment: build strategy: @@ -146,7 +146,7 @@ jobs: *.deb smoke-test-packages: - runs-on: ${{ inputs.build_runner }} + runs-on: ubuntu-22.04 needs: build-binary-package env: ARCH: amd64 @@ -187,7 +187,7 @@ jobs: publish-to-apt: env: DEB_S3_VERSION: "0.11.3" - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 environment: build needs: smoke-test-packages steps: From 5bc091493a824c4a119ab51944bdef6842a78a81 Mon Sep 17 00:00:00 2001 From: "Filipe Oliveira (Personal)" Date: Tue, 11 Feb 2025 16:07:08 +0000 Subject: [PATCH 9/9] Remove ubuntu:bionic logic from smoke-test-packages and removed usage of actions/download-artifact@v3. (#301) --- .github/workflows/release.yml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 840e1af..5a575f7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -150,9 +150,6 @@ jobs: needs: build-binary-package env: ARCH: amd64 - # required by ubuntu:bionic - # https://github.blog/changelog/2024-03-07-github-actions-all-actions-will-run-on-node20-instead-of-node16-by-default/ - ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true strategy: matrix: image: ${{ fromJSON(vars.SMOKE_TEST_IMAGES) }} @@ -166,15 +163,7 @@ jobs: exit 1 fi echo "BUILD_ARCH=$BUILD_ARCH" >> $GITHUB_ENV - - name: Get binary packages for ubuntu:bionic - if: matrix.image == 'ubuntu:bionic' - uses: actions/download-artifact@v3 - with: - name: binary-${{ env.BUILD_ARCH }}-${{ env.ARCH }} - path: binary-${{ env.BUILD_ARCH }}-${{ env.ARCH }} - - - name: Get binary packages for other versions - if: matrix.image != 'ubuntu:bionic' + - name: Get binary packages uses: actions/download-artifact@v4 with: name: binary-${{ env.BUILD_ARCH }}-${{ env.ARCH }}