redis-benchmarks-specification 0.1.291__py3-none-any.whl → 0.1.293__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of redis-benchmarks-specification might be problematic. Click here for more details.
- redis_benchmarks_specification/__runner__/args.py +6 -0
- redis_benchmarks_specification/__runner__/remote_profiling.py +17 -2
- redis_benchmarks_specification/__runner__/runner.py +622 -57
- redis_benchmarks_specification/test-suites/memtier_benchmark-100Kkeys-hash-hgetall-50-fields-100B-values.yml +21 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-100Kkeys-load-hash-20-fields-with-1B-values-pipeline-30.yml +15 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-100Kkeys-load-hash-50-fields-with-1000B-values.yml +16 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-100Kkeys-load-hash-50-fields-with-100B-values.yml +16 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-100Kkeys-load-hash-50-fields-with-10B-values.yml +15 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-10Kkeys-load-hash-50-fields-with-10000B-values.yml +16 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-10Kkeys-load-list-with-10B-values-pipeline-50.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-10Mkeys-load-hash-5-fields-with-100B-values-pipeline-10.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-10Mkeys-load-hash-5-fields-with-100B-values.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-10Mkeys-load-hash-5-fields-with-10B-values-pipeline-10.yml +6 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-10Mkeys-load-hash-5-fields-with-10B-values.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-10Mkeys-string-get-10B-pipeline-100-nokeyprefix.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-100B-expire-use-case.yml +14 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-10B-expire-use-case.yml +14 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-10B-psetex-expire-use-case.yml +12 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-10B-setex-expire-use-case.yml +12 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-1KiB-expire-use-case.yml +13 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-4KiB-expire-use-case.yml +14 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-bitmap-getbit-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-generic-exists-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-generic-expire-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-generic-expireat-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-generic-pexpire-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-generic-scan-count-500-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-generic-scan-cursor-count-500-pipeline-10.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-generic-scan-cursor-count-5000-pipeline-10.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-generic-scan-cursor-pipeline-10.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-generic-scan-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-generic-scan-type-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-generic-touch-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-generic-ttl-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-hash-hexists.yml +15 -5
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-hash-hget-hgetall-hkeys-hvals-with-100B-values.yml +14 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-hash-hgetall-50-fields-10B-values.yml +22 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-hash-hincrby.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-hash-hincrbyfloat.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-hash-hmget-5-fields-with-100B-values-pipeline-10.yml +13 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-hash-transactions-multi-exec-pipeline-20.yml +9 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-list-lpop-rpop-with-100B-values.yml +12 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-list-lpop-rpop-with-10B-values.yml +12 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-list-lpop-rpop-with-1KiB-values.yml +12 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-list-rpoplpush-with-10B-values.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-hash-5-fields-with-1000B-values-pipeline-10.yml +6 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-hash-5-fields-with-1000B-values.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-hash-hmset-5-fields-with-1000B-values.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-list-rpush-with-10B-values.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-list-with-100B-values.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-list-with-10B-values-pipeline-10.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-list-with-10B-values.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-list-with-1KiB-values.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-set-intset-with-100-elements-19-digits-pipeline-10.yml +30 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-set-intset-with-100-elements-19-digits.yml +30 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-set-intset-with-100-elements-pipeline-10.yml +13 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-set-intset-with-100-elements.yml +12 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-stream-1-fields-with-100B-values-pipeline-10.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-stream-1-fields-with-100B-values.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-stream-5-fields-with-100B-values-pipeline-10.yml +6 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-stream-5-fields-with-100B-values.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-string-with-100B-values-pipeline-10.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-string-with-100B-values.yml +4 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-string-with-10B-values-pipeline-10.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-string-with-10B-values-pipeline-100-nokeyprefix.yml +5 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-string-with-10B-values-pipeline-100.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-string-with-10B-values-pipeline-50.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-string-with-10B-values-pipeline-500.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-string-with-10B-values.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-string-with-1KiB-values.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-string-with-20KiB-values.yml +4 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-zset-listpack-with-100-elements-double-score.yml +63 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-zset-with-10-elements-double-score.yml +7 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-load-zset-with-10-elements-int-score.yml +6 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-append-1-100B-pipeline-10.yml +12 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-append-1-100B.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-decr.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-get-100B-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-get-100B.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-get-10B-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-get-10B-pipeline-100-nokeyprefix.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-get-10B-pipeline-100.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-get-10B-pipeline-50.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-get-10B-pipeline-500.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-get-10B.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-get-1KiB-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-get-1KiB.yml +11 -5
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-get-32B-pipeline-10.yml +9 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-get-32B.yml +9 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-incr-pipeline-10.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-incrby-pipeline-10.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-incrby.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-incrbyfloat-pipeline-10.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-incrbyfloat.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-int-encoding-strlen-pipeline-10.yml +9 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-mget-1KiB.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-mixed-50-50-set-get-100B-expire-pipeline-10.yml +12 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-mixed-50-50-set-get-100B-expire.yml +12 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-mixed-50-50-set-get-100B-pipeline-10.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-mixed-50-50-set-get-100B.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-mixed-50-50-set-get-1KB-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-mixed-50-50-set-get-1KB.yml +9 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-mixed-50-50-set-get-32B-pipeline-10.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-mixed-50-50-set-get-32B.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-mixed-50-50-set-get-512B-pipeline-10.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-mixed-50-50-set-get-512B.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-mixed-50-50-set-get-with-expiration-240B-400_conns.yml +12 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-set-with-ex-100B-pipeline-10.yml +10 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-setex-100B-pipeline-10.yml +10 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-setrange-100B-pipeline-10.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1Mkeys-string-setrange-100B.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-100M-bits-bitmap-bitcount.yml +12 -5
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-1Billion-bits-bitmap-bitcount.yml +12 -5
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-geo-2-elements-geopos.yml +9 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-geo-2-elements-geosearch-fromlonlat-withcoord.yml +10 -5
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-geo-60M-elements-geodist-pipeline-10.yml +7 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-geo-60M-elements-geodist.yml +7 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-geo-60M-elements-geohash-pipeline-10.yml +6 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-geo-60M-elements-geohash.yml +4 -2
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-geo-60M-elements-geopos-pipeline-10.yml +6 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-geo-60M-elements-geopos.yml +4 -2
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-geo-60M-elements-geosearch-fromlonlat-bybox.yml +7 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-geo-60M-elements-geosearch-fromlonlat-pipeline-10.yml +7 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-geo-60M-elements-geosearch-fromlonlat.yml +7 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-hash-1K-fields-hgetall-pipeline-10.yml +256 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-hash-1K-fields-hgetall.yml +254 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-hash-hscan-1K-fields-100B-values-cursor-count-1000.yml +260 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-hash-hscan-1K-fields-10B-values-cursor-count-100.yml +260 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-hash-hscan-1K-fields-10B-values.yml +259 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-hash-hscan-50-fields-10B-values.yml +23 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-10-elements-lrange-all-elements-pipeline-10.yml +8 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-10-elements-lrange-all-elements.yml +6 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-100-elements-int-7bit-uint-lrange-all-elements-pipeline-10.yml +15 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-100-elements-int-lrange-all-elements-pipeline-10.yml +23 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-100-elements-llen-pipeline-10.yml +23 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-100-elements-lrange-all-elements-pipeline-10.yml +23 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-100-elements-lrange-all-elements.yml +21 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-10K-elements-lindex-integer.yml +8 -2
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-10K-elements-lindex-string-pipeline-10.yml +10 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-10K-elements-lindex-string.yml +8 -2
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-10K-elements-linsert-lrem-integer.yml +12 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-10K-elements-linsert-lrem-string.yml +12 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-10K-elements-lpos-integer.yml +8 -2
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-10K-elements-lpos-string.yml +8 -2
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-1K-elements-lrange-all-elements-pipeline-10.yml +173 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-1K-elements-lrange-all-elements.yml +171 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-list-2K-elements-quicklist-lrange-all-elements-longs.yml +228 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-load-hash-1K-fields-with-5B-values.yml +254 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-load-zset-with-5-elements-parsing-float-score.yml +8 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-load-zset-with-5-elements-parsing-hexa-score.yml +8 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-pfadd-4KB-values-pipeline-10.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-10-elements-smembers-pipeline-10.yml +8 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-10-elements-smembers.yml +6 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-10-elements-smismember.yml +9 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-100-elements-sismember-is-a-member.yml +24 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-100-elements-sismember-not-a-member.yml +24 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-100-elements-smembers.yml +21 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-100-elements-smismember.yml +24 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-100-elements-sscan.yml +21 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-10M-elements-sismember-50pct-chance.yml +9 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-10M-elements-srem-50pct-chance.yml +9 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-1K-elements-smembers.yml +171 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-1K-elements-sscan-cursor-count-100.yml +173 -5
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-1K-elements-sscan.yml +171 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-1M-elements-sismember-50pct-chance.yml +8 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-200K-elements-sadd-constant.yml +10 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-set-2M-elements-sadd-increasing.yml +4 -2
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zincrby-1M-elements-pipeline-1.yml +9 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zrank-100K-elements-pipeline-1.yml +9 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zrank-10M-elements-pipeline-1.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zrank-1M-elements-pipeline-1.yml +9 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zrem-5M-elements-pipeline-1.yml +16 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zrevrangebyscore-256K-elements-pipeline-1.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zrevrangebyscore-256K-elements-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zrevrank-1M-elements-pipeline-1.yml +9 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-10-elements-zrange-all-elements-long-scores.yml +12 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-10-elements-zrange-all-elements.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-100-elements-zrange-all-elements.yml +37 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-100-elements-zrangebyscore-all-elements-long-scores.yml +37 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-100-elements-zrangebyscore-all-elements.yml +37 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-100-elements-zscan.yml +35 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-1K-elements-zrange-all-elements.yml +293 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-1K-elements-zscan.yml +291 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-1M-elements-zcard-pipeline-10.yml +7 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-1M-elements-zremrangebyscore-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-1M-elements-zrevrange-5-elements.yml +8 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-1M-elements-zrevrange-withscores-5-elements-pipeline-10.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-1M-elements-zscore-pipeline-10.yml +9 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-600K-elements-zrangestore-1K-elements.yml +10 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-600K-elements-zrangestore-300K-elements.yml +12 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-1key-zset-listpack-zrank-100-elements-pipeline-1.yml +21 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-2keys-lua-eval-hset-expire.yml +6 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-2keys-lua-evalsha-hset-expire.yml +9 -7
- redis_benchmarks_specification/test-suites/memtier_benchmark-2keys-set-10-100-elements-sdiff.yml +26 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-2keys-set-10-100-elements-sinter.yml +26 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-2keys-set-10-100-elements-sunion.yml +26 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-2keys-stream-5-entries-xread-all-entries-pipeline-10.yml +17 -13
- redis_benchmarks_specification/test-suites/memtier_benchmark-2keys-stream-5-entries-xread-all-entries.yml +17 -13
- redis_benchmarks_specification/test-suites/memtier_benchmark-2keys-zset-300-elements-skiplist-encoded-zunion.yml +405 -5
- redis_benchmarks_specification/test-suites/memtier_benchmark-2keys-zset-300-elements-skiplist-encoded-zunionstore.yml +405 -5
- redis_benchmarks_specification/test-suites/memtier_benchmark-3Mkeys-load-string-with-512B-values-pipeline-10.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-3Mkeys-load-string-with-512B-values.yml +5 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-3Mkeys-string-get-with-1KiB-values-400_conns.yml +20 -14
- redis_benchmarks_specification/test-suites/memtier_benchmark-3Mkeys-string-get-with-1KiB-values-40_conns.yml +20 -14
- redis_benchmarks_specification/test-suites/memtier_benchmark-3Mkeys-string-get-with-1KiB-values-pipeline-10-2000_conns.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-3Mkeys-string-get-with-1KiB-values-pipeline-10-400_conns.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-3Mkeys-string-get-with-1KiB-values-pipeline-10-40_conns.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-3Mkeys-string-mixed-20-80-with-512B-values-400_conns.yml +20 -14
- redis_benchmarks_specification/test-suites/memtier_benchmark-3Mkeys-string-mixed-20-80-with-512B-values-pipeline-10-2000_conns.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-3Mkeys-string-mixed-20-80-with-512B-values-pipeline-10-400_conns.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-3Mkeys-string-mixed-20-80-with-512B-values-pipeline-10-5200_conns.yml +11 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-3Mkeys-string-mixed-50-50-with-512B-values-with-expiration-pipeline-10-400_conns.yml +9 -4
- redis_benchmarks_specification/test-suites/memtier_benchmark-connection-hello-pipeline-10.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-connection-hello.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-nokeys-connection-ping-pipeline-10.yml +2 -2
- redis_benchmarks_specification/test-suites/memtier_benchmark-nokeys-pubsub-mixed-100-channels-128B-100-publishers-100-subscribers.yml +19 -15
- redis_benchmarks_specification/test-suites/memtier_benchmark-nokeys-pubsub-mixed-100-channels-128B-100-publishers-1000-subscribers.yml +19 -15
- redis_benchmarks_specification/test-suites/memtier_benchmark-nokeys-pubsub-mixed-100-channels-128B-100-publishers-5000-subscribers.yml +19 -15
- redis_benchmarks_specification/test-suites/memtier_benchmark-nokeys-pubsub-mixed-100-channels-128B-100-publishers-50K-subscribers-5k-conns.yml +19 -15
- redis_benchmarks_specification/test-suites/memtier_benchmark-nokeys-pubsub-publish-1K-channels-10B-no-subscribers.yml +4 -3
- redis_benchmarks_specification/test-suites/memtier_benchmark-nokeys-server-time-pipeline-10.yml +2 -2
- redis_benchmarks_specification/vector-search-test-suites/vector_db_benchmark_test.yml +0 -3
- {redis_benchmarks_specification-0.1.291.dist-info → redis_benchmarks_specification-0.1.293.dist-info}/METADATA +1 -1
- {redis_benchmarks_specification-0.1.291.dist-info → redis_benchmarks_specification-0.1.293.dist-info}/RECORD +227 -227
- {redis_benchmarks_specification-0.1.291.dist-info → redis_benchmarks_specification-0.1.293.dist-info}/LICENSE +0 -0
- {redis_benchmarks_specification-0.1.291.dist-info → redis_benchmarks_specification-0.1.293.dist-info}/WHEEL +0 -0
- {redis_benchmarks_specification-0.1.291.dist-info → redis_benchmarks_specification-0.1.293.dist-info}/entry_points.txt +0 -0
|
@@ -4,6 +4,7 @@ import logging
|
|
|
4
4
|
import math
|
|
5
5
|
import os
|
|
6
6
|
import shutil
|
|
7
|
+
import signal
|
|
7
8
|
import subprocess
|
|
8
9
|
import sys
|
|
9
10
|
import tempfile
|
|
@@ -66,6 +67,23 @@ from redis_benchmarks_specification.__runner__.args import create_client_runner_
|
|
|
66
67
|
from redis_benchmarks_specification.__runner__.remote_profiling import RemoteProfiler
|
|
67
68
|
|
|
68
69
|
|
|
70
|
+
# Global flag to track if user wants to exit
|
|
71
|
+
_exit_requested = False
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def signal_handler(signum, frame):
|
|
75
|
+
"""Handle Ctrl+C signal to exit gracefully"""
|
|
76
|
+
global _exit_requested
|
|
77
|
+
if not _exit_requested:
|
|
78
|
+
_exit_requested = True
|
|
79
|
+
logging.info("Ctrl+C detected. Exiting after current test completes...")
|
|
80
|
+
print("\nCtrl+C detected. Exiting after current test completes...")
|
|
81
|
+
else:
|
|
82
|
+
logging.info("Ctrl+C detected again. Force exiting...")
|
|
83
|
+
print("\nForce exiting...")
|
|
84
|
+
sys.exit(1)
|
|
85
|
+
|
|
86
|
+
|
|
69
87
|
def run_local_command_with_timeout(command_str, timeout_seconds, description="command"):
|
|
70
88
|
"""
|
|
71
89
|
Run a local command with timeout support.
|
|
@@ -203,6 +221,176 @@ def extract_expected_benchmark_duration(
|
|
|
203
221
|
return 30
|
|
204
222
|
|
|
205
223
|
|
|
224
|
+
def detect_object_encoding(redis_conn, dbconfig):
|
|
225
|
+
"""
|
|
226
|
+
Detect object encoding by scanning 1% of the dataset.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
redis_conn: Redis connection
|
|
230
|
+
dbconfig: Database configuration containing keyspace info
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
Dict with encoding information
|
|
234
|
+
"""
|
|
235
|
+
try:
|
|
236
|
+
# Get total key count
|
|
237
|
+
total_keys = redis_conn.dbsize()
|
|
238
|
+
logging.debug(f"Object encoding detection: DBSIZE reports {total_keys} keys")
|
|
239
|
+
|
|
240
|
+
if total_keys == 0:
|
|
241
|
+
logging.warning("No keys found in database for encoding detection")
|
|
242
|
+
return {
|
|
243
|
+
"encoding": "unknown",
|
|
244
|
+
"confidence": 0.0,
|
|
245
|
+
"sample_size": 0,
|
|
246
|
+
"total_keys": 0,
|
|
247
|
+
"encoding_distribution": {}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
# Determine scanning strategy based on dataset size
|
|
251
|
+
if total_keys <= 1000:
|
|
252
|
+
# For small datasets, scan all keys for complete accuracy
|
|
253
|
+
sample_size = total_keys
|
|
254
|
+
scan_all_keys = True
|
|
255
|
+
logging.info(f"Scanning all {total_keys} keys (small dataset - complete analysis)")
|
|
256
|
+
else:
|
|
257
|
+
# For large datasets, sample 1% (minimum 10, maximum 1000)
|
|
258
|
+
sample_size = max(10, min(1000, int(total_keys * 0.01)))
|
|
259
|
+
scan_all_keys = False
|
|
260
|
+
logging.info(f"Sampling {sample_size} keys out of {total_keys} total keys ({(sample_size/total_keys)*100:.2f}%)")
|
|
261
|
+
|
|
262
|
+
# Use SCAN to get keys
|
|
263
|
+
encoding_counts = {}
|
|
264
|
+
scanned_keys = []
|
|
265
|
+
cursor = 0
|
|
266
|
+
|
|
267
|
+
if scan_all_keys:
|
|
268
|
+
# Scan all keys in the database
|
|
269
|
+
while True:
|
|
270
|
+
cursor, keys = redis_conn.scan(cursor=cursor, count=100)
|
|
271
|
+
scanned_keys.extend(keys)
|
|
272
|
+
|
|
273
|
+
# Break if we've completed a full scan
|
|
274
|
+
if cursor == 0:
|
|
275
|
+
break
|
|
276
|
+
else:
|
|
277
|
+
# Sample keys until we reach our target sample size
|
|
278
|
+
while len(scanned_keys) < sample_size:
|
|
279
|
+
cursor, keys = redis_conn.scan(cursor=cursor, count=min(100, sample_size - len(scanned_keys)))
|
|
280
|
+
scanned_keys.extend(keys)
|
|
281
|
+
|
|
282
|
+
# Break if we've completed a full scan
|
|
283
|
+
if cursor == 0:
|
|
284
|
+
break
|
|
285
|
+
|
|
286
|
+
# Limit to our target sample size
|
|
287
|
+
scanned_keys = scanned_keys[:sample_size]
|
|
288
|
+
|
|
289
|
+
logging.debug(f"SCAN completed: found {len(scanned_keys)} keys, cursor ended at {cursor}")
|
|
290
|
+
|
|
291
|
+
# If SCAN didn't find any keys but we know there are keys, try KEYS command as fallback
|
|
292
|
+
if len(scanned_keys) == 0 and total_keys > 0:
|
|
293
|
+
logging.warning(f"SCAN found no keys but DBSIZE reports {total_keys} keys. Trying KEYS fallback.")
|
|
294
|
+
try:
|
|
295
|
+
# Use KEYS * as fallback (only for small datasets to avoid blocking)
|
|
296
|
+
if total_keys <= 1000:
|
|
297
|
+
all_keys = redis_conn.keys('*')
|
|
298
|
+
scanned_keys = all_keys[:sample_size] if not scan_all_keys else all_keys
|
|
299
|
+
logging.info(f"KEYS fallback found {len(scanned_keys)} keys")
|
|
300
|
+
else:
|
|
301
|
+
logging.error(f"Cannot use KEYS fallback for large dataset ({total_keys} keys)")
|
|
302
|
+
except Exception as e:
|
|
303
|
+
logging.error(f"KEYS fallback failed: {e}")
|
|
304
|
+
|
|
305
|
+
# Final check: if we still have no keys, return early
|
|
306
|
+
if len(scanned_keys) == 0:
|
|
307
|
+
logging.error(f"No keys found for encoding detection despite DBSIZE={total_keys}")
|
|
308
|
+
return {
|
|
309
|
+
"encoding": "unknown",
|
|
310
|
+
"confidence": 0.0,
|
|
311
|
+
"sample_size": 0,
|
|
312
|
+
"total_keys": total_keys,
|
|
313
|
+
"encoding_distribution": {},
|
|
314
|
+
"is_complete_scan": scan_all_keys,
|
|
315
|
+
"error": "No keys found by SCAN or KEYS commands"
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
# Get encoding for each sampled key
|
|
319
|
+
successful_encodings = 0
|
|
320
|
+
for i, key in enumerate(scanned_keys):
|
|
321
|
+
try:
|
|
322
|
+
# Use the redis-py object_encoding method instead of raw command
|
|
323
|
+
encoding = redis_conn.object("ENCODING", key)
|
|
324
|
+
if isinstance(encoding, bytes):
|
|
325
|
+
encoding = encoding.decode('utf-8')
|
|
326
|
+
elif encoding is None:
|
|
327
|
+
# Key might have expired or been deleted
|
|
328
|
+
logging.debug(f"Key '{key}' returned None encoding (key may have expired)")
|
|
329
|
+
continue
|
|
330
|
+
|
|
331
|
+
encoding_counts[encoding] = encoding_counts.get(encoding, 0) + 1
|
|
332
|
+
successful_encodings += 1
|
|
333
|
+
|
|
334
|
+
# Log first few keys for debugging
|
|
335
|
+
if i < 3:
|
|
336
|
+
logging.debug(f"Key '{key}' has encoding '{encoding}'")
|
|
337
|
+
|
|
338
|
+
except Exception as e:
|
|
339
|
+
logging.warning(f"Failed to get encoding for key {key}: {e}")
|
|
340
|
+
continue
|
|
341
|
+
|
|
342
|
+
logging.debug(f"Successfully got encoding for {successful_encodings}/{len(scanned_keys)} keys")
|
|
343
|
+
|
|
344
|
+
if not encoding_counts:
|
|
345
|
+
logging.warning(f"No object encodings detected! Scanned {len(scanned_keys)} keys, successful encodings: {successful_encodings}")
|
|
346
|
+
return {
|
|
347
|
+
"encoding": "unknown",
|
|
348
|
+
"confidence": 0.0,
|
|
349
|
+
"sample_size": 0,
|
|
350
|
+
"total_keys": total_keys,
|
|
351
|
+
"encoding_distribution": {},
|
|
352
|
+
"is_complete_scan": scan_all_keys
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
# Determine dominant encoding
|
|
356
|
+
total_sampled = sum(encoding_counts.values())
|
|
357
|
+
dominant_encoding = max(encoding_counts.items(), key=lambda x: x[1])
|
|
358
|
+
confidence = dominant_encoding[1] / total_sampled
|
|
359
|
+
|
|
360
|
+
# Calculate encoding distribution percentages
|
|
361
|
+
encoding_distribution = {
|
|
362
|
+
enc: (count / total_sampled) * 100
|
|
363
|
+
for enc, count in encoding_counts.items()
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
result = {
|
|
367
|
+
"encoding": dominant_encoding[0],
|
|
368
|
+
"confidence": confidence,
|
|
369
|
+
"sample_size": total_sampled,
|
|
370
|
+
"total_keys": total_keys,
|
|
371
|
+
"encoding_distribution": encoding_distribution,
|
|
372
|
+
"is_complete_scan": scan_all_keys
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
scan_type = "complete scan" if scan_all_keys else "sample"
|
|
376
|
+
logging.info(f"Object encoding analysis ({scan_type}): {dominant_encoding[0]} ({confidence*100:.1f}% confidence)")
|
|
377
|
+
if len(encoding_counts) > 1:
|
|
378
|
+
logging.info(f"Encoding distribution: {encoding_distribution}")
|
|
379
|
+
|
|
380
|
+
return result
|
|
381
|
+
|
|
382
|
+
except Exception as e:
|
|
383
|
+
logging.error(f"Failed to detect object encoding: {e}")
|
|
384
|
+
return {
|
|
385
|
+
"encoding": "error",
|
|
386
|
+
"confidence": 0.0,
|
|
387
|
+
"sample_size": 0,
|
|
388
|
+
"total_keys": 0,
|
|
389
|
+
"encoding_distribution": {},
|
|
390
|
+
"error": str(e)
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
|
|
206
394
|
def run_multiple_clients(
|
|
207
395
|
benchmark_config,
|
|
208
396
|
docker_client,
|
|
@@ -631,6 +819,9 @@ def run_multiple_clients(
|
|
|
631
819
|
|
|
632
820
|
|
|
633
821
|
def main():
|
|
822
|
+
# Register signal handler for graceful exit on Ctrl+C
|
|
823
|
+
signal.signal(signal.SIGINT, signal_handler)
|
|
824
|
+
|
|
634
825
|
_, _, project_version = populate_with_poetry_data()
|
|
635
826
|
project_name_suffix = "redis-benchmarks-spec-client-runner"
|
|
636
827
|
project_name = f"{project_name_suffix} (solely client)"
|
|
@@ -1087,7 +1278,10 @@ def process_self_contained_coordinator_stream(
|
|
|
1087
1278
|
total_test_suite_runs = 0
|
|
1088
1279
|
dry_run_count = 0
|
|
1089
1280
|
dry_run_tests = [] # Track test names for dry run output
|
|
1281
|
+
memory_results = [] # Track memory results for memory comparison mode
|
|
1282
|
+
loaded_datasets = set() # Track datasets that have been loaded (for memory comparison mode)
|
|
1090
1283
|
dry_run = args.dry_run
|
|
1284
|
+
memory_comparison_only = args.memory_comparison_only
|
|
1091
1285
|
dry_run_include_preload = args.dry_run_include_preload
|
|
1092
1286
|
defaults_filename = args.defaults_filename
|
|
1093
1287
|
override_test_runs = args.override_test_runs
|
|
@@ -1100,7 +1294,49 @@ def process_self_contained_coordinator_stream(
|
|
|
1100
1294
|
_,
|
|
1101
1295
|
) = get_defaults(defaults_filename)
|
|
1102
1296
|
|
|
1297
|
+
# For memory comparison mode, analyze datasets before starting
|
|
1298
|
+
if memory_comparison_only:
|
|
1299
|
+
unique_datasets = set()
|
|
1300
|
+
total_tests_with_datasets = 0
|
|
1301
|
+
|
|
1302
|
+
logging.info("Analyzing datasets for memory comparison mode...")
|
|
1303
|
+
for test_file in testsuite_spec_files:
|
|
1304
|
+
if defaults_filename in test_file:
|
|
1305
|
+
continue
|
|
1306
|
+
try:
|
|
1307
|
+
with open(test_file, "r") as stream:
|
|
1308
|
+
benchmark_config = yaml.safe_load(stream)
|
|
1309
|
+
|
|
1310
|
+
if "dbconfig" in benchmark_config:
|
|
1311
|
+
# Skip load tests (keyspacelen = 0) in memory comparison mode
|
|
1312
|
+
keyspacelen = benchmark_config["dbconfig"].get("check", {}).get("keyspacelen", None)
|
|
1313
|
+
if keyspacelen is not None and keyspacelen == 0:
|
|
1314
|
+
logging.debug(f"Skipping load test {test_file} (keyspacelen=0)")
|
|
1315
|
+
continue
|
|
1316
|
+
|
|
1317
|
+
dataset_name = benchmark_config["dbconfig"].get("dataset_name")
|
|
1318
|
+
if dataset_name:
|
|
1319
|
+
unique_datasets.add(dataset_name)
|
|
1320
|
+
total_tests_with_datasets += 1
|
|
1321
|
+
|
|
1322
|
+
except Exception as e:
|
|
1323
|
+
logging.warning(f"Error analyzing {test_file}: {e}")
|
|
1324
|
+
|
|
1325
|
+
logging.info(f"Memory comparison mode analysis:")
|
|
1326
|
+
logging.info(f" Total tests with datasets: {total_tests_with_datasets}")
|
|
1327
|
+
logging.info(f" Unique datasets to load: {len(unique_datasets)}")
|
|
1328
|
+
logging.info(f" Dataset ingestion savings: {total_tests_with_datasets - len(unique_datasets)} skipped loads")
|
|
1329
|
+
logging.info(f" Load tests skipped: Tests with keyspacelen=0 are automatically excluded")
|
|
1330
|
+
|
|
1331
|
+
if len(unique_datasets) > 0:
|
|
1332
|
+
logging.info(f" Unique datasets: {', '.join(sorted(unique_datasets))}")
|
|
1333
|
+
|
|
1103
1334
|
for test_file in tqdm.tqdm(testsuite_spec_files):
|
|
1335
|
+
# Check if user requested exit via Ctrl+C
|
|
1336
|
+
if _exit_requested:
|
|
1337
|
+
logging.info("Exit requested by user. Stopping test execution.")
|
|
1338
|
+
break
|
|
1339
|
+
|
|
1104
1340
|
if defaults_filename in test_file:
|
|
1105
1341
|
continue
|
|
1106
1342
|
client_containers = []
|
|
@@ -1110,6 +1346,11 @@ def process_self_contained_coordinator_stream(
|
|
|
1110
1346
|
None, None, stream, ""
|
|
1111
1347
|
)
|
|
1112
1348
|
|
|
1349
|
+
# Check if user requested exit via Ctrl+C
|
|
1350
|
+
if _exit_requested:
|
|
1351
|
+
logging.info(f"Exit requested by user. Skipping test {test_name}.")
|
|
1352
|
+
break
|
|
1353
|
+
|
|
1113
1354
|
if tls_enabled:
|
|
1114
1355
|
test_name = test_name + "-tls"
|
|
1115
1356
|
logging.info(
|
|
@@ -1188,28 +1429,17 @@ def process_self_contained_coordinator_stream(
|
|
|
1188
1429
|
git_version = detected_info["github_version"]
|
|
1189
1430
|
logging.info(f"Auto-detected github_version: {git_version}")
|
|
1190
1431
|
|
|
1191
|
-
# Auto-detect git hash
|
|
1192
|
-
if git_hash == "NA":
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
redis_git_sha1 = server_info.get("redis_git_sha1", "")
|
|
1196
|
-
redis_build_id = server_info.get("redis_build_id", "")
|
|
1197
|
-
|
|
1198
|
-
# Use git_sha1 if available and not empty/zero
|
|
1199
|
-
if redis_git_sha1 and redis_git_sha1 not in ("", "0", "00000000"):
|
|
1200
|
-
git_hash = redis_git_sha1
|
|
1201
|
-
logging.info(f"Auto-detected git_hash from redis_git_sha1: {git_hash}")
|
|
1202
|
-
# Fallback to build_id if git_sha1 is not available
|
|
1203
|
-
elif redis_build_id and redis_build_id not in ("", "0"):
|
|
1204
|
-
git_hash = redis_build_id
|
|
1205
|
-
logging.info(f"Auto-detected git_hash from redis_build_id: {git_hash}")
|
|
1206
|
-
except Exception as e:
|
|
1207
|
-
logging.warning(f"Failed to auto-detect git hash: {e}")
|
|
1432
|
+
# Auto-detect git hash if it's the default value
|
|
1433
|
+
if git_hash == "NA" and detected_info["github_hash"] != "unknown":
|
|
1434
|
+
git_hash = detected_info["github_hash"]
|
|
1435
|
+
logging.info(f"Auto-detected git_hash: {git_hash}")
|
|
1208
1436
|
|
|
1209
1437
|
# Update tf_github_org and tf_github_repo with detected values
|
|
1210
1438
|
tf_github_org = github_org
|
|
1211
1439
|
tf_github_repo = github_repo
|
|
1212
1440
|
redis_conns = [r]
|
|
1441
|
+
|
|
1442
|
+
|
|
1213
1443
|
if oss_cluster_api_enabled:
|
|
1214
1444
|
redis_conns = []
|
|
1215
1445
|
logging.info("updating redis connections from cluster slots")
|
|
@@ -1287,6 +1517,15 @@ def process_self_contained_coordinator_stream(
|
|
|
1287
1517
|
for conn in redis_conns:
|
|
1288
1518
|
conn.flushall()
|
|
1289
1519
|
|
|
1520
|
+
# Send MEMORY PURGE after FLUSHALL for memory comparison mode
|
|
1521
|
+
if memory_comparison_only:
|
|
1522
|
+
try:
|
|
1523
|
+
logging.info("Sending MEMORY PURGE after FLUSHALL at test start")
|
|
1524
|
+
for conn in redis_conns:
|
|
1525
|
+
conn.execute_command("MEMORY", "PURGE")
|
|
1526
|
+
except Exception as e:
|
|
1527
|
+
logging.warning(f"MEMORY PURGE failed after FLUSHALL at test start: {e}")
|
|
1528
|
+
|
|
1290
1529
|
benchmark_required_memory = get_benchmark_required_memory(
|
|
1291
1530
|
benchmark_config
|
|
1292
1531
|
)
|
|
@@ -1437,6 +1676,20 @@ def process_self_contained_coordinator_stream(
|
|
|
1437
1676
|
)
|
|
1438
1677
|
continue
|
|
1439
1678
|
|
|
1679
|
+
# For memory comparison mode, only run tests with dbconfig
|
|
1680
|
+
if memory_comparison_only and "dbconfig" not in benchmark_config:
|
|
1681
|
+
logging.warning(
|
|
1682
|
+
"Skipping test {} in memory comparison mode as it does not contain dbconfig".format(
|
|
1683
|
+
test_name
|
|
1684
|
+
)
|
|
1685
|
+
)
|
|
1686
|
+
delete_temporary_files(
|
|
1687
|
+
temporary_dir_client=temporary_dir_client,
|
|
1688
|
+
full_result_path=None,
|
|
1689
|
+
benchmark_tool_global=benchmark_tool_global,
|
|
1690
|
+
)
|
|
1691
|
+
continue
|
|
1692
|
+
|
|
1440
1693
|
if dry_run is True:
|
|
1441
1694
|
dry_run_count = dry_run_count + 1
|
|
1442
1695
|
dry_run_tests.append(test_name)
|
|
@@ -1448,46 +1701,68 @@ def process_self_contained_coordinator_stream(
|
|
|
1448
1701
|
continue
|
|
1449
1702
|
if "dbconfig" in benchmark_config:
|
|
1450
1703
|
if "preload_tool" in benchmark_config["dbconfig"]:
|
|
1451
|
-
#
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
tls_skip_verify,
|
|
1470
|
-
test_tls_cert,
|
|
1471
|
-
test_tls_key,
|
|
1472
|
-
test_tls_cacert,
|
|
1473
|
-
resp_version,
|
|
1474
|
-
args.benchmark_local_install,
|
|
1475
|
-
password,
|
|
1476
|
-
oss_cluster_api_enabled,
|
|
1477
|
-
unix_socket,
|
|
1478
|
-
buffer_timeout,
|
|
1479
|
-
args,
|
|
1480
|
-
)
|
|
1481
|
-
if res is False:
|
|
1482
|
-
logging.warning(
|
|
1483
|
-
"Skipping this test given preload result was false"
|
|
1704
|
+
# Check if this dataset has already been loaded (for memory comparison mode)
|
|
1705
|
+
dataset_name = benchmark_config["dbconfig"].get("dataset_name")
|
|
1706
|
+
skip_preload = False
|
|
1707
|
+
|
|
1708
|
+
if memory_comparison_only and dataset_name:
|
|
1709
|
+
if dataset_name in loaded_datasets:
|
|
1710
|
+
logging.info(f"Skipping preload for dataset '{dataset_name}' - already loaded")
|
|
1711
|
+
skip_preload = True
|
|
1712
|
+
else:
|
|
1713
|
+
logging.info(f"Loading dataset '{dataset_name}' for the first time")
|
|
1714
|
+
loaded_datasets.add(dataset_name)
|
|
1715
|
+
|
|
1716
|
+
if not skip_preload:
|
|
1717
|
+
# Get timeout buffer for preload
|
|
1718
|
+
buffer_timeout = getattr(
|
|
1719
|
+
args,
|
|
1720
|
+
"timeout_buffer",
|
|
1721
|
+
getattr(args, "container_timeout_buffer", 60),
|
|
1484
1722
|
)
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1723
|
+
|
|
1724
|
+
res = data_prepopulation_step(
|
|
1725
|
+
benchmark_config,
|
|
1726
|
+
benchmark_tool_workdir,
|
|
1727
|
+
client_cpuset_cpus,
|
|
1728
|
+
docker_client,
|
|
1729
|
+
git_hash,
|
|
1730
|
+
port,
|
|
1731
|
+
temporary_dir_client,
|
|
1732
|
+
test_name,
|
|
1733
|
+
host,
|
|
1734
|
+
tls_enabled,
|
|
1735
|
+
tls_skip_verify,
|
|
1736
|
+
test_tls_cert,
|
|
1737
|
+
test_tls_key,
|
|
1738
|
+
test_tls_cacert,
|
|
1739
|
+
resp_version,
|
|
1740
|
+
args.benchmark_local_install,
|
|
1741
|
+
password,
|
|
1742
|
+
oss_cluster_api_enabled,
|
|
1743
|
+
unix_socket,
|
|
1744
|
+
buffer_timeout,
|
|
1745
|
+
args,
|
|
1489
1746
|
)
|
|
1490
|
-
|
|
1747
|
+
if res is False:
|
|
1748
|
+
logging.warning(
|
|
1749
|
+
"Skipping this test given preload result was false"
|
|
1750
|
+
)
|
|
1751
|
+
delete_temporary_files(
|
|
1752
|
+
temporary_dir_client=temporary_dir_client,
|
|
1753
|
+
full_result_path=None,
|
|
1754
|
+
benchmark_tool_global=benchmark_tool_global,
|
|
1755
|
+
)
|
|
1756
|
+
continue
|
|
1757
|
+
# Send MEMORY PURGE before preload for memory comparison mode (if FLUSHALL wasn't already done)
|
|
1758
|
+
if memory_comparison_only and not args.flushall_on_every_test_start:
|
|
1759
|
+
try:
|
|
1760
|
+
logging.info("Sending MEMORY PURGE before preload for memory comparison mode")
|
|
1761
|
+
for conn in redis_conns:
|
|
1762
|
+
conn.execute_command("MEMORY", "PURGE")
|
|
1763
|
+
except Exception as e:
|
|
1764
|
+
logging.warning(f"MEMORY PURGE failed before preload: {e}")
|
|
1765
|
+
|
|
1491
1766
|
execute_init_commands(
|
|
1492
1767
|
benchmark_config, r, dbconfig_keyname="dbconfig"
|
|
1493
1768
|
)
|
|
@@ -1506,6 +1781,172 @@ def process_self_contained_coordinator_stream(
|
|
|
1506
1781
|
redis_conns,
|
|
1507
1782
|
)
|
|
1508
1783
|
|
|
1784
|
+
# For memory comparison mode, collect memory stats after preload and skip client benchmark
|
|
1785
|
+
if memory_comparison_only:
|
|
1786
|
+
# Skip load tests (keyspacelen = 0) in memory comparison mode
|
|
1787
|
+
keyspacelen = benchmark_config.get("dbconfig", {}).get("check", {}).get("keyspacelen", None)
|
|
1788
|
+
if keyspacelen is not None and keyspacelen == 0:
|
|
1789
|
+
logging.info(f"Skipping load test {test_name} in memory comparison mode (keyspacelen=0)")
|
|
1790
|
+
delete_temporary_files(
|
|
1791
|
+
temporary_dir_client=temporary_dir_client,
|
|
1792
|
+
full_result_path=None,
|
|
1793
|
+
benchmark_tool_global=benchmark_tool_global,
|
|
1794
|
+
)
|
|
1795
|
+
continue
|
|
1796
|
+
|
|
1797
|
+
# Handle dry run for memory comparison mode
|
|
1798
|
+
if dry_run:
|
|
1799
|
+
dry_run_count = dry_run_count + 1
|
|
1800
|
+
dry_run_tests.append(test_name)
|
|
1801
|
+
logging.info(f"[DRY RUN] Would collect memory stats for test {test_name}")
|
|
1802
|
+
|
|
1803
|
+
# Add dataset info to dry run output
|
|
1804
|
+
dataset_name = benchmark_config.get("dbconfig", {}).get("dataset_name")
|
|
1805
|
+
if dataset_name:
|
|
1806
|
+
logging.info(f"[DRY RUN] Dataset: {dataset_name}")
|
|
1807
|
+
|
|
1808
|
+
delete_temporary_files(
|
|
1809
|
+
temporary_dir_client=temporary_dir_client,
|
|
1810
|
+
full_result_path=None,
|
|
1811
|
+
benchmark_tool_global=benchmark_tool_global,
|
|
1812
|
+
)
|
|
1813
|
+
continue
|
|
1814
|
+
|
|
1815
|
+
logging.info(f"Collecting memory stats for test {test_name}")
|
|
1816
|
+
try:
|
|
1817
|
+
# Use raw command to avoid parsing issues with some Redis versions
|
|
1818
|
+
memory_stats_raw = r.execute_command("MEMORY", "STATS")
|
|
1819
|
+
# Convert list response to dict
|
|
1820
|
+
memory_stats = {}
|
|
1821
|
+
for i in range(0, len(memory_stats_raw), 2):
|
|
1822
|
+
key = memory_stats_raw[i].decode() if isinstance(memory_stats_raw[i], bytes) else str(memory_stats_raw[i])
|
|
1823
|
+
value = memory_stats_raw[i + 1]
|
|
1824
|
+
if isinstance(value, bytes):
|
|
1825
|
+
try:
|
|
1826
|
+
value = float(value.decode())
|
|
1827
|
+
except ValueError:
|
|
1828
|
+
value = value.decode()
|
|
1829
|
+
memory_stats[key] = value
|
|
1830
|
+
except Exception as e:
|
|
1831
|
+
logging.error(f"Failed to collect memory stats: {e}")
|
|
1832
|
+
# Fallback to basic memory info
|
|
1833
|
+
info = r.info("memory")
|
|
1834
|
+
memory_stats = {
|
|
1835
|
+
"total.allocated": info.get("used_memory", 0),
|
|
1836
|
+
"dataset.bytes": info.get("used_memory_dataset", 0),
|
|
1837
|
+
"keys.count": r.dbsize(),
|
|
1838
|
+
"keys.bytes-per-key": 0,
|
|
1839
|
+
"dataset.percentage": 0,
|
|
1840
|
+
"overhead.total": 0,
|
|
1841
|
+
"fragmentation": info.get("mem_fragmentation_ratio", 1.0),
|
|
1842
|
+
"fragmentation.bytes": 0,
|
|
1843
|
+
"allocator.allocated": info.get("used_memory", 0),
|
|
1844
|
+
"allocator.resident": info.get("used_memory_rss", 0),
|
|
1845
|
+
"allocator-fragmentation.ratio": 1.0,
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
# Detect object encoding by scanning 1% of the dataset
|
|
1849
|
+
object_encoding_info = detect_object_encoding(r, benchmark_config.get("dbconfig", {}))
|
|
1850
|
+
logging.info(f"Object encoding detection: {object_encoding_info.get('encoding', 'unknown')} "
|
|
1851
|
+
f"({object_encoding_info.get('confidence', 0)*100:.1f}% confidence)")
|
|
1852
|
+
|
|
1853
|
+
# Extract key memory metrics
|
|
1854
|
+
memory_result = {
|
|
1855
|
+
"test_name": test_name,
|
|
1856
|
+
"total_allocated": memory_stats.get("total.allocated", 0),
|
|
1857
|
+
"dataset_bytes": memory_stats.get("dataset.bytes", 0),
|
|
1858
|
+
"keys_count": memory_stats.get("keys.count", 0),
|
|
1859
|
+
"keys_bytes_per_key": memory_stats.get("keys.bytes-per-key", 0),
|
|
1860
|
+
"dataset_percentage": memory_stats.get("dataset.percentage", 0),
|
|
1861
|
+
"overhead_total": memory_stats.get("overhead.total", 0),
|
|
1862
|
+
"fragmentation": memory_stats.get("fragmentation", 0),
|
|
1863
|
+
"fragmentation_bytes": memory_stats.get("fragmentation.bytes", 0),
|
|
1864
|
+
"allocator_allocated": memory_stats.get("allocator.allocated", 0),
|
|
1865
|
+
"allocator_resident": memory_stats.get("allocator.resident", 0),
|
|
1866
|
+
"allocator_fragmentation_ratio": memory_stats.get("allocator-fragmentation.ratio", 0),
|
|
1867
|
+
# Object encoding information
|
|
1868
|
+
"object_encoding": object_encoding_info.get("encoding", "unknown"),
|
|
1869
|
+
"encoding_confidence": object_encoding_info.get("confidence", 0.0),
|
|
1870
|
+
"encoding_sample_size": object_encoding_info.get("sample_size", 0),
|
|
1871
|
+
"encoding_distribution": object_encoding_info.get("encoding_distribution", {}),
|
|
1872
|
+
"encoding_is_complete_scan": object_encoding_info.get("is_complete_scan", False),
|
|
1873
|
+
}
|
|
1874
|
+
memory_results.append(memory_result)
|
|
1875
|
+
|
|
1876
|
+
# Push memory metrics to datasink
|
|
1877
|
+
if datasink_push_results_redistimeseries:
|
|
1878
|
+
memory_metrics_dict = {
|
|
1879
|
+
"memory.total_allocated": memory_result["total_allocated"],
|
|
1880
|
+
"memory.dataset_bytes": memory_result["dataset_bytes"],
|
|
1881
|
+
"memory.keys_count": memory_result["keys_count"],
|
|
1882
|
+
"memory.keys_bytes_per_key": memory_result["keys_bytes_per_key"],
|
|
1883
|
+
"memory.dataset_percentage": memory_result["dataset_percentage"],
|
|
1884
|
+
"memory.overhead_total": memory_result["overhead_total"],
|
|
1885
|
+
"memory.fragmentation": memory_result["fragmentation"],
|
|
1886
|
+
"memory.fragmentation_bytes": memory_result["fragmentation_bytes"],
|
|
1887
|
+
"memory.allocator_allocated": memory_result["allocator_allocated"],
|
|
1888
|
+
"memory.allocator_resident": memory_result["allocator_resident"],
|
|
1889
|
+
"memory.allocator_fragmentation_ratio": memory_result["allocator_fragmentation_ratio"],
|
|
1890
|
+
"memory.encoding_confidence": memory_result["encoding_confidence"],
|
|
1891
|
+
"memory.encoding_sample_size": memory_result["encoding_sample_size"],
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
# Add object encoding to metadata
|
|
1895
|
+
metadata["object_encoding"] = memory_result["object_encoding"]
|
|
1896
|
+
metadata["encoding_confidence"] = f"{memory_result['encoding_confidence']:.3f}"
|
|
1897
|
+
metadata["encoding_sample_size"] = str(memory_result["encoding_sample_size"])
|
|
1898
|
+
metadata["encoding_scan_type"] = "complete" if memory_result.get("encoding_is_complete_scan", False) else "sample"
|
|
1899
|
+
|
|
1900
|
+
# Add encoding distribution to metadata if multiple encodings found
|
|
1901
|
+
if len(memory_result["encoding_distribution"]) > 1:
|
|
1902
|
+
for enc, percentage in memory_result["encoding_distribution"].items():
|
|
1903
|
+
metadata[f"encoding_dist_{enc}"] = f"{percentage:.1f}%"
|
|
1904
|
+
|
|
1905
|
+
# Set datapoint_time_ms for memory comparison mode
|
|
1906
|
+
datapoint_time_ms = start_time_ms
|
|
1907
|
+
|
|
1908
|
+
exporter_datasink_common(
|
|
1909
|
+
benchmark_config,
|
|
1910
|
+
0, # benchmark_duration_seconds = 0 for memory only
|
|
1911
|
+
build_variant_name,
|
|
1912
|
+
datapoint_time_ms,
|
|
1913
|
+
dataset_load_duration_seconds,
|
|
1914
|
+
datasink_conn,
|
|
1915
|
+
datasink_push_results_redistimeseries,
|
|
1916
|
+
git_branch,
|
|
1917
|
+
git_version,
|
|
1918
|
+
metadata,
|
|
1919
|
+
redis_conns,
|
|
1920
|
+
memory_metrics_dict,
|
|
1921
|
+
running_platform,
|
|
1922
|
+
args.deployment_name,
|
|
1923
|
+
args.deployment_type,
|
|
1924
|
+
test_name,
|
|
1925
|
+
tf_github_org,
|
|
1926
|
+
tf_github_repo,
|
|
1927
|
+
tf_triggering_env,
|
|
1928
|
+
topology_spec_name,
|
|
1929
|
+
default_metrics,
|
|
1930
|
+
git_hash,
|
|
1931
|
+
)
|
|
1932
|
+
|
|
1933
|
+
# Send MEMORY PURGE after memory comparison (if FLUSHALL at test end is not enabled)
|
|
1934
|
+
if not args.flushall_on_every_test_end:
|
|
1935
|
+
try:
|
|
1936
|
+
logging.info("Sending MEMORY PURGE after memory comparison")
|
|
1937
|
+
for conn in redis_conns:
|
|
1938
|
+
conn.execute_command("MEMORY", "PURGE")
|
|
1939
|
+
except Exception as e:
|
|
1940
|
+
logging.warning(f"MEMORY PURGE failed after memory comparison: {e}")
|
|
1941
|
+
|
|
1942
|
+
logging.info(f"Memory comparison completed for test {test_name}")
|
|
1943
|
+
delete_temporary_files(
|
|
1944
|
+
temporary_dir_client=temporary_dir_client,
|
|
1945
|
+
full_result_path=None,
|
|
1946
|
+
benchmark_tool_global=benchmark_tool_global,
|
|
1947
|
+
)
|
|
1948
|
+
continue
|
|
1949
|
+
|
|
1509
1950
|
if dry_run_include_preload is True:
|
|
1510
1951
|
dry_run_count = dry_run_count + 1
|
|
1511
1952
|
dry_run_tests.append(test_name)
|
|
@@ -2070,6 +2511,19 @@ def process_self_contained_coordinator_stream(
|
|
|
2070
2511
|
for r in redis_conns:
|
|
2071
2512
|
r.flushall()
|
|
2072
2513
|
|
|
2514
|
+
# Send MEMORY PURGE after FLUSHALL for memory comparison mode
|
|
2515
|
+
if memory_comparison_only:
|
|
2516
|
+
try:
|
|
2517
|
+
logging.info("Sending MEMORY PURGE after FLUSHALL at test end")
|
|
2518
|
+
for r in redis_conns:
|
|
2519
|
+
r.execute_command("MEMORY", "PURGE")
|
|
2520
|
+
except Exception as e:
|
|
2521
|
+
logging.warning(f"MEMORY PURGE failed after FLUSHALL at test end: {e}")
|
|
2522
|
+
|
|
2523
|
+
except KeyboardInterrupt:
|
|
2524
|
+
logging.info("KeyboardInterrupt caught. Exiting...")
|
|
2525
|
+
print("\nKeyboardInterrupt caught. Exiting...")
|
|
2526
|
+
break
|
|
2073
2527
|
except:
|
|
2074
2528
|
logging.critical(
|
|
2075
2529
|
"Some unexpected exception was caught "
|
|
@@ -2080,6 +2534,11 @@ def process_self_contained_coordinator_stream(
|
|
|
2080
2534
|
traceback.print_exc(file=sys.stdout)
|
|
2081
2535
|
print("-" * 60)
|
|
2082
2536
|
test_result = False
|
|
2537
|
+
|
|
2538
|
+
# Check if user requested exit via Ctrl+C
|
|
2539
|
+
if _exit_requested:
|
|
2540
|
+
logging.info("Exit requested by user. Stopping after exception.")
|
|
2541
|
+
break
|
|
2083
2542
|
# tear-down
|
|
2084
2543
|
logging.info("Tearing down setup")
|
|
2085
2544
|
for container in client_containers:
|
|
@@ -2114,6 +2573,11 @@ def process_self_contained_coordinator_stream(
|
|
|
2114
2573
|
benchmark_tool_global=benchmark_tool_global,
|
|
2115
2574
|
)
|
|
2116
2575
|
|
|
2576
|
+
# Check if user requested exit via Ctrl+C
|
|
2577
|
+
if _exit_requested:
|
|
2578
|
+
logging.info("Exit requested by user. Printing summary before exit.")
|
|
2579
|
+
print("\nExecution stopped by user request. Printing summary of completed tests...")
|
|
2580
|
+
|
|
2117
2581
|
# Print Redis server information section before results
|
|
2118
2582
|
if len(results_matrix) > 0:
|
|
2119
2583
|
# Get redis_conns from the first test context (we need to pass it somehow)
|
|
@@ -2136,6 +2600,10 @@ def process_self_contained_coordinator_stream(
|
|
|
2136
2600
|
)
|
|
2137
2601
|
writer.write_table()
|
|
2138
2602
|
|
|
2603
|
+
# Add note if execution was stopped early
|
|
2604
|
+
if _exit_requested:
|
|
2605
|
+
print("\n(Note: Execution was stopped early by user request - showing results for completed tests only)")
|
|
2606
|
+
|
|
2139
2607
|
if client_aggregated_results_folder != "":
|
|
2140
2608
|
os.makedirs(client_aggregated_results_folder, exist_ok=True)
|
|
2141
2609
|
dest_fpath = f"{client_aggregated_results_folder}/aggregate-results.csv"
|
|
@@ -2148,15 +2616,112 @@ def process_self_contained_coordinator_stream(
|
|
|
2148
2616
|
)
|
|
2149
2617
|
csv_writer.dump(dest_fpath)
|
|
2150
2618
|
|
|
2619
|
+
# Print memory comparison summary if in memory comparison mode
|
|
2620
|
+
if memory_comparison_only and memory_results:
|
|
2621
|
+
logging.info("\n" + "="*80)
|
|
2622
|
+
logging.info("MEMORY COMPARISON SUMMARY")
|
|
2623
|
+
logging.info("="*80)
|
|
2624
|
+
logging.info(f"Total unique datasets loaded: {len(loaded_datasets)}")
|
|
2625
|
+
if loaded_datasets:
|
|
2626
|
+
logging.info(f"Datasets: {', '.join(sorted(loaded_datasets))}")
|
|
2627
|
+
logging.info("="*80)
|
|
2628
|
+
|
|
2629
|
+
# Create memory summary table
|
|
2630
|
+
memory_headers = [
|
|
2631
|
+
"Test Name",
|
|
2632
|
+
"Total Allocated",
|
|
2633
|
+
"Dataset Bytes",
|
|
2634
|
+
"Keys Count",
|
|
2635
|
+
"Bytes/Key",
|
|
2636
|
+
"Dataset %",
|
|
2637
|
+
"Overhead",
|
|
2638
|
+
"Fragmentation",
|
|
2639
|
+
"Alloc Fragmentation",
|
|
2640
|
+
"Object Encoding",
|
|
2641
|
+
"Encoding Confidence",
|
|
2642
|
+
"Scan Type"
|
|
2643
|
+
]
|
|
2644
|
+
|
|
2645
|
+
memory_matrix = []
|
|
2646
|
+
for result in memory_results:
|
|
2647
|
+
# Convert bytes to human readable format
|
|
2648
|
+
total_mb = result["total_allocated"] / (1024 * 1024)
|
|
2649
|
+
dataset_mb = result["dataset_bytes"] / (1024 * 1024)
|
|
2650
|
+
overhead_mb = result["overhead_total"] / (1024 * 1024)
|
|
2651
|
+
|
|
2652
|
+
memory_matrix.append([
|
|
2653
|
+
result["test_name"],
|
|
2654
|
+
f"{total_mb:.1f}MB",
|
|
2655
|
+
f"{dataset_mb:.1f}MB",
|
|
2656
|
+
f"{result['keys_count']:,}",
|
|
2657
|
+
f"{result['keys_bytes_per_key']:.0f}B",
|
|
2658
|
+
f"{result['dataset_percentage']:.1f}%",
|
|
2659
|
+
f"{overhead_mb:.1f}MB",
|
|
2660
|
+
f"{result['fragmentation']:.2f}",
|
|
2661
|
+
f"{result['allocator_fragmentation_ratio']:.3f}",
|
|
2662
|
+
result.get("object_encoding", "unknown"),
|
|
2663
|
+
f"{result.get('encoding_confidence', 0.0)*100:.1f}%",
|
|
2664
|
+
"complete" if result.get("encoding_is_complete_scan", False) else "sample"
|
|
2665
|
+
])
|
|
2666
|
+
|
|
2667
|
+
memory_writer = MarkdownTableWriter(
|
|
2668
|
+
table_name="Memory Usage Summary",
|
|
2669
|
+
headers=memory_headers,
|
|
2670
|
+
value_matrix=memory_matrix,
|
|
2671
|
+
)
|
|
2672
|
+
memory_writer.write_table()
|
|
2673
|
+
|
|
2151
2674
|
if dry_run is True:
|
|
2675
|
+
mode_description = "memory comparison" if memory_comparison_only else "benchmark"
|
|
2152
2676
|
logging.info(
|
|
2153
|
-
"Number of tests that would have been run: {}".format(dry_run_count)
|
|
2677
|
+
"Number of tests that would have been run ({}): {}".format(mode_description, dry_run_count)
|
|
2154
2678
|
)
|
|
2679
|
+
if _exit_requested:
|
|
2680
|
+
logging.info("(Note: Execution was stopped early by user request)")
|
|
2155
2681
|
if dry_run_tests:
|
|
2156
|
-
logging.info("Tests that would be run:")
|
|
2682
|
+
logging.info(f"Tests that would be run ({mode_description} mode):")
|
|
2683
|
+
for test in dry_run_tests:
|
|
2684
|
+
logging.info(f" - {test}")
|
|
2157
2685
|
final_test_regex = "|".join(dry_run_tests)
|
|
2158
2686
|
logging.info(f"Final test regex: {final_test_regex}")
|
|
2159
2687
|
|
|
2688
|
+
# For memory comparison mode, show dataset analysis
|
|
2689
|
+
if memory_comparison_only:
|
|
2690
|
+
unique_datasets = set()
|
|
2691
|
+
tests_with_datasets = 0
|
|
2692
|
+
|
|
2693
|
+
for test_file in testsuite_spec_files:
|
|
2694
|
+
if defaults_filename in test_file:
|
|
2695
|
+
continue
|
|
2696
|
+
try:
|
|
2697
|
+
with open(test_file, "r") as stream:
|
|
2698
|
+
benchmark_config = yaml.safe_load(stream)
|
|
2699
|
+
|
|
2700
|
+
test_name = extract_test_name_from_test_configuration_file(test_file)
|
|
2701
|
+
if test_name in dry_run_tests and "dbconfig" in benchmark_config:
|
|
2702
|
+
# Skip load tests in dry run analysis too
|
|
2703
|
+
keyspacelen = benchmark_config["dbconfig"].get("check", {}).get("keyspacelen", None)
|
|
2704
|
+
if keyspacelen is not None and keyspacelen == 0:
|
|
2705
|
+
continue
|
|
2706
|
+
|
|
2707
|
+
dataset_name = benchmark_config["dbconfig"].get("dataset_name")
|
|
2708
|
+
if dataset_name:
|
|
2709
|
+
unique_datasets.add(dataset_name)
|
|
2710
|
+
tests_with_datasets += 1
|
|
2711
|
+
|
|
2712
|
+
except Exception as e:
|
|
2713
|
+
logging.debug(f"Error analyzing {test_file} for dry run: {e}")
|
|
2714
|
+
|
|
2715
|
+
if tests_with_datasets > 0:
|
|
2716
|
+
logging.info(f"\nMemory comparison analysis:")
|
|
2717
|
+
logging.info(f" Tests with datasets: {tests_with_datasets}")
|
|
2718
|
+
logging.info(f" Unique datasets: {len(unique_datasets)}")
|
|
2719
|
+
logging.info(f" Dataset ingestion savings: {tests_with_datasets - len(unique_datasets)} skipped loads")
|
|
2720
|
+
if unique_datasets:
|
|
2721
|
+
logging.info(f" Datasets that would be loaded:")
|
|
2722
|
+
for dataset in sorted(unique_datasets):
|
|
2723
|
+
logging.info(f" - {dataset}")
|
|
2724
|
+
|
|
2160
2725
|
|
|
2161
2726
|
def get_maxmemory(r):
|
|
2162
2727
|
memory_info = r.info("memory")
|