summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-14 13:40:54 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-14 13:40:54 +0000
commit317c0644ccf108aa23ef3fd8358bd66c2840bfc0 (patch)
treec417b3d25c86b775989cb5ac042f37611b626c8a
parentInitial commit. (diff)
downloadredis-317c0644ccf108aa23ef3fd8358bd66c2840bfc0.tar.xz
redis-317c0644ccf108aa23ef3fd8358bd66c2840bfc0.zip
Adding upstream version 5:7.2.4.upstream/5%7.2.4
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--.codespell/.codespellrc5
-rw-r--r--.codespell/requirements.txt1
-rw-r--r--.codespell/wordlist.txt21
-rw-r--r--.gitattributes6
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md24
-rw-r--r--.github/ISSUE_TEMPLATE/crash_report.md25
-rw-r--r--.github/ISSUE_TEMPLATE/feature_request.md24
-rw-r--r--.github/ISSUE_TEMPLATE/other_stuff.md8
-rw-r--r--.github/ISSUE_TEMPLATE/question.md21
-rw-r--r--.github/dependabot.yml15
-rw-r--r--.github/workflows/ci.yml84
-rw-r--r--.github/workflows/codeql-analysis.yml33
-rw-r--r--.github/workflows/daily.yml1087
-rw-r--r--.github/workflows/external.yml82
-rw-r--r--.github/workflows/reply-schemas-linter.yml22
-rw-r--r--.github/workflows/spell-check.yml32
-rw-r--r--.gitignore43
-rw-r--r--00-RELEASENOTES510
-rw-r--r--BUGS1
-rw-r--r--CODE_OF_CONDUCT.md96
-rw-r--r--CONTRIBUTING.md56
-rw-r--r--COPYING10
-rw-r--r--INSTALL1
-rw-r--r--MANIFESTO106
-rw-r--r--Makefile11
-rw-r--r--README.md506
-rw-r--r--SECURITY.md43
-rw-r--r--TLS.md104
-rw-r--r--deps/Makefile118
-rw-r--r--deps/README.md106
-rw-r--r--deps/fpconv/LICENSE.txt23
-rw-r--r--deps/fpconv/Makefile27
-rw-r--r--deps/fpconv/README.md9
-rw-r--r--deps/fpconv/fpconv_dtoa.c373
-rw-r--r--deps/fpconv/fpconv_dtoa.h45
-rw-r--r--deps/fpconv/fpconv_powers.h133
-rw-r--r--deps/hdr_histogram/COPYING.txt121
-rw-r--r--deps/hdr_histogram/LICENSE.txt41
-rw-r--r--deps/hdr_histogram/Makefile27
-rw-r--r--deps/hdr_histogram/README.md78
-rw-r--r--deps/hdr_histogram/hdr_atomic.h146
-rw-r--r--deps/hdr_histogram/hdr_histogram.c1229
-rw-r--r--deps/hdr_histogram/hdr_histogram.h521
-rw-r--r--deps/hdr_histogram/hdr_redis_malloc.h13
-rw-r--r--deps/hdr_histogram/hdr_tests.h22
-rw-r--r--deps/hiredis/.github/release-drafter-config.yml49
-rw-r--r--deps/hiredis/.github/workflows/build.yml177
-rw-r--r--deps/hiredis/.github/workflows/release-drafter.yml19
-rw-r--r--deps/hiredis/.github/workflows/test.yml100
-rw-r--r--deps/hiredis/.gitignore9
-rw-r--r--deps/hiredis/.travis.yml125
-rw-r--r--deps/hiredis/CHANGELOG.md580
-rw-r--r--deps/hiredis/CMakeLists.txt237
-rw-r--r--deps/hiredis/COPYING29
-rw-r--r--deps/hiredis/Makefile354
-rw-r--r--deps/hiredis/README.md821
-rw-r--r--deps/hiredis/adapters/ae.h130
-rw-r--r--deps/hiredis/adapters/glib.h156
-rw-r--r--deps/hiredis/adapters/ivykis.h84
-rw-r--r--deps/hiredis/adapters/libev.h188
-rw-r--r--deps/hiredis/adapters/libevent.h175
-rw-r--r--deps/hiredis/adapters/libhv.h123
-rw-r--r--deps/hiredis/adapters/libsdevent.h177
-rw-r--r--deps/hiredis/adapters/libuv.h171
-rw-r--r--deps/hiredis/adapters/macosx.h115
-rw-r--r--deps/hiredis/adapters/poll.h197
-rw-r--r--deps/hiredis/adapters/qt.h135
-rw-r--r--deps/hiredis/adapters/redismoduleapi.h144
-rw-r--r--deps/hiredis/alloc.c90
-rw-r--r--deps/hiredis/alloc.h96
-rw-r--r--deps/hiredis/appveyor.yml24
-rw-r--r--deps/hiredis/async.c1034
-rw-r--r--deps/hiredis/async.h152
-rw-r--r--deps/hiredis/async_private.h75
-rw-r--r--deps/hiredis/dict.c343
-rw-r--r--deps/hiredis/dict.h125
-rw-r--r--deps/hiredis/examples/CMakeLists.txt61
-rw-r--r--deps/hiredis/examples/example-ae.c62
-rw-r--r--deps/hiredis/examples/example-glib.c73
-rw-r--r--deps/hiredis/examples/example-ivykis.c60
-rw-r--r--deps/hiredis/examples/example-libev.c54
-rw-r--r--deps/hiredis/examples/example-libevent-ssl.c90
-rw-r--r--deps/hiredis/examples/example-libevent.c67
-rw-r--r--deps/hiredis/examples/example-libhv.c70
-rw-r--r--deps/hiredis/examples/example-libsdevent.c86
-rw-r--r--deps/hiredis/examples/example-libuv.c81
-rw-r--r--deps/hiredis/examples/example-macosx.c66
-rw-r--r--deps/hiredis/examples/example-poll.c62
-rw-r--r--deps/hiredis/examples/example-push.c159
-rw-r--r--deps/hiredis/examples/example-qt.cpp46
-rw-r--r--deps/hiredis/examples/example-qt.h32
-rw-r--r--deps/hiredis/examples/example-redismoduleapi.c101
-rw-r--r--deps/hiredis/examples/example-ssl.c112
-rw-r--r--deps/hiredis/examples/example.c145
-rw-r--r--deps/hiredis/fmacros.h14
-rw-r--r--deps/hiredis/fuzzing/format_command_fuzzer.c56
-rw-r--r--deps/hiredis/hiredis-config.cmake.in13
-rw-r--r--deps/hiredis/hiredis.c1219
-rw-r--r--deps/hiredis/hiredis.h362
-rw-r--r--deps/hiredis/hiredis.pc.in12
-rw-r--r--deps/hiredis/hiredis.targets11
-rw-r--r--deps/hiredis/hiredis_ssl-config.cmake.in16
-rw-r--r--deps/hiredis/hiredis_ssl.h163
-rw-r--r--deps/hiredis/hiredis_ssl.pc.in13
-rw-r--r--deps/hiredis/net.c672
-rw-r--r--deps/hiredis/net.h57
-rw-r--r--deps/hiredis/read.c788
-rw-r--r--deps/hiredis/read.h129
-rw-r--r--deps/hiredis/sds.c1292
-rw-r--r--deps/hiredis/sds.h280
-rw-r--r--deps/hiredis/sdsalloc.h44
-rw-r--r--deps/hiredis/sdscompat.h94
-rw-r--r--deps/hiredis/sockcompat.c280
-rw-r--r--deps/hiredis/sockcompat.h95
-rw-r--r--deps/hiredis/ssl.c617
-rw-r--r--deps/hiredis/test.c2435
-rwxr-xr-xdeps/hiredis/test.sh112
-rw-r--r--deps/hiredis/win32.h56
-rw-r--r--deps/jemalloc/.appveyor.yml41
-rw-r--r--deps/jemalloc/.autom4te.cfg3
-rw-r--r--deps/jemalloc/.cirrus.yml46
-rw-r--r--deps/jemalloc/.clang-format122
-rw-r--r--deps/jemalloc/.gitattributes1
-rw-r--r--deps/jemalloc/.gitignore100
-rw-r--r--deps/jemalloc/.travis.yml413
-rw-r--r--deps/jemalloc/COPYING27
-rw-r--r--deps/jemalloc/ChangeLog1618
-rw-r--r--deps/jemalloc/INSTALL.md424
-rw-r--r--deps/jemalloc/Makefile.in762
-rw-r--r--deps/jemalloc/README20
-rw-r--r--deps/jemalloc/TUNING.md129
-rw-r--r--deps/jemalloc/VERSION1
-rwxr-xr-xdeps/jemalloc/autogen.sh17
-rw-r--r--deps/jemalloc/bin/jemalloc-config.in83
-rw-r--r--deps/jemalloc/bin/jemalloc.sh.in9
-rw-r--r--deps/jemalloc/bin/jeprof.in5723
-rwxr-xr-xdeps/jemalloc/build-aux/config.guess1701
-rwxr-xr-xdeps/jemalloc/build-aux/config.sub1855
-rwxr-xr-xdeps/jemalloc/build-aux/install-sh250
-rw-r--r--deps/jemalloc/config.stamp.in0
-rwxr-xr-xdeps/jemalloc/configure16792
-rw-r--r--deps/jemalloc/configure.ac2669
-rw-r--r--deps/jemalloc/doc/html.xsl.in5
-rw-r--r--deps/jemalloc/doc/jemalloc.xml.in3763
-rw-r--r--deps/jemalloc/doc/manpages.xsl.in4
-rw-r--r--deps/jemalloc/doc/stylesheet.xsl10
-rw-r--r--deps/jemalloc/doc_internal/PROFILING_INTERNALS.md127
-rw-r--r--deps/jemalloc/doc_internal/jemalloc.svg1
-rw-r--r--deps/jemalloc/include/jemalloc/internal/activity_callback.h23
-rw-r--r--deps/jemalloc/include/jemalloc/internal/arena_externs.h121
-rw-r--r--deps/jemalloc/include/jemalloc/internal/arena_inlines_a.h24
-rw-r--r--deps/jemalloc/include/jemalloc/internal/arena_inlines_b.h550
-rw-r--r--deps/jemalloc/include/jemalloc/internal/arena_stats.h114
-rw-r--r--deps/jemalloc/include/jemalloc/internal/arena_structs.h101
-rw-r--r--deps/jemalloc/include/jemalloc/internal/arena_types.h58
-rw-r--r--deps/jemalloc/include/jemalloc/internal/assert.h56
-rw-r--r--deps/jemalloc/include/jemalloc/internal/atomic.h107
-rw-r--r--deps/jemalloc/include/jemalloc/internal/atomic_c11.h97
-rw-r--r--deps/jemalloc/include/jemalloc/internal/atomic_gcc_atomic.h129
-rw-r--r--deps/jemalloc/include/jemalloc/internal/atomic_gcc_sync.h195
-rw-r--r--deps/jemalloc/include/jemalloc/internal/atomic_msvc.h158
-rw-r--r--deps/jemalloc/include/jemalloc/internal/background_thread_externs.h33
-rw-r--r--deps/jemalloc/include/jemalloc/internal/background_thread_inlines.h48
-rw-r--r--deps/jemalloc/include/jemalloc/internal/background_thread_structs.h66
-rw-r--r--deps/jemalloc/include/jemalloc/internal/base.h110
-rw-r--r--deps/jemalloc/include/jemalloc/internal/bin.h82
-rw-r--r--deps/jemalloc/include/jemalloc/internal/bin_info.h50
-rw-r--r--deps/jemalloc/include/jemalloc/internal/bin_stats.h57
-rw-r--r--deps/jemalloc/include/jemalloc/internal/bin_types.h17
-rw-r--r--deps/jemalloc/include/jemalloc/internal/bit_util.h422
-rw-r--r--deps/jemalloc/include/jemalloc/internal/bitmap.h368
-rw-r--r--deps/jemalloc/include/jemalloc/internal/buf_writer.h32
-rw-r--r--deps/jemalloc/include/jemalloc/internal/cache_bin.h670
-rw-r--r--deps/jemalloc/include/jemalloc/internal/ckh.h101
-rw-r--r--deps/jemalloc/include/jemalloc/internal/counter.h34
-rw-r--r--deps/jemalloc/include/jemalloc/internal/ctl.h159
-rw-r--r--deps/jemalloc/include/jemalloc/internal/decay.h186
-rw-r--r--deps/jemalloc/include/jemalloc/internal/div.h41
-rw-r--r--deps/jemalloc/include/jemalloc/internal/ecache.h55
-rw-r--r--deps/jemalloc/include/jemalloc/internal/edata.h698
-rw-r--r--deps/jemalloc/include/jemalloc/internal/edata_cache.h49
-rw-r--r--deps/jemalloc/include/jemalloc/internal/ehooks.h412
-rw-r--r--deps/jemalloc/include/jemalloc/internal/emap.h357
-rw-r--r--deps/jemalloc/include/jemalloc/internal/emitter.h510
-rw-r--r--deps/jemalloc/include/jemalloc/internal/eset.h77
-rw-r--r--deps/jemalloc/include/jemalloc/internal/exp_grow.h50
-rw-r--r--deps/jemalloc/include/jemalloc/internal/extent.h137
-rw-r--r--deps/jemalloc/include/jemalloc/internal/extent_dss.h26
-rw-r--r--deps/jemalloc/include/jemalloc/internal/extent_mmap.h10
-rw-r--r--deps/jemalloc/include/jemalloc/internal/fb.h373
-rw-r--r--deps/jemalloc/include/jemalloc/internal/fxp.h126
-rw-r--r--deps/jemalloc/include/jemalloc/internal/hash.h320
-rw-r--r--deps/jemalloc/include/jemalloc/internal/hook.h163
-rw-r--r--deps/jemalloc/include/jemalloc/internal/hpa.h182
-rw-r--r--deps/jemalloc/include/jemalloc/internal/hpa_hooks.h17
-rw-r--r--deps/jemalloc/include/jemalloc/internal/hpa_opts.h74
-rw-r--r--deps/jemalloc/include/jemalloc/internal/hpdata.h413
-rw-r--r--deps/jemalloc/include/jemalloc/internal/inspect.h40
-rw-r--r--deps/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h108
-rw-r--r--deps/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h.in427
-rw-r--r--deps/jemalloc/include/jemalloc/internal/jemalloc_internal_externs.h75
-rw-r--r--deps/jemalloc/include/jemalloc/internal/jemalloc_internal_includes.h84
-rw-r--r--deps/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_a.h122
-rw-r--r--deps/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_b.h103
-rw-r--r--deps/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_c.h391
-rw-r--r--deps/jemalloc/include/jemalloc/internal/jemalloc_internal_macros.h111
-rw-r--r--deps/jemalloc/include/jemalloc/internal/jemalloc_internal_types.h130
-rw-r--r--deps/jemalloc/include/jemalloc/internal/jemalloc_preamble.h.in263
-rw-r--r--deps/jemalloc/include/jemalloc/internal/large_externs.h24
-rw-r--r--deps/jemalloc/include/jemalloc/internal/lockedint.h204
-rw-r--r--deps/jemalloc/include/jemalloc/internal/log.h115
-rw-r--r--deps/jemalloc/include/jemalloc/internal/malloc_io.h105
-rw-r--r--deps/jemalloc/include/jemalloc/internal/mpsc_queue.h134
-rw-r--r--deps/jemalloc/include/jemalloc/internal/mutex.h319
-rw-r--r--deps/jemalloc/include/jemalloc/internal/mutex_prof.h117
-rw-r--r--deps/jemalloc/include/jemalloc/internal/nstime.h73
-rw-r--r--deps/jemalloc/include/jemalloc/internal/pa.h243
-rw-r--r--deps/jemalloc/include/jemalloc/internal/pac.h179
-rw-r--r--deps/jemalloc/include/jemalloc/internal/pages.h119
-rw-r--r--deps/jemalloc/include/jemalloc/internal/pai.h95
-rw-r--r--deps/jemalloc/include/jemalloc/internal/peak.h37
-rw-r--r--deps/jemalloc/include/jemalloc/internal/peak_event.h24
-rw-r--r--deps/jemalloc/include/jemalloc/internal/ph.h520
-rwxr-xr-xdeps/jemalloc/include/jemalloc/internal/private_namespace.sh5
-rwxr-xr-xdeps/jemalloc/include/jemalloc/internal/private_symbols.sh51
-rw-r--r--deps/jemalloc/include/jemalloc/internal/prng.h168
-rw-r--r--deps/jemalloc/include/jemalloc/internal/prof_data.h37
-rw-r--r--deps/jemalloc/include/jemalloc/internal/prof_externs.h95
-rw-r--r--deps/jemalloc/include/jemalloc/internal/prof_hook.h21
-rw-r--r--deps/jemalloc/include/jemalloc/internal/prof_inlines.h261
-rw-r--r--deps/jemalloc/include/jemalloc/internal/prof_log.h22
-rw-r--r--deps/jemalloc/include/jemalloc/internal/prof_recent.h23
-rw-r--r--deps/jemalloc/include/jemalloc/internal/prof_stats.h17
-rw-r--r--deps/jemalloc/include/jemalloc/internal/prof_structs.h221
-rw-r--r--deps/jemalloc/include/jemalloc/internal/prof_sys.h30
-rw-r--r--deps/jemalloc/include/jemalloc/internal/prof_types.h75
-rw-r--r--deps/jemalloc/include/jemalloc/internal/psset.h131
-rwxr-xr-xdeps/jemalloc/include/jemalloc/internal/public_namespace.sh6
-rwxr-xr-xdeps/jemalloc/include/jemalloc/internal/public_unnamespace.sh6
-rw-r--r--deps/jemalloc/include/jemalloc/internal/ql.h197
-rw-r--r--deps/jemalloc/include/jemalloc/internal/qr.h140
-rw-r--r--deps/jemalloc/include/jemalloc/internal/quantum.h87
-rw-r--r--deps/jemalloc/include/jemalloc/internal/rb.h1856
-rw-r--r--deps/jemalloc/include/jemalloc/internal/rtree.h554
-rw-r--r--deps/jemalloc/include/jemalloc/internal/rtree_tsd.h62
-rw-r--r--deps/jemalloc/include/jemalloc/internal/safety_check.h31
-rw-r--r--deps/jemalloc/include/jemalloc/internal/san.h191
-rw-r--r--deps/jemalloc/include/jemalloc/internal/san_bump.h52
-rw-r--r--deps/jemalloc/include/jemalloc/internal/sc.h357
-rw-r--r--deps/jemalloc/include/jemalloc/internal/sec.h120
-rw-r--r--deps/jemalloc/include/jemalloc/internal/sec_opts.h59
-rw-r--r--deps/jemalloc/include/jemalloc/internal/seq.h55
-rw-r--r--deps/jemalloc/include/jemalloc/internal/slab_data.h12
-rw-r--r--deps/jemalloc/include/jemalloc/internal/smoothstep.h232
-rwxr-xr-xdeps/jemalloc/include/jemalloc/internal/smoothstep.sh101
-rw-r--r--deps/jemalloc/include/jemalloc/internal/spin.h40
-rw-r--r--deps/jemalloc/include/jemalloc/internal/stats.h54
-rw-r--r--deps/jemalloc/include/jemalloc/internal/sz.h371
-rw-r--r--deps/jemalloc/include/jemalloc/internal/tcache_externs.h75
-rw-r--r--deps/jemalloc/include/jemalloc/internal/tcache_inlines.h193
-rw-r--r--deps/jemalloc/include/jemalloc/internal/tcache_structs.h68
-rw-r--r--deps/jemalloc/include/jemalloc/internal/tcache_types.h35
-rw-r--r--deps/jemalloc/include/jemalloc/internal/test_hooks.h24
-rw-r--r--deps/jemalloc/include/jemalloc/internal/thread_event.h301
-rw-r--r--deps/jemalloc/include/jemalloc/internal/ticker.h175
-rw-r--r--deps/jemalloc/include/jemalloc/internal/tsd.h518
-rw-r--r--deps/jemalloc/include/jemalloc/internal/tsd_generic.h182
-rw-r--r--deps/jemalloc/include/jemalloc/internal/tsd_malloc_thread_cleanup.h61
-rw-r--r--deps/jemalloc/include/jemalloc/internal/tsd_tls.h60
-rw-r--r--deps/jemalloc/include/jemalloc/internal/tsd_types.h10
-rw-r--r--deps/jemalloc/include/jemalloc/internal/tsd_win.h139
-rw-r--r--deps/jemalloc/include/jemalloc/internal/typed_list.h55
-rw-r--r--deps/jemalloc/include/jemalloc/internal/util.h123
-rw-r--r--deps/jemalloc/include/jemalloc/internal/witness.h378
-rwxr-xr-xdeps/jemalloc/include/jemalloc/jemalloc.sh27
-rw-r--r--deps/jemalloc/include/jemalloc/jemalloc_defs.h.in54
-rw-r--r--deps/jemalloc/include/jemalloc/jemalloc_macros.h.in153
-rwxr-xr-xdeps/jemalloc/include/jemalloc/jemalloc_mangle.sh45
-rw-r--r--deps/jemalloc/include/jemalloc/jemalloc_protos.h.in71
-rwxr-xr-xdeps/jemalloc/include/jemalloc/jemalloc_rename.sh22
-rw-r--r--deps/jemalloc/include/jemalloc/jemalloc_typedefs.h.in77
-rw-r--r--deps/jemalloc/include/msvc_compat/C99/stdbool.h20
-rw-r--r--deps/jemalloc/include/msvc_compat/C99/stdint.h247
-rw-r--r--deps/jemalloc/include/msvc_compat/strings.h58
-rw-r--r--deps/jemalloc/include/msvc_compat/windows_extra.h6
-rw-r--r--deps/jemalloc/jemalloc.pc.in12
-rw-r--r--deps/jemalloc/m4/ax_cxx_compile_stdcxx.m4951
-rw-r--r--deps/jemalloc/msvc/ReadMe.txt23
-rw-r--r--deps/jemalloc/msvc/jemalloc_vc2015.sln63
-rw-r--r--deps/jemalloc/msvc/jemalloc_vc2017.sln63
-rw-r--r--deps/jemalloc/msvc/projects/vc2015/jemalloc/jemalloc.vcxproj380
-rw-r--r--deps/jemalloc/msvc/projects/vc2015/jemalloc/jemalloc.vcxproj.filters197
-rw-r--r--deps/jemalloc/msvc/projects/vc2015/test_threads/test_threads.vcxproj327
-rw-r--r--deps/jemalloc/msvc/projects/vc2015/test_threads/test_threads.vcxproj.filters26
-rw-r--r--deps/jemalloc/msvc/projects/vc2017/jemalloc/jemalloc.vcxproj379
-rw-r--r--deps/jemalloc/msvc/projects/vc2017/jemalloc/jemalloc.vcxproj.filters197
-rw-r--r--deps/jemalloc/msvc/projects/vc2017/test_threads/test_threads.vcxproj326
-rw-r--r--deps/jemalloc/msvc/projects/vc2017/test_threads/test_threads.vcxproj.filters26
-rw-r--r--deps/jemalloc/msvc/test_threads/test_threads.cpp89
-rw-r--r--deps/jemalloc/msvc/test_threads/test_threads.h3
-rw-r--r--deps/jemalloc/msvc/test_threads/test_threads_main.cpp11
-rwxr-xr-xdeps/jemalloc/run_tests.sh1
-rwxr-xr-xdeps/jemalloc/scripts/check-formatting.sh28
-rw-r--r--deps/jemalloc/scripts/freebsd/before_install.sh3
-rw-r--r--deps/jemalloc/scripts/freebsd/before_script.sh10
-rw-r--r--deps/jemalloc/scripts/freebsd/script.sh3
-rwxr-xr-xdeps/jemalloc/scripts/gen_run_tests.py130
-rwxr-xr-xdeps/jemalloc/scripts/gen_travis.py327
-rw-r--r--deps/jemalloc/scripts/linux/before_install.sh13
-rw-r--r--deps/jemalloc/scripts/windows/before_install.sh83
-rw-r--r--deps/jemalloc/scripts/windows/before_script.sh20
-rw-r--r--deps/jemalloc/scripts/windows/script.sh10
-rw-r--r--deps/jemalloc/src/arena.c1891
-rw-r--r--deps/jemalloc/src/background_thread.c820
-rw-r--r--deps/jemalloc/src/base.c529
-rw-r--r--deps/jemalloc/src/bin.c69
-rw-r--r--deps/jemalloc/src/bin_info.c30
-rw-r--r--deps/jemalloc/src/bitmap.c120
-rw-r--r--deps/jemalloc/src/buf_writer.c144
-rw-r--r--deps/jemalloc/src/cache_bin.c99
-rw-r--r--deps/jemalloc/src/ckh.c569
-rw-r--r--deps/jemalloc/src/counter.c30
-rw-r--r--deps/jemalloc/src/ctl.c4414
-rw-r--r--deps/jemalloc/src/decay.c295
-rw-r--r--deps/jemalloc/src/div.c55
-rw-r--r--deps/jemalloc/src/ecache.c35
-rw-r--r--deps/jemalloc/src/edata.c6
-rw-r--r--deps/jemalloc/src/edata_cache.c154
-rw-r--r--deps/jemalloc/src/ehooks.c275
-rw-r--r--deps/jemalloc/src/emap.c386
-rw-r--r--deps/jemalloc/src/eset.c282
-rw-r--r--deps/jemalloc/src/exp_grow.c8
-rw-r--r--deps/jemalloc/src/extent.c1326
-rw-r--r--deps/jemalloc/src/extent_dss.c277
-rw-r--r--deps/jemalloc/src/extent_mmap.c41
-rw-r--r--deps/jemalloc/src/fxp.c124
-rw-r--r--deps/jemalloc/src/hook.c195
-rw-r--r--deps/jemalloc/src/hpa.c1044
-rw-r--r--deps/jemalloc/src/hpa_hooks.c63
-rw-r--r--deps/jemalloc/src/hpdata.c325
-rw-r--r--deps/jemalloc/src/inspect.c77
-rw-r--r--deps/jemalloc/src/jemalloc.c4485
-rw-r--r--deps/jemalloc/src/jemalloc_cpp.cpp254
-rw-r--r--deps/jemalloc/src/large.c322
-rw-r--r--deps/jemalloc/src/log.c78
-rw-r--r--deps/jemalloc/src/malloc_io.c697
-rw-r--r--deps/jemalloc/src/mutex.c228
-rw-r--r--deps/jemalloc/src/nstime.c289
-rw-r--r--deps/jemalloc/src/pa.c277
-rw-r--r--deps/jemalloc/src/pa_extra.c191
-rw-r--r--deps/jemalloc/src/pac.c587
-rw-r--r--deps/jemalloc/src/pages.c824
-rw-r--r--deps/jemalloc/src/pai.c31
-rw-r--r--deps/jemalloc/src/peak_event.c82
-rw-r--r--deps/jemalloc/src/prof.c789
-rw-r--r--deps/jemalloc/src/prof_data.c1447
-rw-r--r--deps/jemalloc/src/prof_log.c717
-rw-r--r--deps/jemalloc/src/prof_recent.c600
-rw-r--r--deps/jemalloc/src/prof_stats.c57
-rw-r--r--deps/jemalloc/src/prof_sys.c669
-rw-r--r--deps/jemalloc/src/psset.c385
-rw-r--r--deps/jemalloc/src/rtree.c261
-rw-r--r--deps/jemalloc/src/safety_check.c36
-rw-r--r--deps/jemalloc/src/san.c208
-rw-r--r--deps/jemalloc/src/san_bump.c104
-rw-r--r--deps/jemalloc/src/sc.c306
-rw-r--r--deps/jemalloc/src/sec.c422
-rw-r--r--deps/jemalloc/src/stats.c1973
-rw-r--r--deps/jemalloc/src/sz.c114
-rw-r--r--deps/jemalloc/src/tcache.c1101
-rw-r--r--deps/jemalloc/src/test_hooks.c12
-rw-r--r--deps/jemalloc/src/thread_event.c343
-rw-r--r--deps/jemalloc/src/ticker.c32
-rwxr-xr-xdeps/jemalloc/src/ticker.py15
-rw-r--r--deps/jemalloc/src/tsd.c549
-rw-r--r--deps/jemalloc/src/witness.c122
-rw-r--r--deps/jemalloc/src/zone.c469
-rw-r--r--deps/jemalloc/test/analyze/prof_bias.c60
-rw-r--r--deps/jemalloc/test/analyze/rand.c276
-rw-r--r--deps/jemalloc/test/analyze/sizes.c53
-rw-r--r--deps/jemalloc/test/include/test/SFMT-alti.h186
-rw-r--r--deps/jemalloc/test/include/test/SFMT-params.h132
-rw-r--r--deps/jemalloc/test/include/test/SFMT-params11213.h81
-rw-r--r--deps/jemalloc/test/include/test/SFMT-params1279.h81
-rw-r--r--deps/jemalloc/test/include/test/SFMT-params132049.h81
-rw-r--r--deps/jemalloc/test/include/test/SFMT-params19937.h81
-rw-r--r--deps/jemalloc/test/include/test/SFMT-params216091.h81
-rw-r--r--deps/jemalloc/test/include/test/SFMT-params2281.h81
-rw-r--r--deps/jemalloc/test/include/test/SFMT-params4253.h81
-rw-r--r--deps/jemalloc/test/include/test/SFMT-params44497.h81
-rw-r--r--deps/jemalloc/test/include/test/SFMT-params607.h81
-rw-r--r--deps/jemalloc/test/include/test/SFMT-params86243.h81
-rw-r--r--deps/jemalloc/test/include/test/SFMT-sse2.h157
-rw-r--r--deps/jemalloc/test/include/test/SFMT.h146
-rw-r--r--deps/jemalloc/test/include/test/arena_util.h155
-rw-r--r--deps/jemalloc/test/include/test/bench.h60
-rw-r--r--deps/jemalloc/test/include/test/bgthd.h17
-rw-r--r--deps/jemalloc/test/include/test/btalloc.h30
-rw-r--r--deps/jemalloc/test/include/test/extent_hooks.h289
-rw-r--r--deps/jemalloc/test/include/test/jemalloc_test.h.in180
-rw-r--r--deps/jemalloc/test/include/test/jemalloc_test_defs.h.in9
-rw-r--r--deps/jemalloc/test/include/test/math.h306
-rw-r--r--deps/jemalloc/test/include/test/mq.h107
-rw-r--r--deps/jemalloc/test/include/test/mtx.h21
-rw-r--r--deps/jemalloc/test/include/test/nbits.h111
-rw-r--r--deps/jemalloc/test/include/test/san.h14
-rw-r--r--deps/jemalloc/test/include/test/sleep.h1
-rw-r--r--deps/jemalloc/test/include/test/test.h583
-rw-r--r--deps/jemalloc/test/include/test/thd.h9
-rw-r--r--deps/jemalloc/test/include/test/timer.h11
-rw-r--r--deps/jemalloc/test/integration/MALLOCX_ARENA.c66
-rw-r--r--deps/jemalloc/test/integration/aligned_alloc.c157
-rw-r--r--deps/jemalloc/test/integration/allocated.c124
-rw-r--r--deps/jemalloc/test/integration/cpp/basic.cpp24
-rw-r--r--deps/jemalloc/test/integration/cpp/infallible_new_false.cpp23
-rw-r--r--deps/jemalloc/test/integration/cpp/infallible_new_false.sh8
-rw-r--r--deps/jemalloc/test/integration/cpp/infallible_new_true.cpp67
-rw-r--r--deps/jemalloc/test/integration/cpp/infallible_new_true.sh8
-rw-r--r--deps/jemalloc/test/integration/extent.c287
-rw-r--r--deps/jemalloc/test/integration/extent.sh5
-rw-r--r--deps/jemalloc/test/integration/malloc.c16
-rw-r--r--deps/jemalloc/test/integration/mallocx.c274
-rw-r--r--deps/jemalloc/test/integration/mallocx.sh5
-rw-r--r--deps/jemalloc/test/integration/overflow.c59
-rw-r--r--deps/jemalloc/test/integration/posix_memalign.c128
-rw-r--r--deps/jemalloc/test/integration/rallocx.c308
-rw-r--r--deps/jemalloc/test/integration/sdallocx.c55
-rw-r--r--deps/jemalloc/test/integration/slab_sizes.c80
-rw-r--r--deps/jemalloc/test/integration/slab_sizes.sh4
-rw-r--r--deps/jemalloc/test/integration/smallocx.c312
-rw-r--r--deps/jemalloc/test/integration/smallocx.sh5
-rw-r--r--deps/jemalloc/test/integration/thread_arena.c86
-rw-r--r--deps/jemalloc/test/integration/thread_tcache_enabled.c87
-rw-r--r--deps/jemalloc/test/integration/xallocx.c384
-rw-r--r--deps/jemalloc/test/integration/xallocx.sh5
-rw-r--r--deps/jemalloc/test/src/SFMT.c719
-rw-r--r--deps/jemalloc/test/src/btalloc.c6
-rw-r--r--deps/jemalloc/test/src/btalloc_0.c3
-rw-r--r--deps/jemalloc/test/src/btalloc_1.c3
-rw-r--r--deps/jemalloc/test/src/math.c2
-rw-r--r--deps/jemalloc/test/src/mtx.c61
-rw-r--r--deps/jemalloc/test/src/sleep.c27
-rw-r--r--deps/jemalloc/test/src/test.c234
-rw-r--r--deps/jemalloc/test/src/thd.c34
-rw-r--r--deps/jemalloc/test/src/timer.c55
-rw-r--r--deps/jemalloc/test/stress/batch_alloc.c198
-rw-r--r--deps/jemalloc/test/stress/fill_flush.c76
-rw-r--r--deps/jemalloc/test/stress/hookbench.c73
-rw-r--r--deps/jemalloc/test/stress/large_microbench.c33
-rw-r--r--deps/jemalloc/test/stress/mallctl.c74
-rw-r--r--deps/jemalloc/test/stress/microbench.c126
-rw-r--r--deps/jemalloc/test/test.sh.in80
-rw-r--r--deps/jemalloc/test/unit/SFMT.c1599
-rw-r--r--deps/jemalloc/test/unit/a0.c16
-rw-r--r--deps/jemalloc/test/unit/arena_decay.c436
-rw-r--r--deps/jemalloc/test/unit/arena_decay.sh3
-rw-r--r--deps/jemalloc/test/unit/arena_reset.c361
-rw-r--r--deps/jemalloc/test/unit/arena_reset_prof.c4
-rw-r--r--deps/jemalloc/test/unit/arena_reset_prof.sh3
-rw-r--r--deps/jemalloc/test/unit/atomic.c229
-rw-r--r--deps/jemalloc/test/unit/background_thread.c118
-rw-r--r--deps/jemalloc/test/unit/background_thread_enable.c96
-rw-r--r--deps/jemalloc/test/unit/base.c265
-rw-r--r--deps/jemalloc/test/unit/batch_alloc.c189
-rw-r--r--deps/jemalloc/test/unit/batch_alloc.sh3
-rw-r--r--deps/jemalloc/test/unit/batch_alloc_prof.c1
-rw-r--r--deps/jemalloc/test/unit/batch_alloc_prof.sh3
-rw-r--r--deps/jemalloc/test/unit/binshard.c154
-rw-r--r--deps/jemalloc/test/unit/binshard.sh3
-rw-r--r--deps/jemalloc/test/unit/bit_util.c307
-rw-r--r--deps/jemalloc/test/unit/bitmap.c343
-rw-r--r--deps/jemalloc/test/unit/buf_writer.c196
-rw-r--r--deps/jemalloc/test/unit/cache_bin.c384
-rw-r--r--deps/jemalloc/test/unit/ckh.c211
-rw-r--r--deps/jemalloc/test/unit/counter.c80
-rw-r--r--deps/jemalloc/test/unit/decay.c283
-rw-r--r--deps/jemalloc/test/unit/div.c29
-rw-r--r--deps/jemalloc/test/unit/double_free.c77
-rw-r--r--deps/jemalloc/test/unit/double_free.h1
-rw-r--r--deps/jemalloc/test/unit/edata_cache.c226
-rw-r--r--deps/jemalloc/test/unit/emitter.c533
-rw-r--r--deps/jemalloc/test/unit/extent_quantize.c141
-rw-r--r--deps/jemalloc/test/unit/fb.c954
-rw-r--r--deps/jemalloc/test/unit/fork.c141
-rw-r--r--deps/jemalloc/test/unit/fxp.c394
-rw-r--r--deps/jemalloc/test/unit/hash.c173
-rw-r--r--deps/jemalloc/test/unit/hook.c586
-rw-r--r--deps/jemalloc/test/unit/hpa.c459
-rw-r--r--deps/jemalloc/test/unit/hpa_background_thread.c188
-rw-r--r--deps/jemalloc/test/unit/hpa_background_thread.sh4
-rw-r--r--deps/jemalloc/test/unit/hpdata.c244
-rw-r--r--deps/jemalloc/test/unit/huge.c108
-rw-r--r--deps/jemalloc/test/unit/inspect.c278
-rw-r--r--deps/jemalloc/test/unit/inspect.sh5
-rw-r--r--deps/jemalloc/test/unit/junk.c195
-rw-r--r--deps/jemalloc/test/unit/junk.sh5
-rw-r--r--deps/jemalloc/test/unit/junk_alloc.c1
-rw-r--r--deps/jemalloc/test/unit/junk_alloc.sh5
-rw-r--r--deps/jemalloc/test/unit/junk_free.c1
-rw-r--r--deps/jemalloc/test/unit/junk_free.sh5
-rw-r--r--deps/jemalloc/test/unit/log.c198
-rw-r--r--deps/jemalloc/test/unit/mallctl.c1274
-rw-r--r--deps/jemalloc/test/unit/malloc_conf_2.c29
-rw-r--r--deps/jemalloc/test/unit/malloc_conf_2.sh1
-rw-r--r--deps/jemalloc/test/unit/malloc_io.c268
-rw-r--r--deps/jemalloc/test/unit/math.c390
-rw-r--r--deps/jemalloc/test/unit/mpsc_queue.c304
-rw-r--r--deps/jemalloc/test/unit/mq.c89
-rw-r--r--deps/jemalloc/test/unit/mtx.c57
-rw-r--r--deps/jemalloc/test/unit/nstime.c252
-rw-r--r--deps/jemalloc/test/unit/oversize_threshold.c133
-rw-r--r--deps/jemalloc/test/unit/pa.c126
-rw-r--r--deps/jemalloc/test/unit/pack.c166
-rw-r--r--deps/jemalloc/test/unit/pack.sh4
-rw-r--r--deps/jemalloc/test/unit/pages.c29
-rw-r--r--deps/jemalloc/test/unit/peak.c47
-rw-r--r--deps/jemalloc/test/unit/ph.c330
-rw-r--r--deps/jemalloc/test/unit/prng.c189
-rw-r--r--deps/jemalloc/test/unit/prof_accum.c84
-rw-r--r--deps/jemalloc/test/unit/prof_accum.sh5
-rw-r--r--deps/jemalloc/test/unit/prof_active.c119
-rw-r--r--deps/jemalloc/test/unit/prof_active.sh5
-rw-r--r--deps/jemalloc/test/unit/prof_gdump.c77
-rw-r--r--deps/jemalloc/test/unit/prof_gdump.sh6
-rw-r--r--deps/jemalloc/test/unit/prof_hook.c169
-rw-r--r--deps/jemalloc/test/unit/prof_hook.sh6
-rw-r--r--deps/jemalloc/test/unit/prof_idump.c57
-rw-r--r--deps/jemalloc/test/unit/prof_idump.sh8
-rw-r--r--deps/jemalloc/test/unit/prof_log.c151
-rw-r--r--deps/jemalloc/test/unit/prof_log.sh5
-rw-r--r--deps/jemalloc/test/unit/prof_mdump.c216
-rw-r--r--deps/jemalloc/test/unit/prof_mdump.sh6
-rw-r--r--deps/jemalloc/test/unit/prof_recent.c678
-rw-r--r--deps/jemalloc/test/unit/prof_recent.sh5
-rw-r--r--deps/jemalloc/test/unit/prof_reset.c266
-rw-r--r--deps/jemalloc/test/unit/prof_reset.sh5
-rw-r--r--deps/jemalloc/test/unit/prof_stats.c151
-rw-r--r--deps/jemalloc/test/unit/prof_stats.sh5
-rw-r--r--deps/jemalloc/test/unit/prof_sys_thread_name.c77
-rw-r--r--deps/jemalloc/test/unit/prof_sys_thread_name.sh5
-rw-r--r--deps/jemalloc/test/unit/prof_tctx.c48
-rw-r--r--deps/jemalloc/test/unit/prof_tctx.sh5
-rw-r--r--deps/jemalloc/test/unit/prof_thread_name.c122
-rw-r--r--deps/jemalloc/test/unit/prof_thread_name.sh5
-rw-r--r--deps/jemalloc/test/unit/psset.c748
-rw-r--r--deps/jemalloc/test/unit/ql.c317
-rw-r--r--deps/jemalloc/test/unit/qr.c243
-rw-r--r--deps/jemalloc/test/unit/rb.c1019
-rw-r--r--deps/jemalloc/test/unit/retained.c188
-rw-r--r--deps/jemalloc/test/unit/rtree.c289
-rw-r--r--deps/jemalloc/test/unit/safety_check.c163
-rw-r--r--deps/jemalloc/test/unit/safety_check.sh5
-rw-r--r--deps/jemalloc/test/unit/san.c207
-rw-r--r--deps/jemalloc/test/unit/san.sh3
-rw-r--r--deps/jemalloc/test/unit/san_bump.c111
-rw-r--r--deps/jemalloc/test/unit/sc.c33
-rw-r--r--deps/jemalloc/test/unit/sec.c634
-rw-r--r--deps/jemalloc/test/unit/seq.c95
-rw-r--r--deps/jemalloc/test/unit/size_check.c79
-rw-r--r--deps/jemalloc/test/unit/size_check.sh5
-rw-r--r--deps/jemalloc/test/unit/size_classes.c188
-rw-r--r--deps/jemalloc/test/unit/slab.c39
-rw-r--r--deps/jemalloc/test/unit/smoothstep.c102
-rw-r--r--deps/jemalloc/test/unit/spin.c18
-rw-r--r--deps/jemalloc/test/unit/stats.c431
-rw-r--r--deps/jemalloc/test/unit/stats_print.c999
-rw-r--r--deps/jemalloc/test/unit/sz.c66
-rw-r--r--deps/jemalloc/test/unit/tcache_max.c175
-rw-r--r--deps/jemalloc/test/unit/tcache_max.sh3
-rw-r--r--deps/jemalloc/test/unit/test_hooks.c38
-rw-r--r--deps/jemalloc/test/unit/thread_event.c34
-rw-r--r--deps/jemalloc/test/unit/thread_event.sh5
-rw-r--r--deps/jemalloc/test/unit/ticker.c100
-rw-r--r--deps/jemalloc/test/unit/tsd.c274
-rw-r--r--deps/jemalloc/test/unit/uaf.c262
-rw-r--r--deps/jemalloc/test/unit/witness.c280
-rw-r--r--deps/jemalloc/test/unit/zero.c59
-rw-r--r--deps/jemalloc/test/unit/zero.sh5
-rw-r--r--deps/jemalloc/test/unit/zero_realloc_abort.c26
-rw-r--r--deps/jemalloc/test/unit/zero_realloc_abort.sh3
-rw-r--r--deps/jemalloc/test/unit/zero_realloc_alloc.c48
-rw-r--r--deps/jemalloc/test/unit/zero_realloc_alloc.sh3
-rw-r--r--deps/jemalloc/test/unit/zero_realloc_free.c33
-rw-r--r--deps/jemalloc/test/unit/zero_realloc_free.sh3
-rw-r--r--deps/jemalloc/test/unit/zero_reallocs.c40
-rw-r--r--deps/jemalloc/test/unit/zero_reallocs.sh3
-rw-r--r--deps/linenoise/.gitignore3
-rw-r--r--deps/linenoise/Makefile21
-rw-r--r--deps/linenoise/README.markdown247
-rw-r--r--deps/linenoise/example.c79
-rw-r--r--deps/linenoise/linenoise.c1230
-rw-r--r--deps/linenoise/linenoise.h75
-rw-r--r--deps/lua/COPYRIGHT34
-rw-r--r--deps/lua/HISTORY183
-rw-r--r--deps/lua/INSTALL99
-rw-r--r--deps/lua/Makefile128
-rw-r--r--deps/lua/README37
-rw-r--r--deps/lua/doc/contents.html497
-rw-r--r--deps/lua/doc/cover.pngbin0 -> 3305 bytes
-rw-r--r--deps/lua/doc/logo.gifbin0 -> 4232 bytes
-rw-r--r--deps/lua/doc/lua.1163
-rw-r--r--deps/lua/doc/lua.css83
-rw-r--r--deps/lua/doc/lua.html172
-rw-r--r--deps/lua/doc/luac.1136
-rw-r--r--deps/lua/doc/luac.html145
-rw-r--r--deps/lua/doc/manual.css24
-rw-r--r--deps/lua/doc/manual.html8804
-rw-r--r--deps/lua/doc/readme.html40
-rw-r--r--deps/lua/etc/Makefile44
-rw-r--r--deps/lua/etc/README37
-rw-r--r--deps/lua/etc/all.c38
-rw-r--r--deps/lua/etc/lua.hpp9
-rw-r--r--deps/lua/etc/lua.icobin0 -> 1078 bytes
-rw-r--r--deps/lua/etc/lua.pc31
-rw-r--r--deps/lua/etc/luavs.bat28
-rw-r--r--deps/lua/etc/min.c39
-rw-r--r--deps/lua/etc/noparser.c50
-rw-r--r--deps/lua/etc/strict.lua41
-rw-r--r--deps/lua/src/Makefile183
-rw-r--r--deps/lua/src/fpconv.c205
-rw-r--r--deps/lua/src/fpconv.h22
-rw-r--r--deps/lua/src/lapi.c1109
-rw-r--r--deps/lua/src/lapi.h16
-rw-r--r--deps/lua/src/lauxlib.c652
-rw-r--r--deps/lua/src/lauxlib.h174
-rw-r--r--deps/lua/src/lbaselib.c653
-rw-r--r--deps/lua/src/lcode.c831
-rw-r--r--deps/lua/src/lcode.h76
-rw-r--r--deps/lua/src/ldblib.c398
-rw-r--r--deps/lua/src/ldebug.c637
-rw-r--r--deps/lua/src/ldebug.h33
-rw-r--r--deps/lua/src/ldo.c519
-rw-r--r--deps/lua/src/ldo.h57
-rw-r--r--deps/lua/src/ldump.c164
-rw-r--r--deps/lua/src/lfunc.c174
-rw-r--r--deps/lua/src/lfunc.h34
-rw-r--r--deps/lua/src/lgc.c710
-rw-r--r--deps/lua/src/lgc.h110
-rw-r--r--deps/lua/src/linit.c38
-rw-r--r--deps/lua/src/liolib.c556
-rw-r--r--deps/lua/src/llex.c463
-rw-r--r--deps/lua/src/llex.h81
-rw-r--r--deps/lua/src/llimits.h128
-rw-r--r--deps/lua/src/lmathlib.c263
-rw-r--r--deps/lua/src/lmem.c86
-rw-r--r--deps/lua/src/lmem.h49
-rw-r--r--deps/lua/src/loadlib.c666
-rw-r--r--deps/lua/src/lobject.c214
-rw-r--r--deps/lua/src/lobject.h382
-rw-r--r--deps/lua/src/lopcodes.c102
-rw-r--r--deps/lua/src/lopcodes.h268
-rw-r--r--deps/lua/src/loslib.c243
-rw-r--r--deps/lua/src/lparser.c1339
-rw-r--r--deps/lua/src/lparser.h82
-rw-r--r--deps/lua/src/lstate.c214
-rw-r--r--deps/lua/src/lstate.h169
-rw-r--r--deps/lua/src/lstring.c111
-rw-r--r--deps/lua/src/lstring.h31
-rw-r--r--deps/lua/src/lstrlib.c871
-rw-r--r--deps/lua/src/ltable.c589
-rw-r--r--deps/lua/src/ltable.h40
-rw-r--r--deps/lua/src/ltablib.c287
-rw-r--r--deps/lua/src/ltm.c75
-rw-r--r--deps/lua/src/ltm.h54
-rw-r--r--deps/lua/src/lua.c392
-rw-r--r--deps/lua/src/lua.h391
-rw-r--r--deps/lua/src/lua_bit.c190
-rw-r--r--deps/lua/src/lua_cjson.c1429
-rw-r--r--deps/lua/src/lua_cmsgpack.c981
-rw-r--r--deps/lua/src/lua_struct.c429
-rw-r--r--deps/lua/src/luac.c200
-rw-r--r--deps/lua/src/luaconf.h763
-rw-r--r--deps/lua/src/lualib.h53
-rw-r--r--deps/lua/src/lundump.c227
-rw-r--r--deps/lua/src/lundump.h36
-rw-r--r--deps/lua/src/lvm.c769
-rw-r--r--deps/lua/src/lvm.h36
-rw-r--r--deps/lua/src/lzio.c82
-rw-r--r--deps/lua/src/lzio.h67
-rw-r--r--deps/lua/src/print.c227
-rw-r--r--deps/lua/src/strbuf.c197
-rw-r--r--deps/lua/src/strbuf.h146
-rw-r--r--deps/lua/test/README26
-rw-r--r--deps/lua/test/bisect.lua27
-rw-r--r--deps/lua/test/cf.lua16
-rw-r--r--deps/lua/test/echo.lua5
-rw-r--r--deps/lua/test/env.lua7
-rw-r--r--deps/lua/test/factorial.lua32
-rw-r--r--deps/lua/test/fib.lua40
-rw-r--r--deps/lua/test/fibfor.lua13
-rw-r--r--deps/lua/test/globals.lua13
-rw-r--r--deps/lua/test/hello.lua3
-rw-r--r--deps/lua/test/life.lua111
-rw-r--r--deps/lua/test/luac.lua7
-rw-r--r--deps/lua/test/printf.lua7
-rw-r--r--deps/lua/test/readonly.lua12
-rw-r--r--deps/lua/test/sieve.lua29
-rw-r--r--deps/lua/test/sort.lua66
-rw-r--r--deps/lua/test/table.lua12
-rw-r--r--deps/lua/test/trace-calls.lua32
-rw-r--r--deps/lua/test/trace-globals.lua38
-rw-r--r--deps/lua/test/xd.lua14
-rw-r--r--redis.conf2295
-rwxr-xr-xruntest14
-rwxr-xr-xruntest-cluster14
-rwxr-xr-xruntest-moduleapi58
-rwxr-xr-xruntest-sentinel14
-rw-r--r--sentinel.conf361
-rw-r--r--src/.gitignore5
-rw-r--r--src/Makefile514
-rw-r--r--src/acl.c3150
-rw-r--r--src/adlist.c417
-rw-r--r--src/adlist.h100
-rw-r--r--src/ae.c512
-rw-r--r--src/ae.h136
-rw-r--r--src/ae_epoll.c139
-rw-r--r--src/ae_evport.c321
-rw-r--r--src/ae_kqueue.c190
-rw-r--r--src/ae_select.c110
-rw-r--r--src/anet.c706
-rw-r--r--src/anet.h75
-rw-r--r--src/aof.c2742
-rw-r--r--src/asciilogo.h47
-rw-r--r--src/atomicvar.h158
-rw-r--r--src/bio.c345
-rw-r--r--src/bio.h54
-rw-r--r--src/bitops.c1267
-rw-r--r--src/blocked.c763
-rw-r--r--src/call_reply.c560
-rw-r--r--src/call_reply.h60
-rw-r--r--src/childinfo.c183
-rw-r--r--src/cli_commands.c13
-rw-r--r--src/cli_commands.h46
-rw-r--r--src/cli_common.c408
-rw-r--r--src/cli_common.h54
-rw-r--r--src/cluster.c7717
-rw-r--r--src/cluster.h447
-rw-r--r--src/commands.c13
-rw-r--r--src/commands.def10899
-rw-r--r--src/commands.h40
-rw-r--r--src/commands/acl-cat.json42
-rw-r--r--src/commands/acl-deluser.json33
-rw-r--r--src/commands/acl-dryrun.json47
-rw-r--r--src/commands/acl-genpass.json28
-rw-r--r--src/commands/acl-getuser.json91
-rw-r--r--src/commands/acl-help.json23
-rw-r--r--src/commands/acl-list.json25
-rw-r--r--src/commands/acl-load.json21
-rw-r--r--src/commands/acl-log.json90
-rw-r--r--src/commands/acl-save.json25
-rw-r--r--src/commands/acl-setuser.json47
-rw-r--r--src/commands/acl-users.json25
-rw-r--r--src/commands/acl-whoami.json21
-rw-r--r--src/commands/acl.json12
-rw-r--r--src/commands/append.json53
-rw-r--r--src/commands/asking.json19
-rw-r--r--src/commands/auth.json43
-rw-r--r--src/commands/bgrewriteaof.json19
-rw-r--r--src/commands/bgsave.json40
-rw-r--r--src/commands/bitcount.json87
-rw-r--r--src/commands/bitfield.json159
-rw-r--r--src/commands/bitfield_ro.json69
-rw-r--r--src/commands/bitop.json99
-rw-r--r--src/commands/bitpos.json106
-rw-r--r--src/commands/blmove.json117
-rw-r--r--src/commands/blmpop.json105
-rw-r--r--src/commands/blpop.json80
-rw-r--r--src/commands/brpop.json79
-rw-r--r--src/commands/brpoplpush.json96
-rw-r--r--src/commands/bzmpop.json117
-rw-r--r--src/commands/bzpopmax.json85
-rw-r--r--src/commands/bzpopmin.json85
-rw-r--r--src/commands/client-caching.json41
-rw-r--r--src/commands/client-getname.json32
-rw-r--r--src/commands/client-getredir.json37
-rw-r--r--src/commands/client-help.json26
-rw-r--r--src/commands/client-id.json24
-rw-r--r--src/commands/client-info.json27
-rw-r--r--src/commands/client-kill.json159
-rw-r--r--src/commands/client-list.json93
-rw-r--r--src/commands/client-no-evict.json42
-rw-r--r--src/commands/client-no-touch.json40
-rw-r--r--src/commands/client-pause.json54
-rw-r--r--src/commands/client-reply.json47
-rw-r--r--src/commands/client-setinfo.json45
-rw-r--r--src/commands/client-setname.json33
-rw-r--r--src/commands/client-tracking.json80
-rw-r--r--src/commands/client-trackinginfo.json80
-rw-r--r--src/commands/client-unblock.json56
-rw-r--r--src/commands/client-unpause.json24
-rw-r--r--src/commands/client.json12
-rw-r--r--src/commands/cluster-addslots.json26
-rw-r--r--src/commands/cluster-addslotsrange.json36
-rw-r--r--src/commands/cluster-bumpepoch.json33
-rw-r--r--src/commands/cluster-count-failure-reports.json29
-rw-r--r--src/commands/cluster-countkeysinslot.json25
-rw-r--r--src/commands/cluster-delslots.json26
-rw-r--r--src/commands/cluster-delslotsrange.json36
-rw-r--r--src/commands/cluster-failover.json38
-rw-r--r--src/commands/cluster-flushslots.json19
-rw-r--r--src/commands/cluster-forget.json25
-rw-r--r--src/commands/cluster-getkeysinslot.json35
-rw-r--r--src/commands/cluster-help.json22
-rw-r--r--src/commands/cluster-info.json21
-rw-r--r--src/commands/cluster-keyslot.json25
-rw-r--r--src/commands/cluster-links.json60
-rw-r--r--src/commands/cluster-meet.json41
-rw-r--r--src/commands/cluster-myid.json18
-rw-r--r--src/commands/cluster-myshardid.json22
-rw-r--r--src/commands/cluster-nodes.json21
-rw-r--r--src/commands/cluster-replicas.json32
-rw-r--r--src/commands/cluster-replicate.json25
-rw-r--r--src/commands/cluster-reset.json38
-rw-r--r--src/commands/cluster-saveconfig.json19
-rw-r--r--src/commands/cluster-set-config-epoch.json25
-rw-r--r--src/commands/cluster-setslot.json54
-rw-r--r--src/commands/cluster-shards.json90
-rw-r--r--src/commands/cluster-slaves.json37
-rw-r--r--src/commands/cluster-slots.json136
-rw-r--r--src/commands/cluster.json9
-rw-r--r--src/commands/command-count.json23
-rw-r--r--src/commands/command-docs.json211
-rw-r--r--src/commands/command-getkeys.json39
-rw-r--r--src/commands/command-getkeysandflags.json55
-rw-r--r--src/commands/command-help.json26
-rw-r--r--src/commands/command-info.json213
-rw-r--r--src/commands/command-list.json55
-rw-r--r--src/commands/command.json21
-rw-r--r--src/commands/config-get.json36
-rw-r--r--src/commands/config-help.json22
-rw-r--r--src/commands/config-resetstat.json24
-rw-r--r--src/commands/config-rewrite.json24
-rw-r--r--src/commands/config-set.json47
-rw-r--r--src/commands/config.json9
-rw-r--r--src/commands/copy.json91
-rw-r--r--src/commands/dbsize.json25
-rw-r--r--src/commands/debug.json20
-rw-r--r--src/commands/decr.json50
-rw-r--r--src/commands/decrby.json54
-rw-r--r--src/commands/del.json53
-rw-r--r--src/commands/discard.json23
-rw-r--r--src/commands/dump.json58
-rw-r--r--src/commands/echo.json28
-rw-r--r--src/commands/eval.json69
-rw-r--r--src/commands/eval_ro.json68
-rw-r--r--src/commands/evalsha.json68
-rw-r--r--src/commands/evalsha_ro.json67
-rw-r--r--src/commands/exec.json31
-rw-r--r--src/commands/exists.json58
-rw-r--r--src/commands/expire.json94
-rw-r--r--src/commands/expireat.json94
-rw-r--r--src/commands/expiretime.json61
-rw-r--r--src/commands/failover.json54
-rw-r--r--src/commands/fcall.json69
-rw-r--r--src/commands/fcall_ro.json68
-rw-r--r--src/commands/flushall.json55
-rw-r--r--src/commands/flushdb.json55
-rw-r--r--src/commands/function-delete.json31
-rw-r--r--src/commands/function-dump.json21
-rw-r--r--src/commands/function-flush.json44
-rw-r--r--src/commands/function-help.json25
-rw-r--r--src/commands/function-kill.json25
-rw-r--r--src/commands/function-list.json87
-rw-r--r--src/commands/function-load.json39
-rw-r--r--src/commands/function-restore.json54
-rw-r--r--src/commands/function-stats.json81
-rw-r--r--src/commands/function.json9
-rw-r--r--src/commands/geoadd.json98
-rw-r--r--src/commands/geodist.json91
-rw-r--r--src/commands/geohash.json56
-rw-r--r--src/commands/geopos.json76
-rw-r--r--src/commands/georadius.json270
-rw-r--r--src/commands/georadius_ro.json201
-rw-r--r--src/commands/georadiusbymember.json261
-rw-r--r--src/commands/georadiusbymember_ro.json190
-rw-r--r--src/commands/geosearch.json267
-rw-r--r--src/commands/geosearchstore.json228
-rw-r--r--src/commands/get.json56
-rw-r--r--src/commands/getbit.json59
-rw-r--r--src/commands/getdel.json57
-rw-r--r--src/commands/getex.json90
-rw-r--r--src/commands/getrange.json55
-rw-r--r--src/commands/getset.json67
-rw-r--r--src/commands/hdel.json59
-rw-r--r--src/commands/hello.json111
-rw-r--r--src/commands/hexists.json59
-rw-r--r--src/commands/hget.json60
-rw-r--r--src/commands/hgetall.json53
-rw-r--r--src/commands/hincrby.json58
-rw-r--r--src/commands/hincrbyfloat.json58
-rw-r--r--src/commands/hkeys.json54
-rw-r--r--src/commands/hlen.json47
-rw-r--r--src/commands/hmget.json64
-rw-r--r--src/commands/hmset.json68
-rw-r--r--src/commands/hrandfield.json101
-rw-r--r--src/commands/hscan.json81
-rw-r--r--src/commands/hset.json70
-rw-r--r--src/commands/hsetnx.json65
-rw-r--r--src/commands/hstrlen.json52
-rw-r--r--src/commands/hvals.json53
-rw-r--r--src/commands/incr.json50
-rw-r--r--src/commands/incrby.json54
-rw-r--r--src/commands/incrbyfloat.json54
-rw-r--r--src/commands/info.json41
-rw-r--r--src/commands/keys.json34
-rw-r--r--src/commands/lastsave.json26
-rw-r--r--src/commands/latency-doctor.json26
-rw-r--r--src/commands/latency-graph.json32
-rw-r--r--src/commands/latency-help.json22
-rw-r--r--src/commands/latency-histogram.json54
-rw-r--r--src/commands/latency-history.json49
-rw-r--r--src/commands/latency-latest.json49
-rw-r--r--src/commands/latency-reset.json33
-rw-r--r--src/commands/latency.json9
-rw-r--r--src/commands/lcs.json127
-rw-r--r--src/commands/lindex.json59
-rw-r--r--src/commands/linsert.json85
-rw-r--r--src/commands/llen.json48
-rw-r--r--src/commands/lmove.json104
-rw-r--r--src/commands/lmpop.json100
-rw-r--r--src/commands/lolwut.json25
-rw-r--r--src/commands/lpop.json77
-rw-r--r--src/commands/lpos.json85
-rw-r--r--src/commands/lpush.json60
-rw-r--r--src/commands/lpushx.json61
-rw-r--r--src/commands/lrange.json58
-rw-r--r--src/commands/lrem.json56
-rw-r--r--src/commands/lset.json55
-rw-r--r--src/commands/ltrim.json54
-rw-r--r--src/commands/memory-doctor.json20
-rw-r--r--src/commands/memory-help.json22
-rw-r--r--src/commands/memory-malloc-stats.json20
-rw-r--r--src/commands/memory-purge.json18
-rw-r--r--src/commands/memory-stats.json121
-rw-r--r--src/commands/memory-usage.json58
-rw-r--r--src/commands/memory.json9
-rw-r--r--src/commands/mget.json63
-rw-r--r--src/commands/migrate.json181
-rw-r--r--src/commands/module-help.json22
-rw-r--r--src/commands/module-list.json47
-rw-r--r--src/commands/module-load.json32
-rw-r--r--src/commands/module-loadex.json51
-rw-r--r--src/commands/module-unload.json26
-rw-r--r--src/commands/module.json9
-rw-r--r--src/commands/monitor.json16
-rw-r--r--src/commands/move.json61
-rw-r--r--src/commands/mset.json62
-rw-r--r--src/commands/msetnx.json67
-rw-r--r--src/commands/multi.json23
-rw-r--r--src/commands/object-encoding.json58
-rw-r--r--src/commands/object-freq.json50
-rw-r--r--src/commands/object-help.json25
-rw-r--r--src/commands/object-idletime.json50
-rw-r--r--src/commands/object-refcount.json50
-rw-r--r--src/commands/object.json9
-rw-r--r--src/commands/persist.json56
-rw-r--r--src/commands/pexpire.json94
-rw-r--r--src/commands/pexpireat.json94
-rw-r--r--src/commands/pexpiretime.json61
-rw-r--r--src/commands/pfadd.json63
-rw-r--r--src/commands/pfcount.json50
-rw-r--r--src/commands/pfdebug.json52
-rw-r--r--src/commands/pfmerge.json73
-rw-r--r--src/commands/pfselftest.json22
-rw-r--r--src/commands/ping.json40
-rw-r--r--src/commands/psetex.json60
-rw-r--r--src/commands/psubscribe.json24
-rw-r--r--src/commands/psync.json25
-rw-r--r--src/commands/pttl.json70
-rw-r--r--src/commands/publish.json33
-rw-r--r--src/commands/pubsub-channels.json31
-rw-r--r--src/commands/pubsub-help.json22
-rw-r--r--src/commands/pubsub-numpat.json21
-rw-r--r--src/commands/pubsub-numsub.json28
-rw-r--r--src/commands/pubsub-shardchannels.json31
-rw-r--r--src/commands/pubsub-shardnumsub.json28
-rw-r--r--src/commands/pubsub.json9
-rw-r--r--src/commands/punsubscribe.json25
-rw-r--r--src/commands/quit.json29
-rw-r--r--src/commands/randomkey.json34
-rw-r--r--src/commands/readonly.json21
-rw-r--r--src/commands/readwrite.json21
-rw-r--r--src/commands/rename.json72
-rw-r--r--src/commands/renamenx.json86
-rw-r--r--src/commands/replconf.json23
-rw-r--r--src/commands/replicaof.json59
-rw-r--r--src/commands/reset.json24
-rw-r--r--src/commands/restore-asking.json102
-rw-r--r--src/commands/restore.json98
-rw-r--r--src/commands/role.json134
-rw-r--r--src/commands/rpop.json76
-rw-r--r--src/commands/rpoplpush.json85
-rw-r--r--src/commands/rpush.json61
-rw-r--r--src/commands/rpushx.json61
-rw-r--r--src/commands/sadd.json60
-rw-r--r--src/commands/save.json19
-rw-r--r--src/commands/scan.json72
-rw-r--r--src/commands/scard.json48
-rw-r--r--src/commands/script-debug.json43
-rw-r--r--src/commands/script-exists.json44
-rw-r--r--src/commands/script-flush.json50
-rw-r--r--src/commands/script-help.json25
-rw-r--r--src/commands/script-kill.json25
-rw-r--r--src/commands/script-load.json32
-rw-r--r--src/commands/script.json9
-rw-r--r--src/commands/sdiff.json55
-rw-r--r--src/commands/sdiffstore.json73
-rw-r--r--src/commands/select.json27
-rw-r--r--src/commands/sentinel-ckquorum.json26
-rw-r--r--src/commands/sentinel-config.json121
-rw-r--r--src/commands/sentinel-debug.json49
-rw-r--r--src/commands/sentinel-failover.json25
-rw-r--r--src/commands/sentinel-flushconfig.json20
-rw-r--r--src/commands/sentinel-get-master-addr-by-name.json38
-rw-r--r--src/commands/sentinel-help.json24
-rw-r--r--src/commands/sentinel-info-cache.json64
-rw-r--r--src/commands/sentinel-is-master-down-by-addr.json61
-rw-r--r--src/commands/sentinel-master.json29
-rw-r--r--src/commands/sentinel-masters.json26
-rw-r--r--src/commands/sentinel-monitor.json37
-rw-r--r--src/commands/sentinel-myid.json20
-rw-r--r--src/commands/sentinel-pending-scripts.json52
-rw-r--r--src/commands/sentinel-remove.json25
-rw-r--r--src/commands/sentinel-replicas.json32
-rw-r--r--src/commands/sentinel-reset.json26
-rw-r--r--src/commands/sentinel-sentinels.json32
-rw-r--r--src/commands/sentinel-set.json40
-rw-r--r--src/commands/sentinel-simulate-failure.json52
-rw-r--r--src/commands/sentinel-slaves.json37
-rw-r--r--src/commands/sentinel.json14
-rw-r--r--src/commands/set.json152
-rw-r--r--src/commands/setbit.json64
-rw-r--r--src/commands/setex.json60
-rw-r--r--src/commands/setnx.json66
-rw-r--r--src/commands/setrange.json57
-rw-r--r--src/commands/shutdown.json69
-rw-r--r--src/commands/sinter.json55
-rw-r--r--src/commands/sintercard.json60
-rw-r--r--src/commands/sinterstore.json73
-rw-r--r--src/commands/sismember.json59
-rw-r--r--src/commands/slaveof.json64
-rw-r--r--src/commands/slowlog-get.json74
-rw-r--r--src/commands/slowlog-help.json22
-rw-r--r--src/commands/slowlog-len.json26
-rw-r--r--src/commands/slowlog-reset.json23
-rw-r--r--src/commands/slowlog.json9
-rw-r--r--src/commands/smembers.json54
-rw-r--r--src/commands/smismember.json66
-rw-r--r--src/commands/smove.json84
-rw-r--r--src/commands/sort.json162
-rw-r--r--src/commands/sort_ro.json132
-rw-r--r--src/commands/spop.json80
-rw-r--r--src/commands/spublish.json51
-rw-r--r--src/commands/srandmember.json83
-rw-r--r--src/commands/srem.json60
-rw-r--r--src/commands/sscan.json81
-rw-r--r--src/commands/ssubscribe.json42
-rw-r--r--src/commands/strlen.json48
-rw-r--r--src/commands/subscribe.json25
-rw-r--r--src/commands/substr.json60
-rw-r--r--src/commands/sunion.json55
-rw-r--r--src/commands/sunionstore.json73
-rw-r--r--src/commands/sunsubscribe.json43
-rw-r--r--src/commands/swapdb.json31
-rw-r--r--src/commands/sync.json15
-rw-r--r--src/commands/time.json28
-rw-r--r--src/commands/touch.json53
-rw-r--r--src/commands/ttl.json70
-rw-r--r--src/commands/type.json55
-rw-r--r--src/commands/unlink.json54
-rw-r--r--src/commands/unsubscribe.json25
-rw-r--r--src/commands/unwatch.json23
-rw-r--r--src/commands/wait.json34
-rw-r--r--src/commands/waitaof.json52
-rw-r--r--src/commands/watch.json50
-rw-r--r--src/commands/xack.json58
-rw-r--r--src/commands/xadd.json161
-rw-r--r--src/commands/xautoclaim.json158
-rw-r--r--src/commands/xclaim.json138
-rw-r--r--src/commands/xdel.json54
-rw-r--r--src/commands/xgroup-create.json85
-rw-r--r--src/commands/xgroup-createconsumer.json64
-rw-r--r--src/commands/xgroup-delconsumer.json57
-rw-r--r--src/commands/xgroup-destroy.json59
-rw-r--r--src/commands/xgroup-help.json25
-rw-r--r--src/commands/xgroup-setid.json79
-rw-r--r--src/commands/xgroup.json9
-rw-r--r--src/commands/xinfo-consumers.json80
-rw-r--r--src/commands/xinfo-groups.json92
-rw-r--r--src/commands/xinfo-help.json25
-rw-r--r--src/commands/xinfo-stream.json361
-rw-r--r--src/commands/xinfo.json9
-rw-r--r--src/commands/xlen.json48
-rw-r--r--src/commands/xpending.json160
-rw-r--r--src/commands/xrange.json87
-rw-r--r--src/commands/xread.json108
-rw-r--r--src/commands/xreadgroup.json134
-rw-r--r--src/commands/xrevrange.json86
-rw-r--r--src/commands/xsetid.json72
-rw-r--r--src/commands/xtrim.json108
-rw-r--r--src/commands/zadd.json144
-rw-r--r--src/commands/zcard.json47
-rw-r--r--src/commands/zcount.json56
-rw-r--r--src/commands/zdiff.json85
-rw-r--r--src/commands/zdiffstore.json77
-rw-r--r--src/commands/zincrby.json58
-rw-r--r--src/commands/zinter.json115
-rw-r--r--src/commands/zintercard.json60
-rw-r--r--src/commands/zinterstore.json108
-rw-r--r--src/commands/zlexcount.json57
-rw-r--r--src/commands/zmpop.json111
-rw-r--r--src/commands/zmscore.json65
-rw-r--r--src/commands/zpopmax.json89
-rw-r--r--src/commands/zpopmin.json89
-rw-r--r--src/commands/zrandmember.json101
-rw-r--r--src/commands/zrange.json137
-rw-r--r--src/commands/zrangebylex.json80
-rw-r--r--src/commands/zrangebyscore.json119
-rw-r--r--src/commands/zrangestore.json118
-rw-r--r--src/commands/zrank.json86
-rw-r--r--src/commands/zrem.json60
-rw-r--r--src/commands/zremrangebylex.json55
-rw-r--r--src/commands/zremrangebyrank.json55
-rw-r--r--src/commands/zremrangebyscore.json55
-rw-r--r--src/commands/zrevrange.json94
-rw-r--r--src/commands/zrevrangebylex.json80
-rw-r--r--src/commands/zrevrangebyscore.json118
-rw-r--r--src/commands/zrevrank.json86
-rw-r--r--src/commands/zscan.json81
-rw-r--r--src/commands/zscore.json60
-rw-r--r--src/commands/zunion.json115
-rw-r--r--src/commands/zunionstore.json107
-rw-r--r--src/config.c3413
-rw-r--r--src/config.h321
-rw-r--r--src/connection.c208
-rw-r--r--src/connection.h454
-rw-r--r--src/connhelpers.h88
-rw-r--r--src/crc16.c88
-rw-r--r--src/crc16_slottable.h835
-rw-r--r--src/crc64.c161
-rw-r--r--src/crc64.h13
-rw-r--r--src/crcspeed.c282
-rw-r--r--src/crcspeed.h60
-rw-r--r--src/db.c2558
-rw-r--r--src/debug.c2322
-rw-r--r--src/debugmacro.h46
-rw-r--r--src/defrag.c1079
-rw-r--r--src/dict.c1749
-rw-r--r--src/dict.h231
-rw-r--r--src/endianconv.c129
-rw-r--r--src/endianconv.h78
-rw-r--r--src/eval.c1667
-rw-r--r--src/evict.c757
-rw-r--r--src/expire.c754
-rw-r--r--src/fmacros.h76
-rw-r--r--src/function_lua.c506
-rw-r--r--src/functions.c1139
-rw-r--r--src/functions.h136
-rw-r--r--src/geo.c1005
-rw-r--r--src/geo.h22
-rw-r--r--src/geohash.c299
-rw-r--r--src/geohash.h135
-rw-r--r--src/geohash_helper.c280
-rw-r--r--src/geohash_helper.h65
-rw-r--r--src/hyperloglog.c1618
-rw-r--r--src/intset.c560
-rw-r--r--src/intset.h57
-rw-r--r--src/latency.c739
-rw-r--r--src/latency.h108
-rw-r--r--src/lazyfree.c227
-rw-r--r--src/listpack.c2660
-rw-r--r--src/listpack.h106
-rw-r--r--src/listpack_malloc.h49
-rw-r--r--src/localtime.c123
-rw-r--r--src/logreqres.c315
-rw-r--r--src/lolwut.c188
-rw-r--r--src/lolwut.h55
-rw-r--r--src/lolwut5.c177
-rw-r--r--src/lolwut6.c201
-rw-r--r--src/lzf.h100
-rw-r--r--src/lzfP.h190
-rw-r--r--src/lzf_c.c302
-rw-r--r--src/lzf_d.c191
-rw-r--r--src/memtest.c377
-rwxr-xr-xsrc/mkreleasehdr.sh16
-rw-r--r--src/module.c13846
-rw-r--r--src/modules/.gitignore2
-rw-r--r--src/modules/Makefile69
-rw-r--r--src/modules/helloacl.c190
-rw-r--r--src/modules/helloblock.c218
-rw-r--r--src/modules/hellocluster.c118
-rw-r--r--src/modules/hellodict.c131
-rw-r--r--src/modules/hellohook.c92
-rw-r--r--src/modules/hellotimer.c75
-rw-r--r--src/modules/hellotype.c362
-rw-r--r--src/modules/helloworld.c621
-rw-r--r--src/monotonic.c180
-rw-r--r--src/monotonic.h61
-rw-r--r--src/mt19937-64.c187
-rw-r--r--src/mt19937-64.h87
-rw-r--r--src/multi.c500
-rw-r--r--src/networking.c4578
-rw-r--r--src/notify.c145
-rw-r--r--src/object.c1688
-rw-r--r--src/pqsort.c185
-rw-r--r--src/pqsort.h40
-rw-r--r--src/pubsub.c754
-rw-r--r--src/quicklist.c3257
-rw-r--r--src/quicklist.h214
-rw-r--r--src/rand.c93
-rw-r--r--src/rand.h38
-rw-r--r--src/rax.c1927
-rw-r--r--src/rax.h216
-rw-r--r--src/rax_malloc.h44
-rw-r--r--src/rdb.c3722
-rw-r--r--src/rdb.h184
-rw-r--r--src/redis-benchmark.c2060
-rw-r--r--src/redis-check-aof.c566
-rw-r--r--src/redis-check-rdb.c447
-rw-r--r--src/redis-cli.c9983
-rwxr-xr-xsrc/redis-trib.rb129
-rw-r--r--src/redisassert.c53
-rw-r--r--src/redisassert.h49
-rw-r--r--src/redismodule.h1685
-rw-r--r--src/release.c69
-rw-r--r--src/replication.c4241
-rw-r--r--src/resp_parser.c228
-rw-r--r--src/resp_parser.h94
-rw-r--r--src/rio.c520
-rw-r--r--src/rio.h185
-rw-r--r--src/script.c578
-rw-r--r--src/script.h111
-rw-r--r--src/script_lua.c1722
-rw-r--r--src/script_lua.h87
-rw-r--r--src/sds.c1496
-rw-r--r--src/sds.h287
-rw-r--r--src/sdsalloc.h54
-rw-r--r--src/sentinel.c5484
-rw-r--r--src/server.c7365
-rw-r--r--src/server.h3744
-rw-r--r--src/setcpuaffinity.c155
-rw-r--r--src/setproctitle.c331
-rw-r--r--src/sha1.c239
-rw-r--r--src/sha1.h27
-rw-r--r--src/sha256.c163
-rw-r--r--src/sha256.h35
-rw-r--r--src/siphash.c373
-rw-r--r--src/slowlog.c206
-rw-r--r--src/slowlog.h51
-rw-r--r--src/socket.c471
-rw-r--r--src/solarisfixes.h54
-rw-r--r--src/sort.c619
-rw-r--r--src/sparkline.c179
-rw-r--r--src/sparkline.h56
-rw-r--r--src/stream.h147
-rw-r--r--src/strl.c86
-rw-r--r--src/syncio.c145
-rw-r--r--src/syscheck.c375
-rw-r--r--src/syscheck.h46
-rw-r--r--src/t_hash.c1163
-rw-r--r--src/t_list.c1388
-rw-r--r--src/t_set.c1680
-rw-r--r--src/t_stream.c4038
-rw-r--r--src/t_string.c951
-rw-r--r--src/t_zset.c4460
-rw-r--r--src/testhelp.h62
-rw-r--r--src/timeout.c202
-rw-r--r--src/tls.c1204
-rw-r--r--src/tracking.c660
-rw-r--r--src/unix.c207
-rw-r--r--src/util.c1431
-rw-r--r--src/util.h99
-rw-r--r--src/valgrind.sup26
-rw-r--r--src/version.h2
-rw-r--r--src/ziplist.c2666
-rw-r--r--src/ziplist.h74
-rw-r--r--src/zipmap.c542
-rw-r--r--src/zipmap.h54
-rw-r--r--src/zmalloc.c851
-rw-r--r--src/zmalloc.h167
-rw-r--r--tests/README.md63
-rw-r--r--tests/assets/corrupt_empty_keys.rdbbin0 -> 280 bytes
-rw-r--r--tests/assets/corrupt_ziplist.rdbbin0 -> 1415 bytes
-rw-r--r--tests/assets/default.conf37
-rw-r--r--tests/assets/encodings.rdbbin0 -> 667 bytes
-rw-r--r--tests/assets/hash-ziplist.rdbbin0 -> 137 bytes
-rw-r--r--tests/assets/hash-zipmap.rdbbin0 -> 35 bytes
-rw-r--r--tests/assets/list-quicklist.rdbbin0 -> 123 bytes
-rw-r--r--tests/assets/minimal.conf5
-rw-r--r--tests/assets/nodefaultuser.acl2
-rw-r--r--tests/assets/rdb-preamble.aofbin0 -> 169 bytes
-rw-r--r--tests/assets/scriptbackup.rdbbin0 -> 225 bytes
-rw-r--r--tests/assets/test_cli_hint_suite.txt111
-rw-r--r--tests/assets/user.acl3
-rw-r--r--tests/assets/userwithselectors.acl2
-rw-r--r--tests/assets/zset-ziplist.rdbbin0 -> 135 bytes
-rw-r--r--tests/cluster/cluster.tcl222
-rw-r--r--tests/cluster/run.tcl32
-rw-r--r--tests/cluster/tests/00-base.tcl89
-rw-r--r--tests/cluster/tests/01-faildet.tcl38
-rw-r--r--tests/cluster/tests/02-failover.tcl65
-rw-r--r--tests/cluster/tests/03-failover-loop.tcl117
-rw-r--r--tests/cluster/tests/04-resharding.tcl196
-rw-r--r--tests/cluster/tests/05-slave-selection.tcl188
-rw-r--r--tests/cluster/tests/06-slave-stop-cond.tcl77
-rw-r--r--tests/cluster/tests/07-replica-migration.tcl103
-rw-r--r--tests/cluster/tests/08-update-msg.tcl90
-rw-r--r--tests/cluster/tests/09-pubsub.tcl40
-rw-r--r--tests/cluster/tests/10-manual-failover.tcl192
-rw-r--r--tests/cluster/tests/11-manual-takeover.tcl71
-rw-r--r--tests/cluster/tests/12-replica-migration-2.tcl75
-rw-r--r--tests/cluster/tests/12.1-replica-migration-3.tcl65
-rw-r--r--tests/cluster/tests/13-no-failover-option.tcl61
-rw-r--r--tests/cluster/tests/14-consistency-check.tcl124
-rw-r--r--tests/cluster/tests/15-cluster-slots.tcl128
-rw-r--r--tests/cluster/tests/16-transactions-on-replica.tcl85
-rw-r--r--tests/cluster/tests/17-diskless-load-swapdb.tcl86
-rw-r--r--tests/cluster/tests/18-info.tcl45
-rw-r--r--tests/cluster/tests/19-cluster-nodes-slots.tcl50
-rw-r--r--tests/cluster/tests/20-half-migrated-slot.tcl98
-rw-r--r--tests/cluster/tests/21-many-slot-migration.tcl64
-rw-r--r--tests/cluster/tests/22-replica-in-sync.tcl146
-rw-r--r--tests/cluster/tests/25-pubsubshard-slot-migration.tcl171
-rw-r--r--tests/cluster/tests/26-pubsubshard.tcl94
-rw-r--r--tests/cluster/tests/28-cluster-shards.tcl287
-rw-r--r--tests/cluster/tests/29-slot-migration-response.tcl50
-rw-r--r--tests/cluster/tests/helpers/onlydots.tcl16
-rw-r--r--tests/cluster/tests/includes/init-tests.tcl91
-rw-r--r--tests/cluster/tests/includes/utils.tcl36
-rw-r--r--tests/cluster/tmp/.gitignore2
-rw-r--r--tests/helpers/bg_block_op.tcl55
-rw-r--r--tests/helpers/bg_complex_data.tcl13
-rw-r--r--tests/helpers/fake_redis_node.tcl58
-rw-r--r--tests/helpers/gen_write_load.tcl18
-rw-r--r--tests/instances.tcl742
-rw-r--r--tests/integration/aof-multi-part.tcl1332
-rw-r--r--tests/integration/aof-race.tcl37
-rw-r--r--tests/integration/aof.tcl681
-rw-r--r--tests/integration/block-repl.tcl51
-rw-r--r--tests/integration/convert-ziplist-hash-on-load.tcl28
-rw-r--r--tests/integration/convert-ziplist-zset-on-load.tcl28
-rw-r--r--tests/integration/convert-zipmap-hash-on-load.tcl39
-rw-r--r--tests/integration/corrupt-dump-fuzzer.tcl230
-rw-r--r--tests/integration/corrupt-dump.tcl833
-rw-r--r--tests/integration/dismiss-mem.tcl101
-rw-r--r--tests/integration/failover.tcl294
-rw-r--r--tests/integration/logging.tcl61
-rw-r--r--tests/integration/psync2-master-restart.tcl218
-rw-r--r--tests/integration/psync2-pingoff.tcl250
-rw-r--r--tests/integration/psync2-reg.tcl82
-rw-r--r--tests/integration/psync2.tcl384
-rw-r--r--tests/integration/rdb.tcl419
-rw-r--r--tests/integration/redis-benchmark.tcl171
-rw-r--r--tests/integration/redis-cli.tcl609
-rw-r--r--tests/integration/replication-2.tcl93
-rw-r--r--tests/integration/replication-3.tcl130
-rw-r--r--tests/integration/replication-4.tcl295
-rw-r--r--tests/integration/replication-buffer.tcl307
-rw-r--r--tests/integration/replication-psync.tcl143
-rw-r--r--tests/integration/replication.tcl1456
-rw-r--r--tests/integration/shutdown.tcl234
-rw-r--r--tests/modules/Makefile83
-rw-r--r--tests/modules/aclcheck.c269
-rw-r--r--tests/modules/auth.c270
-rw-r--r--tests/modules/basics.c1052
-rw-r--r--tests/modules/blockedclient.c712
-rw-r--r--tests/modules/blockonbackground.c295
-rw-r--r--tests/modules/blockonkeys.c645
-rw-r--r--tests/modules/cmdintrospection.c158
-rw-r--r--tests/modules/commandfilter.c251
-rw-r--r--tests/modules/datatype.c314
-rw-r--r--tests/modules/datatype2.c739
-rw-r--r--tests/modules/defragtest.c235
-rw-r--r--tests/modules/eventloop.c276
-rw-r--r--tests/modules/fork.c96
-rw-r--r--tests/modules/getchannels.c69
-rw-r--r--tests/modules/getkeys.c178
-rw-r--r--tests/modules/hash.c90
-rw-r--r--tests/modules/hooks.c516
-rw-r--r--tests/modules/infotest.c119
-rw-r--r--tests/modules/keyspace_events.c440
-rw-r--r--tests/modules/keyspecs.c236
-rw-r--r--tests/modules/list.c252
-rw-r--r--tests/modules/mallocsize.c237
-rw-r--r--tests/modules/misc.c571
-rw-r--r--tests/modules/moduleauthtwo.c43
-rw-r--r--tests/modules/moduleconfigs.c195
-rw-r--r--tests/modules/moduleconfigstwo.c39
-rw-r--r--tests/modules/postnotifications.c303
-rw-r--r--tests/modules/propagate.c403
-rw-r--r--tests/modules/publish.c57
-rw-r--r--tests/modules/rdbloadsave.c162
-rw-r--r--tests/modules/reply.c214
-rw-r--r--tests/modules/scan.c121
-rw-r--r--tests/modules/stream.c258
-rw-r--r--tests/modules/subcommands.c112
-rw-r--r--tests/modules/test_lazyfree.c196
-rw-r--r--tests/modules/testrdb.c405
-rw-r--r--tests/modules/timer.c102
-rw-r--r--tests/modules/usercall.c228
-rw-r--r--tests/modules/zset.c91
-rw-r--r--tests/sentinel/run.tcl36
-rw-r--r--tests/sentinel/tests/00-base.tcl210
-rw-r--r--tests/sentinel/tests/01-conf-update.tcl50
-rw-r--r--tests/sentinel/tests/02-slaves-reconf.tcl91
-rw-r--r--tests/sentinel/tests/03-runtime-reconf.tcl225
-rw-r--r--tests/sentinel/tests/04-slave-selection.tcl5
-rw-r--r--tests/sentinel/tests/05-manual.tcl94
-rw-r--r--tests/sentinel/tests/06-ckquorum.tcl42
-rw-r--r--tests/sentinel/tests/07-down-conditions.tcl104
-rw-r--r--tests/sentinel/tests/08-hostname-conf.tcl69
-rw-r--r--tests/sentinel/tests/09-acl-support.tcl56
-rw-r--r--tests/sentinel/tests/10-replica-priority.tcl76
-rw-r--r--tests/sentinel/tests/11-port-0.tcl33
-rw-r--r--tests/sentinel/tests/12-master-reboot.tcl103
-rw-r--r--tests/sentinel/tests/13-info-command.tcl47
-rw-r--r--tests/sentinel/tests/14-debug-command.tcl9
-rw-r--r--tests/sentinel/tests/15-config-set-config-get.tcl58
-rwxr-xr-xtests/sentinel/tests/helpers/check_leaked_fds.tcl79
-rw-r--r--tests/sentinel/tests/includes/init-tests.tcl63
-rw-r--r--tests/sentinel/tests/includes/sentinel.conf9
-rw-r--r--tests/sentinel/tests/includes/start-init-tests.tcl18
-rw-r--r--tests/sentinel/tests/includes/utils.tcl22
-rw-r--r--tests/sentinel/tmp/.gitignore2
-rw-r--r--tests/support/aofmanifest.tcl169
-rw-r--r--tests/support/benchmark.tcl33
-rw-r--r--tests/support/cli.tcl36
-rw-r--r--tests/support/cluster.tcl367
-rw-r--r--tests/support/cluster_util.tcl201
-rw-r--r--tests/support/redis.tcl466
-rw-r--r--tests/support/response_transformers.tcl105
-rw-r--r--tests/support/server.tcl789
-rw-r--r--tests/support/test.tcl267
-rw-r--r--tests/support/tmpfile.tcl15
-rw-r--r--tests/support/util.tcl1117
-rw-r--r--tests/test_helper.tcl937
-rw-r--r--tests/tmp/.gitignore1
-rw-r--r--tests/unit/acl-v2.tcl525
-rw-r--r--tests/unit/acl.tcl1173
-rw-r--r--tests/unit/aofrw.tcl232
-rw-r--r--tests/unit/auth.tcl89
-rw-r--r--tests/unit/bitfield.tcl263
-rw-r--r--tests/unit/bitops.tcl593
-rw-r--r--tests/unit/client-eviction.tcl586
-rw-r--r--tests/unit/cluster/announced-endpoints.tcl42
-rw-r--r--tests/unit/cluster/cli.tcl416
-rw-r--r--tests/unit/cluster/cluster-response-tls.tcl110
-rw-r--r--tests/unit/cluster/hostnames.tcl203
-rw-r--r--tests/unit/cluster/human-announced-nodename.tcl29
-rw-r--r--tests/unit/cluster/links.tcl292
-rw-r--r--tests/unit/cluster/misc.tcl26
-rw-r--r--tests/unit/cluster/multi-slot-operations.tcl109
-rw-r--r--tests/unit/cluster/scripting.tcl70
-rw-r--r--tests/unit/cluster/slot-ownership.tcl61
-rw-r--r--tests/unit/dump.tcl410
-rw-r--r--tests/unit/expire.tcl835
-rw-r--r--tests/unit/functions.tcl1233
-rw-r--r--tests/unit/geo.tcl768
-rw-r--r--tests/unit/hyperloglog.tcl271
-rw-r--r--tests/unit/info-command.tcl62
-rw-r--r--tests/unit/info.tcl346
-rw-r--r--tests/unit/introspection-2.tcl245
-rw-r--r--tests/unit/introspection.tcl829
-rw-r--r--tests/unit/keyspace.tcl502
-rw-r--r--tests/unit/latency-monitor.tcl166
-rw-r--r--tests/unit/lazyfree.tcl90
-rw-r--r--tests/unit/limits.tcl21
-rw-r--r--tests/unit/maxmemory.tcl590
-rw-r--r--tests/unit/memefficiency.tcl580
-rw-r--r--tests/unit/moduleapi/aclcheck.tcl137
-rw-r--r--tests/unit/moduleapi/async_rm_call.tcl437
-rw-r--r--tests/unit/moduleapi/auth.tcl90
-rw-r--r--tests/unit/moduleapi/basics.tcl46
-rw-r--r--tests/unit/moduleapi/blockedclient.tcl287
-rw-r--r--tests/unit/moduleapi/blockonbackground.tcl126
-rw-r--r--tests/unit/moduleapi/blockonkeys.tcl366
-rw-r--r--tests/unit/moduleapi/cluster.tcl222
-rw-r--r--tests/unit/moduleapi/cmdintrospection.tcl50
-rw-r--r--tests/unit/moduleapi/commandfilter.tcl175
-rw-r--r--tests/unit/moduleapi/datatype.tcl134
-rw-r--r--tests/unit/moduleapi/datatype2.tcl232
-rw-r--r--tests/unit/moduleapi/defrag.tcl46
-rw-r--r--tests/unit/moduleapi/eventloop.tcl28
-rw-r--r--tests/unit/moduleapi/fork.tcl49
-rw-r--r--tests/unit/moduleapi/getchannels.tcl40
-rw-r--r--tests/unit/moduleapi/getkeys.tcl80
-rw-r--r--tests/unit/moduleapi/hash.tcl27
-rw-r--r--tests/unit/moduleapi/hooks.tcl321
-rw-r--r--tests/unit/moduleapi/infotest.tcl131
-rw-r--r--tests/unit/moduleapi/infra.tcl25
-rw-r--r--tests/unit/moduleapi/keyspace_events.tcl118
-rw-r--r--tests/unit/moduleapi/keyspecs.tcl160
-rw-r--r--tests/unit/moduleapi/list.tcl160
-rw-r--r--tests/unit/moduleapi/mallocsize.tcl21
-rw-r--r--tests/unit/moduleapi/misc.tcl555
-rw-r--r--tests/unit/moduleapi/moduleauth.tcl405
-rw-r--r--tests/unit/moduleapi/moduleconfigs.tcl247
-rw-r--r--tests/unit/moduleapi/postnotifications.tcl219
-rw-r--r--tests/unit/moduleapi/propagate.tcl763
-rw-r--r--tests/unit/moduleapi/publish.tcl34
-rw-r--r--tests/unit/moduleapi/rdbloadsave.tcl200
-rw-r--r--tests/unit/moduleapi/reply.tcl152
-rw-r--r--tests/unit/moduleapi/scan.tcl69
-rw-r--r--tests/unit/moduleapi/stream.tcl176
-rw-r--r--tests/unit/moduleapi/subcommands.tcl57
-rw-r--r--tests/unit/moduleapi/test_lazyfree.tcl32
-rw-r--r--tests/unit/moduleapi/testrdb.tcl306
-rw-r--r--tests/unit/moduleapi/timer.tcl99
-rw-r--r--tests/unit/moduleapi/usercall.tcl136
-rw-r--r--tests/unit/moduleapi/zset.tcl40
-rw-r--r--tests/unit/multi.tcl923
-rw-r--r--tests/unit/networking.tcl172
-rw-r--r--tests/unit/obuf-limits.tcl230
-rw-r--r--tests/unit/oom-score-adj.tcl131
-rw-r--r--tests/unit/other.tcl428
-rw-r--r--tests/unit/pause.tcl364
-rw-r--r--tests/unit/printver.tcl6
-rw-r--r--tests/unit/protocol.tcl250
-rw-r--r--tests/unit/pubsub.tcl506
-rw-r--r--tests/unit/pubsubshard.tcl164
-rw-r--r--tests/unit/querybuf.tcl96
-rw-r--r--tests/unit/quit.tcl33
-rw-r--r--tests/unit/replybufsize.tcl47
-rw-r--r--tests/unit/scan.tcl433
-rw-r--r--tests/unit/scripting.tcl2213
-rw-r--r--tests/unit/shutdown.tcl133
-rw-r--r--tests/unit/slowlog.tcl228
-rw-r--r--tests/unit/sort.tcl359
-rw-r--r--tests/unit/tls.tcl158
-rw-r--r--tests/unit/tracking.tcl902
-rw-r--r--tests/unit/type/hash.tcl846
-rw-r--r--tests/unit/type/incr.tcl214
-rw-r--r--tests/unit/type/list-2.tcl47
-rw-r--r--tests/unit/type/list-3.tcl232
-rw-r--r--tests/unit/type/list-common.tcl4
-rw-r--r--tests/unit/type/list.tcl2363
-rw-r--r--tests/unit/type/set.tcl1305
-rw-r--r--tests/unit/type/stream-cgroups.tcl1297
-rw-r--r--tests/unit/type/stream.tcl940
-rw-r--r--tests/unit/type/string.tcl674
-rw-r--r--tests/unit/type/zset.tcl2654
-rw-r--r--tests/unit/violations.tcl103
-rw-r--r--tests/unit/wait.tcl505
-rw-r--r--utils/build-static-symbols.tcl22
-rw-r--r--utils/cluster_fail_time.tcl50
-rw-r--r--utils/corrupt_rdb.c45
-rw-r--r--utils/create-cluster/.gitignore6
-rw-r--r--utils/create-cluster/README27
-rwxr-xr-xutils/create-cluster/create-cluster125
-rwxr-xr-xutils/gen-test-certs.sh58
-rwxr-xr-xutils/generate-command-code.py623
-rwxr-xr-xutils/generate-commands-json.py136
-rwxr-xr-xutils/generate-module-api-doc.rb205
-rw-r--r--utils/graphs/commits-over-time/README.md16
-rwxr-xr-xutils/graphs/commits-over-time/genhtml.tcl96
-rw-r--r--utils/hyperloglog/.gitignore1
-rw-r--r--utils/hyperloglog/hll-err.rb27
-rw-r--r--utils/hyperloglog/hll-gnuplot-graph.rb88
-rwxr-xr-xutils/install_server.sh291
-rw-r--r--utils/lru/README19
-rw-r--r--utils/lru/lfu-simulation.c158
-rw-r--r--utils/lru/test-lru.rb223
-rw-r--r--utils/redis-copy.rb35
-rw-r--r--utils/redis-sha1.rb52
-rwxr-xr-xutils/redis_init_script50
-rwxr-xr-xutils/redis_init_script.tpl44
-rwxr-xr-xutils/releasetools/01_create_tarball.sh14
-rwxr-xr-xutils/releasetools/02_upload_tarball.sh23
-rwxr-xr-xutils/releasetools/03_test_release.sh28
-rwxr-xr-xutils/releasetools/04_release_hash.sh13
-rwxr-xr-xutils/releasetools/changelog.tcl35
-rw-r--r--utils/reply_schema_linter.js31
-rwxr-xr-xutils/req-res-log-validator.py350
-rw-r--r--utils/req-res-validator/requirements.txt2
-rwxr-xr-xutils/speed-regression.tcl130
-rw-r--r--utils/srandmember/README.md14
-rw-r--r--utils/srandmember/showdist.rb33
-rw-r--r--utils/srandmember/showfreq.rb23
-rw-r--r--utils/systemd-redis_multiple_servers@.service37
-rw-r--r--utils/systemd-redis_server.service43
-rw-r--r--utils/tracking_collisions.c76
-rwxr-xr-xutils/whatisdoing.sh24
1582 files changed, 442082 insertions, 0 deletions
diff --git a/.codespell/.codespellrc b/.codespell/.codespellrc
new file mode 100644
index 0000000..75b9257
--- /dev/null
+++ b/.codespell/.codespellrc
@@ -0,0 +1,5 @@
+[codespell]
+quiet-level = 2
+count =
+skip = ./deps,./src/crc16_slottable.h,tmp*,./.git,./lcov-html
+ignore-words = ./.codespell/wordlist.txt
diff --git a/.codespell/requirements.txt b/.codespell/requirements.txt
new file mode 100644
index 0000000..407f174
--- /dev/null
+++ b/.codespell/requirements.txt
@@ -0,0 +1 @@
+codespell==2.2.4
diff --git a/.codespell/wordlist.txt b/.codespell/wordlist.txt
new file mode 100644
index 0000000..0bc0beb
--- /dev/null
+++ b/.codespell/wordlist.txt
@@ -0,0 +1,21 @@
+ake
+bale
+fle
+fo
+gameboy
+mutli
+nd
+nees
+oll
+optin
+ot
+smove
+te
+tre
+cancelability
+ist
+statics
+filetest
+ro
+exat
+clen \ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..697a900
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,6 @@
+# We set commands.c's merge driver to `binary` so when it conflicts during a
+# merge git will leave the local version unmodified. This way our Makefile
+# will rebuild it based on src/commands/*.json before trying to compile it.
+# Otherwise the file gets modified and gets the same timestamp as the .json
+# files. So the Makefile doesn't attempt to rebuild it before compiling.
+src/commands.c merge=binary
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..00f21a8
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,24 @@
+---
+name: Bug report
+about: Help us improve Redis by reporting a bug
+title: '[BUG]'
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+
+A short description of the bug.
+
+**To reproduce**
+
+Steps to reproduce the behavior and/or a minimal code sample.
+
+**Expected behavior**
+
+A description of what you expected to happen.
+
+**Additional information**
+
+Any additional information that is relevant to the problem.
diff --git a/.github/ISSUE_TEMPLATE/crash_report.md b/.github/ISSUE_TEMPLATE/crash_report.md
new file mode 100644
index 0000000..1118ac1
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/crash_report.md
@@ -0,0 +1,25 @@
+---
+name: Crash report
+about: Submit a crash report
+title: '[CRASH] <short description>'
+labels: ''
+assignees: ''
+
+---
+
+Notice!
+- If a Redis module was involved, please open an issue in the module's repo instead!
+- If you're using docker on Apple M1, please make sure the image you're using was compiled for ARM!
+
+
+**Crash report**
+
+Paste the complete crash log between the quotes below. Please include a few lines from the log preceding the crash report to provide some context.
+
+```
+```
+
+**Additional information**
+
+1. OS distribution and version
+2. Steps to reproduce (if any)
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..732dc64
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,24 @@
+---
+name: Feature request
+about: Suggest a feature for Redis
+title: '[NEW]'
+labels: ''
+assignees: ''
+
+---
+
+**The problem/use-case that the feature addresses**
+
+A description of the problem that the feature will solve, or the use-case with which the feature will be used.
+
+**Description of the feature**
+
+A description of what you want to happen.
+
+**Alternatives you've considered**
+
+Any alternative solutions or features you've considered, including references to existing open and closed feature requests in this repository.
+
+**Additional information**
+
+Any additional information that is relevant to the feature request.
diff --git a/.github/ISSUE_TEMPLATE/other_stuff.md b/.github/ISSUE_TEMPLATE/other_stuff.md
new file mode 100644
index 0000000..e82cf00
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/other_stuff.md
@@ -0,0 +1,8 @@
+---
+name: Other
+about: Can't find the right issue type? Use this one!
+title: ''
+labels: ''
+assignees: ''
+
+---
diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md
new file mode 100644
index 0000000..338f942
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/question.md
@@ -0,0 +1,21 @@
+---
+name: Question
+about: Ask the Redis developers
+title: '[QUESTION]'
+labels: ''
+assignees: ''
+
+---
+
+Please keep in mind that this issue tracker should be used for reporting bugs or proposing improvements to the Redis server.
+
+Generally, questions about using Redis should be directed to the [community](https://redis.io/community):
+
+* [the mailing list](https://groups.google.com/forum/#!forum/redis-db)
+* [the `redis` tag at StackOverflow](http://stackoverflow.com/questions/tagged/redis)
+* [/r/redis subreddit](http://www.reddit.com/r/redis)
+* [github discussions](https://github.com/redis/redis/discussions)
+
+It is also possible that your question was already asked here, so please do a quick issues search before submitting. Lastly, if your question is about one of Redis' [clients](https://redis.io/clients), you may to contact your client's developers for help.
+
+That said, please feel free to replace all this with your question :)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..f00019d
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,15 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: github-actions
+ directory: /
+ schedule:
+ interval: weekly
+ - package-ecosystem: pip
+ directory: /.codespell
+ schedule:
+ interval: weekly
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..43547a4
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,84 @@
+name: CI
+
+on: [push, pull_request]
+
+jobs:
+
+ test-ubuntu-latest:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: make
+ # Fail build if there are warnings
+ # build with TLS just for compilation coverage
+ run: make REDIS_CFLAGS='-Werror' BUILD_TLS=yes
+ - name: test
+ run: |
+ sudo apt-get install tcl8.6 tclx
+ ./runtest --verbose --tags -slow --dump-logs
+ - name: module api test
+ run: ./runtest-moduleapi --verbose --dump-logs
+ - name: validate commands.def up to date
+ run: |
+ touch src/commands/ping.json
+ make commands.def
+ dirty=$(git diff)
+ if [[ ! -z $dirty ]]; then echo $dirty; exit 1; fi
+
+ test-sanitizer-address:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: make
+ # build with TLS module just for compilation coverage
+ run: make SANITIZER=address REDIS_CFLAGS='-Werror' BUILD_TLS=module
+ - name: testprep
+ run: sudo apt-get install tcl8.6 tclx -y
+ - name: test
+ run: ./runtest --verbose --tags -slow --dump-logs
+ - name: module api test
+ run: ./runtest-moduleapi --verbose --dump-logs
+
+ build-debian-old:
+ runs-on: ubuntu-latest
+ container: debian:buster
+ steps:
+ - uses: actions/checkout@v3
+ - name: make
+ run: |
+ apt-get update && apt-get install -y build-essential
+ make REDIS_CFLAGS='-Werror'
+
+ build-macos-latest:
+ runs-on: macos-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: make
+ run: make REDIS_CFLAGS='-Werror'
+
+ build-32bit:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: make
+ run: |
+ sudo apt-get update && sudo apt-get install libc6-dev-i386
+ make REDIS_CFLAGS='-Werror' 32bit
+
+ build-libc-malloc:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: make
+ run: make REDIS_CFLAGS='-Werror' MALLOC=libc
+
+ build-centos7-jemalloc:
+ runs-on: ubuntu-latest
+ container: centos:7
+ steps:
+ - uses: actions/checkout@v3
+ - name: make
+ run: |
+ yum -y install gcc make
+ make REDIS_CFLAGS='-Werror'
+
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 0000000..dc7413e
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,33 @@
+name: "CodeQL"
+
+on:
+ pull_request:
+ schedule:
+ # run weekly new vulnerability was added to the database
+ - cron: '0 0 * * 0'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+ if: github.event_name != 'schedule' || github.repository == 'redis/redis'
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ 'cpp' ]
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v2
+ with:
+ languages: ${{ matrix.language }}
+
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v2
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v2
diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml
new file mode 100644
index 0000000..72720e6
--- /dev/null
+++ b/.github/workflows/daily.yml
@@ -0,0 +1,1087 @@
+name: Daily
+
+on:
+ pull_request:
+ branches:
+ # any PR to a release branch.
+ - '[0-9].[0-9]'
+ schedule:
+ - cron: '0 0 * * *'
+ workflow_dispatch:
+ inputs:
+ skipjobs:
+ description: 'jobs to skip (delete the ones you wanna keep, do not leave empty)'
+ default: 'valgrind,sanitizer,tls,freebsd,macos,alpine,32bit,iothreads,ubuntu,centos,malloc,specific,fortify,reply-schema'
+ skiptests:
+ description: 'tests to skip (delete the ones you wanna keep, do not leave empty)'
+ default: 'redis,modules,sentinel,cluster,unittest'
+ test_args:
+ description: 'extra test arguments'
+ default: ''
+ cluster_test_args:
+ description: 'extra cluster / sentinel test arguments'
+ default: ''
+ use_repo:
+ description: 'repo owner and name'
+ default: 'redis/redis'
+ use_git_ref:
+ description: 'git branch or sha to use'
+ default: 'unstable'
+
+
+jobs:
+
+ test-ubuntu-jemalloc:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'ubuntu')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: make REDIS_CFLAGS='-Werror -DREDIS_TEST'
+ - name: testprep
+ run: sudo apt-get install tcl8.6 tclx
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --accurate --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: ./runtest-moduleapi --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: ./runtest-cluster ${{github.event.inputs.cluster_test_args}}
+ - name: unittest
+ if: true && !contains(github.event.inputs.skiptests, 'unittest')
+ run: ./src/redis-server test all --accurate
+
+ test-ubuntu-jemalloc-fortify:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'fortify')
+ container: ubuntu:lunar
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: |
+ apt-get update && apt-get install -y make gcc-13
+ update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 100
+ make CC=gcc REDIS_CFLAGS='-Werror -DREDIS_TEST -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3'
+ - name: testprep
+ run: apt-get install -y tcl8.6 tclx procps
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --accurate --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: ./runtest-moduleapi --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: ./runtest-cluster ${{github.event.inputs.cluster_test_args}}
+ - name: unittest
+ if: true && !contains(github.event.inputs.skiptests, 'unittest')
+ run: ./src/redis-server test all --accurate
+
+ test-ubuntu-libc-malloc:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'malloc')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: make MALLOC=libc REDIS_CFLAGS='-Werror'
+ - name: testprep
+ run: sudo apt-get install tcl8.6 tclx
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --accurate --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: ./runtest-moduleapi --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: ./runtest-cluster ${{github.event.inputs.cluster_test_args}}
+
+ test-ubuntu-no-malloc-usable-size:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'malloc')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: make MALLOC=libc CFLAGS=-DNO_MALLOC_USABLE_SIZE REDIS_CFLAGS='-Werror'
+ - name: testprep
+ run: sudo apt-get install tcl8.6 tclx
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --accurate --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: ./runtest-moduleapi --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: ./runtest-cluster ${{github.event.inputs.cluster_test_args}}
+
+ test-ubuntu-32bit:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, '32bit')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: |
+ sudo apt-get update && sudo apt-get install libc6-dev-i386
+ make 32bit REDIS_CFLAGS='-Werror -DREDIS_TEST'
+ - name: testprep
+ run: sudo apt-get install tcl8.6 tclx
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --accurate --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: |
+ make -C tests/modules 32bit # the script below doesn't have an argument, we must build manually ahead of time
+ ./runtest-moduleapi --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: ./runtest-cluster ${{github.event.inputs.cluster_test_args}}
+ - name: unittest
+ if: true && !contains(github.event.inputs.skiptests, 'unittest')
+ run: ./src/redis-server test all --accurate
+
+ test-ubuntu-tls:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'tls')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: |
+ make BUILD_TLS=yes REDIS_CFLAGS='-Werror'
+ - name: testprep
+ run: |
+ sudo apt-get install tcl8.6 tclx tcl-tls
+ ./utils/gen-test-certs.sh
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: |
+ ./runtest --accurate --verbose --dump-logs --tls --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: |
+ ./runtest-moduleapi --verbose --dump-logs --tls --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: |
+ ./runtest-sentinel --tls ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: |
+ ./runtest-cluster --tls ${{github.event.inputs.cluster_test_args}}
+
+ test-ubuntu-tls-no-tls:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'tls')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: |
+ make BUILD_TLS=yes REDIS_CFLAGS='-Werror'
+ - name: testprep
+ run: |
+ sudo apt-get install tcl8.6 tclx tcl-tls
+ ./utils/gen-test-certs.sh
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: |
+ ./runtest --accurate --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: |
+ ./runtest-moduleapi --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: |
+ ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: |
+ ./runtest-cluster ${{github.event.inputs.cluster_test_args}}
+
+ test-ubuntu-io-threads:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'iothreads')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: |
+ make REDIS_CFLAGS='-Werror'
+ - name: testprep
+ run: sudo apt-get install tcl8.6 tclx
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --config io-threads 4 --config io-threads-do-reads yes --accurate --verbose --tags network --dump-logs ${{github.event.inputs.test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: ./runtest-cluster --config io-threads 4 --config io-threads-do-reads yes ${{github.event.inputs.cluster_test_args}}
+
+ test-ubuntu-reclaim-cache:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'specific')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: |
+ make REDIS_CFLAGS='-Werror'
+ - name: testprep
+ run: |
+ sudo apt-get install vmtouch
+ mkdir /tmp/master
+ mkdir /tmp/slave
+ - name: warm up
+ run: |
+ ./src/redis-server --daemonize yes --logfile /dev/null
+ ./src/redis-benchmark -n 1 > /dev/null
+ ./src/redis-cli save | grep OK > /dev/null
+ vmtouch -v ./dump.rdb > /dev/null
+ - name: test
+ run: |
+ echo "test SAVE doesn't increase cache"
+ CACHE0=$(grep -w file /sys/fs/cgroup/memory.stat | awk '{print $2}')
+ echo "$CACHE0"
+ ./src/redis-server --daemonize yes --logfile /dev/null --dir /tmp/master --port 8080 --repl-diskless-sync no --pidfile /tmp/master/redis.pid --rdbcompression no --enable-debug-command yes
+ ./src/redis-cli -p 8080 debug populate 10000 k 102400
+ ./src/redis-server --daemonize yes --logfile /dev/null --dir /tmp/slave --port 8081 --repl-diskless-load disabled --rdbcompression no
+ ./src/redis-cli -p 8080 save > /dev/null
+ VMOUT=$(vmtouch -v /tmp/master/dump.rdb)
+ echo $VMOUT
+ grep -q " 0%" <<< $VMOUT
+ CACHE=$(grep -w file /sys/fs/cgroup/memory.stat | awk '{print $2}')
+ echo "$CACHE"
+ if [ "$(( $CACHE-$CACHE0 ))" -gt "8000000" ]; then exit 1; fi
+
+ echo "test replication doesn't increase cache"
+ ./src/redis-cli -p 8081 REPLICAOF 127.0.0.1 8080 > /dev/null
+ while [ $(./src/redis-cli -p 8081 info replication | grep "master_link_status:down") ]; do sleep 1; done;
+ sleep 1 # wait for the completion of cache reclaim bio
+ VMOUT=$(vmtouch -v /tmp/master/dump.rdb)
+ echo $VMOUT
+ grep -q " 0%" <<< $VMOUT
+ VMOUT=$(vmtouch -v /tmp/slave/dump.rdb)
+ echo $VMOUT
+ grep -q " 0%" <<< $VMOUT
+ CACHE=$(grep -w file /sys/fs/cgroup/memory.stat | awk '{print $2}')
+ echo "$CACHE"
+ if [ "$(( $CACHE-$CACHE0 ))" -gt "8000000" ]; then exit 1; fi
+
+ echo "test reboot doesn't increase cache"
+ PID=$(cat /tmp/master/redis.pid)
+ kill -15 $PID
+ while [ -x /proc/${PID} ]; do sleep 1; done
+ ./src/redis-server --daemonize yes --logfile /dev/null --dir /tmp/master --port 8080
+ while [ $(./src/redis-cli -p 8080 info persistence | grep "loading:1") ]; do sleep 1; done;
+ sleep 1 # wait for the completion of cache reclaim bio
+ VMOUT=$(vmtouch -v /tmp/master/dump.rdb)
+ echo $VMOUT
+ grep -q " 0%" <<< $VMOUT
+ CACHE=$(grep -w file /sys/fs/cgroup/memory.stat | awk '{print $2}')
+ echo "$CACHE"
+ if [ "$(( $CACHE-$CACHE0 ))" -gt "8000000" ]; then exit 1; fi
+
+ test-valgrind-test:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'valgrind') && !contains(github.event.inputs.skiptests, 'redis')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: make valgrind REDIS_CFLAGS='-Werror -DREDIS_TEST'
+ - name: testprep
+ run: |
+ sudo apt-get update
+ sudo apt-get install tcl8.6 tclx valgrind -y
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --valgrind --no-latency --verbose --clients 1 --timeout 2400 --dump-logs ${{github.event.inputs.test_args}}
+
+ test-valgrind-misc:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'valgrind') && !(contains(github.event.inputs.skiptests, 'modules') && contains(github.event.inputs.skiptests, 'unittest'))
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: make valgrind REDIS_CFLAGS='-Werror -DREDIS_TEST'
+ - name: testprep
+ run: |
+ sudo apt-get update
+ sudo apt-get install tcl8.6 tclx valgrind -y
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: ./runtest-moduleapi --valgrind --no-latency --verbose --clients 1 --timeout 2400 --dump-logs ${{github.event.inputs.test_args}}
+ - name: unittest
+ if: true && !contains(github.event.inputs.skiptests, 'unittest')
+ run: |
+ valgrind --track-origins=yes --suppressions=./src/valgrind.sup --show-reachable=no --show-possibly-lost=no --leak-check=full --log-file=err.txt ./src/redis-server test all --valgrind
+ if grep -q 0x err.txt; then cat err.txt; exit 1; fi
+
+ test-valgrind-no-malloc-usable-size-test:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'valgrind') && !contains(github.event.inputs.skiptests, 'redis')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: make valgrind CFLAGS="-DNO_MALLOC_USABLE_SIZE -DREDIS_TEST" REDIS_CFLAGS='-Werror'
+ - name: testprep
+ run: |
+ sudo apt-get update
+ sudo apt-get install tcl8.6 tclx valgrind -y
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --valgrind --no-latency --verbose --clients 1 --timeout 2400 --dump-logs ${{github.event.inputs.test_args}}
+
+ test-valgrind-no-malloc-usable-size-misc:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'valgrind') && !(contains(github.event.inputs.skiptests, 'modules') && contains(github.event.inputs.skiptests, 'unittest'))
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: make valgrind CFLAGS="-DNO_MALLOC_USABLE_SIZE -DREDIS_TEST" REDIS_CFLAGS='-Werror'
+ - name: testprep
+ run: |
+ sudo apt-get update
+ sudo apt-get install tcl8.6 tclx valgrind -y
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: ./runtest-moduleapi --valgrind --no-latency --verbose --clients 1 --timeout 2400 --dump-logs ${{github.event.inputs.test_args}}
+ - name: unittest
+ if: true && !contains(github.event.inputs.skiptests, 'unittest')
+ run: |
+ valgrind --track-origins=yes --suppressions=./src/valgrind.sup --show-reachable=no --show-possibly-lost=no --leak-check=full --log-file=err.txt ./src/redis-server test all --valgrind
+ if grep -q 0x err.txt; then cat err.txt; exit 1; fi
+
+ test-sanitizer-address:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'sanitizer')
+ timeout-minutes: 14400
+ strategy:
+ matrix:
+ compiler: [ gcc, clang ]
+ env:
+ CC: ${{ matrix.compiler }}
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: make SANITIZER=address REDIS_CFLAGS='-DREDIS_TEST -Werror'
+ - name: testprep
+ run: |
+ sudo apt-get update
+ sudo apt-get install tcl8.6 tclx -y
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --accurate --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: ./runtest-moduleapi --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: ./runtest-cluster ${{github.event.inputs.cluster_test_args}}
+ - name: unittest
+ if: true && !contains(github.event.inputs.skiptests, 'unittest')
+ run: ./src/redis-server test all
+
+ test-sanitizer-undefined:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'sanitizer')
+ timeout-minutes: 14400
+ strategy:
+ matrix:
+ compiler: [ gcc, clang ]
+ env:
+ CC: ${{ matrix.compiler }}
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: make SANITIZER=undefined REDIS_CFLAGS='-DREDIS_TEST -Werror' LUA_DEBUG=yes # we (ab)use this flow to also check Lua C API violations
+ - name: testprep
+ run: |
+ sudo apt-get update
+ sudo apt-get install tcl8.6 tclx -y
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --accurate --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: ./runtest-moduleapi --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: ./runtest-cluster ${{github.event.inputs.cluster_test_args}}
+ - name: unittest
+ if: true && !contains(github.event.inputs.skiptests, 'unittest')
+ run: ./src/redis-server test all --accurate
+
+ test-centos7-jemalloc:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'centos')
+ container: centos:7
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: |
+ yum -y install gcc make
+ make REDIS_CFLAGS='-Werror'
+ - name: testprep
+ run: yum -y install which tcl tclx
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --accurate --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: ./runtest-moduleapi --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: ./runtest-cluster ${{github.event.inputs.cluster_test_args}}
+
+ test-centos7-tls-module:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'tls')
+ container: centos:7
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: |
+ yum -y install centos-release-scl epel-release
+ yum -y install devtoolset-7 openssl-devel openssl
+ scl enable devtoolset-7 "make BUILD_TLS=module REDIS_CFLAGS='-Werror'"
+ - name: testprep
+ run: |
+ yum -y install tcl tcltls tclx
+ ./utils/gen-test-certs.sh
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: |
+ ./runtest --accurate --verbose --dump-logs --tls-module --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: |
+ ./runtest-moduleapi --verbose --dump-logs --tls-module --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: |
+ ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: |
+ ./runtest-cluster --tls-module ${{github.event.inputs.cluster_test_args}}
+
+ test-centos7-tls-module-no-tls:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'tls')
+ container: centos:7
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: |
+ yum -y install centos-release-scl epel-release
+ yum -y install devtoolset-7 openssl-devel openssl
+ scl enable devtoolset-7 "make BUILD_TLS=module REDIS_CFLAGS='-Werror'"
+ - name: testprep
+ run: |
+ yum -y install tcl tcltls tclx
+ ./utils/gen-test-certs.sh
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: |
+ ./runtest --accurate --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: |
+ ./runtest-moduleapi --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: |
+ ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: |
+ ./runtest-cluster ${{github.event.inputs.cluster_test_args}}
+
+ test-macos-latest:
+ runs-on: macos-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'macos') && !(contains(github.event.inputs.skiptests, 'redis') && contains(github.event.inputs.skiptests, 'modules'))
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: make REDIS_CFLAGS='-Werror'
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --accurate --verbose --verbose --clients 1 --no-latency --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: ./runtest-moduleapi --verbose --verbose --clients 1 --no-latency --dump-logs ${{github.event.inputs.test_args}}
+
+ test-macos-latest-sentinel:
+ runs-on: macos-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'macos') && !contains(github.event.inputs.skiptests, 'sentinel')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: make REDIS_CFLAGS='-Werror'
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+
+ test-macos-latest-cluster:
+ runs-on: macos-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'macos') && !contains(github.event.inputs.skiptests, 'cluster')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: make REDIS_CFLAGS='-Werror'
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: ./runtest-cluster ${{github.event.inputs.cluster_test_args}}
+
+ test-freebsd:
+ runs-on: macos-12
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'freebsd') && !(contains(github.event.inputs.skiptests, 'redis') && contains(github.event.inputs.skiptests, 'modules'))
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: test
+ uses: vmactions/freebsd-vm@v0.3.1
+ with:
+ usesh: true
+ sync: rsync
+ copyback: false
+ prepare: pkg install -y bash gmake lang/tcl86 lang/tclx
+ run: >
+ gmake || exit 1 ;
+ if echo "${{github.event.inputs.skiptests}}" | grep -vq redis ; then ./runtest --verbose --timeout 2400 --no-latency --dump-logs ${{github.event.inputs.test_args}} || exit 1 ; fi ;
+ if echo "${{github.event.inputs.skiptests}}" | grep -vq modules ; then MAKE=gmake ./runtest-moduleapi --verbose --timeout 2400 --no-latency --dump-logs ${{github.event.inputs.test_args}} || exit 1 ; fi ;
+
+ test-freebsd-sentinel:
+ runs-on: macos-12
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'freebsd') && !contains(github.event.inputs.skiptests, 'sentinel')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: test
+ uses: vmactions/freebsd-vm@v0.3.1
+ with:
+ usesh: true
+ sync: rsync
+ copyback: false
+ prepare: pkg install -y bash gmake lang/tcl86 lang/tclx
+ run: >
+ gmake || exit 1 ;
+ if echo "${{github.event.inputs.skiptests}}" | grep -vq sentinel ; then ./runtest-sentinel ${{github.event.inputs.cluster_test_args}} || exit 1 ; fi ;
+
+ test-freebsd-cluster:
+ runs-on: macos-12
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'freebsd') && !contains(github.event.inputs.skiptests, 'cluster')
+ timeout-minutes: 14400
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: test
+ uses: vmactions/freebsd-vm@v0.3.1
+ with:
+ usesh: true
+ sync: rsync
+ copyback: false
+ prepare: pkg install -y bash gmake lang/tcl86 lang/tclx
+ run: >
+ gmake || exit 1 ;
+ if echo "${{github.event.inputs.skiptests}}" | grep -vq cluster ; then ./runtest-cluster ${{github.event.inputs.cluster_test_args}} || exit 1 ; fi ;
+
+ test-alpine-jemalloc:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'alpine')
+ container: alpine:latest
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: |
+ apk add build-base
+ make REDIS_CFLAGS='-Werror'
+ - name: testprep
+ run: apk add tcl procps tclx
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --accurate --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: ./runtest-moduleapi --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: ./runtest-cluster ${{github.event.inputs.cluster_test_args}}
+
+ test-alpine-libc-malloc:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'alpine')
+ container: alpine:latest
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: |
+ apk add build-base
+ make REDIS_CFLAGS='-Werror' USE_JEMALLOC=no CFLAGS=-DUSE_MALLOC_USABLE_SIZE
+ - name: testprep
+ run: apk add tcl procps tclx
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --accurate --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: ./runtest-moduleapi --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: ./runtest-sentinel ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: ./runtest-cluster ${{github.event.inputs.cluster_test_args}}
+
+ reply-schemas-validator:
+ runs-on: ubuntu-latest
+ timeout-minutes: 14400
+ if: |
+ (github.event_name == 'workflow_dispatch' || (github.event_name != 'workflow_dispatch' && github.repository == 'redis/redis')) &&
+ !contains(github.event.inputs.skipjobs, 'reply-schema')
+ steps:
+ - name: prep
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "GITHUB_REPOSITORY=${{github.event.inputs.use_repo}}" >> $GITHUB_ENV
+ echo "GITHUB_HEAD_REF=${{github.event.inputs.use_git_ref}}" >> $GITHUB_ENV
+ echo "skipjobs: ${{github.event.inputs.skipjobs}}"
+ echo "skiptests: ${{github.event.inputs.skiptests}}"
+ echo "test_args: ${{github.event.inputs.test_args}}"
+ echo "cluster_test_args: ${{github.event.inputs.cluster_test_args}}"
+ - uses: actions/checkout@v3
+ with:
+ repository: ${{ env.GITHUB_REPOSITORY }}
+ ref: ${{ env.GITHUB_HEAD_REF }}
+ - name: make
+ run: make REDIS_CFLAGS='-Werror -DLOG_REQ_RES'
+ - name: testprep
+ run: sudo apt-get install tcl8.6 tclx
+ - name: test
+ if: true && !contains(github.event.inputs.skiptests, 'redis')
+ run: ./runtest --log-req-res --no-latency --dont-clean --force-resp3 --tags -slow --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: module api test
+ if: true && !contains(github.event.inputs.skiptests, 'modules')
+ run: ./runtest-moduleapi --log-req-res --no-latency --dont-clean --force-resp3 --dont-pre-clean --verbose --dump-logs ${{github.event.inputs.test_args}}
+ - name: sentinel tests
+ if: true && !contains(github.event.inputs.skiptests, 'sentinel')
+ run: ./runtest-sentinel --log-req-res --dont-clean --force-resp3 ${{github.event.inputs.cluster_test_args}}
+ - name: cluster tests
+ if: true && !contains(github.event.inputs.skiptests, 'cluster')
+ run: ./runtest-cluster --log-req-res --dont-clean --force-resp3 ${{github.event.inputs.cluster_test_args}}
+ - name: Install Python dependencies
+ uses: py-actions/py-dependency-install@v4
+ with:
+ path: "./utils/req-res-validator/requirements.txt"
+ - name: validator
+ run: ./utils/req-res-log-validator.py --verbose --fail-missing-reply-schemas ${{ (!contains(github.event.inputs.skiptests, 'redis') && !contains(github.event.inputs.skiptests, 'module') && !contains(github.event.inputs.sentinel, 'redis') && !contains(github.event.inputs.skiptests, 'cluster')) && github.event.inputs.test_args == '' && github.event.inputs.cluster_test_args == '' && '--fail-commands-not-all-hit' || '' }}
+
diff --git a/.github/workflows/external.yml b/.github/workflows/external.yml
new file mode 100644
index 0000000..15a9afb
--- /dev/null
+++ b/.github/workflows/external.yml
@@ -0,0 +1,82 @@
+name: External Server Tests
+
+on:
+ pull_request:
+ push:
+ schedule:
+ - cron: '0 0 * * *'
+
+jobs:
+ test-external-standalone:
+ runs-on: ubuntu-latest
+ if: github.event_name != 'schedule' || github.repository == 'redis/redis'
+ timeout-minutes: 14400
+ steps:
+ - uses: actions/checkout@v3
+ - name: Build
+ run: make REDIS_CFLAGS=-Werror
+ - name: Start redis-server
+ run: |
+ ./src/redis-server --daemonize yes --save "" --logfile external-redis.log \
+ --enable-protected-configs yes --enable-debug-command yes --enable-module-command yes
+ - name: Run external test
+ run: |
+ ./runtest \
+ --host 127.0.0.1 --port 6379 \
+ --tags -slow
+ - name: Archive redis log
+ if: ${{ failure() }}
+ uses: actions/upload-artifact@v3
+ with:
+ name: test-external-redis-log
+ path: external-redis.log
+
+ test-external-cluster:
+ runs-on: ubuntu-latest
+ if: github.event_name != 'schedule' || github.repository == 'redis/redis'
+ timeout-minutes: 14400
+ steps:
+ - uses: actions/checkout@v3
+ - name: Build
+ run: make REDIS_CFLAGS=-Werror
+ - name: Start redis-server
+ run: |
+ ./src/redis-server --cluster-enabled yes --daemonize yes --save "" --logfile external-redis.log \
+ --enable-protected-configs yes --enable-debug-command yes --enable-module-command yes
+ - name: Create a single node cluster
+ run: ./src/redis-cli cluster addslots $(for slot in {0..16383}; do echo $slot; done); sleep 5
+ - name: Run external test
+ run: |
+ ./runtest \
+ --host 127.0.0.1 --port 6379 \
+ --cluster-mode \
+ --tags -slow
+ - name: Archive redis log
+ if: ${{ failure() }}
+ uses: actions/upload-artifact@v3
+ with:
+ name: test-external-cluster-log
+ path: external-redis.log
+
+ test-external-nodebug:
+ runs-on: ubuntu-latest
+ if: github.event_name != 'schedule' || github.repository == 'redis/redis'
+ timeout-minutes: 14400
+ steps:
+ - uses: actions/checkout@v3
+ - name: Build
+ run: make REDIS_CFLAGS=-Werror
+ - name: Start redis-server
+ run: |
+ ./src/redis-server --daemonize yes --save "" --logfile external-redis.log
+ - name: Run external test
+ run: |
+ ./runtest \
+ --host 127.0.0.1 --port 6379 \
+ --tags "-slow -needs:debug"
+ - name: Archive redis log
+ if: ${{ failure() }}
+ uses: actions/upload-artifact@v3
+ with:
+ name: test-external-redis-log
+ path: external-redis.log
diff --git a/.github/workflows/reply-schemas-linter.yml b/.github/workflows/reply-schemas-linter.yml
new file mode 100644
index 0000000..13fc8ab
--- /dev/null
+++ b/.github/workflows/reply-schemas-linter.yml
@@ -0,0 +1,22 @@
+name: Reply-schemas linter
+
+on:
+ push:
+ paths:
+ - 'src/commands/*.json'
+ pull_request:
+ paths:
+ - 'src/commands/*.json'
+
+jobs:
+ reply-schemas-linter:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Setup nodejs
+ uses: actions/setup-node@v3
+ - name: Install packages
+ run: npm install ajv
+ - name: linter
+ run: node ./utils/reply_schema_linter.js
+
diff --git a/.github/workflows/spell-check.yml b/.github/workflows/spell-check.yml
new file mode 100644
index 0000000..5336074
--- /dev/null
+++ b/.github/workflows/spell-check.yml
@@ -0,0 +1,32 @@
+# A CI action that using codespell to check spell.
+# .github/.codespellrc is a config file.
+# .github/wordlist.txt is a list of words that will ignore word checks.
+# More details please check the following link:
+# https://github.com/codespell-project/codespell
+name: Spellcheck
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ build:
+ name: Spellcheck
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: pip cache
+ uses: actions/cache@v3
+ with:
+ path: ~/.cache/pip
+ key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
+ restore-keys: ${{ runner.os }}-pip-
+
+ - name: Install prerequisites
+ run: sudo pip install -r ./.codespell/requirements.txt
+
+ - name: Spell check
+ run: codespell --config=./.codespell/.codespellrc
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5ed94f1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,43 @@
+.*.swp
+*.o
+*.xo
+*.so
+*.d
+*.log
+dump.rdb
+redis-benchmark
+redis-check-aof
+redis-check-rdb
+redis-check-dump
+redis-cli
+redis-sentinel
+redis-server
+doc-tools
+release
+misc/*
+src/release.h
+appendonly.aof*
+appendonlydir
+SHORT_TERM_TODO
+release.h
+src/transfer.sh
+src/configs
+redis.ds
+src/redis.conf
+src/nodes.conf
+deps/lua/src/lua
+deps/lua/src/luac
+deps/lua/src/liblua.a
+deps/hdr_histogram/libhdrhistogram.a
+deps/fpconv/libfpconv.a
+tests/tls/*
+.make-*
+.prerequisites
+*.dSYM
+Makefile.dep
+.vscode/*
+.idea/*
+.ccls
+.ccls-cache/*
+compile_commands.json
+redis.code-workspace
diff --git a/00-RELEASENOTES b/00-RELEASENOTES
new file mode 100644
index 0000000..40efaba
--- /dev/null
+++ b/00-RELEASENOTES
@@ -0,0 +1,510 @@
+Redis 7.2 release notes
+=======================
+
+--------------------------------------------------------------------------------
+Upgrade urgency levels:
+
+LOW: No need to upgrade unless there are new features you want to use.
+MODERATE: Program an upgrade of the server, but it's not urgent.
+HIGH: There is a critical bug that may affect a subset of users. Upgrade!
+CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP.
+SECURITY: There are security fixes in the release.
+--------------------------------------------------------------------------------
+
+
+================================================================================
+Redis 7.2.4 Released Tue 09 Jan 2024 10:45:52 IST
+================================================================================
+
+Upgrade urgency SECURITY: See security fixes below.
+
+Security fixes
+==============
+* (CVE-2023-41056) In some cases, Redis may incorrectly handle resizing of memory
+ buffers which can result in incorrect accounting of buffer sizes and lead to
+ heap overflow and potential remote code execution.
+
+Bug fixes
+=========
+
+* Fix crashes of cluster commands clusters with mixed versions of 7.0 and 7.2 (#12805, #12832)
+* Fix slot ownership not being properly handled when deleting a slot from a node (#12564)
+* Fix atomicity issues with the RedisModuleEvent_Key module API event (#12733)
+
+
+================================================================================
+Redis 7.2.3 Released Wed 01 Nov 2023 12:00:00 IST
+================================================================================
+
+Upgrade urgency: HIGH, Fixes critical bugs affecting most users.
+
+Bug fixes
+=========
+
+* Fix file descriptor leak preventing deleted files from freeing disk space on
+ replicas (#12693)
+* Fix a possible crash after cluster node removal (#12702)
+
+
+================================================================================
+Redis 7.2.2 Released Wed 18 Oct 2023 10:33:40 IDT
+================================================================================
+
+Upgrade urgency SECURITY: See security fixes below.
+
+Security fixes
+==============
+
+* (CVE-2023-45145) The wrong order of listen(2) and chmod(2) calls creates a
+ race condition that can be used by another process to bypass desired Unix
+ socket permissions on startup.
+
+
+Platform / toolchain support related changes
+=================================================
+
+* Fix compilation error on MacOS 13 (#12611)
+
+Bug fixes
+=========
+
+* WAITAOF could timeout in the absence of write traffic in case a new AOF is
+ created and an AOF rewrite can't immediately start (#12620)
+
+Redis cluster
+=============
+
+* Fix crash when running rebalance command in a mixed cluster of 7.0 and 7.2
+ nodes (#12604)
+* Fix the return type of the slot number in cluster shards to integer, which
+ makes it consistent with past behavior (#12561)
+* Fix CLUSTER commands are called from modules or scripts to return TLS info
+ appropriately (#12569)
+
+Changes in CLI tools
+====================
+
+* redis-cli, fix crash on reconnect when in SUBSCRIBE mode (#12571)
+
+Module API changes
+==================
+
+* Fix overflow calculation for next timer event (#12474)
+
+
+================================================================================
+Redis 7.2.1 Released Wed 06 Sep 2023 15:00:00 IDT
+================================================================================
+
+Upgrade urgency SECURITY: See security fixes below.
+
+Security Fixes
+==============
+
+* (CVE-2023-41053) Redis does not correctly identify keys accessed by SORT_RO and,
+ as a result, may grant users executing this command access to keys that are not
+ explicitly authorized by the ACL configuration.
+
+
+Bug Fixes
+=========
+
+* Fix crashes when joining a node to an existing 7.0 Redis Cluster (#12538)
+* Correct request_policy and response_policy command tips on for some admin /
+ configuration commands (#12545, #12530)
+
+
+================================================================================
+Redis 7.2.0 GA Released Tue Aug 15 12:00:00 IDT 2023
+================================================================================
+
+Upgrade urgency LOW: This is the first stable Release for Redis 7.2.
+
+Bug Fixes
+=========
+
+* redis-cli in cluster mode handles `unknown-endpoint` (#12273)
+* Update request / response policy hints for a few commands (#12417)
+* Ensure that the function load timeout is disabled during loading from RDB/AOF and on replicas. (#12451)
+* Fix false success and a memory leak for ACL selector with bad parenthesis combination (#12452)
+* Fix the assertion when script timeout occurs after it signaled a blocked client (#12459)
+
+Fixes for issues in previous releases of Redis 7.2
+--------------------------------------------------
+
+* Update MONITOR client's memory correctly for INFO and client-eviction (#12420)
+* The response of cluster nodes was unnecessarily adding an extra comma when no
+ hostname was present. (#12411)
+
+================================================================================
+Redis 7.2 RC3 Released Mon July 10 12:00:00 IDT 2023
+================================================================================
+
+Upgrade urgency LOW: This is the third Release Candidate for Redis 7.2.
+Upgrade urgency SECURITY: If you're using a previous release candidate of 7.2.
+
+Security Fixes:
+* (CVE-2022-24834) A specially crafted Lua script executing in Redis can trigger
+ a heap overflow in the cjson and cmsgpack libraries, and result in heap
+ corruption and potentially remote code execution. The problem exists in all
+ versions of Redis with Lua scripting support, starting from 2.6, and affects
+ only authenticated and authorized users.
+* (CVE-2023-36824) Extracting key names from a command and a list of arguments
+ may, in some cases, trigger a heap overflow and result in reading random heap
+ memory, heap corruption and potentially remote code execution. Specifically:
+ using COMMAND GETKEYS* and validation of key names in ACL rules.
+
+New Features
+============
+
+New administrative and introspection commands and command arguments
+-------------------------------------------------------------------
+
+* Make SENTINEL CONFIG [SET|GET] variadic. (#10362)
+
+Potentially Breaking / Behavior Changes
+=======================================
+
+* Cluster SHARD IDs are no longer visible in the cluster nodes output,
+ introduced in 7.2-RC1. (#10536, #12166)
+* When calling PUBLISH with a RESP3 client that's also subscribed to the same channel,
+ the order is changed and the reply is sent before the published message (#12326)
+
+New configuration options
+=========================
+
+* Add a new loglevel "nothing" to disable logging (#12133)
+* Add cluster-announce-human-nodename - a unique identifier for a node that is
+ be used in logs for debugging (#9564)
+
+Other General Improvements
+==========================
+
+* Allow CLUSTER SLOTS / SHARDS commands during loading (#12269)
+* Support TLS service when "tls-cluster" is not enabled and persist both plain
+ and TLS port in nodes.conf (#12233)
+* Update SPOP and RESTORE commands to replicate unlink commands to replicas
+ when the server is configured to use async server deletes (#12320)
+* Try lazyfree the temporary zset in ZUNION / ZINTER / ZDIFF (#12229)
+
+Performance and resource utilization improvements
+=================================================
+
+* Optimize PSUBSCRIBE and PUNSUBSCRIBE from O(N*M) to O(N) (#12298)
+* Optimize SCAN, SSCAN, HSCAN, ZSCAN commands (#12209)
+* Set Jemalloc --disable-cache-oblivious to reduce memory overhead (#12315)
+* Optimize ZINTERCARD to avoid create a temporary zset (#12229)
+* Optimize HRANDFIELD and ZRANDMEMBER listpack encoded (#12205)
+* Numerous other optimizations (#12155, #12082, #11626, #11944, #12316, #12250,
+ #12177, #12185)
+
+
+Changes in CLI tools
+====================
+
+* redis-cli: Handle RESP3 double responses that contain a NaN (#12254)
+* redis-cli: Support URIs with IPv6 (#11834)
+
+Module API changes
+==================
+
+* Align semantics of the new (v7.2 RC2) RM_ReplyWithErrorFormat with RM_ReplyWithError.
+ This is a breaking change that affects the generated error code. (#12321)
+* Forbid RM_AddPostNotificationJob on loading and on read-only replicas (#12304)
+* Add ability for module command filter to know which client is being handled (#12219)
+
+Bug Fixes
+=========
+
+* Fix broken protocol when PUBLISH is used inside MULTI when the RESP3
+ publishing client is also subscribed for the channel (#12326)
+* Fix WAIT to be effective after a blocked module command being unblocked (#12220)
+* Re-enable downscale rehashing while there is a fork child (#12276)
+* Fix possible hang in HRANDFIELD, SRANDMEMBER, ZRANDMEMBER when used with `<count>` (#12276)
+* Improve fairness issue in RANDOMKEY, HRANDFIELD, SRANDMEMBER, ZRANDMEMBER, SPOP, and eviction (#12276)
+* Cluster: fix a race condition where a slot migration may revert on a subsequent failover or node joining (#12344)
+
+Fixes for issues in previous releases of Redis 7.2
+--------------------------------------------------
+
+* Fix XREADGROUP BLOCK with ">" from hanging (#12301)
+* Fix assertion when a blocked command is rejected when re-processed. (#12247)
+* Fix use after free on a blocking RM_Call. (#12342)
+
+================================================================================
+Redis 7.2 RC2 Released Mon May 15 12:00:00 IST 2023
+================================================================================
+
+Upgrade urgency LOW: This is the second Release Candidate for Redis 7.2.
+
+INFO fields and introspection changes
+=====================================
+
+* Add a few low level event loop metrics to help diagnose latency (#11963)
+
+Performance and resource utilization improvements
+=================================================
+
+* Minor performance improvement to SADD and HSET (#12019)
+
+Platform / toolchain support related changes
+=================================================
+
+* Upgrade to Jemalloc 5.3.0, resolves a rare fork child hang (#12115)
+* Fix a compiler fortification induced crash when used with link time optimizations (#11982)
+* Fix local clients detection, 127.*.*.* instead of 127.0.0.1 (#11664)
+* Report AOF failure status to systemd in shutdown (#12065)
+
+Changes in CLI tools
+====================
+
+* redis-cli: Reimplement and improve help hints based on actual command arg docs (#10515)
+* redis-cli: Add option --count for tuning SCAN based features (#12042)
+* redis-benchmark: Add --seed option to seed the random number generator (#11945)
+
+Module API changes
+==================
+
+* Add RM_RdbLoad and RM_RdbSave APIs (#11852)
+* Add RM_ReplyWithErrorFormat that can support format string (#11923)
+* Fix: Delete empty key when RM_ZsetAdd, RM_ZsetIncrby, RM_StreamAdd fail (#12129)
+
+Bug Fixes
+=========
+
+* LPOS with RANK set to LONG_MIN returning wrong result (#12167)
+* Avoid unnecessary full sync after master restart in a rare case (#12088)
+* Iterate clients fairly when processing background chores (#12025)
+* Avoid incorrect shrinking of query buffer when reading large data from clients (#12000)
+* Sentinel: Fix config rewrite error when old known-slave is used (#11775)
+* ACL: Disconnect pub-sub subscribers when revoking allchannels permission (#11992)
+* Add a missing fsync of AOF file in rare cases (#11973)
+
+Fixes for issues in previous releases of Redis 7.2
+--------------------------------------------------
+
+* Fix tracking of command duration metrics for MULTI, EVAL, WAIT and modules (#11970)
+
+================================================================================
+Redis 7.2 RC1 Released Wed Mar 22 12:00:00 IST 2023
+================================================================================
+
+Upgrade urgency LOW: This is the first Release Candidate for Redis 7.2.
+
+Redis Release Candidate (RC) versions are early versions that are made available
+for early adopters in the community to test them. We do not consider
+them suitable for production environments.
+
+Introduction to the Redis 7.2 release
+=====================================
+
+Redis 7.2 includes optimizations, several new commands, some improvements,
+bug fixes, and several new module APIs.
+
+In particular, users should be aware of the following changes:
+
+1. Redis 7.2 uses a new format (version 11) for RDB files, which is incompatible
+ with older versions.
+2. See section about breaking changes mentioned below.
+3. If you use modules, see the module API breaking changes section below.
+
+Here is a comprehensive list of changes in this release compared to 7.0.10.
+Each one includes the PR number that added it so that you can get more details
+at https://github.com/redis/redis/pull/<number>
+
+New Features
+============
+
+* Introduce WAITAOF command, to block the client until a specified number
+ of Redises have synced all previous write commands to the AOF on disk,
+ see https://redis.io/commands/waitaof/
+
+New user commands or command arguments
+--------------------------------------
+
+* WAITAOF blocks until writes have been synced to disk (#11713)
+* Add WITHSCORE option to ZRANK and ZREVRANK (#11235)
+
+New administrative and introspection commands and command arguments
+-------------------------------------------------------------------
+
+* CLIENT SETINFO lets client library report name and version Redis (#11758)
+* CLIENT NO-TOUCH for clients to run commands without affecting LRU/LFU of keys (#11483)
+* Introduce Shard IDs to logically group nodes in cluster mode based on
+ replication. Shard IDs are automatically assigned and visible via
+ `CLUSTER MYSHARDID`. (#10536)
+
+Command replies that have been extended
+---------------------------------------
+
+* ACL LOG - Add entry id, timestamp created, and timestamp last updated time (#11477)
+* COMMAND DOCS - Repurpose arg names as the unique ID (#11051)
+* CLIENT LIST has `T` flag to indicate CLIENT NO-TOUCH (#11483)
+* CLIENT LIST show lib-name, lib-ver (#11758)
+
+Potentially Breaking / Behavior Changes
+=======================================
+
+* Client side tracking for scripts now tracks the keys that are read by the
+ script instead of the keys that are declared by the caller of EVAL / FCALL (#11770)
+* Freeze time sampling during command execution and in scripts (#10300)
+* When a blocked command is being unblocked, checks like ACL, OOM, etc are
+ re-evaluated (#11012)
+* Unify ACL failure error message text and error codes (#11160)
+* Blocked stream command that's released when key no longer exists carries a
+ different error code (#11012)
+* Command stats are updated for blocked commands only when / if the command
+ actually executes (#11012)
+* The way ACL users are stored internally no longer removes redundant command
+ and category rules, which may alter the way those rules are displayed as part
+ of `ACL SAVE`, `ACL GETUSER` and `ACL LIST` (#11224)
+* Client connections created for TLS-based replication use SNI if possible (#11458)
+* Stream consumers: Re-purpose seen-time, add active-time (#11099)
+* XREADGROUP and X[AUTO]CLAIM create the consumer regardless of whether it was
+ able to perform some reading/claiming (#11099)
+* ACL default newly created user set sanitize-payload flag in ACL LIST/GETUSER #11279
+* Fix HELLO command not to affect the client state unless successful (#11659)
+* Normalize `NAN` in replies to a single nan type, like we do with `inf` (#11597)
+
+Deprecations
+============
+
+* Mark the QUIT command as deprecated (#11439)
+* Delete RDB loading code for pre-release RDB formats (#11058)
+
+Performance and resource utilization improvements
+=================================================
+
+* Significant memory optimization of small list type keys (#11303)
+* Significant memory optimization for small set type keys (#11290)
+* Significant memory optimization for large sets (#11595)
+* Significant speed optimization in ZRANGE replies WITHSCORES in case of integer scores (#11779)
+* Significant speed optimization in double replies, mainly sorted sets commands (#10587)
+* Optimize the performance of commands with multiple keys in cluster mode (#11044)
+* Incrementally reclaim OS page cache of RDB file (#11248)
+* Improve memory management of cluster bus links when there is a large number of pending messages (#11343)
+* Minor performance improvement for workloads that use commands without pipelining (#11220)
+
+Changes in CLI tools
+====================
+
+* redis-cli accepts commands in subscribed mode (#11873)
+
+Other General Improvements
+==========================
+
+* WAIT now no longer waits for the replication offset after your last command,
+ but rather the replication offset after your last write (#11713)
+* Automatically propagate node deletion to other nodes in a cluster when
+ `CLUSTER FORGET` is called, allowing nodes to be deleted with a single call
+ in most cases (#10869)
+* Blocking commands that were disallowed in scripts now behave in scripts the
+ same they did in MULTI (#11568)
+
+Platform / toolchain support related changes
+=================================================
+
+* 32-bit builds compiled without HAVE_MALLOC_SIZE (not jemalloc or glibc)
+ will consume more memory (#11595)
+* Use jemalloc by default also on ARM (#11407)
+* Adds stack trace and register dump support in crash report for illumos/solaris (#11335)
+
+
+New configuration options
+=========================
+
+* locale-collate runtime config to control setlocale affecting Lua and SORT (#11059)
+* Add CONFIG SET and GET loglevel feature in Sentinel (#11214)
+
+INFO fields and introspection changes
+=====================================
+
+* Added 4 new info fields for authentication errors and commands denied access
+ for keys, channels and commands (#11288)
+* INFO SERVER includes a list of listeners (#9320)
+
+
+Module API changes
+==================
+
+* Make it possible for module commands to be part of ACL categories (#11708)
+* Add K flag to RM_Call to allow running blocking commands and set a callback to get the response (#11568)
+* Add RM_AddPostNotificationJob to allow writes after keyspace notification hooks (#11199)
+* RedisModule_Event_Key to notify about keys being unlinked together with reason and value (#9406)
+* Add RM_BlockClient[Set|Get]PrivateData to associate a module data with the blocked client (#11568)
+* APIs to allow modules to participate / handle AUTH validation (#11659)
+* RM_GetContextFlags supports a new flag: REDISMODULE_CTX_FLAGS_SERVER_STARTUP (#9320)
+* Add REDISMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS and RedisModule_GetModuleOptionsAll (#11199)
+* RM_BlockClientOnKeysWithFlags allows module to request being unblocked when the key is deleted (#11310)
+* Introduce aux_save2 makes it possible to skip saving that field in the RDB and
+ enable loading the file in the absence of the module (#11374)
+* Add a dry run flag to RM_Call to do validations before actual execution (#11158)
+* Add RM_Microseconds and RM_CachedMicroseconds (#11016)
+* Add RM_ACLAddLogEntryByUserName API to be used without a user object (#11659)
+* Make it possible to keep the RM_Call reply for longer than the context lifetime in case
+ auto memory was not used (#11568)
+
+Potentially Breaking Changes in Module API
+------------------------------------------
+
+* RM_Call only enforces OOM on scripts if 'M' flag is set (#11425)
+* Block some specific characters in module command names (#11434)
+* Fix replication inconsistency on modules that uses keyspace notifications (#10969)
+* Prevent command, configs, data types registration after the onload handler (#11708)
+
+Bug Fixes
+=========
+
+* Introduce socket shutdown to properly disconnect a client while a fork is active (#11376)
+* CLIENT RESET clears the CLIENT NO-EVICT flag (#11483)
+* Reduce memory usage on strings loaded by a module from an RDB file (#11050)
+* Fix a bug where nodes in a cluster may not replicate or handle internal events for
+ keys deleted when another node in the cluster claimed a slot (#11084)
+* Fix HINCRBYFLOAT not to create a key if the new value is invalid (#11149)
+* Make cluster config file saving atomic and fsync acl file saving (#10924)
+* WAIT command would not block if used in RM_Call (#11713)
+* Minor fixes to command metadata in COMMAND command (#11201, #10273)
+
+
+Thanks to all the users and developers who made this release possible.
+We'll follow up with more RC releases, until the code looks production ready
+and we don't get reports of serious issues for a while.
+
+A special thank you for the amount of work put into this release by:
+
+- Meir Shpilraien
+- Guy Benoish
+- Viktor Söderqvist
+- Zhu Binbin
+- Oran Agra
+- sundb
+- Ran Shidlansik
+- Zhenwei Pi
+- Jason Elbaum
+- Karthik Subbarao
+- Madelyn Olson
+- Huang Zhw
+- Ping Xie
+- Ozan Tezcan
+- Chen Tianjie
+- Deng Ju
+- Wen Hui
+- Brennan Cathcart
+- Itamar Haber
+- Shaya Potter
+- Roshan Khatri
+- Slava Koyfman
+- Zhu Tian
+- Moti Cohen
+- Arad Zilberstein
+- Basel Naamna
+- Mingyi Kang
+- Uri Yagelnik
+- Filipe Oliveira
+- Zhao Zhao
+- Valentino Geron
+- Yaacov Hazan
+- Adi Pinsky
+- David Carlier
+- Li Changjun
+
diff --git a/BUGS b/BUGS
new file mode 100644
index 0000000..7af2593
--- /dev/null
+++ b/BUGS
@@ -0,0 +1 @@
+Please check https://github.com/redis/redis/issues
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..d66769b
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,96 @@
+Contributor Covenant Code of Conduct
+Our Pledge
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+Our Standards
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others’ private information, such as a physical or email
+address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+professional setting
+
+Enforcement Responsibilities
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+Scope
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+Enforcement
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+this email address: redis@redis.io.
+All complaints will be reviewed and investigated promptly and fairly.
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+Enforcement Guidelines
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+1. Correction
+Community Impact: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+Consequence: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+2. Warning
+Community Impact: A violation through a single incident or series
+of actions.
+Consequence: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+3. Temporary Ban
+Community Impact: A serious violation of community standards, including
+sustained inappropriate behavior.
+Consequence: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+4. Permanent Ban
+Community Impact: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+Consequence: A permanent ban from any sort of public interaction within
+the community.
+Attribution
+This Code of Conduct is adapted from the Contributor Covenant,
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+Community Impact Guidelines were inspired by Mozilla’s code of conduct
+enforcement ladder.
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..56b7183
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,56 @@
+Note: by contributing code to the Redis project in any form, including sending
+a pull request via Github, a code fragment or patch via private email or
+public discussion groups, you agree to release your code under the terms
+of the BSD license that you can find in the COPYING file included in the Redis
+source distribution. You will include BSD license in the COPYING file within
+each source file that you contribute.
+
+# IMPORTANT: HOW TO USE REDIS GITHUB ISSUES
+
+Github issues SHOULD ONLY BE USED to report bugs, and for DETAILED feature
+requests. Everything else belongs to the Redis Google Group:
+
+ https://groups.google.com/forum/m/#!forum/Redis-db
+
+PLEASE DO NOT POST GENERAL QUESTIONS that are not about bugs or suspected
+bugs in the Github issues system. We'll be very happy to help you and provide
+all the support in the mailing list.
+
+There is also an active community of Redis users at Stack Overflow:
+
+ https://stackoverflow.com/questions/tagged/redis
+
+Issues and pull requests for documentation belong on the redis-doc repo:
+
+ https://github.com/redis/redis-doc
+
+If you are reporting a security bug or vulnerability, see SECURITY.md.
+
+# How to provide a patch for a new feature
+
+1. If it is a major feature or a semantical change, please don't start coding
+straight away: if your feature is not a conceptual fit you'll lose a lot of
+time writing the code without any reason. Start by posting in the mailing list
+and creating an issue at Github with the description of, exactly, what you want
+to accomplish and why. Use cases are important for features to be accepted.
+Here you'll see if there is consensus about your idea.
+
+2. If in step 1 you get an acknowledgment from the project leaders, use the
+ following procedure to submit a patch:
+
+ a. Fork Redis on github ( https://docs.github.com/en/github/getting-started-with-github/fork-a-repo )
+ b. Create a topic branch (git checkout -b my_branch)
+ c. Push to your branch (git push origin my_branch)
+ d. Initiate a pull request on github ( https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request )
+ e. Done :)
+
+3. Keep in mind that we are very overloaded, so issues and PRs sometimes wait
+for a *very* long time. However this is not lack of interest, as the project
+gets more and more users, we find ourselves in a constant need to prioritize
+certain issues/PRs over others. If you think your issue/PR is very important
+try to popularize it, have other users commenting and sharing their point of
+view and so forth. This helps.
+
+4. For minor fixes just open a pull request on Github.
+
+Thanks!
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..a381681
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,10 @@
+Copyright (c) 2006-2020, Salvatore Sanfilippo
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of Redis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..3083f1a
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1 @@
+See README
diff --git a/MANIFESTO b/MANIFESTO
new file mode 100644
index 0000000..3727894
--- /dev/null
+++ b/MANIFESTO
@@ -0,0 +1,106 @@
+[Note: this is the Redis manifesto, for general information about
+ installing and running Redis read the README file instead.]
+
+Redis Manifesto
+===============
+
+1 - A DSL for Abstract Data Types. Redis is a DSL (Domain Specific Language)
+ that manipulates abstract data types and implemented as a TCP daemon.
+ Commands manipulate a key space where keys are binary-safe strings and
+ values are different kinds of abstract data types. Every data type
+ represents an abstract version of a fundamental data structure. For instance
+ Redis Lists are an abstract representation of linked lists. In Redis, the
+ essence of a data type isn't just the kind of operations that the data types
+ support, but also the space and time complexity of the data type and the
+ operations performed upon it.
+
+2 - Memory storage is #1. The Redis data set, composed of defined key-value
+ pairs, is primarily stored in the computer's memory. The amount of memory in
+ all kinds of computers, including entry-level servers, is increasing
+ significantly each year. Memory is fast, and allows Redis to have very
+ predictable performance. Datasets composed of 10k or 40 millions keys will
+ perform similarly. Complex data types like Redis Sorted Sets are easy to
+ implement and manipulate in memory with good performance, making Redis very
+ simple. Redis will continue to explore alternative options (where data can
+ be optionally stored on disk, say) but the main goal of the project remains
+ the development of an in-memory database.
+
+3 - Fundamental data structures for a fundamental API. The Redis API is a direct
+ consequence of fundamental data structures. APIs can often be arbitrary but
+ not an API that resembles the nature of fundamental data structures. If we
+ ever meet intelligent life forms from another part of the universe, they'll
+ likely know, understand and recognize the same basic data structures we have
+ in our computer science books. Redis will avoid intermediate layers in API,
+ so that the complexity is obvious and more complex operations can be
+ performed as the sum of the basic operations.
+
+4 - We believe in code efficiency. Computers get faster and faster, yet we
+ believe that abusing computing capabilities is not wise: the amount of
+ operations you can do for a given amount of energy remains anyway a
+ significant parameter: it allows to do more with less computers and, at
+ the same time, having a smaller environmental impact. Similarly Redis is
+ able to "scale down" to smaller devices. It is perfectly usable in a
+ Raspberry Pi and other small ARM based computers. Faster code having
+ just the layers of abstractions that are really needed will also result,
+ often, in more predictable performances. We think likewise about memory
+ usage, one of the fundamental goals of the Redis project is to
+ incrementally build more and more memory efficient data structures, so that
+ problems that were not approachable in RAM in the past will be perfectly
+ fine to handle in the future.
+
+5 - Code is like a poem; it's not just something we write to reach some
+ practical result. Sometimes people that are far from the Redis philosophy
+ suggest using other code written by other authors (frequently in other
+ languages) in order to implement something Redis currently lacks. But to us
+ this is like if Shakespeare decided to end Enrico IV using the Paradiso from
+ the Divina Commedia. Is using any external code a bad idea? Not at all. Like
+ in "One Thousand and One Nights" smaller self contained stories are embedded
+ in a bigger story, we'll be happy to use beautiful self contained libraries
+ when needed. At the same time, when writing the Redis story we're trying to
+ write smaller stories that will fit in to other code.
+
+6 - We're against complexity. We believe designing systems is a fight against
+ complexity. We'll accept to fight the complexity when it's worthwhile but
+ we'll try hard to recognize when a small feature is not worth 1000s of lines
+ of code. Most of the time the best way to fight complexity is by not
+ creating it at all. Complexity is also a form of lock-in: code that is
+ very hard to understand cannot be modified by users in an independent way
+ regardless of the license. One of the main Redis goals is to remain
+ understandable, enough for a single programmer to have a clear idea of how
+ it works in detail just reading the source code for a couple of weeks.
+
+7 - Threading is not a silver bullet. Instead of making Redis threaded we
+ believe on the idea of an efficient (mostly) single threaded Redis core.
+ Multiple of such cores, that may run in the same computer or may run
+ in multiple computers, are abstracted away as a single big system by
+ higher order protocols and features: Redis Cluster and the upcoming
+ Redis Proxy are our main goals. A shared nothing approach is not just
+ much simpler (see the previous point in this document), is also optimal
+ in NUMA systems. In the specific case of Redis it allows for each instance
+ to have a more limited amount of data, making the Redis persist-by-fork
+ approach more sounding. In the future we may explore parallelism only for
+ I/O, which is the low hanging fruit: minimal complexity could provide an
+ improved single process experience.
+
+8 - Two levels of API. The Redis API has two levels: 1) a subset of the API fits
+ naturally into a distributed version of Redis and 2) a more complex API that
+ supports multi-key operations. Both are useful if used judiciously but
+ there's no way to make the more complex multi-keys API distributed in an
+ opaque way without violating our other principles. We don't want to provide
+ the illusion of something that will work magically when actually it can't in
+ all cases. Instead we'll provide commands to quickly migrate keys from one
+ instance to another to perform multi-key operations and expose the
+ trade-offs to the user.
+
+9 - We optimize for joy. We believe writing code is a lot of hard work, and the
+ only way it can be worth is by enjoying it. When there is no longer joy in
+ writing code, the best thing to do is stop. To prevent this, we'll avoid
+ taking paths that will make Redis less of a joy to develop.
+
+10 - All the above points are put together in what we call opportunistic
+ programming: trying to get the most for the user with minimal increases
+ in complexity (hanging fruits). Solve 95% of the problem with 5% of the
+ code when it is acceptable. Avoid a fixed schedule but follow the flow of
+ user requests, inspiration, Redis internal readiness for certain features
+ (sometimes many past changes reach a critical point making a previously
+ complex feature very easy to obtain).
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..e614ede
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,11 @@
+# Top level makefile, the real shit is at src/Makefile
+
+default: all
+
+.DEFAULT:
+ cd src && $(MAKE) $@
+
+install:
+ cd src && $(MAKE) $@
+
+.PHONY: install
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4a1ce79
--- /dev/null
+++ b/README.md
@@ -0,0 +1,506 @@
+This README is just a fast *quick start* document. You can find more detailed documentation at [redis.io](https://redis.io).
+
+What is Redis?
+--------------
+
+Redis is often referred to as a *data structures* server. What this means is that Redis provides access to mutable data structures via a set of commands, which are sent using a *server-client* model with TCP sockets and a simple protocol. So different processes can query and modify the same data structures in a shared way.
+
+Data structures implemented into Redis have a few special properties:
+
+* Redis cares to store them on disk, even if they are always served and modified into the server memory. This means that Redis is fast, but that it is also non-volatile.
+* The implementation of data structures emphasizes memory efficiency, so data structures inside Redis will likely use less memory compared to the same data structure modelled using a high-level programming language.
+* Redis offers a number of features that are natural to find in a database, like replication, tunable levels of durability, clustering, and high availability.
+
+Another good example is to think of Redis as a more complex version of memcached, where the operations are not just SETs and GETs, but operations that work with complex data types like Lists, Sets, ordered data structures, and so forth.
+
+If you want to know more, this is a list of selected starting points:
+
+* Introduction to Redis data types. https://redis.io/topics/data-types-intro
+* Try Redis directly inside your browser. https://try.redis.io
+* The full list of Redis commands. https://redis.io/commands
+* There is much more inside the official Redis documentation. https://redis.io/documentation
+
+Building Redis
+--------------
+
+Redis can be compiled and used on Linux, OSX, OpenBSD, NetBSD, FreeBSD.
+We support big endian and little endian architectures, and both 32 bit
+and 64 bit systems.
+
+It may compile on Solaris derived systems (for instance SmartOS) but our
+support for this platform is *best effort* and Redis is not guaranteed to
+work as well as in Linux, OSX, and \*BSD.
+
+It is as simple as:
+
+ % make
+
+To build with TLS support, you'll need OpenSSL development libraries (e.g.
+libssl-dev on Debian/Ubuntu) and run:
+
+ % make BUILD_TLS=yes
+
+To build with systemd support, you'll need systemd development libraries (such
+as libsystemd-dev on Debian/Ubuntu or systemd-devel on CentOS) and run:
+
+ % make USE_SYSTEMD=yes
+
+To append a suffix to Redis program names, use:
+
+ % make PROG_SUFFIX="-alt"
+
+You can build a 32 bit Redis binary using:
+
+ % make 32bit
+
+After building Redis, it is a good idea to test it using:
+
+ % make test
+
+If TLS is built, running the tests with TLS enabled (you will need `tcl-tls`
+installed):
+
+ % ./utils/gen-test-certs.sh
+ % ./runtest --tls
+
+
+Fixing build problems with dependencies or cached build options
+---------
+
+Redis has some dependencies which are included in the `deps` directory.
+`make` does not automatically rebuild dependencies even if something in
+the source code of dependencies changes.
+
+When you update the source code with `git pull` or when code inside the
+dependencies tree is modified in any other way, make sure to use the following
+command in order to really clean everything and rebuild from scratch:
+
+ % make distclean
+
+This will clean: jemalloc, lua, hiredis, linenoise and other dependencies.
+
+Also if you force certain build options like 32bit target, no C compiler
+optimizations (for debugging purposes), and other similar build time options,
+those options are cached indefinitely until you issue a `make distclean`
+command.
+
+Fixing problems building 32 bit binaries
+---------
+
+If after building Redis with a 32 bit target you need to rebuild it
+with a 64 bit target, or the other way around, you need to perform a
+`make distclean` in the root directory of the Redis distribution.
+
+In case of build errors when trying to build a 32 bit binary of Redis, try
+the following steps:
+
+* Install the package libc6-dev-i386 (also try g++-multilib).
+* Try using the following command line instead of `make 32bit`:
+ `make CFLAGS="-m32 -march=native" LDFLAGS="-m32"`
+
+Allocator
+---------
+
+Selecting a non-default memory allocator when building Redis is done by setting
+the `MALLOC` environment variable. Redis is compiled and linked against libc
+malloc by default, with the exception of jemalloc being the default on Linux
+systems. This default was picked because jemalloc has proven to have fewer
+fragmentation problems than libc malloc.
+
+To force compiling against libc malloc, use:
+
+ % make MALLOC=libc
+
+To compile against jemalloc on Mac OS X systems, use:
+
+ % make MALLOC=jemalloc
+
+Monotonic clock
+---------------
+
+By default, Redis will build using the POSIX clock_gettime function as the
+monotonic clock source. On most modern systems, the internal processor clock
+can be used to improve performance. Cautions can be found here:
+ http://oliveryang.net/2015/09/pitfalls-of-TSC-usage/
+
+To build with support for the processor's internal instruction clock, use:
+
+ % make CFLAGS="-DUSE_PROCESSOR_CLOCK"
+
+Verbose build
+-------------
+
+Redis will build with a user-friendly colorized output by default.
+If you want to see a more verbose output, use the following:
+
+ % make V=1
+
+Running Redis
+-------------
+
+To run Redis with the default configuration, just type:
+
+ % cd src
+ % ./redis-server
+
+If you want to provide your redis.conf, you have to run it using an additional
+parameter (the path of the configuration file):
+
+ % cd src
+ % ./redis-server /path/to/redis.conf
+
+It is possible to alter the Redis configuration by passing parameters directly
+as options using the command line. Examples:
+
+ % ./redis-server --port 9999 --replicaof 127.0.0.1 6379
+ % ./redis-server /etc/redis/6379.conf --loglevel debug
+
+All the options in redis.conf are also supported as options using the command
+line, with exactly the same name.
+
+Running Redis with TLS:
+------------------
+
+Please consult the [TLS.md](TLS.md) file for more information on
+how to use Redis with TLS.
+
+Playing with Redis
+------------------
+
+You can use redis-cli to play with Redis. Start a redis-server instance,
+then in another terminal try the following:
+
+ % cd src
+ % ./redis-cli
+ redis> ping
+ PONG
+ redis> set foo bar
+ OK
+ redis> get foo
+ "bar"
+ redis> incr mycounter
+ (integer) 1
+ redis> incr mycounter
+ (integer) 2
+ redis>
+
+You can find the list of all the available commands at https://redis.io/commands.
+
+Installing Redis
+-----------------
+
+In order to install Redis binaries into /usr/local/bin, just use:
+
+ % make install
+
+You can use `make PREFIX=/some/other/directory install` if you wish to use a
+different destination.
+
+`make install` will just install binaries in your system, but will not configure
+init scripts and configuration files in the appropriate place. This is not
+needed if you just want to play a bit with Redis, but if you are installing
+it the proper way for a production system, we have a script that does this
+for Ubuntu and Debian systems:
+
+ % cd utils
+ % ./install_server.sh
+
+_Note_: `install_server.sh` will not work on Mac OSX; it is built for Linux only.
+
+The script will ask you a few questions and will setup everything you need
+to run Redis properly as a background daemon that will start again on
+system reboots.
+
+You'll be able to stop and start Redis using the script named
+`/etc/init.d/redis_<portnumber>`, for instance `/etc/init.d/redis_6379`.
+
+Code contributions
+-----------------
+
+Note: By contributing code to the Redis project in any form, including sending
+a pull request via Github, a code fragment or patch via private email or
+public discussion groups, you agree to release your code under the terms
+of the BSD license that you can find in the [COPYING][1] file included in the Redis
+source distribution.
+
+Please see the [CONTRIBUTING.md][2] file in this source distribution for more
+information. For security bugs and vulnerabilities, please see [SECURITY.md][3].
+
+[1]: https://github.com/redis/redis/blob/unstable/COPYING
+[2]: https://github.com/redis/redis/blob/unstable/CONTRIBUTING.md
+[3]: https://github.com/redis/redis/blob/unstable/SECURITY.md
+
+Redis internals
+===
+
+If you are reading this README you are likely in front of a Github page
+or you just untarred the Redis distribution tar ball. In both the cases
+you are basically one step away from the source code, so here we explain
+the Redis source code layout, what is in each file as a general idea, the
+most important functions and structures inside the Redis server and so forth.
+We keep all the discussion at a high level without digging into the details
+since this document would be huge otherwise and our code base changes
+continuously, but a general idea should be a good starting point to
+understand more. Moreover most of the code is heavily commented and easy
+to follow.
+
+Source code layout
+---
+
+The Redis root directory just contains this README, the Makefile which
+calls the real Makefile inside the `src` directory and an example
+configuration for Redis and Sentinel. You can find a few shell
+scripts that are used in order to execute the Redis, Redis Cluster and
+Redis Sentinel unit tests, which are implemented inside the `tests`
+directory.
+
+Inside the root are the following important directories:
+
+* `src`: contains the Redis implementation, written in C.
+* `tests`: contains the unit tests, implemented in Tcl.
+* `deps`: contains libraries Redis uses. Everything needed to compile Redis is inside this directory; your system just needs to provide `libc`, a POSIX compatible interface and a C compiler. Notably `deps` contains a copy of `jemalloc`, which is the default allocator of Redis under Linux. Note that under `deps` there are also things which started with the Redis project, but for which the main repository is not `redis/redis`.
+
+There are a few more directories but they are not very important for our goals
+here. We'll focus mostly on `src`, where the Redis implementation is contained,
+exploring what there is inside each file. The order in which files are
+exposed is the logical one to follow in order to disclose different layers
+of complexity incrementally.
+
+Note: lately Redis was refactored quite a bit. Function names and file
+names have been changed, so you may find that this documentation reflects the
+`unstable` branch more closely. For instance, in Redis 3.0 the `server.c`
+and `server.h` files were named `redis.c` and `redis.h`. However the overall
+structure is the same. Keep in mind that all the new developments and pull
+requests should be performed against the `unstable` branch.
+
+server.h
+---
+
+The simplest way to understand how a program works is to understand the
+data structures it uses. So we'll start from the main header file of
+Redis, which is `server.h`.
+
+All the server configuration and in general all the shared state is
+defined in a global structure called `server`, of type `struct redisServer`.
+A few important fields in this structure are:
+
+* `server.db` is an array of Redis databases, where data is stored.
+* `server.commands` is the command table.
+* `server.clients` is a linked list of clients connected to the server.
+* `server.master` is a special client, the master, if the instance is a replica.
+
+There are tons of other fields. Most fields are commented directly inside
+the structure definition.
+
+Another important Redis data structure is the one defining a client.
+In the past it was called `redisClient`, now just `client`. The structure
+has many fields, here we'll just show the main ones:
+```c
+struct client {
+ int fd;
+ sds querybuf;
+ int argc;
+ robj **argv;
+ redisDb *db;
+ int flags;
+ list *reply;
+ // ... many other fields ...
+ char buf[PROTO_REPLY_CHUNK_BYTES];
+}
+```
+The client structure defines a *connected client*:
+
+* The `fd` field is the client socket file descriptor.
+* `argc` and `argv` are populated with the command the client is executing, so that functions implementing a given Redis command can read the arguments.
+* `querybuf` accumulates the requests from the client, which are parsed by the Redis server according to the Redis protocol and executed by calling the implementations of the commands the client is executing.
+* `reply` and `buf` are dynamic and static buffers that accumulate the replies the server sends to the client. These buffers are incrementally written to the socket as soon as the file descriptor is writable.
+
+As you can see in the client structure above, arguments in a command
+are described as `robj` structures. The following is the full `robj`
+structure, which defines a *Redis object*:
+
+```c
+struct redisObject {
+ unsigned type:4;
+ unsigned encoding:4;
+ unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
+ * LFU data (least significant 8 bits frequency
+ * and most significant 16 bits access time). */
+ int refcount;
+ void *ptr;
+};
+```
+
+Basically this structure can represent all the basic Redis data types like
+strings, lists, sets, sorted sets and so forth. The interesting thing is that
+it has a `type` field, so that it is possible to know what type a given
+object has, and a `refcount`, so that the same object can be referenced
+in multiple places without allocating it multiple times. Finally the `ptr`
+field points to the actual representation of the object, which might vary
+even for the same type, depending on the `encoding` used.
+
+Redis objects are used extensively in the Redis internals, however in order
+to avoid the overhead of indirect accesses, recently in many places
+we just use plain dynamic strings not wrapped inside a Redis object.
+
+server.c
+---
+
+This is the entry point of the Redis server, where the `main()` function
+is defined. The following are the most important steps in order to startup
+the Redis server.
+
+* `initServerConfig()` sets up the default values of the `server` structure.
+* `initServer()` allocates the data structures needed to operate, setup the listening socket, and so forth.
+* `aeMain()` starts the event loop which listens for new connections.
+
+There are two special functions called periodically by the event loop:
+
+1. `serverCron()` is called periodically (according to `server.hz` frequency), and performs tasks that must be performed from time to time, like checking for timed out clients.
+2. `beforeSleep()` is called every time the event loop fired, Redis served a few requests, and is returning back into the event loop.
+
+Inside server.c you can find code that handles other vital things of the Redis server:
+
+* `call()` is used in order to call a given command in the context of a given client.
+* `activeExpireCycle()` handles eviction of keys with a time to live set via the `EXPIRE` command.
+* `performEvictions()` is called when a new write command should be performed but Redis is out of memory according to the `maxmemory` directive.
+* The global variable `redisCommandTable` defines all the Redis commands, specifying the name of the command, the function implementing the command, the number of arguments required, and other properties of each command.
+
+commands.c
+---
+This file is auto generated by utils/generate-command-code.py, the content is based on the JSON files in the src/commands folder.
+These are meant to be the single source of truth about the Redis commands, and all the metadata about them.
+These JSON files are not meant to be used by anyone directly, instead that metadata can be obtained via the `COMMAND` command.
+
+networking.c
+---
+
+This file defines all the I/O functions with clients, masters and replicas
+(which in Redis are just special clients):
+
+* `createClient()` allocates and initializes a new client.
+* The `addReply*()` family of functions are used by command implementations in order to append data to the client structure, that will be transmitted to the client as a reply for a given command executed.
+* `writeToClient()` transmits the data pending in the output buffers to the client and is called by the *writable event handler* `sendReplyToClient()`.
+* `readQueryFromClient()` is the *readable event handler* and accumulates data read from the client into the query buffer.
+* `processInputBuffer()` is the entry point in order to parse the client query buffer according to the Redis protocol. Once commands are ready to be processed, it calls `processCommand()` which is defined inside `server.c` in order to actually execute the command.
+* `freeClient()` deallocates, disconnects and removes a client.
+
+aof.c and rdb.c
+---
+
+As you can guess from the names, these files implement the RDB and AOF
+persistence for Redis. Redis uses a persistence model based on the `fork()`
+system call in order to create a process with the same (shared) memory
+content of the main Redis process. This secondary process dumps the content
+of the memory on disk. This is used by `rdb.c` to create the snapshots
+on disk and by `aof.c` in order to perform the AOF rewrite when the
+append only file gets too big.
+
+The implementation inside `aof.c` has additional functions in order to
+implement an API that allows commands to append new commands into the AOF
+file as clients execute them.
+
+The `call()` function defined inside `server.c` is responsible for calling
+the functions that in turn will write the commands into the AOF.
+
+db.c
+---
+
+Certain Redis commands operate on specific data types; others are general.
+Examples of generic commands are `DEL` and `EXPIRE`. They operate on keys
+and not on their values specifically. All those generic commands are
+defined inside `db.c`.
+
+Moreover `db.c` implements an API in order to perform certain operations
+on the Redis dataset without directly accessing the internal data structures.
+
+The most important functions inside `db.c` which are used in many command
+implementations are the following:
+
+* `lookupKeyRead()` and `lookupKeyWrite()` are used in order to get a pointer to the value associated to a given key, or `NULL` if the key does not exist.
+* `dbAdd()` and its higher level counterpart `setKey()` create a new key in a Redis database.
+* `dbDelete()` removes a key and its associated value.
+* `emptyDb()` removes an entire single database or all the databases defined.
+
+The rest of the file implements the generic commands exposed to the client.
+
+object.c
+---
+
+The `robj` structure defining Redis objects was already described. Inside
+`object.c` there are all the functions that operate with Redis objects at
+a basic level, like functions to allocate new objects, handle the reference
+counting and so forth. Notable functions inside this file:
+
+* `incrRefCount()` and `decrRefCount()` are used in order to increment or decrement an object reference count. When it drops to 0 the object is finally freed.
+* `createObject()` allocates a new object. There are also specialized functions to allocate string objects having a specific content, like `createStringObjectFromLongLong()` and similar functions.
+
+This file also implements the `OBJECT` command.
+
+replication.c
+---
+
+This is one of the most complex files inside Redis, it is recommended to
+approach it only after getting a bit familiar with the rest of the code base.
+In this file there is the implementation of both the master and replica role
+of Redis.
+
+One of the most important functions inside this file is `replicationFeedSlaves()` that writes commands to the clients representing replica instances connected
+to our master, so that the replicas can get the writes performed by the clients:
+this way their data set will remain synchronized with the one in the master.
+
+This file also implements both the `SYNC` and `PSYNC` commands that are
+used in order to perform the first synchronization between masters and
+replicas, or to continue the replication after a disconnection.
+
+Script
+---
+
+The script unit is composed of 3 units:
+* `script.c` - integration of scripts with Redis (commands execution, set replication/resp, ...)
+* `script_lua.c` - responsible to execute Lua code, uses script.c to interact with Redis from within the Lua code.
+* `function_lua.c` - contains the Lua engine implementation, uses script_lua.c to execute the Lua code.
+* `functions.c` - contains Redis Functions implementation (FUNCTION command), uses functions_lua.c if the function it wants to invoke needs the Lua engine.
+* `eval.c` - contains the `eval` implementation using `script_lua.c` to invoke the Lua code.
+
+
+Other C files
+---
+
+* `t_hash.c`, `t_list.c`, `t_set.c`, `t_string.c`, `t_zset.c` and `t_stream.c` contains the implementation of the Redis data types. They implement both an API to access a given data type, and the client command implementations for these data types.
+* `ae.c` implements the Redis event loop, it's a self contained library which is simple to read and understand.
+* `sds.c` is the Redis string library, check https://github.com/antirez/sds for more information.
+* `anet.c` is a library to use POSIX networking in a simpler way compared to the raw interface exposed by the kernel.
+* `dict.c` is an implementation of a non-blocking hash table which rehashes incrementally.
+* `cluster.c` implements the Redis Cluster. Probably a good read only after being very familiar with the rest of the Redis code base. If you want to read `cluster.c` make sure to read the [Redis Cluster specification][4].
+
+[4]: https://redis.io/topics/cluster-spec
+
+Anatomy of a Redis command
+---
+
+All the Redis commands are defined in the following way:
+
+```c
+void foobarCommand(client *c) {
+ printf("%s",c->argv[1]->ptr); /* Do something with the argument. */
+ addReply(c,shared.ok); /* Reply something to the client. */
+}
+```
+
+The command function is referenced by a JSON file, together with its metadata, see `commands.c` described above for details.
+The command flags are documented in the comment above the `struct redisCommand` in `server.h`.
+For other details, please refer to the `COMMAND` command. https://redis.io/commands/command/
+
+After the command operates in some way, it returns a reply to the client,
+usually using `addReply()` or a similar function defined inside `networking.c`.
+
+There are tons of command implementations inside the Redis source code
+that can serve as examples of actual commands implementations (e.g. pingCommand). Writing
+a few toy commands can be a good exercise to get familiar with the code base.
+
+There are also many other files not described here, but it is useless to
+cover everything. We just want to help you with the first steps.
+Eventually you'll find your way inside the Redis code base :-)
+
+Enjoy!
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..ea66aaf
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,43 @@
+# Security Policy
+
+## Supported Versions
+
+Redis is generally backwards compatible with very few exceptions, so we
+recommend users to always use the latest version to experience stability,
+performance and security.
+
+We generally backport security issues to a single previous major version,
+unless this is not possible or feasible with a reasonable effort.
+
+| Version | Supported |
+| ------- | ------------------ |
+| 7.0.x | :white_check_mark: |
+| 6.2.x | :white_check_mark: |
+| 6.0.x | :white_check_mark: |
+| < 6.0 | :x: |
+
+## Reporting a Vulnerability
+
+If you believe you’ve discovered a serious vulnerability, please contact the
+Redis core team at redis@redis.io. We will evaluate your report and if
+necessary issue a fix and an advisory. If the issue was previously undisclosed,
+we’ll also mention your name in the credits.
+
+## Responsible Disclosure
+
+In some cases, we may apply a responsible disclosure process to reported or
+otherwise discovered vulnerabilities. We will usually do that for a critical
+vulnerability, and only if we have a good reason to believe information about
+it is not yet public.
+
+This process involves providing an early notification about the vulnerability,
+its impact and mitigations to a short list of vendors under a time-limited
+embargo on public disclosure.
+
+Vendors on the list are individuals or organizations that maintain Redis
+distributions or provide Redis as a service, who have third party users who
+will benefit from the vendor’s ability to prepare for a new version or deploy a
+fix early.
+
+If you believe you should be on the list, please contact us and we will
+consider your request based on the above criteria.
diff --git a/TLS.md b/TLS.md
new file mode 100644
index 0000000..b9bce7e
--- /dev/null
+++ b/TLS.md
@@ -0,0 +1,104 @@
+TLS Support
+===========
+
+Getting Started
+---------------
+
+### Building
+
+To build with TLS support you'll need OpenSSL development libraries (e.g.
+libssl-dev on Debian/Ubuntu).
+
+To build TLS support as Redis built-in:
+Run `make BUILD_TLS=yes`.
+
+Or to build TLS as Redis module:
+Run `make BUILD_TLS=module`.
+
+Note that sentinel mode does not support TLS module.
+
+### Tests
+
+To run Redis test suite with TLS, you'll need TLS support for TCL (i.e.
+`tcl-tls` package on Debian/Ubuntu).
+
+1. Run `./utils/gen-test-certs.sh` to generate a root CA and a server
+ certificate.
+
+2. Run `./runtest --tls` or `./runtest-cluster --tls` to run Redis and Redis
+ Cluster tests in TLS mode.
+
+3. Run `./runtest --tls-module` or `./runtest-cluster --tls-module` to
+ run Redis and Redis cluster tests in TLS mode with Redis module.
+
+### Running manually
+
+To manually run a Redis server with TLS mode (assuming `gen-test-certs.sh` was
+invoked so sample certificates/keys are available):
+
+For TLS built-in mode:
+ ./src/redis-server --tls-port 6379 --port 0 \
+ --tls-cert-file ./tests/tls/redis.crt \
+ --tls-key-file ./tests/tls/redis.key \
+ --tls-ca-cert-file ./tests/tls/ca.crt
+
+For TLS module mode:
+ ./src/redis-server --tls-port 6379 --port 0 \
+ --tls-cert-file ./tests/tls/redis.crt \
+ --tls-key-file ./tests/tls/redis.key \
+ --tls-ca-cert-file ./tests/tls/ca.crt \
+ --loadmodule src/redis-tls.so
+
+To connect to this Redis server with `redis-cli`:
+
+ ./src/redis-cli --tls \
+ --cert ./tests/tls/redis.crt \
+ --key ./tests/tls/redis.key \
+ --cacert ./tests/tls/ca.crt
+
+This will disable TCP and enable TLS on port 6379. It's also possible to have
+both TCP and TLS available, but you'll need to assign different ports.
+
+To make a Replica connect to the master using TLS, use `--tls-replication yes`,
+and to make Redis Cluster use TLS across nodes use `--tls-cluster yes`.
+
+Connections
+-----------
+
+All socket operations now go through a connection abstraction layer that hides
+I/O and read/write event handling from the caller.
+
+**Multi-threading I/O is not currently supported for TLS**, as a TLS connection
+needs to do its own manipulation of AE events which is not thread safe. The
+solution is probably to manage independent AE loops for I/O threads and longer
+term association of connections with threads. This may potentially improve
+overall performance as well.
+
+Sync IO for TLS is currently implemented in a hackish way, i.e. making the
+socket blocking and configuring socket-level timeout. This means the timeout
+value may not be so accurate, and there would be a lot of syscall overhead.
+However I believe that getting rid of syncio completely in favor of pure async
+work is probably a better move than trying to fix that. For replication it would
+probably not be so hard. For cluster keys migration it might be more difficult,
+but there are probably other good reasons to improve that part anyway.
+
+To-Do List
+----------
+
+- [ ] redis-benchmark support. The current implementation is a mix of using
+ hiredis for parsing and basic networking (establishing connections), but
+ directly manipulating sockets for most actions. This will need to be cleaned
+ up for proper TLS support. The best approach is probably to migrate to hiredis
+ async mode.
+- [ ] redis-cli `--slave` and `--rdb` support.
+
+Multi-port
+----------
+
+Consider the implications of allowing TLS to be configured on a separate port,
+making Redis listening on multiple ports:
+
+1. Startup banner port notification
+2. Proctitle
+3. How slaves announce themselves
+4. Cluster bus port calculation
diff --git a/deps/Makefile b/deps/Makefile
new file mode 100644
index 0000000..3bf0363
--- /dev/null
+++ b/deps/Makefile
@@ -0,0 +1,118 @@
+# Redis dependency Makefile
+
+uname_S:= $(shell sh -c 'uname -s 2>/dev/null || echo not')
+
+LUA_DEBUG?=no
+LUA_COVERAGE?=no
+
+CCCOLOR="\033[34m"
+LINKCOLOR="\033[34;1m"
+SRCCOLOR="\033[33m"
+BINCOLOR="\033[37;1m"
+MAKECOLOR="\033[32;1m"
+ENDCOLOR="\033[0m"
+
+default:
+ @echo "Explicit target required"
+
+.PHONY: default
+
+# Prerequisites target
+.make-prerequisites:
+ @touch $@
+
+# Clean everything when CFLAGS is different
+ifneq ($(shell sh -c '[ -f .make-cflags ] && cat .make-cflags || echo none'), $(CFLAGS))
+.make-cflags: distclean
+ -(echo "$(CFLAGS)" > .make-cflags)
+.make-prerequisites: .make-cflags
+endif
+
+# Clean everything when LDFLAGS is different
+ifneq ($(shell sh -c '[ -f .make-ldflags ] && cat .make-ldflags || echo none'), $(LDFLAGS))
+.make-ldflags: distclean
+ -(echo "$(LDFLAGS)" > .make-ldflags)
+.make-prerequisites: .make-ldflags
+endif
+
+distclean:
+ -(cd hiredis && $(MAKE) clean) > /dev/null || true
+ -(cd linenoise && $(MAKE) clean) > /dev/null || true
+ -(cd lua && $(MAKE) clean) > /dev/null || true
+ -(cd jemalloc && [ -f Makefile ] && $(MAKE) distclean) > /dev/null || true
+ -(cd hdr_histogram && $(MAKE) clean) > /dev/null || true
+ -(cd fpconv && $(MAKE) clean) > /dev/null || true
+ -(rm -f .make-*)
+
+.PHONY: distclean
+
+ifneq (,$(filter $(BUILD_TLS),yes module))
+ HIREDIS_MAKE_FLAGS = USE_SSL=1
+endif
+
+hiredis: .make-prerequisites
+ @printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR)
+ cd hiredis && $(MAKE) static $(HIREDIS_MAKE_FLAGS)
+
+.PHONY: hiredis
+
+linenoise: .make-prerequisites
+ @printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR)
+ cd linenoise && $(MAKE)
+
+.PHONY: linenoise
+
+hdr_histogram: .make-prerequisites
+ @printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR)
+ cd hdr_histogram && $(MAKE)
+
+.PHONY: hdr_histogram
+
+fpconv: .make-prerequisites
+ @printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR)
+ cd fpconv && $(MAKE)
+
+.PHONY: fpconv
+
+ifeq ($(uname_S),SunOS)
+ # Make isinf() available
+ LUA_CFLAGS= -D__C99FEATURES__=1
+endif
+
+LUA_CFLAGS+= -Wall -DLUA_ANSI -DENABLE_CJSON_GLOBAL -DREDIS_STATIC='' -DLUA_USE_MKSTEMP $(CFLAGS)
+LUA_LDFLAGS+= $(LDFLAGS)
+ifeq ($(LUA_DEBUG),yes)
+ LUA_CFLAGS+= -O0 -g -DLUA_USE_APICHECK
+else
+ LUA_CFLAGS+= -O2
+endif
+ifeq ($(LUA_COVERAGE),yes)
+ LUA_CFLAGS += -fprofile-arcs -ftest-coverage
+ LUA_LDFLAGS += -fprofile-arcs -ftest-coverage
+endif
+
+# lua's Makefile defines AR="ar rcu", which is unusual, and makes it more
+# challenging to cross-compile lua (and redis). These defines make it easier
+# to fit redis into cross-compilation environments, which typically set AR.
+AR=ar
+ARFLAGS=rc
+
+lua: .make-prerequisites
+ @printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR)
+ cd lua/src && $(MAKE) all CFLAGS="$(LUA_CFLAGS)" MYLDFLAGS="$(LUA_LDFLAGS)" AR="$(AR) $(ARFLAGS)"
+
+.PHONY: lua
+
+JEMALLOC_CFLAGS=$(CFLAGS)
+JEMALLOC_LDFLAGS=$(LDFLAGS)
+
+ifneq ($(DEB_HOST_GNU_TYPE),)
+JEMALLOC_CONFIGURE_OPTS += --host=$(DEB_HOST_GNU_TYPE)
+endif
+
+jemalloc: .make-prerequisites
+ @printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR)
+ cd jemalloc && ./configure --disable-cxx --with-version=5.3.0-0-g0 --with-lg-quantum=3 --disable-cache-oblivious --with-jemalloc-prefix=je_ CFLAGS="$(JEMALLOC_CFLAGS)" LDFLAGS="$(JEMALLOC_LDFLAGS)" $(JEMALLOC_CONFIGURE_OPTS)
+ cd jemalloc && $(MAKE) lib/libjemalloc.a
+
+.PHONY: jemalloc
diff --git a/deps/README.md b/deps/README.md
new file mode 100644
index 0000000..8da051b
--- /dev/null
+++ b/deps/README.md
@@ -0,0 +1,106 @@
+This directory contains all Redis dependencies, except for the libc that
+should be provided by the operating system.
+
+* **Jemalloc** is our memory allocator, used as replacement for libc malloc on Linux by default. It has good performances and excellent fragmentation behavior. This component is upgraded from time to time.
+* **hiredis** is the official C client library for Redis. It is used by redis-cli, redis-benchmark and Redis Sentinel. It is part of the Redis official ecosystem but is developed externally from the Redis repository, so we just upgrade it as needed.
+* **linenoise** is a readline replacement. It is developed by the same authors of Redis but is managed as a separated project and updated as needed.
+* **lua** is Lua 5.1 with minor changes for security and additional libraries.
+* **hdr_histogram** Used for per-command latency tracking histograms.
+
+How to upgrade the above dependencies
+===
+
+Jemalloc
+---
+
+Jemalloc is modified with changes that allow us to implement the Redis
+active defragmentation logic. However this feature of Redis is not mandatory
+and Redis is able to understand if the Jemalloc version it is compiled
+against supports such Redis-specific modifications. So in theory, if you
+are not interested in the active defragmentation, you can replace Jemalloc
+just following these steps:
+
+1. Remove the jemalloc directory.
+2. Substitute it with the new jemalloc source tree.
+3. Edit the Makefile located in the same directory as the README you are
+ reading, and change the --with-version in the Jemalloc configure script
+ options with the version you are using. This is required because otherwise
+ Jemalloc configuration script is broken and will not work nested in another
+ git repository.
+
+However note that we change Jemalloc settings via the `configure` script of Jemalloc using the `--with-lg-quantum` option, setting it to the value of 3 instead of 4. This provides us with more size classes that better suit the Redis data structures, in order to gain memory efficiency.
+
+If you want to upgrade Jemalloc while also providing support for
+active defragmentation, in addition to the above steps you need to perform
+the following additional steps:
+
+5. In Jemalloc tree, file `include/jemalloc/jemalloc_macros.h.in`, make sure
+ to add `#define JEMALLOC_FRAG_HINT`.
+6. Implement the function `je_get_defrag_hint()` inside `src/jemalloc.c`. You
+ can see how it is implemented in the current Jemalloc source tree shipped
+ with Redis, and rewrite it according to the new Jemalloc internals, if they
+ changed, otherwise you could just copy the old implementation if you are
+ upgrading just to a similar version of Jemalloc.
+
+#### Updating/upgrading jemalloc
+
+The jemalloc directory is pulled as a subtree from the upstream jemalloc github repo. To update it you should run from the project root:
+
+1. `git subtree pull --prefix deps/jemalloc https://github.com/jemalloc/jemalloc.git <version-tag> --squash`<br>
+This should hopefully merge the local changes into the new version.
+2. In case any conflicts arise (due to our changes) you'll need to resolve them and commit.
+3. Reconfigure jemalloc:<br>
+```sh
+rm deps/jemalloc/VERSION deps/jemalloc/configure
+cd deps/jemalloc
+./autogen.sh --with-version=<version-tag>-0-g0
+```
+4. Update jemalloc's version in `deps/Makefile`: search for "`--with-version=<old-version-tag>-0-g0`" and update it accordingly.
+5. Commit the changes (VERSION,configure,Makefile).
+
+Hiredis
+---
+
+Hiredis is used by Sentinel, `redis-cli` and `redis-benchmark`. Like Redis, uses the SDS string library, but not necessarily the same version. In order to avoid conflicts, this version has all SDS identifiers prefixed by `hi`.
+
+1. `git subtree pull --prefix deps/hiredis https://github.com/redis/hiredis.git <version-tag> --squash`<br>
+This should hopefully merge the local changes into the new version.
+2. Conflicts will arise (due to our changes) you'll need to resolve them and commit.
+
+Linenoise
+---
+
+Linenoise is rarely upgraded as needed. The upgrade process is trivial since
+Redis uses a non modified version of linenoise, so to upgrade just do the
+following:
+
+1. Remove the linenoise directory.
+2. Substitute it with the new linenoise source tree.
+
+Lua
+---
+
+We use Lua 5.1 and no upgrade is planned currently, since we don't want to break
+Lua scripts for new Lua features: in the context of Redis Lua scripts the
+capabilities of 5.1 are usually more than enough, the release is rock solid,
+and we definitely don't want to break old scripts.
+
+So upgrading of Lua is up to the Redis project maintainers and should be a
+manual procedure performed by taking a diff between the different versions.
+
+Currently we have at least the following differences between official Lua 5.1
+and our version:
+
+1. Makefile is modified to allow a different compiler than GCC.
+2. We have the implementation source code, and directly link to the following external libraries: `lua_cjson.o`, `lua_struct.o`, `lua_cmsgpack.o` and `lua_bit.o`.
+3. There is a security fix in `ldo.c`, line 498: The check for `LUA_SIGNATURE[0]` is removed in order to avoid direct bytecode execution.
+
+Hdr_Histogram
+---
+
+Updated source can be found here: https://github.com/HdrHistogram/HdrHistogram_c
+We use a customized version based on master branch commit e4448cf6d1cd08fff519812d3b1e58bd5a94ac42.
+1. Compare all changes under /hdr_histogram directory to upstream master commit e4448cf6d1cd08fff519812d3b1e58bd5a94ac42
+2. Copy updated files from newer version onto files in /hdr_histogram.
+3. Apply the changes from 1 above to the updated files.
+
diff --git a/deps/fpconv/LICENSE.txt b/deps/fpconv/LICENSE.txt
new file mode 100644
index 0000000..36b7cd9
--- /dev/null
+++ b/deps/fpconv/LICENSE.txt
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/deps/fpconv/Makefile b/deps/fpconv/Makefile
new file mode 100644
index 0000000..2654888
--- /dev/null
+++ b/deps/fpconv/Makefile
@@ -0,0 +1,27 @@
+STD=
+WARN= -Wall
+OPT= -Os
+
+R_CFLAGS= $(STD) $(WARN) $(OPT) $(DEBUG) $(CFLAGS)
+R_LDFLAGS= $(LDFLAGS)
+DEBUG= -g
+
+R_CC=$(CC) $(R_CFLAGS)
+R_LD=$(CC) $(R_LDFLAGS)
+
+AR= ar
+ARFLAGS= rcs
+
+libfpconv.a: fpconv_dtoa.o
+ $(AR) $(ARFLAGS) $@ $+
+
+fpconv_dtoa.o: fpconv_dtoa.h fpconv_dtoa.c
+
+.c.o:
+ $(R_CC) -c $<
+
+clean:
+ rm -f *.o
+ rm -f *.a
+
+
diff --git a/deps/fpconv/README.md b/deps/fpconv/README.md
new file mode 100644
index 0000000..d64ca68
--- /dev/null
+++ b/deps/fpconv/README.md
@@ -0,0 +1,9 @@
+libfpconv
+
+----------------------------------------------
+
+Fast and accurate double to string conversion based on Florian Loitsch's Grisu-algorithm[1].
+
+This port contains a subset of the 'C' version of Fast and accurate double to string conversion based on Florian Loitsch's Grisu-algorithm available at [github.com/night-shift/fpconv](https://github.com/night-shift/fpconv)).
+
+[1] https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
diff --git a/deps/fpconv/fpconv_dtoa.c b/deps/fpconv/fpconv_dtoa.c
new file mode 100644
index 0000000..ad2f2de
--- /dev/null
+++ b/deps/fpconv/fpconv_dtoa.c
@@ -0,0 +1,373 @@
+/* fpconv_dtoa.c -- floating point conversion utilities.
+ *
+ * Fast and accurate double to string conversion based on Florian Loitsch's
+ * Grisu-algorithm[1].
+ *
+ * [1] https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
+ * ----------------------------------------------------------------------------
+ *
+ * Copyright (c) 2013-2019, night-shift <as.smljk at gmail dot com>
+ * Copyright (c) 2009, Florian Loitsch < florian.loitsch at inria dot fr >
+ * All rights reserved.
+ *
+ * Boost Software License - Version 1.0 - August 17th, 2003
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "fpconv_dtoa.h"
+
+#include "fpconv_powers.h"
+
+#include <stdbool.h>
+#include <string.h>
+
+#define fracmask 0x000FFFFFFFFFFFFFU
+#define expmask 0x7FF0000000000000U
+#define hiddenbit 0x0010000000000000U
+#define signmask 0x8000000000000000U
+#define expbias (1023 + 52)
+
+#define absv(n) ((n) < 0 ? -(n) : (n))
+#define minv(a, b) ((a) < (b) ? (a) : (b))
+
+static uint64_t tens[] = { 10000000000000000000U,
+ 1000000000000000000U,
+ 100000000000000000U,
+ 10000000000000000U,
+ 1000000000000000U,
+ 100000000000000U,
+ 10000000000000U,
+ 1000000000000U,
+ 100000000000U,
+ 10000000000U,
+ 1000000000U,
+ 100000000U,
+ 10000000U,
+ 1000000U,
+ 100000U,
+ 10000U,
+ 1000U,
+ 100U,
+ 10U,
+ 1U };
+
+static inline uint64_t get_dbits(double d) {
+ union
+ {
+ double dbl;
+ uint64_t i;
+ } dbl_bits = { d };
+
+ return dbl_bits.i;
+}
+
+static Fp build_fp(double d) {
+ uint64_t bits = get_dbits(d);
+
+ Fp fp;
+ fp.frac = bits & fracmask;
+ fp.exp = (bits & expmask) >> 52;
+
+ if (fp.exp) {
+ fp.frac += hiddenbit;
+ fp.exp -= expbias;
+
+ } else {
+ fp.exp = -expbias + 1;
+ }
+
+ return fp;
+}
+
+static void normalize(Fp *fp) {
+ while ((fp->frac & hiddenbit) == 0) {
+ fp->frac <<= 1;
+ fp->exp--;
+ }
+
+ int shift = 64 - 52 - 1;
+ fp->frac <<= shift;
+ fp->exp -= shift;
+}
+
+static void get_normalized_boundaries(Fp *fp, Fp *lower, Fp *upper) {
+ upper->frac = (fp->frac << 1) + 1;
+ upper->exp = fp->exp - 1;
+
+ while ((upper->frac & (hiddenbit << 1)) == 0) {
+ upper->frac <<= 1;
+ upper->exp--;
+ }
+
+ int u_shift = 64 - 52 - 2;
+
+ upper->frac <<= u_shift;
+ upper->exp = upper->exp - u_shift;
+
+ int l_shift = fp->frac == hiddenbit ? 2 : 1;
+
+ lower->frac = (fp->frac << l_shift) - 1;
+ lower->exp = fp->exp - l_shift;
+
+ lower->frac <<= lower->exp - upper->exp;
+ lower->exp = upper->exp;
+}
+
+static Fp multiply(Fp *a, Fp *b) {
+ const uint64_t lomask = 0x00000000FFFFFFFF;
+
+ uint64_t ah_bl = (a->frac >> 32) * (b->frac & lomask);
+ uint64_t al_bh = (a->frac & lomask) * (b->frac >> 32);
+ uint64_t al_bl = (a->frac & lomask) * (b->frac & lomask);
+ uint64_t ah_bh = (a->frac >> 32) * (b->frac >> 32);
+
+ uint64_t tmp = (ah_bl & lomask) + (al_bh & lomask) + (al_bl >> 32);
+ /* round up */
+ tmp += 1U << 31;
+
+ Fp fp = { ah_bh + (ah_bl >> 32) + (al_bh >> 32) + (tmp >> 32), a->exp + b->exp + 64 };
+
+ return fp;
+}
+
+static void round_digit(char *digits,
+ int ndigits,
+ uint64_t delta,
+ uint64_t rem,
+ uint64_t kappa,
+ uint64_t frac) {
+ while (rem < frac && delta - rem >= kappa &&
+ (rem + kappa < frac || frac - rem > rem + kappa - frac)) {
+ digits[ndigits - 1]--;
+ rem += kappa;
+ }
+}
+
+static int generate_digits(Fp *fp, Fp *upper, Fp *lower, char *digits, int *K) {
+ uint64_t wfrac = upper->frac - fp->frac;
+ uint64_t delta = upper->frac - lower->frac;
+
+ Fp one;
+ one.frac = 1ULL << -upper->exp;
+ one.exp = upper->exp;
+
+ uint64_t part1 = upper->frac >> -one.exp;
+ uint64_t part2 = upper->frac & (one.frac - 1);
+
+ int idx = 0, kappa = 10;
+ uint64_t *divp;
+ /* 1000000000 */
+ for (divp = tens + 10; kappa > 0; divp++) {
+ uint64_t div = *divp;
+ unsigned digit = part1 / div;
+
+ if (digit || idx) {
+ digits[idx++] = digit + '0';
+ }
+
+ part1 -= digit * div;
+ kappa--;
+
+ uint64_t tmp = (part1 << -one.exp) + part2;
+ if (tmp <= delta) {
+ *K += kappa;
+ round_digit(digits, idx, delta, tmp, div << -one.exp, wfrac);
+
+ return idx;
+ }
+ }
+
+ /* 10 */
+ uint64_t *unit = tens + 18;
+
+ while (true) {
+ part2 *= 10;
+ delta *= 10;
+ kappa--;
+
+ unsigned digit = part2 >> -one.exp;
+ if (digit || idx) {
+ digits[idx++] = digit + '0';
+ }
+
+ part2 &= one.frac - 1;
+ if (part2 < delta) {
+ *K += kappa;
+ round_digit(digits, idx, delta, part2, one.frac, wfrac * *unit);
+
+ return idx;
+ }
+
+ unit--;
+ }
+}
+
+static int grisu2(double d, char *digits, int *K) {
+ Fp w = build_fp(d);
+
+ Fp lower, upper;
+ get_normalized_boundaries(&w, &lower, &upper);
+
+ normalize(&w);
+
+ int k;
+ Fp cp = find_cachedpow10(upper.exp, &k);
+
+ w = multiply(&w, &cp);
+ upper = multiply(&upper, &cp);
+ lower = multiply(&lower, &cp);
+
+ lower.frac++;
+ upper.frac--;
+
+ *K = -k;
+
+ return generate_digits(&w, &upper, &lower, digits, K);
+}
+
+static int emit_digits(char *digits, int ndigits, char *dest, int K, bool neg) {
+ int exp = absv(K + ndigits - 1);
+
+ /* write plain integer */
+ if (K >= 0 && (exp < (ndigits + 7))) {
+ memcpy(dest, digits, ndigits);
+ memset(dest + ndigits, '0', K);
+
+ return ndigits + K;
+ }
+
+ /* write decimal w/o scientific notation */
+ if (K < 0 && (K > -7 || exp < 4)) {
+ int offset = ndigits - absv(K);
+ /* fp < 1.0 -> write leading zero */
+ if (offset <= 0) {
+ offset = -offset;
+ dest[0] = '0';
+ dest[1] = '.';
+ memset(dest + 2, '0', offset);
+ memcpy(dest + offset + 2, digits, ndigits);
+
+ return ndigits + 2 + offset;
+
+ /* fp > 1.0 */
+ } else {
+ memcpy(dest, digits, offset);
+ dest[offset] = '.';
+ memcpy(dest + offset + 1, digits + offset, ndigits - offset);
+
+ return ndigits + 1;
+ }
+ }
+
+ /* write decimal w/ scientific notation */
+ ndigits = minv(ndigits, 18 - neg);
+
+ int idx = 0;
+ dest[idx++] = digits[0];
+
+ if (ndigits > 1) {
+ dest[idx++] = '.';
+ memcpy(dest + idx, digits + 1, ndigits - 1);
+ idx += ndigits - 1;
+ }
+
+ dest[idx++] = 'e';
+
+ char sign = K + ndigits - 1 < 0 ? '-' : '+';
+ dest[idx++] = sign;
+
+ int cent = 0;
+
+ if (exp > 99) {
+ cent = exp / 100;
+ dest[idx++] = cent + '0';
+ exp -= cent * 100;
+ }
+ if (exp > 9) {
+ int dec = exp / 10;
+ dest[idx++] = dec + '0';
+ exp -= dec * 10;
+
+ } else if (cent) {
+ dest[idx++] = '0';
+ }
+
+ dest[idx++] = exp % 10 + '0';
+
+ return idx;
+}
+
+static int filter_special(double fp, char *dest) {
+ if (fp == 0.0) {
+ dest[0] = '0';
+ return 1;
+ }
+
+ uint64_t bits = get_dbits(fp);
+
+ bool nan = (bits & expmask) == expmask;
+
+ if (!nan) {
+ return 0;
+ }
+
+ if (bits & fracmask) {
+ dest[0] = 'n';
+ dest[1] = 'a';
+ dest[2] = 'n';
+
+ } else {
+ dest[0] = 'i';
+ dest[1] = 'n';
+ dest[2] = 'f';
+ }
+
+ return 3;
+}
+
+int fpconv_dtoa(double d, char dest[24]) {
+ char digits[18];
+
+ int str_len = 0;
+ bool neg = false;
+
+ if (get_dbits(d) & signmask) {
+ dest[0] = '-';
+ str_len++;
+ neg = true;
+ }
+
+ int spec = filter_special(d, dest + str_len);
+
+ if (spec) {
+ return str_len + spec;
+ }
+
+ int K = 0;
+ int ndigits = grisu2(d, digits, &K);
+
+ str_len += emit_digits(digits, ndigits, dest + str_len, K, neg);
+
+ return str_len;
+}
diff --git a/deps/fpconv/fpconv_dtoa.h b/deps/fpconv/fpconv_dtoa.h
new file mode 100644
index 0000000..328ed83
--- /dev/null
+++ b/deps/fpconv/fpconv_dtoa.h
@@ -0,0 +1,45 @@
+/* fpconv_dtoa.h -- floating point conversion utilities.
+ *
+ * Fast and accurate double to string conversion based on Florian Loitsch's
+ * Grisu-algorithm[1].
+ *
+ * [1] https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
+ * ----------------------------------------------------------------------------
+ *
+ * Copyright (c) 2013-2019, night-shift <as.smljk at gmail dot com>
+ * Copyright (c) 2009, Florian Loitsch < florian.loitsch at inria dot fr >
+ * All rights reserved.
+ *
+ * Boost Software License - Version 1.0 - August 17th, 2003
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef FPCONV_DTOA_H
+#define FPCONV_DTOA_H
+
+int fpconv_dtoa(double fp, char dest[24]);
+
+#endif
+
+/* [1] http://florian.loitsch.com/publications/dtoa-pldi2010.pdf */
diff --git a/deps/fpconv/fpconv_powers.h b/deps/fpconv/fpconv_powers.h
new file mode 100644
index 0000000..bc488f6
--- /dev/null
+++ b/deps/fpconv/fpconv_powers.h
@@ -0,0 +1,133 @@
+/* fpconv_powers.h -- floating point conversion utilities.
+ *
+ * Fast and accurate double to string conversion based on Florian Loitsch's
+ * Grisu-algorithm[1].
+ *
+ * [1] https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
+ * ----------------------------------------------------------------------------
+ *
+ * Copyright (c) 2021, Redis Labs
+ * Copyright (c) 2013-2019, night-shift <as.smljk at gmail dot com>
+ * Copyright (c) 2009, Florian Loitsch < florian.loitsch at inria dot fr >
+ * All rights reserved.
+ *
+ * Boost Software License - Version 1.0 - August 17th, 2003
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdint.h>
+
+#define npowers 87
+#define steppowers 8
+#define firstpower -348 /* 10 ^ -348 */
+
+#define expmax -32
+#define expmin -60
+
+
+typedef struct Fp {
+ uint64_t frac;
+ int exp;
+} Fp;
+
+static Fp powers_ten[] = {
+ { 18054884314459144840U, -1220 }, { 13451937075301367670U, -1193 },
+ { 10022474136428063862U, -1166 }, { 14934650266808366570U, -1140 },
+ { 11127181549972568877U, -1113 }, { 16580792590934885855U, -1087 },
+ { 12353653155963782858U, -1060 }, { 18408377700990114895U, -1034 },
+ { 13715310171984221708U, -1007 }, { 10218702384817765436U, -980 },
+ { 15227053142812498563U, -954 }, { 11345038669416679861U, -927 },
+ { 16905424996341287883U, -901 }, { 12595523146049147757U, -874 },
+ { 9384396036005875287U, -847 }, { 13983839803942852151U, -821 },
+ { 10418772551374772303U, -794 }, { 15525180923007089351U, -768 },
+ { 11567161174868858868U, -741 }, { 17236413322193710309U, -715 },
+ { 12842128665889583758U, -688 }, { 9568131466127621947U, -661 },
+ { 14257626930069360058U, -635 }, { 10622759856335341974U, -608 },
+ { 15829145694278690180U, -582 }, { 11793632577567316726U, -555 },
+ { 17573882009934360870U, -529 }, { 13093562431584567480U, -502 },
+ { 9755464219737475723U, -475 }, { 14536774485912137811U, -449 },
+ { 10830740992659433045U, -422 }, { 16139061738043178685U, -396 },
+ { 12024538023802026127U, -369 }, { 17917957937422433684U, -343 },
+ { 13349918974505688015U, -316 }, { 9946464728195732843U, -289 },
+ { 14821387422376473014U, -263 }, { 11042794154864902060U, -236 },
+ { 16455045573212060422U, -210 }, { 12259964326927110867U, -183 },
+ { 18268770466636286478U, -157 }, { 13611294676837538539U, -130 },
+ { 10141204801825835212U, -103 }, { 15111572745182864684U, -77 },
+ { 11258999068426240000U, -50 }, { 16777216000000000000U, -24 },
+ { 12500000000000000000U, 3 }, { 9313225746154785156U, 30 },
+ { 13877787807814456755U, 56 }, { 10339757656912845936U, 83 },
+ { 15407439555097886824U, 109 }, { 11479437019748901445U, 136 },
+ { 17105694144590052135U, 162 }, { 12744735289059618216U, 189 },
+ { 9495567745759798747U, 216 }, { 14149498560666738074U, 242 },
+ { 10542197943230523224U, 269 }, { 15709099088952724970U, 295 },
+ { 11704190886730495818U, 322 }, { 17440603504673385349U, 348 },
+ { 12994262207056124023U, 375 }, { 9681479787123295682U, 402 },
+ { 14426529090290212157U, 428 }, { 10748601772107342003U, 455 },
+ { 16016664761464807395U, 481 }, { 11933345169920330789U, 508 },
+ { 17782069995880619868U, 534 }, { 13248674568444952270U, 561 },
+ { 9871031767461413346U, 588 }, { 14708983551653345445U, 614 },
+ { 10959046745042015199U, 641 }, { 16330252207878254650U, 667 },
+ { 12166986024289022870U, 694 }, { 18130221999122236476U, 720 },
+ { 13508068024458167312U, 747 }, { 10064294952495520794U, 774 },
+ { 14996968138956309548U, 800 }, { 11173611982879273257U, 827 },
+ { 16649979327439178909U, 853 }, { 12405201291620119593U, 880 },
+ { 9242595204427927429U, 907 }, { 13772540099066387757U, 933 },
+ { 10261342003245940623U, 960 }, { 15290591125556738113U, 986 },
+ { 11392378155556871081U, 1013 }, { 16975966327722178521U, 1039 },
+ { 12648080533535911531U, 1066 }
+};
+
+/**
+ * Grisu needs a cache of precomputed powers-of-ten.
+ * This function, given an exponent and an integer k
+ * return the normalized floating-point approximation of the power of 10.
+ * @param exp
+ * @param k
+ * @return
+ */
+static Fp find_cachedpow10(int exp, int* k)
+{
+ const double one_log_ten = 0.30102999566398114;
+
+ const int approx = -(exp + npowers) * one_log_ten;
+ int idx = (approx - firstpower) / steppowers;
+
+ while(1) {
+ int current = exp + powers_ten[idx].exp + 64;
+
+ if(current < expmin) {
+ idx++;
+ continue;
+ }
+
+ if(current > expmax) {
+ idx--;
+ continue;
+ }
+
+ *k = (firstpower + idx * steppowers);
+
+ return powers_ten[idx];
+ }
+}
diff --git a/deps/hdr_histogram/COPYING.txt b/deps/hdr_histogram/COPYING.txt
new file mode 100644
index 0000000..0e259d4
--- /dev/null
+++ b/deps/hdr_histogram/COPYING.txt
@@ -0,0 +1,121 @@
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+ HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+ i. the right to reproduce, adapt, distribute, perform, display,
+ communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+ likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+ v. rights protecting the extraction, dissemination, use and reuse of data
+ in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation
+ thereof, including any amended or successor version of such
+ directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+ world based on applicable law or treaty, and any national
+ implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+ warranties of any kind concerning the Work, express, implied,
+ statutory or otherwise, including without limitation warranties of
+ title, merchantability, fitness for a particular purpose, non
+ infringement, or the absence of latent or other defects, accuracy, or
+ the present or absence of errors, whether or not discoverable, all to
+ the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without
+ limitation any person's Copyright and Related Rights in the Work.
+ Further, Affirmer disclaims responsibility for obtaining any necessary
+ consents, permissions or other rights required for any use of the
+ Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to
+ this CC0 or use of the Work.
diff --git a/deps/hdr_histogram/LICENSE.txt b/deps/hdr_histogram/LICENSE.txt
new file mode 100644
index 0000000..9b4e66e
--- /dev/null
+++ b/deps/hdr_histogram/LICENSE.txt
@@ -0,0 +1,41 @@
+The code in this repository code was Written by Gil Tene, Michael Barker,
+and Matt Warren, and released to the public domain, as explained at
+http://creativecommons.org/publicdomain/zero/1.0/
+
+For users of this code who wish to consume it under the "BSD" license
+rather than under the public domain or CC0 contribution text mentioned
+above, the code found under this directory is *also* provided under the
+following license (commonly referred to as the BSD 2-Clause License). This
+license does not detract from the above stated release of the code into
+the public domain, and simply represents an additional license granted by
+the Author.
+
+-----------------------------------------------------------------------------
+** Beginning of "BSD 2-Clause License" text. **
+
+ Copyright (c) 2012, 2013, 2014 Gil Tene
+ Copyright (c) 2014 Michael Barker
+ Copyright (c) 2014 Matt Warren
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/deps/hdr_histogram/Makefile b/deps/hdr_histogram/Makefile
new file mode 100644
index 0000000..28dd93e
--- /dev/null
+++ b/deps/hdr_histogram/Makefile
@@ -0,0 +1,27 @@
+STD= -std=c99
+WARN= -Wall
+OPT= -Os
+
+R_CFLAGS= $(STD) $(WARN) $(OPT) $(DEBUG) $(CFLAGS) -DHDR_MALLOC_INCLUDE=\"hdr_redis_malloc.h\"
+R_LDFLAGS= $(LDFLAGS)
+DEBUG= -g
+
+R_CC=$(CC) $(R_CFLAGS)
+R_LD=$(CC) $(R_LDFLAGS)
+
+AR= ar
+ARFLAGS= rcs
+
+libhdrhistogram.a: hdr_histogram.o
+ $(AR) $(ARFLAGS) $@ $+
+
+hdr_histogram.o: hdr_histogram.h hdr_histogram.c
+
+.c.o:
+ $(R_CC) -c $<
+
+clean:
+ rm -f *.o
+ rm -f *.a
+
+
diff --git a/deps/hdr_histogram/README.md b/deps/hdr_histogram/README.md
new file mode 100644
index 0000000..93a156e
--- /dev/null
+++ b/deps/hdr_histogram/README.md
@@ -0,0 +1,78 @@
+HdrHistogram_c: 'C' port of High Dynamic Range (HDR) Histogram
+
+HdrHistogram
+----------------------------------------------
+
+[![Gitter chat](https://badges.gitter.im/HdrHistogram/HdrHistogram.png)](https://gitter.im/HdrHistogram/HdrHistogram)
+
+This port contains a subset of the functionality supported by the Java
+implementation. The current supported features are:
+
+* Standard histogram with 64 bit counts (32/16 bit counts not supported)
+* All iterator types (all values, recorded, percentiles, linear, logarithmic)
+* Histogram serialisation (encoding version 1.2, decoding 1.0-1.2)
+* Reader/writer phaser and interval recorder
+
+Features not supported, but planned
+
+* Auto-resizing of histograms
+
+Features unlikely to be implemented
+
+* Double histograms
+* Atomic/Concurrent histograms
+* 16/32 bit histograms
+
+# Simple Tutorial
+
+## Recording values
+
+```C
+#include <hdr_histogram.h>
+
+struct hdr_histogram* histogram;
+
+// Initialise the histogram
+hdr_init(
+ 1, // Minimum value
+ INT64_C(3600000000), // Maximum value
+ 3, // Number of significant figures
+ &histogram) // Pointer to initialise
+
+// Record value
+hdr_record_value(
+ histogram, // Histogram to record to
+ value) // Value to record
+
+// Record value n times
+hdr_record_values(
+ histogram, // Histogram to record to
+ value, // Value to record
+ 10) // Record value 10 times
+
+// Record value with correction for co-ordinated omission.
+hdr_record_corrected_value(
+ histogram, // Histogram to record to
+ value, // Value to record
+ 1000) // Record with expected interval of 1000.
+
+// Print out the values of the histogram
+hdr_percentiles_print(
+ histogram,
+ stdout, // File to write to
+ 5, // Granularity of printed values
+ 1.0, // Multiplier for results
+ CLASSIC); // Format CLASSIC/CSV supported.
+```
+
+## More examples
+
+For more detailed examples of recording and logging results look at the
+[hdr_decoder](examples/hdr_decoder.c)
+and [hiccup](examples/hiccup.c)
+examples. You can run hiccup and decoder
+and pipe the results of one into the other.
+
+```
+$ ./examples/hiccup | ./examples/hdr_decoder
+```
diff --git a/deps/hdr_histogram/hdr_atomic.h b/deps/hdr_histogram/hdr_atomic.h
new file mode 100644
index 0000000..ae1056a
--- /dev/null
+++ b/deps/hdr_histogram/hdr_atomic.h
@@ -0,0 +1,146 @@
+/**
+ * hdr_atomic.h
+ * Written by Philip Orwig and released to the public domain,
+ * as explained at http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+#ifndef HDR_ATOMIC_H__
+#define HDR_ATOMIC_H__
+
+
+#if defined(_MSC_VER)
+
+#include <stdint.h>
+#include <intrin.h>
+#include <stdbool.h>
+
+static void __inline * hdr_atomic_load_pointer(void** pointer)
+{
+ _ReadBarrier();
+ return *pointer;
+}
+
+static void hdr_atomic_store_pointer(void** pointer, void* value)
+{
+ _WriteBarrier();
+ *pointer = value;
+}
+
+static int64_t __inline hdr_atomic_load_64(int64_t* field)
+{
+ _ReadBarrier();
+ return *field;
+}
+
+static void __inline hdr_atomic_store_64(int64_t* field, int64_t value)
+{
+ _WriteBarrier();
+ *field = value;
+}
+
+static int64_t __inline hdr_atomic_exchange_64(volatile int64_t* field, int64_t value)
+{
+#if defined(_WIN64)
+ return _InterlockedExchange64(field, value);
+#else
+ int64_t comparand;
+ int64_t initial_value = *field;
+ do
+ {
+ comparand = initial_value;
+ initial_value = _InterlockedCompareExchange64(field, value, comparand);
+ }
+ while (comparand != initial_value);
+
+ return initial_value;
+#endif
+}
+
+static int64_t __inline hdr_atomic_add_fetch_64(volatile int64_t* field, int64_t value)
+{
+#if defined(_WIN64)
+ return _InterlockedExchangeAdd64(field, value) + value;
+#else
+ int64_t comparand;
+ int64_t initial_value = *field;
+ do
+ {
+ comparand = initial_value;
+ initial_value = _InterlockedCompareExchange64(field, comparand + value, comparand);
+ }
+ while (comparand != initial_value);
+
+ return initial_value + value;
+#endif
+}
+
+static bool __inline hdr_atomic_compare_exchange_64(volatile int64_t* field, int64_t* expected, int64_t desired)
+{
+ return *expected == _InterlockedCompareExchange64(field, desired, *expected);
+}
+
+#elif defined(__ATOMIC_SEQ_CST)
+
+#define hdr_atomic_load_pointer(x) __atomic_load_n(x, __ATOMIC_SEQ_CST)
+#define hdr_atomic_store_pointer(f,v) __atomic_store_n(f,v, __ATOMIC_SEQ_CST)
+#define hdr_atomic_load_64(x) __atomic_load_n(x, __ATOMIC_SEQ_CST)
+#define hdr_atomic_store_64(f,v) __atomic_store_n(f,v, __ATOMIC_SEQ_CST)
+#define hdr_atomic_exchange_64(f,i) __atomic_exchange_n(f,i, __ATOMIC_SEQ_CST)
+#define hdr_atomic_add_fetch_64(field, value) __atomic_add_fetch(field, value, __ATOMIC_SEQ_CST)
+#define hdr_atomic_compare_exchange_64(field, expected, desired) __atomic_compare_exchange_n(field, expected, desired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
+
+#elif defined(__x86_64__)
+
+#include <stdint.h>
+#include <stdbool.h>
+
+static inline void* hdr_atomic_load_pointer(void** pointer)
+{
+ void* p = *pointer;
+ asm volatile ("" ::: "memory");
+ return p;
+}
+
+static inline void hdr_atomic_store_pointer(void** pointer, void* value)
+{
+ asm volatile ("lock; xchgq %0, %1" : "+q" (value), "+m" (*pointer));
+}
+
+static inline int64_t hdr_atomic_load_64(int64_t* field)
+{
+ int64_t i = *field;
+ asm volatile ("" ::: "memory");
+ return i;
+}
+
+static inline void hdr_atomic_store_64(int64_t* field, int64_t value)
+{
+ asm volatile ("lock; xchgq %0, %1" : "+q" (value), "+m" (*field));
+}
+
+static inline int64_t hdr_atomic_exchange_64(volatile int64_t* field, int64_t value)
+{
+ int64_t result = 0;
+ asm volatile ("lock; xchgq %1, %2" : "=r" (result), "+q" (value), "+m" (*field));
+ return result;
+}
+
+static inline int64_t hdr_atomic_add_fetch_64(volatile int64_t* field, int64_t value)
+{
+ return __sync_add_and_fetch(field, value);
+}
+
+static inline bool hdr_atomic_compare_exchange_64(volatile int64_t* field, int64_t* expected, int64_t desired)
+{
+ int64_t original;
+ asm volatile( "lock; cmpxchgq %2, %1" : "=a"(original), "+m"(*field) : "q"(desired), "0"(*expected));
+ return original == *expected;
+}
+
+#else
+
+#error "Unable to determine atomic operations for your platform"
+
+#endif
+
+#endif /* HDR_ATOMIC_H__ */
diff --git a/deps/hdr_histogram/hdr_histogram.c b/deps/hdr_histogram/hdr_histogram.c
new file mode 100644
index 0000000..f469347
--- /dev/null
+++ b/deps/hdr_histogram/hdr_histogram.c
@@ -0,0 +1,1229 @@
+/**
+ * hdr_histogram.c
+ * Written by Michael Barker and released to the public domain,
+ * as explained at http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include "hdr_histogram.h"
+#include "hdr_tests.h"
+#include "hdr_atomic.h"
+
+#ifndef HDR_MALLOC_INCLUDE
+#define HDR_MALLOC_INCLUDE "hdr_malloc.h"
+#endif
+
+#include HDR_MALLOC_INCLUDE
+
+/* ###### ####### ## ## ## ## ######## ###### */
+/* ## ## ## ## ## ## ### ## ## ## ## */
+/* ## ## ## ## ## #### ## ## ## */
+/* ## ## ## ## ## ## ## ## ## ###### */
+/* ## ## ## ## ## ## #### ## ## */
+/* ## ## ## ## ## ## ## ### ## ## ## */
+/* ###### ####### ####### ## ## ## ###### */
+
+static int32_t normalize_index(const struct hdr_histogram* h, int32_t index)
+{
+ int32_t normalized_index;
+ int32_t adjustment = 0;
+ if (h->normalizing_index_offset == 0)
+ {
+ return index;
+ }
+
+ normalized_index = index - h->normalizing_index_offset;
+
+ if (normalized_index < 0)
+ {
+ adjustment = h->counts_len;
+ }
+ else if (normalized_index >= h->counts_len)
+ {
+ adjustment = -h->counts_len;
+ }
+
+ return normalized_index + adjustment;
+}
+
+static int64_t counts_get_direct(const struct hdr_histogram* h, int32_t index)
+{
+ return h->counts[index];
+}
+
+static int64_t counts_get_normalised(const struct hdr_histogram* h, int32_t index)
+{
+ return counts_get_direct(h, normalize_index(h, index));
+}
+
+static void counts_inc_normalised(
+ struct hdr_histogram* h, int32_t index, int64_t value)
+{
+ int32_t normalised_index = normalize_index(h, index);
+ h->counts[normalised_index] += value;
+ h->total_count += value;
+}
+
+static void counts_inc_normalised_atomic(
+ struct hdr_histogram* h, int32_t index, int64_t value)
+{
+ int32_t normalised_index = normalize_index(h, index);
+
+ hdr_atomic_add_fetch_64(&h->counts[normalised_index], value);
+ hdr_atomic_add_fetch_64(&h->total_count, value);
+}
+
+static void update_min_max(struct hdr_histogram* h, int64_t value)
+{
+ h->min_value = (value < h->min_value && value != 0) ? value : h->min_value;
+ h->max_value = (value > h->max_value) ? value : h->max_value;
+}
+
+static void update_min_max_atomic(struct hdr_histogram* h, int64_t value)
+{
+ int64_t current_min_value;
+ int64_t current_max_value;
+ do
+ {
+ current_min_value = hdr_atomic_load_64(&h->min_value);
+
+ if (0 == value || current_min_value <= value)
+ {
+ break;
+ }
+ }
+ while (!hdr_atomic_compare_exchange_64(&h->min_value, &current_min_value, value));
+
+ do
+ {
+ current_max_value = hdr_atomic_load_64(&h->max_value);
+
+ if (value <= current_max_value)
+ {
+ break;
+ }
+ }
+ while (!hdr_atomic_compare_exchange_64(&h->max_value, &current_max_value, value));
+}
+
+
+/* ## ## ######## #### ## #### ######## ## ## */
+/* ## ## ## ## ## ## ## ## ## */
+/* ## ## ## ## ## ## ## #### */
+/* ## ## ## ## ## ## ## ## */
+/* ## ## ## ## ## ## ## ## */
+/* ## ## ## ## ## ## ## ## */
+/* ####### ## #### ######## #### ## ## */
+
+static int64_t power(int64_t base, int64_t exp)
+{
+ int64_t result = 1;
+ while(exp)
+ {
+ result *= base; exp--;
+ }
+ return result;
+}
+
+#if defined(_MSC_VER)
+# if defined(_WIN64)
+# pragma intrinsic(_BitScanReverse64)
+# else
+# pragma intrinsic(_BitScanReverse)
+# endif
+#endif
+
+static int32_t count_leading_zeros_64(int64_t value)
+{
+#if defined(_MSC_VER)
+ uint32_t leading_zero = 0;
+#if defined(_WIN64)
+ _BitScanReverse64(&leading_zero, value);
+#else
+ uint32_t high = value >> 32;
+ if (_BitScanReverse(&leading_zero, high))
+ {
+ leading_zero += 32;
+ }
+ else
+ {
+ uint32_t low = value & 0x00000000FFFFFFFF;
+ _BitScanReverse(&leading_zero, low);
+ }
+#endif
+ return 63 - leading_zero; /* smallest power of 2 containing value */
+#else
+ return __builtin_clzll(value); /* smallest power of 2 containing value */
+#endif
+}
+
+static int32_t get_bucket_index(const struct hdr_histogram* h, int64_t value)
+{
+ int32_t pow2ceiling = 64 - count_leading_zeros_64(value | h->sub_bucket_mask); /* smallest power of 2 containing value */
+ return pow2ceiling - h->unit_magnitude - (h->sub_bucket_half_count_magnitude + 1);
+}
+
+static int32_t get_sub_bucket_index(int64_t value, int32_t bucket_index, int32_t unit_magnitude)
+{
+ return (int32_t)(value >> (bucket_index + unit_magnitude));
+}
+
+static int32_t counts_index(const struct hdr_histogram* h, int32_t bucket_index, int32_t sub_bucket_index)
+{
+ /* Calculate the index for the first entry in the bucket: */
+ /* (The following is the equivalent of ((bucket_index + 1) * subBucketHalfCount) ): */
+ int32_t bucket_base_index = (bucket_index + 1) << h->sub_bucket_half_count_magnitude;
+ /* Calculate the offset in the bucket: */
+ int32_t offset_in_bucket = sub_bucket_index - h->sub_bucket_half_count;
+ /* The following is the equivalent of ((sub_bucket_index - subBucketHalfCount) + bucketBaseIndex; */
+ return bucket_base_index + offset_in_bucket;
+}
+
+static int64_t value_from_index(int32_t bucket_index, int32_t sub_bucket_index, int32_t unit_magnitude)
+{
+ return ((int64_t) sub_bucket_index) << (bucket_index + unit_magnitude);
+}
+
+int32_t counts_index_for(const struct hdr_histogram* h, int64_t value)
+{
+ int32_t bucket_index = get_bucket_index(h, value);
+ int32_t sub_bucket_index = get_sub_bucket_index(value, bucket_index, h->unit_magnitude);
+
+ return counts_index(h, bucket_index, sub_bucket_index);
+}
+
+int64_t hdr_value_at_index(const struct hdr_histogram *h, int32_t index)
+{
+ int32_t bucket_index = (index >> h->sub_bucket_half_count_magnitude) - 1;
+ int32_t sub_bucket_index = (index & (h->sub_bucket_half_count - 1)) + h->sub_bucket_half_count;
+
+ if (bucket_index < 0)
+ {
+ sub_bucket_index -= h->sub_bucket_half_count;
+ bucket_index = 0;
+ }
+
+ return value_from_index(bucket_index, sub_bucket_index, h->unit_magnitude);
+}
+
+int64_t hdr_size_of_equivalent_value_range(const struct hdr_histogram* h, int64_t value)
+{
+ int32_t bucket_index = get_bucket_index(h, value);
+ int32_t sub_bucket_index = get_sub_bucket_index(value, bucket_index, h->unit_magnitude);
+ int32_t adjusted_bucket = (sub_bucket_index >= h->sub_bucket_count) ? (bucket_index + 1) : bucket_index;
+ return INT64_C(1) << (h->unit_magnitude + adjusted_bucket);
+}
+
+static int64_t size_of_equivalent_value_range_given_bucket_indices(
+ const struct hdr_histogram *h,
+ int32_t bucket_index,
+ int32_t sub_bucket_index)
+{
+ const int32_t adjusted_bucket = (sub_bucket_index >= h->sub_bucket_count) ? (bucket_index + 1) : bucket_index;
+ return INT64_C(1) << (h->unit_magnitude + adjusted_bucket);
+}
+
+static int64_t lowest_equivalent_value(const struct hdr_histogram* h, int64_t value)
+{
+ int32_t bucket_index = get_bucket_index(h, value);
+ int32_t sub_bucket_index = get_sub_bucket_index(value, bucket_index, h->unit_magnitude);
+ return value_from_index(bucket_index, sub_bucket_index, h->unit_magnitude);
+}
+
+static int64_t lowest_equivalent_value_given_bucket_indices(
+ const struct hdr_histogram *h,
+ int32_t bucket_index,
+ int32_t sub_bucket_index)
+{
+ return value_from_index(bucket_index, sub_bucket_index, h->unit_magnitude);
+}
+
+int64_t hdr_next_non_equivalent_value(const struct hdr_histogram *h, int64_t value)
+{
+ return lowest_equivalent_value(h, value) + hdr_size_of_equivalent_value_range(h, value);
+}
+
+static int64_t highest_equivalent_value(const struct hdr_histogram* h, int64_t value)
+{
+ return hdr_next_non_equivalent_value(h, value) - 1;
+}
+
+int64_t hdr_median_equivalent_value(const struct hdr_histogram *h, int64_t value)
+{
+ return lowest_equivalent_value(h, value) + (hdr_size_of_equivalent_value_range(h, value) >> 1);
+}
+
+static int64_t non_zero_min(const struct hdr_histogram* h)
+{
+ if (INT64_MAX == h->min_value)
+ {
+ return INT64_MAX;
+ }
+
+ return lowest_equivalent_value(h, h->min_value);
+}
+
+void hdr_reset_internal_counters(struct hdr_histogram* h)
+{
+ int min_non_zero_index = -1;
+ int max_index = -1;
+ int64_t observed_total_count = 0;
+ int i;
+
+ for (i = 0; i < h->counts_len; i++)
+ {
+ int64_t count_at_index;
+
+ if ((count_at_index = counts_get_direct(h, i)) > 0)
+ {
+ observed_total_count += count_at_index;
+ max_index = i;
+ if (min_non_zero_index == -1 && i != 0)
+ {
+ min_non_zero_index = i;
+ }
+ }
+ }
+
+ if (max_index == -1)
+ {
+ h->max_value = 0;
+ }
+ else
+ {
+ int64_t max_value = hdr_value_at_index(h, max_index);
+ h->max_value = highest_equivalent_value(h, max_value);
+ }
+
+ if (min_non_zero_index == -1)
+ {
+ h->min_value = INT64_MAX;
+ }
+ else
+ {
+ h->min_value = hdr_value_at_index(h, min_non_zero_index);
+ }
+
+ h->total_count = observed_total_count;
+}
+
+static int32_t buckets_needed_to_cover_value(int64_t value, int32_t sub_bucket_count, int32_t unit_magnitude)
+{
+ int64_t smallest_untrackable_value = ((int64_t) sub_bucket_count) << unit_magnitude;
+ int32_t buckets_needed = 1;
+ while (smallest_untrackable_value <= value)
+ {
+ if (smallest_untrackable_value > INT64_MAX / 2)
+ {
+ return buckets_needed + 1;
+ }
+ smallest_untrackable_value <<= 1;
+ buckets_needed++;
+ }
+
+ return buckets_needed;
+}
+
+/* ## ## ######## ## ## ####### ######## ## ## */
+/* ### ### ## ### ### ## ## ## ## ## ## */
+/* #### #### ## #### #### ## ## ## ## #### */
+/* ## ### ## ###### ## ### ## ## ## ######## ## */
+/* ## ## ## ## ## ## ## ## ## ## */
+/* ## ## ## ## ## ## ## ## ## ## */
+/* ## ## ######## ## ## ####### ## ## ## */
+
+int hdr_calculate_bucket_config(
+ int64_t lowest_discernible_value,
+ int64_t highest_trackable_value,
+ int significant_figures,
+ struct hdr_histogram_bucket_config* cfg)
+{
+ int32_t sub_bucket_count_magnitude;
+ int64_t largest_value_with_single_unit_resolution;
+
+ if (lowest_discernible_value < 1 ||
+ significant_figures < 1 || 5 < significant_figures ||
+ lowest_discernible_value * 2 > highest_trackable_value)
+ {
+ return EINVAL;
+ }
+
+ cfg->lowest_discernible_value = lowest_discernible_value;
+ cfg->significant_figures = significant_figures;
+ cfg->highest_trackable_value = highest_trackable_value;
+
+ largest_value_with_single_unit_resolution = 2 * power(10, significant_figures);
+ sub_bucket_count_magnitude = (int32_t) ceil(log((double)largest_value_with_single_unit_resolution) / log(2));
+ cfg->sub_bucket_half_count_magnitude = ((sub_bucket_count_magnitude > 1) ? sub_bucket_count_magnitude : 1) - 1;
+
+ double unit_magnitude = log((double)lowest_discernible_value) / log(2);
+ if (INT32_MAX < unit_magnitude)
+ {
+ return EINVAL;
+ }
+
+ cfg->unit_magnitude = (int32_t) unit_magnitude;
+ cfg->sub_bucket_count = (int32_t) pow(2, (cfg->sub_bucket_half_count_magnitude + 1));
+ cfg->sub_bucket_half_count = cfg->sub_bucket_count / 2;
+ cfg->sub_bucket_mask = ((int64_t) cfg->sub_bucket_count - 1) << cfg->unit_magnitude;
+
+ if (cfg->unit_magnitude + cfg->sub_bucket_half_count_magnitude > 61)
+ {
+ return EINVAL;
+ }
+
+ cfg->bucket_count = buckets_needed_to_cover_value(highest_trackable_value, cfg->sub_bucket_count, (int32_t)cfg->unit_magnitude);
+ cfg->counts_len = (cfg->bucket_count + 1) * (cfg->sub_bucket_count / 2);
+
+ return 0;
+}
+
+void hdr_init_preallocated(struct hdr_histogram* h, struct hdr_histogram_bucket_config* cfg)
+{
+ h->lowest_discernible_value = cfg->lowest_discernible_value;
+ h->highest_trackable_value = cfg->highest_trackable_value;
+ h->unit_magnitude = (int32_t)cfg->unit_magnitude;
+ h->significant_figures = (int32_t)cfg->significant_figures;
+ h->sub_bucket_half_count_magnitude = cfg->sub_bucket_half_count_magnitude;
+ h->sub_bucket_half_count = cfg->sub_bucket_half_count;
+ h->sub_bucket_mask = cfg->sub_bucket_mask;
+ h->sub_bucket_count = cfg->sub_bucket_count;
+ h->min_value = INT64_MAX;
+ h->max_value = 0;
+ h->normalizing_index_offset = 0;
+ h->conversion_ratio = 1.0;
+ h->bucket_count = cfg->bucket_count;
+ h->counts_len = cfg->counts_len;
+ h->total_count = 0;
+}
+
+int hdr_init(
+ int64_t lowest_discernible_value,
+ int64_t highest_trackable_value,
+ int significant_figures,
+ struct hdr_histogram** result)
+{
+ int64_t* counts;
+ struct hdr_histogram_bucket_config cfg;
+ struct hdr_histogram* histogram;
+
+ int r = hdr_calculate_bucket_config(lowest_discernible_value, highest_trackable_value, significant_figures, &cfg);
+ if (r)
+ {
+ return r;
+ }
+
+ counts = (int64_t*) hdr_calloc((size_t) cfg.counts_len, sizeof(int64_t));
+ if (!counts)
+ {
+ return ENOMEM;
+ }
+
+ histogram = (struct hdr_histogram*) hdr_calloc(1, sizeof(struct hdr_histogram));
+ if (!histogram)
+ {
+ hdr_free(counts);
+ return ENOMEM;
+ }
+
+ histogram->counts = counts;
+
+ hdr_init_preallocated(histogram, &cfg);
+ *result = histogram;
+
+ return 0;
+}
+
+void hdr_close(struct hdr_histogram* h)
+{
+ if (h) {
+ hdr_free(h->counts);
+ hdr_free(h);
+ }
+}
+
+int hdr_alloc(int64_t highest_trackable_value, int significant_figures, struct hdr_histogram** result)
+{
+ return hdr_init(1, highest_trackable_value, significant_figures, result);
+}
+
+/* reset a histogram to zero. */
+void hdr_reset(struct hdr_histogram *h)
+{
+ h->total_count=0;
+ h->min_value = INT64_MAX;
+ h->max_value = 0;
+ memset(h->counts, 0, (sizeof(int64_t) * h->counts_len));
+}
+
+size_t hdr_get_memory_size(struct hdr_histogram *h)
+{
+ return sizeof(struct hdr_histogram) + h->counts_len * sizeof(int64_t);
+}
+
+/* ## ## ######## ######## ### ######## ######## ###### */
+/* ## ## ## ## ## ## ## ## ## ## ## ## */
+/* ## ## ## ## ## ## ## ## ## ## ## */
+/* ## ## ######## ## ## ## ## ## ###### ###### */
+/* ## ## ## ## ## ######### ## ## ## */
+/* ## ## ## ## ## ## ## ## ## ## ## */
+/* ####### ## ######## ## ## ## ######## ###### */
+
+
+bool hdr_record_value(struct hdr_histogram* h, int64_t value)
+{
+ return hdr_record_values(h, value, 1);
+}
+
+bool hdr_record_value_atomic(struct hdr_histogram* h, int64_t value)
+{
+ return hdr_record_values_atomic(h, value, 1);
+}
+
+bool hdr_record_values(struct hdr_histogram* h, int64_t value, int64_t count)
+{
+ int32_t counts_index;
+
+ if (value < 0)
+ {
+ return false;
+ }
+
+ counts_index = counts_index_for(h, value);
+
+ if (counts_index < 0 || h->counts_len <= counts_index)
+ {
+ return false;
+ }
+
+ counts_inc_normalised(h, counts_index, count);
+ update_min_max(h, value);
+
+ return true;
+}
+
+bool hdr_record_values_atomic(struct hdr_histogram* h, int64_t value, int64_t count)
+{
+ int32_t counts_index;
+
+ if (value < 0)
+ {
+ return false;
+ }
+
+ counts_index = counts_index_for(h, value);
+
+ if (counts_index < 0 || h->counts_len <= counts_index)
+ {
+ return false;
+ }
+
+ counts_inc_normalised_atomic(h, counts_index, count);
+ update_min_max_atomic(h, value);
+
+ return true;
+}
+
+bool hdr_record_corrected_value(struct hdr_histogram* h, int64_t value, int64_t expected_interval)
+{
+ return hdr_record_corrected_values(h, value, 1, expected_interval);
+}
+
+bool hdr_record_corrected_value_atomic(struct hdr_histogram* h, int64_t value, int64_t expected_interval)
+{
+ return hdr_record_corrected_values_atomic(h, value, 1, expected_interval);
+}
+
+bool hdr_record_corrected_values(struct hdr_histogram* h, int64_t value, int64_t count, int64_t expected_interval)
+{
+ int64_t missing_value;
+
+ if (!hdr_record_values(h, value, count))
+ {
+ return false;
+ }
+
+ if (expected_interval <= 0 || value <= expected_interval)
+ {
+ return true;
+ }
+
+ missing_value = value - expected_interval;
+ for (; missing_value >= expected_interval; missing_value -= expected_interval)
+ {
+ if (!hdr_record_values(h, missing_value, count))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool hdr_record_corrected_values_atomic(struct hdr_histogram* h, int64_t value, int64_t count, int64_t expected_interval)
+{
+ int64_t missing_value;
+
+ if (!hdr_record_values_atomic(h, value, count))
+ {
+ return false;
+ }
+
+ if (expected_interval <= 0 || value <= expected_interval)
+ {
+ return true;
+ }
+
+ missing_value = value - expected_interval;
+ for (; missing_value >= expected_interval; missing_value -= expected_interval)
+ {
+ if (!hdr_record_values_atomic(h, missing_value, count))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+int64_t hdr_add(struct hdr_histogram* h, const struct hdr_histogram* from)
+{
+ struct hdr_iter iter;
+ int64_t dropped = 0;
+ hdr_iter_recorded_init(&iter, from);
+
+ while (hdr_iter_next(&iter))
+ {
+ int64_t value = iter.value;
+ int64_t count = iter.count;
+
+ if (!hdr_record_values(h, value, count))
+ {
+ dropped += count;
+ }
+ }
+
+ return dropped;
+}
+
+int64_t hdr_add_while_correcting_for_coordinated_omission(
+ struct hdr_histogram* h, struct hdr_histogram* from, int64_t expected_interval)
+{
+ struct hdr_iter iter;
+ int64_t dropped = 0;
+ hdr_iter_recorded_init(&iter, from);
+
+ while (hdr_iter_next(&iter))
+ {
+ int64_t value = iter.value;
+ int64_t count = iter.count;
+
+ if (!hdr_record_corrected_values(h, value, count, expected_interval))
+ {
+ dropped += count;
+ }
+ }
+
+ return dropped;
+}
+
+
+
+/* ## ## ### ## ## ## ######## ###### */
+/* ## ## ## ## ## ## ## ## ## ## */
+/* ## ## ## ## ## ## ## ## ## */
+/* ## ## ## ## ## ## ## ###### ###### */
+/* ## ## ######### ## ## ## ## ## */
+/* ## ## ## ## ## ## ## ## ## ## */
+/* ### ## ## ######## ####### ######## ###### */
+
+
+int64_t hdr_max(const struct hdr_histogram* h)
+{
+ if (0 == h->max_value)
+ {
+ return 0;
+ }
+
+ return highest_equivalent_value(h, h->max_value);
+}
+
+int64_t hdr_min(const struct hdr_histogram* h)
+{
+ if (0 < hdr_count_at_index(h, 0))
+ {
+ return 0;
+ }
+
+ 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)
+{
+ double requested_percentile = percentile < 100.0 ? percentile : 100.0;
+ int64_t count_at_percentile =
+ (int64_t) (((requested_percentile / 100) * h->total_count) + 0.5);
+ 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);
+}
+
+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;
+ }
+
+ 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++)
+ {
+ 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;
+ }
+
+ 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])
+ {
+ values[at_pos] = highest_equivalent_value(h, iter.value);
+ at_pos++;
+ }
+ }
+ return 0;
+}
+
+double hdr_mean(const struct hdr_histogram* h)
+{
+ struct hdr_iter iter;
+ int64_t total = 0;
+
+ hdr_iter_init(&iter, h);
+
+ while (hdr_iter_next(&iter))
+ {
+ if (0 != iter.count)
+ {
+ total += iter.count * hdr_median_equivalent_value(h, iter.value);
+ }
+ }
+
+ return (total * 1.0) / h->total_count;
+}
+
+double hdr_stddev(const struct hdr_histogram* h)
+{
+ double mean = hdr_mean(h);
+ double geometric_dev_total = 0.0;
+
+ struct hdr_iter iter;
+ hdr_iter_init(&iter, h);
+
+ while (hdr_iter_next(&iter))
+ {
+ if (0 != iter.count)
+ {
+ double dev = (hdr_median_equivalent_value(h, iter.value) * 1.0) - mean;
+ geometric_dev_total += (dev * dev) * iter.count;
+ }
+ }
+
+ return sqrt(geometric_dev_total / h->total_count);
+}
+
+bool hdr_values_are_equivalent(const struct hdr_histogram* h, int64_t a, int64_t b)
+{
+ return lowest_equivalent_value(h, a) == lowest_equivalent_value(h, b);
+}
+
+int64_t hdr_lowest_equivalent_value(const struct hdr_histogram* h, int64_t value)
+{
+ return lowest_equivalent_value(h, value);
+}
+
+int64_t hdr_count_at_value(const struct hdr_histogram* h, int64_t value)
+{
+ return counts_get_normalised(h, counts_index_for(h, value));
+}
+
+int64_t hdr_count_at_index(const struct hdr_histogram* h, int32_t index)
+{
+ return counts_get_normalised(h, index);
+}
+
+
+/* #### ######## ######## ######## ### ######## ####### ######## ###### */
+/* ## ## ## ## ## ## ## ## ## ## ## ## ## ## */
+/* ## ## ## ## ## ## ## ## ## ## ## ## ## */
+/* ## ## ###### ######## ## ## ## ## ## ######## ###### */
+/* ## ## ## ## ## ######### ## ## ## ## ## ## */
+/* ## ## ## ## ## ## ## ## ## ## ## ## ## ## */
+/* #### ## ######## ## ## ## ## ## ####### ## ## ###### */
+
+
+static bool has_buckets(struct hdr_iter* iter)
+{
+ return iter->counts_index < iter->h->counts_len;
+}
+
+static bool has_next(struct hdr_iter* iter)
+{
+ return iter->cumulative_count < iter->total_count;
+}
+
+static bool move_next(struct hdr_iter* iter)
+{
+ iter->counts_index++;
+
+ if (!has_buckets(iter))
+ {
+ return false;
+ }
+
+ iter->count = counts_get_normalised(iter->h, iter->counts_index);
+ iter->cumulative_count += iter->count;
+ const int64_t value = hdr_value_at_index(iter->h, iter->counts_index);
+ const int32_t bucket_index = get_bucket_index(iter->h, value);
+ const int32_t sub_bucket_index = get_sub_bucket_index(value, bucket_index, iter->h->unit_magnitude);
+ const int64_t leq = lowest_equivalent_value_given_bucket_indices(iter->h, bucket_index, sub_bucket_index);
+ const int64_t size_of_equivalent_value_range = size_of_equivalent_value_range_given_bucket_indices(
+ iter->h, bucket_index, sub_bucket_index);
+ iter->lowest_equivalent_value = leq;
+ iter->value = value;
+ iter->highest_equivalent_value = leq + size_of_equivalent_value_range - 1;
+ iter->median_equivalent_value = leq + (size_of_equivalent_value_range >> 1);
+
+ return true;
+}
+
+static int64_t peek_next_value_from_index(struct hdr_iter* iter)
+{
+ return hdr_value_at_index(iter->h, iter->counts_index + 1);
+}
+
+static bool next_value_greater_than_reporting_level_upper_bound(
+ struct hdr_iter *iter, int64_t reporting_level_upper_bound)
+{
+ if (iter->counts_index >= iter->h->counts_len)
+ {
+ return false;
+ }
+
+ return peek_next_value_from_index(iter) > reporting_level_upper_bound;
+}
+
+static bool basic_iter_next(struct hdr_iter *iter)
+{
+ if (!has_next(iter) || iter->counts_index >= iter->h->counts_len)
+ {
+ return false;
+ }
+
+ move_next(iter);
+
+ return true;
+}
+
+static void update_iterated_values(struct hdr_iter* iter, int64_t new_value_iterated_to)
+{
+ iter->value_iterated_from = iter->value_iterated_to;
+ iter->value_iterated_to = new_value_iterated_to;
+}
+
+static bool all_values_iter_next(struct hdr_iter* iter)
+{
+ bool result = move_next(iter);
+
+ if (result)
+ {
+ update_iterated_values(iter, iter->value);
+ }
+
+ return result;
+}
+
+void hdr_iter_init(struct hdr_iter* iter, const struct hdr_histogram* h)
+{
+ iter->h = h;
+
+ iter->counts_index = -1;
+ iter->total_count = h->total_count;
+ iter->count = 0;
+ iter->cumulative_count = 0;
+ iter->value = 0;
+ iter->highest_equivalent_value = 0;
+ iter->value_iterated_from = 0;
+ iter->value_iterated_to = 0;
+
+ iter->_next_fp = all_values_iter_next;
+}
+