├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── Makefile ├── README.md ├── api ├── librdb-api.h └── librdb-ext-api.h ├── bin └── .gitkeep ├── deps ├── Makefile ├── README.md └── redis │ ├── Makefile │ ├── config.h │ ├── crc64.c │ ├── crc64.h │ ├── crcspeed.c │ ├── crcspeed.h │ ├── endianconv.c │ ├── endianconv.h │ ├── fpconv_dtoa.c │ ├── fpconv_dtoa.h │ ├── fpconv_powers.h │ ├── intset.c │ ├── intset.h │ ├── listpack.c │ ├── listpack.h │ ├── listpack_malloc.h │ ├── lzf.h │ ├── lzfP.h │ ├── lzf_c.c │ ├── lzf_d.c │ ├── rax.c │ ├── rax.h │ ├── rax_malloc.h │ ├── sha256.c │ ├── sha256.h │ ├── stream.h │ ├── t_stream.c │ ├── t_zset.c │ ├── t_zset.h │ ├── util.c │ ├── util.h │ ├── version.h │ ├── ziplist.c │ ├── ziplist.h │ ├── zipmap.c │ └── zipmap.h ├── examples ├── Makefile ├── dumps │ └── multiple_lists_strings.rdb └── example1.c ├── lib └── .gitkeep ├── librdb-ext.pc.in ├── librdb.pc.in ├── runtests ├── src ├── cli │ ├── Makefile │ └── rdb-cli.c ├── ext │ ├── Makefile │ ├── extCommon.c │ ├── extCommon.h │ ├── handlersFilter.c │ ├── handlersToJson.c │ ├── handlersToPrint.c │ ├── handlersToResp.c │ ├── readerFile.c │ ├── readerFileDesc.c │ ├── readerResp.c │ ├── readerResp.h │ ├── respToFileWriter.c │ └── respToRedisLoader.c └── lib │ ├── Makefile │ ├── bulkAlloc.c │ ├── bulkAlloc.h │ ├── defines.h │ ├── parser.c │ ├── parser.h │ ├── parserRaw.c │ ├── version.c │ └── version.h └── test ├── Makefile ├── dumps ├── 100_lists.rdb ├── cluster_slot_info.json ├── cluster_slot_info.rdb ├── empty.rdb ├── function.rdb ├── function2.json ├── function2.rdb ├── future_v19.rdb ├── hash_data.json ├── hash_ex_v12_data.json ├── hash_lp_ex_v12_data.json ├── hash_lp_v11.rdb ├── hash_lp_v11_data.json ├── hash_lp_v11_raw.json ├── hash_lp_v11_struct.json ├── hash_lp_with_hexpire_v12.rdb ├── hash_raw.json ├── hash_struct.json ├── hash_v3.rdb ├── hash_with_expire_v12.rdb ├── hash_zl_v6.rdb ├── hash_zl_v6_data.json ├── hash_zl_v6_raw.json ├── hash_zl_v6_struct.json ├── hash_zm_v2.rdb ├── hash_zm_v2_data.json ├── hash_zm_v2_raw.json ├── hash_zm_v2_struct.json ├── invalid_chksum_v8.rdb ├── mem_policy_lfu.json ├── mem_policy_lfu.rdb ├── mem_policy_lru.json ├── mem_policy_lru.rdb ├── misc_with_stream.rdb ├── module.rdb ├── module_aux.rdb ├── module_aux_data.json ├── module_aux_empty.rdb ├── module_data.json ├── module_raw.json ├── multiple_dbs.rdb ├── multiple_dbs_data.json ├── multiple_lists_strings.rdb ├── multiple_lists_strings_2filters.json ├── multiple_lists_strings_data.json ├── multiple_lists_strings_no_aux.json ├── multiple_lists_strings_raw.json ├── multiple_lists_strings_struct.json ├── multiple_lists_strings_subset_list.json ├── multiple_lists_strings_subset_str.json ├── plain_hash_data.json ├── plain_hash_struct.json ├── plain_list_v6.rdb ├── plain_list_v6_data.json ├── plain_list_v6_raw.json ├── plain_set_v6.rdb ├── plain_set_v6_data.json ├── plain_set_v6_raw.json ├── plain_set_v6_struct.json ├── plain_zset_2_v11.rdb ├── plain_zset_2_v11_data.json ├── plain_zset_2_v11_raw.json ├── plain_zset_2_v11_struct.json ├── plain_zset_v6.rdb ├── plain_zset_v6_data.json ├── plain_zset_v6_raw.json ├── plain_zset_v6_struct.json ├── quicklist.rdb ├── quicklist2_v11.rdb ├── quicklist_data.json ├── quicklist_raw.json ├── quicklist_struct.json ├── redis_ent_opcode_ram_lru.rdb ├── set_expired.json ├── set_expired_v11.rdb ├── set_is_v11.rdb ├── set_is_v11_data.json ├── set_is_v11_raw.json ├── set_is_v11_struct.json ├── set_lp_v11.rdb ├── set_lp_v11_data.json ├── set_lp_v11_raw.json ├── set_lp_v11_struct.json ├── set_not_expired.json ├── set_not_expired_v11.rdb ├── single_key.rdb ├── single_key_data.json ├── single_key_raw.json ├── single_key_struct.json ├── single_list_data.json ├── single_list_raw.json ├── single_list_struct.json ├── stream_data.json ├── stream_data_with_meta.json ├── stream_v11.rdb ├── stream_v11_target_ver_6.2.resp ├── stream_v11_target_ver_7.2.resp ├── string_int_encoded.json ├── string_int_encoded.rdb ├── string_lzf.rdb ├── validate_all_json_files.sh ├── ziplist_data.json ├── ziplist_raw.json ├── ziplist_struct.json ├── ziplist_v3.rdb ├── zset_lp_v11.rdb ├── zset_lp_v11_data.json ├── zset_lp_v11_raw.json ├── zset_lp_v11_struct.json ├── zset_zl_v6.rdb ├── zset_zl_v6_data.json ├── zset_zl_v6_raw.json └── zset_zl_v6_struct.json ├── json_signature_generator.py ├── log └── .gitkeep ├── test_bulk_ops.c ├── test_common.c ├── test_common.h ├── test_main.c ├── test_malloc.c ├── test_pause.c ├── test_rdb_cli.c ├── test_rdb_to_json.c ├── test_rdb_to_redis.c ├── test_rdb_to_resp.c ├── test_resp_reader.c └── tmp └── .gitkeep /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | schedule: 7 | - cron: '0 0 * * 0' # Run every Sunday at midnight UTC 8 | 9 | jobs: 10 | build: 11 | strategy: 12 | matrix: 13 | include: 14 | - os: ubuntu-latest 15 | compiler: gcc 16 | version: "5.0" 17 | - os: ubuntu-latest 18 | compiler: clang 19 | version: "6.0" 20 | - os: ubuntu-latest 21 | compiler: gcc 22 | version: "7.0" 23 | - os: ubuntu-latest 24 | compiler: clang 25 | version: "7.2" 26 | - os: ubuntu-latest 27 | compiler: gcc 28 | version: "7.4" 29 | - os: ubuntu-latest 30 | compiler: clang 31 | version: "unstable" 32 | - os: macos-latest 33 | compiler: gcc 34 | version: "7.4" 35 | - os: macos-latest 36 | compiler: clang 37 | version: "unstable" 38 | 39 | runs-on: ${{ matrix.os }} 40 | 41 | env: 42 | DEBIAN_FRONTEND: noninteractive 43 | CC: ${{ matrix.compiler }} 44 | 45 | steps: 46 | - name: Checkout librdb 47 | uses: actions/checkout@v4 48 | with: 49 | submodules: "recursive" 50 | 51 | - name: Clone Redis (${{ matrix.version }}) 52 | uses: actions/checkout@v4 53 | with: 54 | repository: redis/redis 55 | ref: ${{ matrix.version }} 56 | path: redis 57 | 58 | - name: Install prerequisites 59 | run: | 60 | if [ "${RUNNER_OS}" = "Linux" ]; then 61 | sudo apt-get update 62 | sudo apt-get install -y cmake clang libssl-dev valgrind git bc 63 | 64 | # Build and install cmocka 65 | git clone --depth=1 --branch=stable-1.1 https://git.cryptomilk.org/projects/cmocka.git 66 | cd cmocka 67 | mkdir build 68 | cd build 69 | cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local 70 | make 71 | sudo make install 72 | elif [ "${RUNNER_OS}" = "macOS" ]; then 73 | brew install cmocka bc llvm grep 74 | echo "PATH=$(brew --prefix)/opt/grep/libexec/gnubin:${PATH}" >> "${GITHUB_ENV}" 75 | fi 76 | 77 | - name: Build Redis ${{ matrix.version }} 78 | run: | 79 | make -j -C redis 80 | 81 | if [ $(bc -l <<< "${{ matrix.version }} >= 6.2") -eq 1 ] || [ "${{ matrix.version }}" = "unstable" ]; then 82 | make -j -C redis/tests/modules 83 | fi 84 | 85 | - name: Run tests with shared lib 86 | run: | 87 | LIBRDB_REDIS_FOLDER="$(pwd)/redis/src" make clean debug test 88 | 89 | - name: Run tests with static lib and valgrind 90 | if: runner.os == 'Linux' 91 | run: | 92 | LIBRDB_REDIS_FOLDER="$(pwd)/redis/src" make clean all valgrind 93 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin/* 2 | lib/* 3 | .idea/* 4 | /**/*.o 5 | /**/*.d 6 | *.pc 7 | 8 | /**/rdb-cli.log 9 | src/cli/rdb-cli 10 | 11 | test/log/* 12 | test/tmp/* 13 | test/test_static_lib 14 | test/test_lib 15 | 16 | examples/example1 17 | examples/dumps/*.json 18 | 19 | 20 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps/hiredis"] 2 | path = deps/hiredis 3 | url = https://github.com/redis/hiredis.git 4 | branch = master -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023, Redis Labs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | PREFIX ?= /usr/local 3 | 4 | # Avoid the need for 'ln -r'. 5 | ifneq ($(realpath $(PREFIX)),$(PREFIX)) 6 | $(error PREFIX must be a canonical path) 7 | endif 8 | 9 | DESTDIR ?= 10 | INSTALL = /usr/bin/install -c 11 | BINDIR = $(DESTDIR)$(PREFIX)/bin 12 | LIBDIR = $(DESTDIR)$(PREFIX)/lib 13 | INCDIR = $(DESTDIR)$(PREFIX)/include/librdb/ 14 | LIBRDB_INSTALL_SHARED := yes 15 | LIBRDB_INSTALL_STATIC := yes 16 | 17 | UNAME := $(shell uname) 18 | 19 | ifneq (,$(filter $(UNAME),OpenBSD FreeBSD NetBSD)) 20 | PKGCONFIGDIR = $(DESTDIR)$(PREFIX)/libdata/pkgconfig 21 | else 22 | PKGCONFIGDIR = $(LIBDIR)/pkgconfig 23 | endif 24 | 25 | LIBRDB_VERSION = $(shell sed -n 's|^\#define LIBRDB_VERSION_STRING "\([0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\)"|\1|p' ./src/lib/version.h) 26 | export LIBRDB_VERSION 27 | 28 | # ------------------------- ALL -------------------------------------- 29 | 30 | all: ./deps/hiredis/hiredis.h 31 | $(MAKE) -C deps all 32 | $(MAKE) -C src/lib all 33 | $(MAKE) -C src/ext all 34 | $(MAKE) -C src/cli all 35 | $(MAKE) -C examples all 36 | 37 | clean: 38 | $(MAKE) -C deps clean 39 | $(MAKE) -C src/lib clean 40 | $(MAKE) -C src/ext clean 41 | $(MAKE) -C src/cli clean 42 | $(MAKE) -C examples clean 43 | $(MAKE) -C test clean 44 | rm -f librdb.pc 45 | rm -f librdb-ext.pc 46 | 47 | example: all 48 | cd examples && export LD_LIBRARY_PATH=../lib && ./example1 49 | 50 | ./deps/hiredis/hiredis.h: 51 | git submodule update --init deps/hiredis 52 | 53 | # ------------------------- DEBUG ------------------------------------- 54 | 55 | debug: 56 | OPTIMIZATION="-O0" LIBRDB_DEBUG=1 $(MAKE) 57 | 58 | # ------------------------- TEST -------------------------------------- 59 | 60 | build_test: all 61 | $(MAKE) -C test -f Makefile all 62 | 63 | test: build_test 64 | ./runtests 65 | 66 | valgrind: build_test 67 | ./runtests -v 68 | 69 | # ------------------------- INSTALL -------------------------------------- 70 | 71 | librdb.pc: librdb.pc.in Makefile 72 | sed -e 's|@PREFIX@|$(PREFIX)|' \ 73 | -e 's|@VERSION@|$(LIBRDB_VERSION)|' \ 74 | $< >$@ 75 | 76 | librdb-ext.pc: librdb-ext.pc.in Makefile 77 | sed -e 's|@PREFIX@|$(PREFIX)|' \ 78 | -e 's|@VERSION@|$(LIBRDB_VERSION)|' \ 79 | $< >$@ 80 | 81 | install: all librdb.pc librdb-ext.pc 82 | $(INSTALL) -d $(BINDIR) 83 | $(INSTALL) -m 755 bin/rdb-cli $(BINDIR)/rdb-cli-$(LIBRDB_VERSION) 84 | ln -fs $(BINDIR)/rdb-cli-$(LIBRDB_VERSION) $(BINDIR)/rdb-cli 85 | $(INSTALL) -d $(LIBDIR) 86 | 87 | ifeq ($(LIBRDB_INSTALL_SHARED),yes) 88 | $(INSTALL) -m 755 lib/librdb.so.$(LIBRDB_VERSION) $(LIBDIR)/librdb.so.$(LIBRDB_VERSION) 89 | ln -fs $(LIBDIR)/librdb.so.$(LIBRDB_VERSION) $(LIBDIR)/librdb.so 90 | $(INSTALL) -m 755 lib/librdb-ext.so.$(LIBRDB_VERSION) $(LIBDIR)/librdb-ext.so.$(LIBRDB_VERSION) 91 | ln -fs $(LIBDIR)/librdb-ext.so.$(LIBRDB_VERSION) $(LIBDIR)/librdb-ext.so 92 | $(INSTALL) -d $(PKGCONFIGDIR) 93 | $(INSTALL) -m 644 librdb.pc $(PKGCONFIGDIR) 94 | $(INSTALL) -m 644 librdb-ext.pc $(PKGCONFIGDIR) 95 | endif 96 | 97 | ifeq ($(LIBRDB_INSTALL_STATIC),yes) 98 | $(INSTALL) -m 755 lib/librdb.a $(LIBDIR)/librdb.a.$(LIBRDB_VERSION) 99 | ln -fs $(LIBDIR)/librdb.a.$(LIBRDB_VERSION) $(LIBDIR)/librdb.a 100 | $(INSTALL) -m 755 lib/librdb-ext.a $(LIBDIR)/librdb-ext.a.$(LIBRDB_VERSION) 101 | ln -fs $(LIBDIR)/librdb-ext.a.$(LIBRDB_VERSION) $(LIBDIR)/librdb-ext.a 102 | endif 103 | 104 | $(INSTALL) -d $(INCDIR) 105 | $(INSTALL) -m 644 api/librdb-api.h $(INCDIR) 106 | $(INSTALL) -m 644 api/librdb-ext-api.h $(INCDIR) 107 | 108 | uninstall: 109 | rm -f $(BINDIR)/rdb-cli || true 110 | rm -f $(BINDIR)/rdb-cli-$(LIBRDB_VERSION) 111 | rm -f $(LIBDIR)/librdb.so 112 | rm -f $(LIBDIR)/librdb.so.$(LIBRDB_VERSION) 113 | rm -f $(LIBDIR)/librdb-ext.so 114 | rm -f $(LIBDIR)/librdb-ext.so.$(LIBRDB_VERSION) 115 | rm -f $(LIBDIR)/librdb.a 116 | rm -f $(LIBDIR)/librdb.a.$(LIBRDB_VERSION) 117 | rm -f $(LIBDIR)/librdb-ext.a 118 | rm -f $(LIBDIR)/librdb-ext.a.$(LIBRDB_VERSION) 119 | rm -f $(INCDIR)/librdb-api.h 120 | rm -f $(INCDIR)/librdb-ext-api.h 121 | rm -f $(PKGCONFIGDIR)/librdb.pc 122 | rm -f $(PKGCONFIGDIR)/librdb-ext.pc 123 | 124 | # ------------------------- HELP -------------------------------------- 125 | 126 | help: 127 | @echo "librdb (v$(LIBRDB_VERSION)) target rules:" 128 | @echo " all - Build parser libraries, tests, and run tests" 129 | @echo " debug - Build without compiler optimization and with assert() enabled" 130 | @echo " test - Run tests with shared lib" 131 | @echo " valgrind - Run tests with static lib and valgrind" 132 | @echo " example - Run the example" 133 | @echo " clean - Clean without deps folders" 134 | @echo " install - install to (DESTDIR)/(PREFIX)/bin and (DESTDIR)/(PREFIX)/lib" 135 | @echo " By default PREFIX=/usr/local" 136 | @echo " uninstall - Remove from (DESTDIR)\(PREFIX)/bin and (DESTDIR)/(PREFIX)/lib" 137 | @echo " help - Prints this message" 138 | 139 | 140 | .PHONY: all debug test valgrind example clean install uninstall build_test help 141 | -------------------------------------------------------------------------------- /bin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/bin/.gitkeep -------------------------------------------------------------------------------- /deps/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | $(MAKE) -C redis all 3 | $(MAKE) -C hiredis all 4 | 5 | clean: 6 | $(MAKE) -C redis clean 7 | $(MAKE) -C hiredis clean 8 | 9 | 10 | .PHONY: all clean -------------------------------------------------------------------------------- /deps/README.md: -------------------------------------------------------------------------------- 1 | # deps 2 | The purpose of this folder is to provide the necessary dependencies for the librdb parser. 3 | 4 | # librdb dependencies 5 | 6 | ## redis 7 | The redis subfolder contains a modified subset of files from the Redis repository. These 8 | files have been slightly adapted and used by librdb parser. In the future, there is a 9 | possibility that the librdb library will be integrated into the Redis repository. If this 10 | integration occurs, the contents of this deps folder will reflect part of the required 11 | dependencies and changes needed for the integration. 12 | 13 | To upgrade, use as base reference specified version in version.h file, though it shouldn't 14 | update so often (Otherwise, consider in the future having better methodology to consume 15 | and upgrade redis code). 16 | 17 | ## hiredis 18 | This directory contains the 'hiredis' project as a submodule. It is exclusively utilized 19 | by the tests to manipulate the Redis server. -------------------------------------------------------------------------------- /deps/redis/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES = $(notdir $(basename $(wildcard *.c))) 2 | OBJECTS = $(patsubst %,%.o,$(SOURCES)) 3 | 4 | OPTIMIZATION?=-O3 5 | 6 | STD = -std=c99 7 | WARNS = -Wall -Wextra -pedantic 8 | CFLAGS = -fPIC $(OPTIMIZATION) $(STD) $(WARNS) -fvisibility=hidden 9 | DEBUG = -g3 -DDEBUG=1 10 | LIBS = 11 | 12 | all: $(OBJECTS) 13 | 14 | %.o: %.c 15 | $(CC) $(CFLAGS) -c $< -o $@ $(DEBUG) $(LIBS) 16 | $(CC) -MM $(CFLAGS) $< > $*.d 17 | 18 | # Include object file dependencies 19 | -include $(OBJECTS:.o=.d) 20 | 21 | clean: 22 | @rm -rvf ./*.o ./*.d 23 | 24 | .PHONY: all clean 25 | -------------------------------------------------------------------------------- /deps/redis/crc64.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014, Matt Stancliff 2 | * Copyright (c) 2020, Amazon Web Services 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of Redis nor the names of its contributors may be used 14 | * to endorse or promote products derived from this software without 15 | * specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. */ 28 | #include 29 | #include "crc64.h" 30 | #include "crcspeed.h" 31 | static uint64_t crc64_table[8][256] = {{0}}; 32 | 33 | #define POLY UINT64_C(0xad93d23594c935a9) 34 | /******************** BEGIN GENERATED PYCRC FUNCTIONS ********************/ 35 | /** 36 | * Generated on Sun Dec 21 14:14:07 2014, 37 | * by pycrc v0.8.2, https://www.tty1.net/pycrc/ 38 | * 39 | * LICENSE ON GENERATED CODE: 40 | * ========================== 41 | * As of version 0.6, pycrc is released under the terms of the MIT licence. 42 | * The code generated by pycrc is not considered a substantial portion of the 43 | * software, therefore the author of pycrc will not claim any copyright on 44 | * the generated code. 45 | * ========================== 46 | * 47 | * CRC configuration: 48 | * Width = 64 49 | * Poly = 0xad93d23594c935a9 50 | * XorIn = 0xffffffffffffffff 51 | * ReflectIn = True 52 | * XorOut = 0x0000000000000000 53 | * ReflectOut = True 54 | * Algorithm = bit-by-bit-fast 55 | * 56 | * Modifications after generation (by matt): 57 | * - included finalize step in-line with update for single-call generation 58 | * - re-worked some inner variable architectures 59 | * - adjusted function parameters to match expected prototypes. 60 | *****************************************************************************/ 61 | 62 | /** 63 | * Reflect all bits of a \a data word of \a data_len bytes. 64 | * 65 | * \param data The data word to be reflected. 66 | * \param data_len The width of \a data expressed in number of bits. 67 | * \return The reflected data. 68 | *****************************************************************************/ 69 | static inline uint_fast64_t crc_reflect(uint_fast64_t data, size_t data_len) { 70 | uint_fast64_t ret = data & 0x01; 71 | 72 | for (size_t i = 1; i < data_len; i++) { 73 | data >>= 1; 74 | ret = (ret << 1) | (data & 0x01); 75 | } 76 | 77 | return ret; 78 | } 79 | 80 | /** 81 | * Update the crc value with new data. 82 | * 83 | * \param crc The current crc value. 84 | * \param data Pointer to a buffer of \a data_len bytes. 85 | * \param data_len Number of bytes in the \a data buffer. 86 | * \return The updated crc value. 87 | ******************************************************************************/ 88 | uint64_t _crc64(uint_fast64_t crc, const void *in_data, const uint64_t len) { 89 | const uint8_t *data = in_data; 90 | unsigned long long bit; 91 | 92 | for (uint64_t offset = 0; offset < len; offset++) { 93 | uint8_t c = data[offset]; 94 | for (uint_fast8_t i = 0x01; i & 0xff; i <<= 1) { 95 | bit = crc & 0x8000000000000000; 96 | if (c & i) { 97 | bit = !bit; 98 | } 99 | 100 | crc <<= 1; 101 | if (bit) { 102 | crc ^= POLY; 103 | } 104 | } 105 | 106 | crc &= 0xffffffffffffffff; 107 | } 108 | 109 | crc = crc & 0xffffffffffffffff; 110 | return crc_reflect(crc, 64) ^ 0x0000000000000000; 111 | } 112 | 113 | /******************** END GENERATED PYCRC FUNCTIONS ********************/ 114 | 115 | /* Initializes the 16KB lookup tables. */ 116 | void crc64_init(void) { 117 | crcspeed64native_init(_crc64, crc64_table); 118 | } 119 | 120 | /* Compute crc64 */ 121 | uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l) { 122 | return crcspeed64native(crc64_table, crc, (void *) s, l); 123 | } 124 | 125 | /* Not sure if it is really required to use mutex here, but just in case */ 126 | void crc64_init_thread_safe(void) { 127 | static int crcInitalized = 0; 128 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 129 | 130 | pthread_mutex_lock(&mutex); 131 | if (!crcInitalized) { 132 | crc64_init(); 133 | crcInitalized = 1; 134 | } 135 | pthread_mutex_unlock(&mutex); 136 | } 137 | 138 | /* Test main */ 139 | #ifdef REDIS_TEST 140 | #include 141 | 142 | #define UNUSED(x) (void)(x) 143 | int crc64Test(int argc, char *argv[], int flags) { 144 | UNUSED(argc); 145 | UNUSED(argv); 146 | UNUSED(flags); 147 | crc64_init(); 148 | printf("[calcula]: e9c6d914c4b8d9ca == %016" PRIx64 "\n", 149 | (uint64_t)_crc64(0, "123456789", 9)); 150 | printf("[64speed]: e9c6d914c4b8d9ca == %016" PRIx64 "\n", 151 | (uint64_t)crc64(0, (unsigned char*)"123456789", 9)); 152 | char li[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed " 153 | "do eiusmod tempor incididunt ut labore et dolore magna " 154 | "aliqua. Ut enim ad minim veniam, quis nostrud exercitation " 155 | "ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis " 156 | "aute irure dolor in reprehenderit in voluptate velit esse " 157 | "cillum dolore eu fugiat nulla pariatur. Excepteur sint " 158 | "occaecat cupidatat non proident, sunt in culpa qui officia " 159 | "deserunt mollit anim id est laborum."; 160 | printf("[calcula]: c7794709e69683b3 == %016" PRIx64 "\n", 161 | (uint64_t)_crc64(0, li, sizeof(li))); 162 | printf("[64speed]: c7794709e69683b3 == %016" PRIx64 "\n", 163 | (uint64_t)crc64(0, (unsigned char*)li, sizeof(li))); 164 | return 0; 165 | } 166 | 167 | #endif 168 | 169 | #ifdef REDIS_TEST_MAIN 170 | int main(int argc, char *argv[]) { 171 | return crc64Test(argc, argv); 172 | } 173 | 174 | #endif 175 | -------------------------------------------------------------------------------- /deps/redis/crc64.h: -------------------------------------------------------------------------------- 1 | #ifndef CRC64_H 2 | #define CRC64_H 3 | 4 | #include 5 | 6 | void crc64_init(void); 7 | void crc64_init_thread_safe(void); 8 | uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l); 9 | 10 | 11 | #ifdef REDIS_TEST 12 | int crc64Test(int argc, char *argv[], int flags); 13 | #endif 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /deps/redis/crcspeed.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014, Matt Stancliff 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * * Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of Redis nor the names of its contributors may be used 13 | * to endorse or promote products derived from this software without 14 | * specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. */ 27 | 28 | #ifndef CRCSPEED_H 29 | #define CRCSPEED_H 30 | 31 | #include 32 | #include 33 | 34 | typedef uint64_t (*crcfn64)(uint64_t, const void *, const uint64_t); 35 | typedef uint16_t (*crcfn16)(uint16_t, const void *, const uint64_t); 36 | 37 | /* CRC-64 */ 38 | void crcspeed64little_init(crcfn64 fn, uint64_t table[8][256]); 39 | void crcspeed64big_init(crcfn64 fn, uint64_t table[8][256]); 40 | void crcspeed64native_init(crcfn64 fn, uint64_t table[8][256]); 41 | 42 | uint64_t crcspeed64little(uint64_t table[8][256], uint64_t crc, void *buf, 43 | size_t len); 44 | uint64_t crcspeed64big(uint64_t table[8][256], uint64_t crc, void *buf, 45 | size_t len); 46 | uint64_t crcspeed64native(uint64_t table[8][256], uint64_t crc, void *buf, 47 | size_t len); 48 | 49 | /* CRC-16 */ 50 | void crcspeed16little_init(crcfn16 fn, uint16_t table[8][256]); 51 | void crcspeed16big_init(crcfn16 fn, uint16_t table[8][256]); 52 | void crcspeed16native_init(crcfn16 fn, uint16_t table[8][256]); 53 | 54 | uint16_t crcspeed16little(uint16_t table[8][256], uint16_t crc, void *buf, 55 | size_t len); 56 | uint16_t crcspeed16big(uint16_t table[8][256], uint16_t crc, void *buf, 57 | size_t len); 58 | uint16_t crcspeed16native(uint16_t table[8][256], uint16_t crc, void *buf, 59 | size_t len); 60 | #endif 61 | -------------------------------------------------------------------------------- /deps/redis/endianconv.c: -------------------------------------------------------------------------------- 1 | /* endinconv.c -- Endian conversions utilities. 2 | * 3 | * This functions are never called directly, but always using the macros 4 | * defined into endianconv.h, this way we define everything is a non-operation 5 | * if the arch is already little endian. 6 | * 7 | * Redis tries to encode everything as little endian (but a few things that need 8 | * to be backward compatible are still in big endian) because most of the 9 | * production environments are little endian, and we have a lot of conversions 10 | * in a few places because ziplists, intsets, zipmaps, need to be endian-neutral 11 | * even in memory, since they are serialized on RDB files directly with a single 12 | * write(2) without other additional steps. 13 | * 14 | * ---------------------------------------------------------------------------- 15 | * 16 | * Copyright (c) 2011-2012, Salvatore Sanfilippo 17 | * All rights reserved. 18 | * 19 | * Redistribution and use in source and binary forms, with or without 20 | * modification, are permitted provided that the following conditions are met: 21 | * 22 | * * Redistributions of source code must retain the above copyright notice, 23 | * this list of conditions and the following disclaimer. 24 | * * Redistributions in binary form must reproduce the above copyright 25 | * notice, this list of conditions and the following disclaimer in the 26 | * documentation and/or other materials provided with the distribution. 27 | * * Neither the name of Redis nor the names of its contributors may be used 28 | * to endorse or promote products derived from this software without 29 | * specific prior written permission. 30 | * 31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 32 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 33 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 34 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 35 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 36 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 39 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 | * POSSIBILITY OF SUCH DAMAGE. 42 | */ 43 | 44 | 45 | #include 46 | 47 | /* Toggle the 16 bit unsigned integer pointed by *p from little endian to 48 | * big endian */ 49 | void memrev16(void *p) { 50 | unsigned char *x = p, t; 51 | 52 | t = x[0]; 53 | x[0] = x[1]; 54 | x[1] = t; 55 | } 56 | 57 | /* Toggle the 32 bit unsigned integer pointed by *p from little endian to 58 | * big endian */ 59 | void memrev32(void *p) { 60 | unsigned char *x = p, t; 61 | 62 | t = x[0]; 63 | x[0] = x[3]; 64 | x[3] = t; 65 | t = x[1]; 66 | x[1] = x[2]; 67 | x[2] = t; 68 | } 69 | 70 | /* Toggle the 64 bit unsigned integer pointed by *p from little endian to 71 | * big endian */ 72 | void memrev64(void *p) { 73 | unsigned char *x = p, t; 74 | 75 | t = x[0]; 76 | x[0] = x[7]; 77 | x[7] = t; 78 | t = x[1]; 79 | x[1] = x[6]; 80 | x[6] = t; 81 | t = x[2]; 82 | x[2] = x[5]; 83 | x[5] = t; 84 | t = x[3]; 85 | x[3] = x[4]; 86 | x[4] = t; 87 | } 88 | 89 | uint16_t intrev16(uint16_t v) { 90 | memrev16(&v); 91 | return v; 92 | } 93 | 94 | uint32_t intrev32(uint32_t v) { 95 | memrev32(&v); 96 | return v; 97 | } 98 | 99 | uint64_t intrev64(uint64_t v) { 100 | memrev64(&v); 101 | return v; 102 | } 103 | 104 | #ifdef REDIS_TEST 105 | #include 106 | 107 | #define UNUSED(x) (void)(x) 108 | int endianconvTest(int argc, char *argv[], int flags) { 109 | char buf[32]; 110 | 111 | UNUSED(argc); 112 | UNUSED(argv); 113 | UNUSED(flags); 114 | 115 | sprintf(buf,"ciaoroma"); 116 | memrev16(buf); 117 | printf("%s\n", buf); 118 | 119 | sprintf(buf,"ciaoroma"); 120 | memrev32(buf); 121 | printf("%s\n", buf); 122 | 123 | sprintf(buf,"ciaoroma"); 124 | memrev64(buf); 125 | printf("%s\n", buf); 126 | 127 | return 0; 128 | } 129 | #endif 130 | -------------------------------------------------------------------------------- /deps/redis/endianconv.h: -------------------------------------------------------------------------------- 1 | /* See endianconv.c top comments for more information 2 | * 3 | * ---------------------------------------------------------------------------- 4 | * 5 | * Copyright (c) 2011-2012, Salvatore Sanfilippo 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * * Neither the name of Redis nor the names of its contributors may be used 17 | * to endorse or promote products derived from this software without 18 | * specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | * POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #ifndef __ENDIANCONV_H 34 | #define __ENDIANCONV_H 35 | 36 | #include "config.h" 37 | #include 38 | 39 | void memrev16(void *p); 40 | void memrev32(void *p); 41 | void memrev64(void *p); 42 | uint16_t intrev16(uint16_t v); 43 | uint32_t intrev32(uint32_t v); 44 | uint64_t intrev64(uint64_t v); 45 | 46 | /* variants of the function doing the actual conversion only if the target 47 | * host is big endian */ 48 | #if (BYTE_ORDER == LITTLE_ENDIAN) 49 | #define memrev16ifbe(p) ((void)(0)) 50 | #define memrev32ifbe(p) ((void)(0)) 51 | #define memrev64ifbe(p) ((void)(0)) 52 | #define intrev16ifbe(v) (v) 53 | #define intrev32ifbe(v) (v) 54 | #define intrev64ifbe(v) (v) 55 | #else 56 | #define memrev16ifbe(p) memrev16(p) 57 | #define memrev32ifbe(p) memrev32(p) 58 | #define memrev64ifbe(p) memrev64(p) 59 | #define intrev16ifbe(v) intrev16(v) 60 | #define intrev32ifbe(v) intrev32(v) 61 | #define intrev64ifbe(v) intrev64(v) 62 | #endif 63 | 64 | /* The functions htonu64() and ntohu64() convert the specified value to 65 | * network byte ordering and back. In big endian systems they are no-ops. */ 66 | #if (BYTE_ORDER == BIG_ENDIAN) 67 | #define htonu64(v) (v) 68 | #define ntohu64(v) (v) 69 | #else 70 | #define htonu64(v) intrev64(v) 71 | #define ntohu64(v) intrev64(v) 72 | #endif 73 | 74 | 75 | #ifndef BYTE_ORDER 76 | #error "BYTE_ORDER is not defined. Compilation failed." 77 | #endif 78 | 79 | #ifdef REDIS_TEST 80 | int endianconvTest(int argc, char *argv[], int flags); 81 | #endif 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /deps/redis/fpconv_dtoa.h: -------------------------------------------------------------------------------- 1 | /* fpconv_dtoa.h -- floating point conversion utilities. 2 | * 3 | * Fast and accurate double to string conversion based on Florian Loitsch's 4 | * Grisu-algorithm[1]. 5 | * 6 | * [1] https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf 7 | * ---------------------------------------------------------------------------- 8 | * 9 | * Copyright (c) 2013-2019, night-shift 10 | * Copyright (c) 2009, Florian Loitsch < florian.loitsch at inria dot fr > 11 | * All rights reserved. 12 | * 13 | * Boost Software License - Version 1.0 - August 17th, 2003 14 | * 15 | * Permission is hereby granted, free of charge, to any person or organization 16 | * obtaining a copy of the software and accompanying documentation covered by 17 | * this license (the "Software") to use, reproduce, display, distribute, 18 | * execute, and transmit the Software, and to prepare derivative works of the 19 | * Software, and to permit third-parties to whom the Software is furnished to 20 | * do so, all subject to the following: 21 | * 22 | * The copyright notices in the Software and this entire statement, including 23 | * the above license grant, this restriction and the following disclaimer, 24 | * must be included in all copies of the Software, in whole or in part, and 25 | * all derivative works of the Software, unless such copies or derivative 26 | * works are solely in the form of machine-executable object code generated by 27 | * a source language processor. 28 | * 29 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 32 | * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 33 | * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 34 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 35 | * DEALINGS IN THE SOFTWARE. 36 | */ 37 | 38 | #ifndef FPCONV_DTOA_H 39 | #define FPCONV_DTOA_H 40 | 41 | int fpconv_dtoa(double fp, char dest[24]); 42 | 43 | #endif 44 | 45 | /* [1] http://florian.loitsch.com/publications/dtoa-pldi2010.pdf */ 46 | -------------------------------------------------------------------------------- /deps/redis/fpconv_powers.h: -------------------------------------------------------------------------------- 1 | /* fpconv_powers.h -- floating point conversion utilities. 2 | * 3 | * Fast and accurate double to string conversion based on Florian Loitsch's 4 | * Grisu-algorithm[1]. 5 | * 6 | * [1] https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf 7 | * ---------------------------------------------------------------------------- 8 | * 9 | * Copyright (c) 2021, Redis Labs 10 | * Copyright (c) 2013-2019, night-shift 11 | * Copyright (c) 2009, Florian Loitsch < florian.loitsch at inria dot fr > 12 | * All rights reserved. 13 | * 14 | * Boost Software License - Version 1.0 - August 17th, 2003 15 | * 16 | * Permission is hereby granted, free of charge, to any person or organization 17 | * obtaining a copy of the software and accompanying documentation covered by 18 | * this license (the "Software") to use, reproduce, display, distribute, 19 | * execute, and transmit the Software, and to prepare derivative works of the 20 | * Software, and to permit third-parties to whom the Software is furnished to 21 | * do so, all subject to the following: 22 | * 23 | * The copyright notices in the Software and this entire statement, including 24 | * the above license grant, this restriction and the following disclaimer, 25 | * must be included in all copies of the Software, in whole or in part, and 26 | * all derivative works of the Software, unless such copies or derivative 27 | * works are solely in the form of machine-executable object code generated by 28 | * a source language processor. 29 | * 30 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 31 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 32 | * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 33 | * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 34 | * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 35 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 36 | * DEALINGS IN THE SOFTWARE. 37 | */ 38 | 39 | #include 40 | 41 | #define npowers 87 42 | #define steppowers 8 43 | #define firstpower -348 /* 10 ^ -348 */ 44 | 45 | #define expmax -32 46 | #define expmin -60 47 | 48 | 49 | typedef struct Fp { 50 | uint64_t frac; 51 | int exp; 52 | } Fp; 53 | 54 | static Fp powers_ten[] = { 55 | { 18054884314459144840U, -1220 }, { 13451937075301367670U, -1193 }, 56 | { 10022474136428063862U, -1166 }, { 14934650266808366570U, -1140 }, 57 | { 11127181549972568877U, -1113 }, { 16580792590934885855U, -1087 }, 58 | { 12353653155963782858U, -1060 }, { 18408377700990114895U, -1034 }, 59 | { 13715310171984221708U, -1007 }, { 10218702384817765436U, -980 }, 60 | { 15227053142812498563U, -954 }, { 11345038669416679861U, -927 }, 61 | { 16905424996341287883U, -901 }, { 12595523146049147757U, -874 }, 62 | { 9384396036005875287U, -847 }, { 13983839803942852151U, -821 }, 63 | { 10418772551374772303U, -794 }, { 15525180923007089351U, -768 }, 64 | { 11567161174868858868U, -741 }, { 17236413322193710309U, -715 }, 65 | { 12842128665889583758U, -688 }, { 9568131466127621947U, -661 }, 66 | { 14257626930069360058U, -635 }, { 10622759856335341974U, -608 }, 67 | { 15829145694278690180U, -582 }, { 11793632577567316726U, -555 }, 68 | { 17573882009934360870U, -529 }, { 13093562431584567480U, -502 }, 69 | { 9755464219737475723U, -475 }, { 14536774485912137811U, -449 }, 70 | { 10830740992659433045U, -422 }, { 16139061738043178685U, -396 }, 71 | { 12024538023802026127U, -369 }, { 17917957937422433684U, -343 }, 72 | { 13349918974505688015U, -316 }, { 9946464728195732843U, -289 }, 73 | { 14821387422376473014U, -263 }, { 11042794154864902060U, -236 }, 74 | { 16455045573212060422U, -210 }, { 12259964326927110867U, -183 }, 75 | { 18268770466636286478U, -157 }, { 13611294676837538539U, -130 }, 76 | { 10141204801825835212U, -103 }, { 15111572745182864684U, -77 }, 77 | { 11258999068426240000U, -50 }, { 16777216000000000000U, -24 }, 78 | { 12500000000000000000U, 3 }, { 9313225746154785156U, 30 }, 79 | { 13877787807814456755U, 56 }, { 10339757656912845936U, 83 }, 80 | { 15407439555097886824U, 109 }, { 11479437019748901445U, 136 }, 81 | { 17105694144590052135U, 162 }, { 12744735289059618216U, 189 }, 82 | { 9495567745759798747U, 216 }, { 14149498560666738074U, 242 }, 83 | { 10542197943230523224U, 269 }, { 15709099088952724970U, 295 }, 84 | { 11704190886730495818U, 322 }, { 17440603504673385349U, 348 }, 85 | { 12994262207056124023U, 375 }, { 9681479787123295682U, 402 }, 86 | { 14426529090290212157U, 428 }, { 10748601772107342003U, 455 }, 87 | { 16016664761464807395U, 481 }, { 11933345169920330789U, 508 }, 88 | { 17782069995880619868U, 534 }, { 13248674568444952270U, 561 }, 89 | { 9871031767461413346U, 588 }, { 14708983551653345445U, 614 }, 90 | { 10959046745042015199U, 641 }, { 16330252207878254650U, 667 }, 91 | { 12166986024289022870U, 694 }, { 18130221999122236476U, 720 }, 92 | { 13508068024458167312U, 747 }, { 10064294952495520794U, 774 }, 93 | { 14996968138956309548U, 800 }, { 11173611982879273257U, 827 }, 94 | { 16649979327439178909U, 853 }, { 12405201291620119593U, 880 }, 95 | { 9242595204427927429U, 907 }, { 13772540099066387757U, 933 }, 96 | { 10261342003245940623U, 960 }, { 15290591125556738113U, 986 }, 97 | { 11392378155556871081U, 1013 }, { 16975966327722178521U, 1039 }, 98 | { 12648080533535911531U, 1066 } 99 | }; 100 | 101 | /** 102 | * Grisu needs a cache of precomputed powers-of-ten. 103 | * This function, given an exponent and an integer k 104 | * return the normalized floating-point approximation of the power of 10. 105 | * @param exp 106 | * @param k 107 | * @return 108 | */ 109 | static Fp find_cachedpow10(int exp, int* k) 110 | { 111 | const double one_log_ten = 0.30102999566398114; 112 | 113 | const int approx = -(exp + npowers) * one_log_ten; 114 | int idx = (approx - firstpower) / steppowers; 115 | 116 | while(1) { 117 | int current = exp + powers_ten[idx].exp + 64; 118 | 119 | if(current < expmin) { 120 | idx++; 121 | continue; 122 | } 123 | 124 | if(current > expmax) { 125 | idx--; 126 | continue; 127 | } 128 | 129 | *k = (firstpower + idx * steppowers); 130 | 131 | return powers_ten[idx]; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /deps/redis/intset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2012, Pieter Noordhuis 3 | * Copyright (c) 2009-2012, Salvatore Sanfilippo 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef __INTSET_H 32 | #define __INTSET_H 33 | #include 34 | 35 | typedef struct intset { 36 | uint32_t encoding; 37 | uint32_t length; 38 | int8_t contents[]; 39 | } intset; 40 | 41 | intset *intsetNew(void); 42 | intset *intsetAdd(intset *is, int64_t value, uint8_t *success); 43 | intset *intsetRemove(intset *is, int64_t value, int *success); 44 | uint8_t intsetFind(intset *is, int64_t value); 45 | int64_t intsetRandom(intset *is); 46 | int64_t intsetMax(intset *is); 47 | int64_t intsetMin(intset *is); 48 | uint8_t intsetGet(intset *is, uint32_t pos, int64_t *value); 49 | uint32_t intsetLen(const intset *is); 50 | size_t intsetBlobLen(intset *is); 51 | int intsetValidateIntegrity(const unsigned char *is, size_t size, int deep); 52 | 53 | 54 | #define is_malloc(sz) malloc(sz) 55 | #define is_realloc(ptr,sz) realloc(ptr,sz) 56 | #define is_free free 57 | 58 | #ifdef REDIS_TEST 59 | int intsetTest(int argc, char *argv[], int flags); 60 | #endif 61 | 62 | #endif // __INTSET_H 63 | -------------------------------------------------------------------------------- /deps/redis/listpack.h: -------------------------------------------------------------------------------- 1 | /* Listpack -- A lists of strings serialization format 2 | * 3 | * This file implements the specification you can find at: 4 | * 5 | * https://github.com/antirez/listpack 6 | * 7 | * Copyright (c) 2017, Salvatore Sanfilippo 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions are met: 12 | * 13 | * * Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * * Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * * Neither the name of Redis nor the names of its contributors may be used 19 | * to endorse or promote products derived from this software without 20 | * specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 26 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | #ifndef __LISTPACK_H 36 | #define __LISTPACK_H 37 | 38 | #include 39 | #include 40 | 41 | #define LP_INTBUF_SIZE 21 /* 20 digits of -2^63 + 1 null term = 21. */ 42 | 43 | /* lpInsert() where argument possible values: */ 44 | #define LP_BEFORE 0 45 | #define LP_AFTER 1 46 | #define LP_REPLACE 2 47 | 48 | /* Each entry in the listpack is either a string or an integer. */ 49 | typedef struct { 50 | /* When string is used, it is provided with the length (slen). */ 51 | unsigned char *sval; 52 | uint32_t slen; 53 | /* When integer is used, 'sval' is NULL, and lval holds the value. */ 54 | long long lval; 55 | } listpackEntry; 56 | 57 | unsigned char *lpNew(size_t capacity); 58 | void lpFree(unsigned char *lp); 59 | unsigned char* lpShrinkToFit(unsigned char *lp); 60 | unsigned char *lpInsertString(unsigned char *lp, unsigned char *s, uint32_t slen, 61 | unsigned char *p, int where, unsigned char **newp); 62 | unsigned char *lpInsertInteger(unsigned char *lp, long long lval, 63 | unsigned char *p, int where, unsigned char **newp); 64 | unsigned char *lpPrepend(unsigned char *lp, unsigned char *s, uint32_t slen); 65 | unsigned char *lpPrependInteger(unsigned char *lp, long long lval); 66 | unsigned char *lpAppend(unsigned char *lp, unsigned char *s, uint32_t slen); 67 | unsigned char *lpAppendInteger(unsigned char *lp, long long lval); 68 | unsigned char *lpReplace(unsigned char *lp, unsigned char **p, unsigned char *s, uint32_t slen); 69 | unsigned char *lpReplaceInteger(unsigned char *lp, unsigned char **p, long long lval); 70 | unsigned char *lpDelete(unsigned char *lp, unsigned char *p, unsigned char **newp); 71 | unsigned char *lpDeleteRangeWithEntry(unsigned char *lp, unsigned char **p, unsigned long num); 72 | unsigned char *lpDeleteRange(unsigned char *lp, long index, unsigned long num); 73 | unsigned char *lpMerge(unsigned char **first, unsigned char **second); 74 | unsigned long lpLength(unsigned char *lp); 75 | unsigned char *lpGet(unsigned char *p, int64_t *count, unsigned char *intbuf); 76 | unsigned char *lpGetValue(unsigned char *p, unsigned int *slen, long long *lval); 77 | unsigned char *lpFind(unsigned char *lp, unsigned char *p, unsigned char *s, uint32_t slen, unsigned int skip); 78 | unsigned char *lpFirst(unsigned char *lp); 79 | unsigned char *lpLast(unsigned char *lp); 80 | unsigned char *lpNext(unsigned char *lp, unsigned char *p); 81 | unsigned char *lpPrev(unsigned char *lp, unsigned char *p); 82 | size_t lpBytes(unsigned char *lp); 83 | unsigned char *lpSeek(unsigned char *lp, long index); 84 | typedef int (*listpackValidateEntryCB)(unsigned char *p, unsigned int head_count, void *userdata); 85 | int lpValidateIntegrity(unsigned char *lp, size_t size, int deep, 86 | listpackValidateEntryCB entry_cb, void *cb_userdata); 87 | unsigned char *lpValidateFirst(unsigned char *lp); 88 | int lpValidateNext(unsigned char *lp, unsigned char **pp, size_t lpbytes); 89 | unsigned int lpCompare(unsigned char *p, unsigned char *s, uint32_t slen); 90 | void lpRandomPair(unsigned char *lp, unsigned long total_count, listpackEntry *key, listpackEntry *val); 91 | void lpRandomPairs(unsigned char *lp, unsigned int count, listpackEntry *keys, listpackEntry *vals); 92 | unsigned int lpRandomPairsUnique(unsigned char *lp, unsigned int count, listpackEntry *keys, listpackEntry *vals); 93 | int lpSafeToAdd(unsigned char* lp, size_t add); 94 | void lpRepr(unsigned char *lp); 95 | 96 | #ifdef REDIS_TEST 97 | int listpackTest(int argc, char *argv[], int flags); 98 | #endif 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /deps/redis/listpack_malloc.h: -------------------------------------------------------------------------------- 1 | /* Listpack -- A lists of strings serialization format 2 | * https://github.com/antirez/listpack 3 | * 4 | * Copyright (c) 2017, Salvatore Sanfilippo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of Redis nor the names of its contributors may be used 16 | * to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | /* Allocator selection. 33 | * 34 | * This file is used in order to change the Rax allocator at compile time. 35 | * Just define the following defines to what you want to use. Also add 36 | * the include of your alternate allocator if needed (not needed in order 37 | * to use the default libc allocator). */ 38 | 39 | #ifndef LISTPACK_ALLOC_H 40 | #define LISTPACK_ALLOC_H 41 | 42 | #ifdef __APPLE__ 43 | #include 44 | #else 45 | #include "malloc.h" 46 | #endif 47 | 48 | #define lp_malloc(sz) malloc(sz) 49 | #define lp_realloc(ptr,sz) realloc(ptr,sz) 50 | #define lp_free free 51 | 52 | #ifdef __APPLE__ 53 | #define lp_malloc_size malloc_size 54 | #else 55 | #define lp_malloc_size malloc_usable_size 56 | #endif 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /deps/redis/lzf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2008 Marc Alexander Lehmann 3 | * 4 | * Redistribution and use in source and binary forms, with or without modifica- 5 | * tion, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- 16 | * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- 18 | * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- 22 | * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 23 | * OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * the GNU General Public License ("GPL") version 2 or any later version, 27 | * in which case the provisions of the GPL are applicable instead of 28 | * the above. If you wish to allow the use of your version of this file 29 | * only under the terms of the GPL and not to allow others to use your 30 | * version of this file under the BSD license, indicate your decision 31 | * by deleting the provisions above and replace them with the notice 32 | * and other provisions required by the GPL. If you do not delete the 33 | * provisions above, a recipient may use your version of this file under 34 | * either the BSD or the GPL. 35 | */ 36 | 37 | #ifndef LZF_H 38 | #define LZF_H 39 | 40 | /*********************************************************************** 41 | ** 42 | ** lzf -- an extremely fast/free compression/decompression-method 43 | ** http://liblzf.plan9.de/ 44 | ** 45 | ** This algorithm is believed to be patent-free. 46 | ** 47 | ***********************************************************************/ 48 | 49 | #define LZF_VERSION 0x0105 /* 1.5, API version */ 50 | 51 | /* 52 | * Compress in_len bytes stored at the memory block starting at 53 | * in_data and write the result to out_data, up to a maximum length 54 | * of out_len bytes. 55 | * 56 | * If the output buffer is not large enough or any error occurs return 0, 57 | * otherwise return the number of bytes used, which might be considerably 58 | * more than in_len (but less than 104% of the original size), so it 59 | * makes sense to always use out_len == in_len - 1), to ensure _some_ 60 | * compression, and store the data uncompressed otherwise (with a flag, of 61 | * course. 62 | * 63 | * lzf_compress might use different algorithms on different systems and 64 | * even different runs, thus might result in different compressed strings 65 | * depending on the phase of the moon or similar factors. However, all 66 | * these strings are architecture-independent and will result in the 67 | * original data when decompressed using lzf_decompress. 68 | * 69 | * The buffers must not be overlapping. 70 | * 71 | * If the option LZF_STATE_ARG is enabled, an extra argument must be 72 | * supplied which is not reflected in this header file. Refer to lzfP.h 73 | * and lzf_c.c. 74 | * 75 | */ 76 | size_t 77 | lzf_compress (const void *const in_data, size_t in_len, 78 | void *out_data, size_t out_len); 79 | 80 | /* 81 | * Decompress data compressed with some version of the lzf_compress 82 | * function and stored at location in_data and length in_len. The result 83 | * will be stored at out_data up to a maximum of out_len characters. 84 | * 85 | * If the output buffer is not large enough to hold the decompressed 86 | * data, a 0 is returned and errno is set to E2BIG. Otherwise the number 87 | * of decompressed bytes (i.e. the original length of the data) is 88 | * returned. 89 | * 90 | * If an error in the compressed data is detected, a zero is returned and 91 | * errno is set to EINVAL. 92 | * 93 | * This function is very fast, about as fast as a copying loop. 94 | */ 95 | size_t 96 | lzf_decompress (const void *const in_data, size_t in_len, 97 | void *out_data, size_t out_len); 98 | 99 | #endif 100 | 101 | -------------------------------------------------------------------------------- /deps/redis/lzfP.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2007 Marc Alexander Lehmann 3 | * 4 | * Redistribution and use in source and binary forms, with or without modifica- 5 | * tion, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- 16 | * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- 18 | * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- 22 | * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 23 | * OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * the GNU General Public License ("GPL") version 2 or any later version, 27 | * in which case the provisions of the GPL are applicable instead of 28 | * the above. If you wish to allow the use of your version of this file 29 | * only under the terms of the GPL and not to allow others to use your 30 | * version of this file under the BSD license, indicate your decision 31 | * by deleting the provisions above and replace them with the notice 32 | * and other provisions required by the GPL. If you do not delete the 33 | * provisions above, a recipient may use your version of this file under 34 | * either the BSD or the GPL. 35 | */ 36 | 37 | #ifndef LZFP_h 38 | #define LZFP_h 39 | 40 | #define STANDALONE 1 /* at the moment, this is ok. */ 41 | 42 | #ifndef STANDALONE 43 | # include "lzf.h" 44 | #endif 45 | 46 | /* 47 | * Size of hashtable is (1 << HLOG) * sizeof (char *) 48 | * decompression is independent of the hash table size 49 | * the difference between 15 and 14 is very small 50 | * for small blocks (and 14 is usually a bit faster). 51 | * For a low-memory/faster configuration, use HLOG == 13; 52 | * For best compression, use 15 or 16 (or more, up to 22). 53 | */ 54 | #ifndef HLOG 55 | # define HLOG 16 56 | #endif 57 | 58 | /* 59 | * Sacrifice very little compression quality in favour of compression speed. 60 | * This gives almost the same compression as the default code, and is 61 | * (very roughly) 15% faster. This is the preferred mode of operation. 62 | */ 63 | #ifndef VERY_FAST 64 | # define VERY_FAST 1 65 | #endif 66 | 67 | /* 68 | * Sacrifice some more compression quality in favour of compression speed. 69 | * (roughly 1-2% worse compression for large blocks and 70 | * 9-10% for small, redundant, blocks and >>20% better speed in both cases) 71 | * In short: when in need for speed, enable this for binary data, 72 | * possibly disable this for text data. 73 | */ 74 | #ifndef ULTRA_FAST 75 | # define ULTRA_FAST 0 76 | #endif 77 | 78 | /* 79 | * Unconditionally aligning does not cost very much, so do it if unsure 80 | */ 81 | #ifndef STRICT_ALIGN 82 | # if !(defined(__i386) || defined (__amd64)) 83 | # define STRICT_ALIGN 1 84 | # else 85 | # define STRICT_ALIGN 0 86 | # endif 87 | #endif 88 | 89 | /* 90 | * You may choose to pre-set the hash table (might be faster on some 91 | * modern cpus and large (>>64k) blocks, and also makes compression 92 | * deterministic/repeatable when the configuration otherwise is the same). 93 | */ 94 | #ifndef INIT_HTAB 95 | # define INIT_HTAB 0 96 | #endif 97 | 98 | /* 99 | * Avoid assigning values to errno variable? for some embedding purposes 100 | * (linux kernel for example), this is necessary. NOTE: this breaks 101 | * the documentation in lzf.h. Avoiding errno has no speed impact. 102 | */ 103 | #ifndef AVOID_ERRNO 104 | # define AVOID_ERRNO 0 105 | #endif 106 | 107 | /* 108 | * Whether to pass the LZF_STATE variable as argument, or allocate it 109 | * on the stack. For small-stack environments, define this to 1. 110 | * NOTE: this breaks the prototype in lzf.h. 111 | */ 112 | #ifndef LZF_STATE_ARG 113 | # define LZF_STATE_ARG 0 114 | #endif 115 | 116 | /* 117 | * Whether to add extra checks for input validity in lzf_decompress 118 | * and return EINVAL if the input stream has been corrupted. This 119 | * only shields against overflowing the input buffer and will not 120 | * detect most corrupted streams. 121 | * This check is not normally noticeable on modern hardware 122 | * (<1% slowdown), but might slow down older cpus considerably. 123 | */ 124 | #ifndef CHECK_INPUT 125 | # define CHECK_INPUT 1 126 | #endif 127 | 128 | /* 129 | * Whether to store pointers or offsets inside the hash table. On 130 | * 64 bit architectures, pointers take up twice as much space, 131 | * and might also be slower. Default is to autodetect. 132 | * Notice: Don't set this value to 1, it will result in 'LZF_HSLOT' 133 | * not being able to store offset above UINT32_MAX in 64bit. */ 134 | #define LZF_USE_OFFSETS 0 135 | 136 | /*****************************************************************************/ 137 | /* nothing should be changed below */ 138 | 139 | #ifdef __cplusplus 140 | # include 141 | # include 142 | using namespace std; 143 | #else 144 | # include 145 | # include 146 | #endif 147 | 148 | #ifndef LZF_USE_OFFSETS 149 | # if defined (WIN32) 150 | # define LZF_USE_OFFSETS defined(_M_X64) 151 | # else 152 | # if __cplusplus > 199711L 153 | # include 154 | # else 155 | # include 156 | # endif 157 | # define LZF_USE_OFFSETS (UINTPTR_MAX > 0xffffffffU) 158 | # endif 159 | #endif 160 | 161 | typedef unsigned char u8; 162 | 163 | #if LZF_USE_OFFSETS 164 | # define LZF_HSLOT_BIAS ((const u8 *)in_data) 165 | typedef unsigned int LZF_HSLOT; 166 | #else 167 | # define LZF_HSLOT_BIAS 0 168 | typedef const u8 *LZF_HSLOT; 169 | #endif 170 | 171 | typedef LZF_HSLOT LZF_STATE[1 << (HLOG)]; 172 | 173 | #if !STRICT_ALIGN 174 | /* for unaligned accesses we need a 16 bit datatype. */ 175 | # if USHRT_MAX == 65535 176 | typedef unsigned short u16; 177 | # elif UINT_MAX == 65535 178 | typedef unsigned int u16; 179 | # else 180 | # undef STRICT_ALIGN 181 | # define STRICT_ALIGN 1 182 | # endif 183 | #endif 184 | 185 | #if ULTRA_FAST 186 | # undef VERY_FAST 187 | #endif 188 | 189 | #endif 190 | 191 | -------------------------------------------------------------------------------- /deps/redis/lzf_d.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2010 Marc Alexander Lehmann 3 | * 4 | * Redistribution and use in source and binary forms, with or without modifica- 5 | * tion, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- 16 | * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- 18 | * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- 22 | * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 23 | * OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * the GNU General Public License ("GPL") version 2 or any later version, 27 | * in which case the provisions of the GPL are applicable instead of 28 | * the above. If you wish to allow the use of your version of this file 29 | * only under the terms of the GPL and not to allow others to use your 30 | * version of this file under the BSD license, indicate your decision 31 | * by deleting the provisions above and replace them with the notice 32 | * and other provisions required by the GPL. If you do not delete the 33 | * provisions above, a recipient may use your version of this file under 34 | * either the BSD or the GPL. 35 | */ 36 | 37 | #include "lzfP.h" 38 | 39 | #if AVOID_ERRNO 40 | # define SET_ERRNO(n) 41 | #else 42 | # include 43 | # define SET_ERRNO(n) errno = (n) 44 | #endif 45 | 46 | #if USE_REP_MOVSB /* small win on amd, big loss on intel */ 47 | #if (__i386 || __amd64) && __GNUC__ >= 3 48 | # define lzf_movsb(dst, src, len) \ 49 | asm ("rep movsb" \ 50 | : "=D" (dst), "=S" (src), "=c" (len) \ 51 | : "0" (dst), "1" (src), "2" (len)); 52 | #endif 53 | #endif 54 | 55 | #if defined(__GNUC__) && __GNUC__ >= 7 56 | #pragma GCC diagnostic push 57 | #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" 58 | #endif 59 | size_t 60 | lzf_decompress (const void *const in_data, size_t in_len, 61 | void *out_data, size_t out_len) 62 | { 63 | u8 const *ip = (const u8 *)in_data; 64 | u8 *op = (u8 *)out_data; 65 | u8 const *const in_end = ip + in_len; 66 | u8 *const out_end = op + out_len; 67 | 68 | while (ip < in_end) 69 | { 70 | unsigned int ctrl; 71 | ctrl = *ip++; 72 | 73 | if (ctrl < (1 << 5)) /* literal run */ 74 | { 75 | ctrl++; 76 | 77 | if (op + ctrl > out_end) 78 | { 79 | SET_ERRNO (E2BIG); 80 | return 0; 81 | } 82 | 83 | #if CHECK_INPUT 84 | if (ip + ctrl > in_end) 85 | { 86 | SET_ERRNO (EINVAL); 87 | return 0; 88 | } 89 | #endif 90 | 91 | #ifdef lzf_movsb 92 | lzf_movsb (op, ip, ctrl); 93 | #else 94 | switch (ctrl) 95 | { 96 | case 32: *op++ = *ip++; case 31: *op++ = *ip++; case 30: *op++ = *ip++; case 29: *op++ = *ip++; 97 | case 28: *op++ = *ip++; case 27: *op++ = *ip++; case 26: *op++ = *ip++; case 25: *op++ = *ip++; 98 | case 24: *op++ = *ip++; case 23: *op++ = *ip++; case 22: *op++ = *ip++; case 21: *op++ = *ip++; 99 | case 20: *op++ = *ip++; case 19: *op++ = *ip++; case 18: *op++ = *ip++; case 17: *op++ = *ip++; 100 | case 16: *op++ = *ip++; case 15: *op++ = *ip++; case 14: *op++ = *ip++; case 13: *op++ = *ip++; 101 | case 12: *op++ = *ip++; case 11: *op++ = *ip++; case 10: *op++ = *ip++; case 9: *op++ = *ip++; 102 | case 8: *op++ = *ip++; case 7: *op++ = *ip++; case 6: *op++ = *ip++; case 5: *op++ = *ip++; 103 | case 4: *op++ = *ip++; case 3: *op++ = *ip++; case 2: *op++ = *ip++; case 1: *op++ = *ip++; 104 | } 105 | #endif 106 | } 107 | else /* back reference */ 108 | { 109 | unsigned int len = ctrl >> 5; 110 | 111 | u8 *ref = op - ((ctrl & 0x1f) << 8) - 1; 112 | 113 | #if CHECK_INPUT 114 | if (ip >= in_end) 115 | { 116 | SET_ERRNO (EINVAL); 117 | return 0; 118 | } 119 | #endif 120 | if (len == 7) 121 | { 122 | len += *ip++; 123 | #if CHECK_INPUT 124 | if (ip >= in_end) 125 | { 126 | SET_ERRNO (EINVAL); 127 | return 0; 128 | } 129 | #endif 130 | } 131 | 132 | ref -= *ip++; 133 | 134 | if (op + len + 2 > out_end) 135 | { 136 | SET_ERRNO (E2BIG); 137 | return 0; 138 | } 139 | 140 | if (ref < (u8 *)out_data) 141 | { 142 | SET_ERRNO (EINVAL); 143 | return 0; 144 | } 145 | 146 | #ifdef lzf_movsb 147 | len += 2; 148 | lzf_movsb (op, ref, len); 149 | #else 150 | switch (len) 151 | { 152 | default: 153 | len += 2; 154 | 155 | if (op >= ref + len) 156 | { 157 | /* disjunct areas */ 158 | memcpy (op, ref, len); 159 | op += len; 160 | } 161 | else 162 | { 163 | /* overlapping, use octte by octte copying */ 164 | do 165 | *op++ = *ref++; 166 | while (--len); 167 | } 168 | 169 | break; 170 | 171 | case 9: *op++ = *ref++; /* fall-thru */ 172 | case 8: *op++ = *ref++; /* fall-thru */ 173 | case 7: *op++ = *ref++; /* fall-thru */ 174 | case 6: *op++ = *ref++; /* fall-thru */ 175 | case 5: *op++ = *ref++; /* fall-thru */ 176 | case 4: *op++ = *ref++; /* fall-thru */ 177 | case 3: *op++ = *ref++; /* fall-thru */ 178 | case 2: *op++ = *ref++; /* fall-thru */ 179 | case 1: *op++ = *ref++; /* fall-thru */ 180 | case 0: *op++ = *ref++; /* two octets more */ 181 | *op++ = *ref++; /* fall-thru */ 182 | } 183 | #endif 184 | } 185 | } 186 | 187 | return op - (u8 *)out_data; 188 | } 189 | #if defined(__GNUC__) && __GNUC__ >= 5 190 | #pragma GCC diagnostic pop 191 | #endif 192 | -------------------------------------------------------------------------------- /deps/redis/rax_malloc.h: -------------------------------------------------------------------------------- 1 | /* Rax -- A radix tree implementation. 2 | * 3 | * Copyright (c) 2017, Salvatore Sanfilippo 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | /* Allocator selection. 32 | * 33 | * This file is used in order to change the Rax allocator at compile time. 34 | * Just define the following defines to what you want to use. Also add 35 | * the include of your alternate allocator if needed (not needed in order 36 | * to use the default libc allocator). */ 37 | 38 | #ifndef RAX_ALLOC_H 39 | #define RAX_ALLOC_H 40 | //#include "zmalloc.h" 41 | #include 42 | #define rax_malloc malloc 43 | #define rax_realloc realloc 44 | #define rax_free free 45 | #endif 46 | -------------------------------------------------------------------------------- /deps/redis/sha256.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: sha256.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Implementation of the SHA-256 hashing algorithm. 7 | SHA-256 is one of the three algorithms in the SHA2 8 | specification. The others, SHA-384 and SHA-512, are not 9 | offered in this implementation. 10 | Algorithm specification can be found here: 11 | * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf 12 | This implementation uses little endian byte order. 13 | *********************************************************************/ 14 | 15 | /*************************** HEADER FILES ***************************/ 16 | #include 17 | #include 18 | #include "sha256.h" 19 | 20 | /****************************** MACROS ******************************/ 21 | #define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) 22 | #define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) 23 | 24 | #define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) 25 | #define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 26 | #define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) 27 | #define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) 28 | #define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) 29 | #define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) 30 | 31 | /**************************** VARIABLES *****************************/ 32 | static const WORD k[64] = { 33 | 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, 34 | 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, 35 | 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, 36 | 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, 37 | 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, 38 | 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, 39 | 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, 40 | 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 41 | }; 42 | 43 | /*********************** FUNCTION DEFINITIONS ***********************/ 44 | void sha256_transform(SHA256_CTX *ctx, const BYTE data[]) 45 | { 46 | WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64]; 47 | 48 | for (i = 0, j = 0; i < 16; ++i, j += 4) { 49 | m[i] = ((WORD) data[j + 0] << 24) | 50 | ((WORD) data[j + 1] << 16) | 51 | ((WORD) data[j + 2] << 8) | 52 | ((WORD) data[j + 3]); 53 | } 54 | 55 | for ( ; i < 64; ++i) 56 | m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; 57 | 58 | a = ctx->state[0]; 59 | b = ctx->state[1]; 60 | c = ctx->state[2]; 61 | d = ctx->state[3]; 62 | e = ctx->state[4]; 63 | f = ctx->state[5]; 64 | g = ctx->state[6]; 65 | h = ctx->state[7]; 66 | 67 | for (i = 0; i < 64; ++i) { 68 | t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; 69 | t2 = EP0(a) + MAJ(a,b,c); 70 | h = g; 71 | g = f; 72 | f = e; 73 | e = d + t1; 74 | d = c; 75 | c = b; 76 | b = a; 77 | a = t1 + t2; 78 | } 79 | 80 | ctx->state[0] += a; 81 | ctx->state[1] += b; 82 | ctx->state[2] += c; 83 | ctx->state[3] += d; 84 | ctx->state[4] += e; 85 | ctx->state[5] += f; 86 | ctx->state[6] += g; 87 | ctx->state[7] += h; 88 | } 89 | 90 | void sha256_init(SHA256_CTX *ctx) 91 | { 92 | ctx->datalen = 0; 93 | ctx->bitlen = 0; 94 | ctx->state[0] = 0x6a09e667; 95 | ctx->state[1] = 0xbb67ae85; 96 | ctx->state[2] = 0x3c6ef372; 97 | ctx->state[3] = 0xa54ff53a; 98 | ctx->state[4] = 0x510e527f; 99 | ctx->state[5] = 0x9b05688c; 100 | ctx->state[6] = 0x1f83d9ab; 101 | ctx->state[7] = 0x5be0cd19; 102 | } 103 | 104 | void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len) 105 | { 106 | WORD i; 107 | 108 | for (i = 0; i < len; ++i) { 109 | ctx->data[ctx->datalen] = data[i]; 110 | ctx->datalen++; 111 | if (ctx->datalen == 64) { 112 | sha256_transform(ctx, ctx->data); 113 | ctx->bitlen += 512; 114 | ctx->datalen = 0; 115 | } 116 | } 117 | } 118 | 119 | void sha256_final(SHA256_CTX *ctx, BYTE hash[]) 120 | { 121 | WORD i; 122 | 123 | i = ctx->datalen; 124 | 125 | // Pad whatever data is left in the buffer. 126 | if (ctx->datalen < 56) { 127 | ctx->data[i++] = 0x80; 128 | while (i < 56) 129 | ctx->data[i++] = 0x00; 130 | } 131 | else { 132 | ctx->data[i++] = 0x80; 133 | while (i < 64) 134 | ctx->data[i++] = 0x00; 135 | sha256_transform(ctx, ctx->data); 136 | memset(ctx->data, 0, 56); 137 | } 138 | 139 | // Append to the padding the total message's length in bits and transform. 140 | ctx->bitlen += ctx->datalen * 8; 141 | ctx->data[63] = ctx->bitlen; 142 | ctx->data[62] = ctx->bitlen >> 8; 143 | ctx->data[61] = ctx->bitlen >> 16; 144 | ctx->data[60] = ctx->bitlen >> 24; 145 | ctx->data[59] = ctx->bitlen >> 32; 146 | ctx->data[58] = ctx->bitlen >> 40; 147 | ctx->data[57] = ctx->bitlen >> 48; 148 | ctx->data[56] = ctx->bitlen >> 56; 149 | sha256_transform(ctx, ctx->data); 150 | 151 | // Since this implementation uses little endian byte ordering and SHA uses big endian, 152 | // reverse all the bytes when copying the final state to the output hash. 153 | for (i = 0; i < 4; ++i) { 154 | hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; 155 | hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; 156 | hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; 157 | hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; 158 | hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; 159 | hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; 160 | hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; 161 | hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /deps/redis/sha256.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: sha256.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding SHA256 implementation. 7 | *********************************************************************/ 8 | 9 | #ifndef SHA256_H 10 | #define SHA256_H 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | #include 15 | 16 | /****************************** MACROS ******************************/ 17 | #define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest 18 | 19 | /**************************** DATA TYPES ****************************/ 20 | typedef uint8_t BYTE; // 8-bit byte 21 | typedef uint32_t WORD; // 32-bit word 22 | 23 | typedef struct { 24 | BYTE data[64]; 25 | WORD datalen; 26 | unsigned long long bitlen; 27 | WORD state[8]; 28 | } SHA256_CTX; 29 | 30 | /*********************** FUNCTION DECLARATIONS **********************/ 31 | void sha256_init(SHA256_CTX *ctx); 32 | void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len); 33 | void sha256_final(SHA256_CTX *ctx, BYTE hash[]); 34 | 35 | #endif // SHA256_H 36 | -------------------------------------------------------------------------------- /deps/redis/stream.h: -------------------------------------------------------------------------------- 1 | #ifndef STREAM_H 2 | #define STREAM_H 3 | 4 | #include "listpack.h" 5 | 6 | /* Stream item ID: a 128 bit number composed of a milliseconds time and 7 | * a sequence counter. IDs generated in the same millisecond (or in a past 8 | * millisecond if the clock jumped backward) will use the millisecond time 9 | * of the latest generated ID and an incremented sequence. */ 10 | typedef struct streamID { 11 | uint64_t ms; /* Unix time in milliseconds. */ 12 | uint64_t seq; /* Sequence number. */ 13 | } streamID; 14 | 15 | /* Copied from Redis repo (/src/stream.h) 16 | * We define an iterator to iterate stream items in an abstract way, without 17 | * caring about the radix tree + listpack representation. Technically speaking 18 | * the iterator is only used inside streamReplyWithRange(), so could just 19 | * be implemented inside the function, but practically there is the AOF 20 | * rewriting code that also needs to iterate the stream to emit the XADD 21 | * commands. */ 22 | typedef struct streamIterator { 23 | //stream *stream; /* The stream we are iterating. */ 24 | streamID master_id; /* ID of the master entry at listpack head. */ 25 | uint64_t master_fields_count; /* Master entries # of fields. */ 26 | unsigned char *master_fields_start; /* Master entries start in listpack. */ 27 | unsigned char *master_fields_ptr; /* Master field to emit next. */ 28 | int entry_flags; /* Flags of entry we are emitting. */ 29 | int rev; /* True if iterating end to start (reverse). */ 30 | int skip_tombstones; /* True if not emitting tombstone entries. */ 31 | uint64_t start_key[2]; /* Start key as 128 bit big endian. */ 32 | uint64_t end_key[2]; /* End key as 128 bit big endian. */ 33 | // raxIterator ri; /* Rax iterator. */ 34 | unsigned char *lp; /* Current listpack. */ 35 | unsigned char *lp_ele; /* Current listpack cursor. */ 36 | unsigned char *lp_flags; /* Current entry flags pointer. */ 37 | /* Buffers used to hold the string of lpGet() when the element is 38 | * integer encoded, so that there is no string representation of the 39 | * element inside the listpack itself. */ 40 | unsigned char field_buf[LP_INTBUF_SIZE]; 41 | unsigned char value_buf[LP_INTBUF_SIZE]; 42 | } streamIterator; 43 | 44 | int streamIteratorGetID(streamIterator *si, streamID *id, int64_t *numfields); 45 | void streamIteratorGetField(streamIterator *si, unsigned char **fieldptr, unsigned char **valueptr, int64_t *fieldlen, int64_t *valuelen); 46 | void streamIteratorStart(streamIterator *si, char *raxnodekey, unsigned char *listpack); 47 | 48 | #endif //STREAM_H 49 | -------------------------------------------------------------------------------- /deps/redis/t_zset.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2012, Salvatore Sanfilippo 3 | * Copyright (c) 2009-2012, Pieter Noordhuis 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | double zzlStrtod(unsigned char *vstr, unsigned int vlen) { 35 | char buf[128]; 36 | if (vlen > sizeof(buf) - 1) 37 | vlen = sizeof(buf) - 1; 38 | memcpy(buf,vstr,vlen); 39 | buf[vlen] = '\0'; 40 | return strtod(buf,NULL); 41 | } 42 | -------------------------------------------------------------------------------- /deps/redis/t_zset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2012, Salvatore Sanfilippo 3 | * Copyright (c) 2009-2012, Pieter Noordhuis 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef LIBRDB_T_ZSET_H 32 | #define LIBRDB_T_ZSET_H 33 | 34 | double zzlStrtod(unsigned char *vstr, unsigned int vlen); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /deps/redis/util.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRDB_UTIL_H 2 | #define LIBRDB_UTIL_H 3 | 4 | #include 5 | 6 | #ifdef __GNUC__ 7 | #define likely(x) __builtin_expect(!!(x), 1) 8 | #define unlikely(x) __builtin_expect(!!(x), 0) 9 | #else 10 | #define likely(x) (x) 11 | #define unlikely(x) (x) 12 | #endif 13 | 14 | /* Bytes needed for long -> str + '\0' */ 15 | #define LONG_STR_SIZE 21 16 | 17 | /* The maximum number of characters needed to for d2string/fpconv_dtoa call. 18 | * Since it uses %g and not %f, some 40 chars should be enough. */ 19 | #define MAX_D2STRING_CHARS 128 20 | 21 | int string2ll(const char *s, size_t slen, long long *value); 22 | int ll2string(char *s, size_t len, long long value); 23 | int ull2string(char *s, size_t len, unsigned long long value); 24 | int lpStringToInt64(const char *s, unsigned long slen, int64_t *value); 25 | unsigned int getEnvVar(const char* varName, unsigned int defaultVal); 26 | 27 | /* This is the exact function that is used in redis zset implementation for 28 | * double <-> string conversions. Using some other function may result in 29 | * incompatibilities as you can also convert double to string that results in 30 | * loss of precision, or it might not represent inf, -inf or nan values 31 | * similar to this function output. */ 32 | int d2string(char *buf, size_t len, double value); 33 | 34 | #endif /*LIBRDB_UTIL_H*/ 35 | -------------------------------------------------------------------------------- /deps/redis/version.h: -------------------------------------------------------------------------------- 1 | #define REDIS_VERSION "7.0.11" 2 | #define REDIS_VERSION_NUM 0x0007000b 3 | -------------------------------------------------------------------------------- /deps/redis/ziplist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2012, Pieter Noordhuis 3 | * Copyright (c) 2009-2012, Salvatore Sanfilippo 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef _ZIPLIST_H 32 | #define _ZIPLIST_H 33 | 34 | #define ZIPLIST_HEAD 0 35 | #define ZIPLIST_TAIL 1 36 | 37 | /* Each entry in the ziplist is either a string or an integer. */ 38 | typedef struct { 39 | /* When string is used, it is provided with the length (slen). */ 40 | unsigned char *sval; 41 | unsigned int slen; 42 | /* When integer is used, 'sval' is NULL, and lval holds the value. */ 43 | long long lval; 44 | } ziplistEntry; 45 | 46 | unsigned char *ziplistNew(void); 47 | unsigned char *ziplistMerge(unsigned char **first, unsigned char **second); 48 | unsigned char *ziplistPush(unsigned char *zl, unsigned char *s, unsigned int slen, int where); 49 | unsigned char *ziplistIndex(unsigned char *zl, int index); 50 | unsigned char *ziplistNext(unsigned char *zl, unsigned char *p); 51 | unsigned char *ziplistPrev(unsigned char *zl, unsigned char *p); 52 | unsigned int ziplistGet(unsigned char *p, unsigned char **sval, unsigned int *slen, long long *lval); 53 | unsigned char *ziplistInsert(unsigned char *zl, unsigned char *p, unsigned char *s, unsigned int slen); 54 | unsigned char *ziplistDelete(unsigned char *zl, unsigned char **p); 55 | unsigned char *ziplistDeleteRange(unsigned char *zl, int index, unsigned int num); 56 | unsigned char *ziplistReplace(unsigned char *zl, unsigned char *p, unsigned char *s, unsigned int slen); 57 | unsigned int ziplistCompare(unsigned char *p, unsigned char *s, unsigned int slen); 58 | unsigned char *ziplistFind(unsigned char *zl, unsigned char *p, unsigned char *vstr, unsigned int vlen, unsigned int skip); 59 | unsigned int ziplistLen(unsigned char *zl); 60 | size_t ziplistBlobLen(unsigned char *zl); 61 | void ziplistRepr(unsigned char *zl); 62 | typedef int (*ziplistValidateEntryCB)(unsigned char* p, unsigned int head_count, void* userdata); 63 | int ziplistValidateIntegrity(unsigned char *zl, size_t size, int deep, 64 | ziplistValidateEntryCB entry_cb, void *cb_userdata); 65 | void ziplistRandomPair(unsigned char *zl, unsigned long total_count, ziplistEntry *key, ziplistEntry *val); 66 | void ziplistRandomPairs(unsigned char *zl, unsigned int count, ziplistEntry *keys, ziplistEntry *vals); 67 | unsigned int ziplistRandomPairsUnique(unsigned char *zl, unsigned int count, ziplistEntry *keys, ziplistEntry *vals); 68 | int ziplistSafeToAdd(unsigned char* zl, size_t add); 69 | 70 | 71 | #endif /* _ZIPLIST_H */ 72 | -------------------------------------------------------------------------------- /deps/redis/zipmap.h: -------------------------------------------------------------------------------- 1 | /* String -> String Map data structure optimized for size. 2 | * 3 | * See zipmap.c for more info. 4 | * 5 | * -------------------------------------------------------------------------- 6 | * 7 | * Copyright (c) 2009-2010, Salvatore Sanfilippo 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions are met: 12 | * 13 | * * Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * * Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * * Neither the name of Redis nor the names of its contributors may be used 19 | * to endorse or promote products derived from this software without 20 | * specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 26 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | #ifndef _ZIPMAP_H 36 | #define _ZIPMAP_H 37 | 38 | unsigned char *zipmapNew(void); 39 | unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char *val, unsigned int vlen, int *update); 40 | unsigned char *zipmapDel(unsigned char *zm, unsigned char *key, unsigned int klen, int *deleted); 41 | unsigned char *zipmapRewind(unsigned char *zm); 42 | unsigned char *zipmapNext(unsigned char *zm, unsigned char **key, unsigned int *klen, unsigned char **value, unsigned int *vlen); 43 | int zipmapGet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char **value, unsigned int *vlen); 44 | int zipmapExists(unsigned char *zm, unsigned char *key, unsigned int klen); 45 | unsigned int zipmapLen(unsigned char *zm); 46 | size_t zipmapBlobLen(unsigned char *zm); 47 | void zipmapRepr(unsigned char *p); 48 | int zipmapValidateIntegrity(unsigned char *zm, size_t size, int deep); 49 | 50 | #ifdef REDIS_TEST 51 | int zipmapTest(int argc, char *argv[], int flags); 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | default: all 2 | 3 | LIB_NAME = rdb 4 | LIB_DIR = ../lib 5 | LIB_NAME_EXT = $(LIB_NAME)-ext 6 | 7 | # Artifacts: 8 | TARGET_TEST = example1 9 | 10 | ######################################################################################### 11 | SOURCES = $(notdir $(basename $(wildcard *.c))) 12 | OBJECTS = $(patsubst %,%.o,$(SOURCES)) 13 | TARGETS = $(basename $(SOURCES)) 14 | 15 | OPTIMIZATION?=-O3 16 | 17 | STD = -std=c99 18 | STACK = -fstack-protector-all -Wstack-protector 19 | WARNS = -Wall -Wextra -pedantic -Werror 20 | CFLAGS = -fPIC $(OPTIMIZATION) $(STD) $(STACK) $(WARNS) 21 | DEBUG = -g3 -DDEBUG=1 22 | LIBS = -L /usr/lib -L $(LIB_DIR) -l $(LIB_NAME) -l $(LIB_NAME_EXT) 23 | 24 | ifeq ($(BUILD_TLS),yes) 25 | CFLAGS+=-DUSE_OPENSSL=1 26 | LIBS+=-lssl -lcrypto 27 | endif 28 | 29 | ######################################### RULES ####################################### 30 | all: $(TARGET_TEST) 31 | @echo "Done."; 32 | 33 | $(TARGET_TEST): %: %.c 34 | $(CC) $(CFLAGS) -o $@ $< $(DEBUG) $(LIBS) 35 | 36 | clean: 37 | @rm -rvf $(TARGETS) ./*.o; 38 | 39 | .PHONY: all clean -------------------------------------------------------------------------------- /examples/dumps/multiple_lists_strings.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/examples/dumps/multiple_lists_strings.rdb -------------------------------------------------------------------------------- /examples/example1.c: -------------------------------------------------------------------------------- 1 | /* The following C file serves as an illustration of how to use the librdb 2 | * library for transforming Redis RDB files into JSON format. If you wish to see 3 | * the various parsing components being invoked in the background, simply set 4 | * the environment variable LIBRDB_DEBUG_DATA to 1. 5 | * 6 | * $ export LIBRDB_DEBUG_DATA=1 7 | * $ make example 8 | * 9 | */ 10 | #include 11 | #include 12 | #include "../api/librdb-api.h" /* RDB library header */ 13 | #include "../api/librdb-ext-api.h" /* RDB library extension header */ 14 | 15 | 16 | void logger(RdbLogLevel l, const char *msg) { 17 | static char *logLevelStr[] = { 18 | [RDB_LOG_ERR] = "| ERROR |", 19 | [RDB_LOG_WRN] = "| WARN |", 20 | [RDB_LOG_INF] = "| INFO |", 21 | [RDB_LOG_DBG] = "| DEBUG |", 22 | }; 23 | printf("%s %s\n", logLevelStr[l], msg); 24 | } 25 | 26 | /******************************************************************* 27 | * Example of RDB to Json file conversion. It also shows the usage 28 | * of two FilterKey. 29 | *******************************************************************/ 30 | int main(void) { 31 | RdbParser *parser; 32 | RdbxReaderFile *reader; 33 | RdbxToJson *rdbToJson; 34 | RdbxFilter *filterKey; 35 | RdbRes err=RDB_OK; 36 | 37 | const char *infile = "./dumps/multiple_lists_strings.rdb"; 38 | const char *outfile = "./dumps/multiple_lists_strings.json"; 39 | 40 | parser = RDB_createParserRdb(NULL); 41 | if (!parser) { 42 | logger(RDB_LOG_ERR, "Failed to create parser"); 43 | return RDB_ERR_FAILED_CREATE_PARSER; 44 | } 45 | 46 | RDB_setLogger(parser, logger); 47 | 48 | reader = RDBX_createReaderFile(parser, infile); 49 | if (!reader) goto PARSER_ERROR; 50 | 51 | /* Create RDB to JSON built-in Handlers */ 52 | rdbToJson = RDBX_createHandlersToJson(parser, outfile, NULL); 53 | if (!rdbToJson) goto PARSER_ERROR; 54 | 55 | /* Filter keys that starts with the word `mylist` */ 56 | filterKey = RDBX_createHandlersFilterKey(parser, "mylist.*", 0 /*exclude*/); 57 | if (!filterKey) goto PARSER_ERROR; 58 | 59 | /* Run the parser */ 60 | RdbStatus status = RDB_parse(parser); 61 | if (status != RDB_STATUS_OK) goto PARSER_ERROR; 62 | printf ("Parsed successfully RDB to JSON file: %s\n", outfile); 63 | 64 | goto PARSER_END; 65 | 66 | PARSER_ERROR: 67 | err = RDB_getErrorCode(parser); 68 | assert(err != RDB_OK); 69 | logger(RDB_LOG_ERR, RDB_getErrorMessage(parser)); 70 | 71 | PARSER_END: 72 | RDB_deleteParser(parser); 73 | return err; 74 | } 75 | -------------------------------------------------------------------------------- /lib/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/lib/.gitkeep -------------------------------------------------------------------------------- /librdb-ext.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${exec_prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: librdb-ext 7 | Description: Extension library for parsing Redis RDB to JSON and RESP protocols 8 | Version: @VERSION@ 9 | Libs: -L${libdir} -lrdb-ext 10 | Requires: librdb 11 | Cflags: -I${includedir} 12 | -------------------------------------------------------------------------------- /librdb.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${exec_prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: librdb 7 | Description: Library for parsing Redis RDB files 8 | Version: @VERSION@ 9 | Libs: -L${libdir} -lrdb 10 | Cflags: -I${includedir} 11 | -------------------------------------------------------------------------------- /runtests: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | VALGRIND=0 4 | REDIS_FOLDER="" 5 | SPECIFIC_TEST="" 6 | SPECIFIC_TEST_GROUP="" 7 | 8 | while [[ $# -gt 0 ]]; do 9 | case $1 in 10 | -v|--valgrind) 11 | VALGRIND=1 12 | shift ;; 13 | -f|--redis-folder) 14 | REDIS_FOLDER=" --redis-folder $2 " 15 | shift 2 ;; 16 | -t|--test) 17 | SPECIFIC_TEST=" --test $2 " 18 | shift 2 ;; 19 | -g|--test-group) 20 | SPECIFIC_TEST_GROUP=" --test-group $2 " 21 | shift 2 ;; 22 | *|-h) 23 | echo "Usage: $(basename $0) [-v|--valgrind] [-f|--folder REDIS_FOLDER] [-t|--test TEST] [-g|--test-group GROUP]" 24 | exit 1 ;; 25 | esac 26 | done 27 | 28 | export LD_LIBRARY_PATH="`pwd`/lib"${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}:/usr/local/lib 29 | 30 | if [[ ${VALGRIND} -ne 0 ]]; then 31 | valgrind \ 32 | --track-origins=yes \ 33 | --leak-check=full \ 34 | --leak-resolution=high \ 35 | --error-exitcode=1 \ 36 | --log-file=test/log/valgrind.log \ 37 | ./test/test_static_lib -v $REDIS_FOLDER $SPECIFIC_TEST $SPECIFIC_TEST_GROUP && exit 0 38 | 39 | sed -n -e '/SUMMARY:/,$p' ./test/log/valgrind.log | tail -n 20 40 | echo -en "\n(Entire log available at: ./test/log/valgrind.log)\n" 41 | exit 1 42 | 43 | else 44 | ./test/test_lib $REDIS_FOLDER $SPECIFIC_TEST $SPECIFIC_TEST_GROUP 45 | fi 46 | -------------------------------------------------------------------------------- /src/cli/Makefile: -------------------------------------------------------------------------------- 1 | default: all 2 | 3 | LIB_DIR = ../../lib 4 | LIB_NAME = rdb 5 | LIB_FILENAME = librdb.a 6 | LIB_NAME_EXT = rdb-ext 7 | LIB_FILENAME_EXT = librdb-ext.a 8 | 9 | # Artifacts: 10 | TARGET_APP = rdb-cli 11 | 12 | ######################################################################################### 13 | SOURCES = $(notdir $(basename $(wildcard *.c))) 14 | OBJECTS = $(patsubst %,%.o,$(SOURCES)) 15 | TARGETS = $(basename $(SOURCES)) 16 | 17 | OPTIMIZATION ?= -O3 18 | 19 | STD = -std=c99 20 | STACK = -fstack-protector-all -Wstack-protector 21 | WARNS = -Wall -Wextra -pedantic -Werror 22 | CFLAGS = -fPIC $(OPTIMIZATION) $(STD) $(STACK) $(WARNS) 23 | DEBUG = -g3 -DDEBUG=1 24 | 25 | ifeq ($(shell uname -s),Darwin) 26 | LIBS = -L $(LIB_DIR) -l $(LIB_NAME_EXT) -l $(LIB_NAME) 27 | else 28 | LIBS = -L $(LIB_DIR) -l:$(LIB_FILENAME) -l:$(LIB_FILENAME_EXT) 29 | endif 30 | 31 | ifeq ($(BUILD_TLS),yes) 32 | CFLAGS+=-DUSE_OPENSSL=1 33 | LIBS += -lssl -lcrypto 34 | endif 35 | 36 | ######################################### RULES ####################################### 37 | all: $(TARGET_APP) 38 | rm -f ../../bin/$(TARGET_APP) 39 | cp $(TARGET_APP) ../../bin/ 40 | @echo "Done."; 41 | 42 | $(TARGET_APP): %: %.c lib_dependency 43 | $(CC) $(CFLAGS) -o $@ $< $(DEBUG) $(LIBS) 44 | 45 | lib_dependency: $(LIB_DIR)/$(LIB_FILENAME_EXT) 46 | 47 | clean: 48 | @rm -rvf $(TARGETS) ./*.o ../../bin/$(TARGET_APP) 49 | 50 | .PHONY: all clean lib_dependency -------------------------------------------------------------------------------- /src/ext/Makefile: -------------------------------------------------------------------------------- 1 | default: all 2 | 3 | LIB_DIR = ../../lib 4 | LIB_NAME = rdb 5 | LIB_NAME_EXT = $(LIB_NAME)-ext 6 | LIBRDB_SONAME_EXT = lib$(LIB_NAME_EXT).so.${LIBRDB_VERSION} 7 | 8 | # Artifacts: 9 | TARGET_LIB_EXT = $(LIB_DIR)/$(LIBRDB_SONAME_EXT) 10 | TARGET_LIB_STATIC_EXT = $(LIB_DIR)/lib$(LIB_NAME_EXT).a 11 | 12 | ######################################################################################### 13 | SOURCES = $(notdir $(basename $(wildcard *.c))) 14 | OBJECTS = $(patsubst %,%.o,$(SOURCES)) 15 | 16 | # Source files in deps/redis directory. For now, librdb.so and librdb-ext.so, 17 | # each will have its own copy. Take care not to pass Redis structs from one lib 18 | # to another! 19 | REDIS_SOURCES = $(notdir $(basename $(wildcard ../../deps/redis/*.c))) 20 | REDIS_OBJECTS = $(patsubst %,../../deps/redis/%.o,$(REDIS_SOURCES)) 21 | 22 | OPTIMIZATION? = -O3 23 | LIBRDB_DEBUG? = 0 24 | 25 | STD = -std=c99 26 | STACK = -fstack-protector-all -Wstack-protector 27 | WARNS = -Wall -Wextra -pedantic -Werror 28 | CFLAGS = -fPIC $(OPTIMIZATION) $(STD) $(STACK) $(WARNS) -fvisibility=hidden 29 | DEBUG = -g3 -DLIBRDB_DEBUG=$(LIBRDB_DEBUG) 30 | LDFLAGS = 31 | LIBS = -L $(LIB_DIR) -l $(LIB_NAME) 32 | 33 | ifeq ($(BUILD_TLS),yes) 34 | CFLAGS += -DUSE_OPENSSL=1 35 | endif 36 | 37 | # Platform-specific overrides 38 | uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') 39 | 40 | ifeq ($(uname_S),Darwin) 41 | SONAME_FLAG = -install_name 42 | SHARED_FLAG = -dynamiclib 43 | else 44 | SONAME_FLAG = -soname 45 | SHARED_FLAG = -shared 46 | endif 47 | 48 | ######################################### RULES ####################################### 49 | all: $(TARGET_LIB_EXT) $(TARGET_LIB_STATIC_EXT) 50 | @echo "Done."; 51 | 52 | $(TARGET_LIB_EXT): $(OBJECTS) $(REDIS_OBJECTS) 53 | $(CC) -o $@ $(SHARED_FLAG) -Wl,$(SONAME_FLAG),${LIBRDB_SONAME_EXT} ${LDFLAGS} $^ $(LIBS) 54 | 55 | $(TARGET_LIB_STATIC_EXT): $(OBJECTS) $(REDIS_OBJECTS) 56 | ar rcs $@ $^ 57 | 58 | # Include object file dependencies 59 | -include $(OBJECTS:.o=.d) $(REDIS_OBJECTS:.o=.d) 60 | 61 | %.o: %.c 62 | $(CC) $(CFLAGS) -c $*.c -o $*.o $(DEBUG) 63 | $(CC) -MM $(CFLAGS) $*.c > $*.d 64 | 65 | clean: 66 | @rm -rvf $(TARGET_LIB_EXT) $(TARGET_LIB_STATIC_EXT) ./*.o ./*.d; 67 | -------------------------------------------------------------------------------- /src/ext/extCommon.c: -------------------------------------------------------------------------------- 1 | #include "extCommon.h" 2 | #include "../../deps/redis/util.h" 3 | 4 | /* Example:: Input: length=123 return: buf="\r\n$123\r\n" */ 5 | void iov_length(struct iovec *iov, long long length, char *buf, int bufsize) { 6 | int len = 0; 7 | buf[0] = '\r'; 8 | buf[1] = '\n'; 9 | buf[2] = '$'; 10 | len = ll2string(buf+3, bufsize-5, length); 11 | buf[len + 3] = '\r'; 12 | buf[len + 4] = '\n'; 13 | iov_plain(iov, buf, len+5); 14 | } 15 | 16 | /* For value 123 the function will return in buf: "123\r\n" */ 17 | int iov_value(struct iovec *iov, long long value, char *buf, int bufsize) { 18 | int len = 0; 19 | len = ll2string(buf, bufsize-2, value); /* -2 for: 'r' and '\n' */ 20 | buf[len] = '\r'; 21 | buf[len+1] = '\n'; 22 | iov_plain(iov, buf, len+2); 23 | return len; 24 | } 25 | -------------------------------------------------------------------------------- /src/ext/extCommon.h: -------------------------------------------------------------------------------- 1 | #ifndef RDBX_COMMON_H 2 | #define RDBX_COMMON_H 3 | 4 | #include 5 | #include 6 | 7 | /* Extension lib must rely only on API (and not core parser headers) */ 8 | #include "../../api/librdb-api.h" 9 | #include "../../api/librdb-ext-api.h" 10 | 11 | #define UNUSED(...) unused( (void *) NULL, __VA_ARGS__); 12 | static inline void unused(void *dummy, ...) { (void)(dummy);} 13 | 14 | #ifdef __GNUC__ 15 | #define likely(x) __builtin_expect(!!(x), 1) 16 | #define unlikely(x) __builtin_expect(!!(x), 0) 17 | #else 18 | #define likely(x) (x) 19 | #define unlikely(x) (x) 20 | #endif 21 | 22 | #define IF_NOT_OK_RETURN(cmd) do {RdbRes s; s = cmd; if (unlikely(s!=RDB_OK)) return s;} while (0) 23 | 24 | /*** IOVEC manipulation ***/ 25 | // INPUT: str="ABC" OUTPUT: iov={ "ABC" , 3 } 26 | #define IOV_CONST(iov, str) iov_plain(iov, str, sizeof(str)-1) 27 | 28 | // INPUT: str="ABC", len=3 OUTPUT: iov={ "ABC" , 3 } 29 | #define IOV_STRING(iov, str, len) iov_plain(iov, str, len) 30 | 31 | // INPUT: len=45678 OUTPUT: iov={ "\r\n$45678\r\n" , 10 } 32 | #define IOV_LENGTH(iov, len, ar) iov_length(iov, len, ar, sizeof(ar)) 33 | 34 | // INPUT: val=45678 OUTPUT: iov={ "45678\r\n" , 7 } 35 | #define IOV_VALUE(iov, val, ar) iov_value(iov, val, ar, sizeof(ar)) 36 | 37 | // INPUT: val=45678 OUTPUT: iov={{ "$5\r\n" , 4 } , { "45678\r\n" , 7 }} 38 | #define IOV_LEN_AND_VAL(iov, val, ar1, ar2) \ 39 | do {\ 40 | int l = IOV_VALUE((iov)+1, val, ar2); \ 41 | IOV_LENGTH( (iov), l, ar1); \ 42 | } while (0); 43 | 44 | int iov_value(struct iovec *iov, long long count, char *buf, int bufsize); 45 | 46 | void iov_length(struct iovec *iov, long long length, char *buf, int bufsize); 47 | 48 | static inline void iov_plain(struct iovec *iov, const char *s, size_t l) { 49 | iov->iov_base = (void *) s; 50 | iov->iov_len = l; 51 | } 52 | 53 | /*** hidden LIB API function (not declared in librdb-api.h) ***/ 54 | _LIBRDB_API char *__RDB_key(RdbParser *p, char *key, char buf[9]); 55 | 56 | #endif /*define RDBX_COMMON_H*/ 57 | -------------------------------------------------------------------------------- /src/ext/readerFile.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "extCommon.h" 5 | 6 | struct RdbxReaderFile { 7 | RdbParser *parser; 8 | char *filename; 9 | FILE *file; 10 | }; 11 | 12 | static void deleteReaderFile(RdbParser *p, void *rdata) { 13 | if (!rdata) return; 14 | RdbxReaderFile *readerData = (RdbxReaderFile *) rdata; 15 | 16 | RDB_log(p, RDB_LOG_DBG, "RDB Reader: Closing file %s", readerData->filename); 17 | 18 | if (readerData->filename) 19 | RDB_free(p, readerData->filename); 20 | 21 | if(readerData->file) 22 | fclose(readerData->file); 23 | 24 | RDB_free(p, readerData); 25 | } 26 | 27 | /* Attempts to read entire len, otherwise returns error */ 28 | static RdbStatus readFile(void *data, void *buf, size_t len) { 29 | RdbxReaderFile *readerFile = data; 30 | size_t readLen = fread(buf, sizeof(char), len, readerFile->file); 31 | 32 | if (likely(readLen == len)) 33 | return RDB_STATUS_OK; 34 | 35 | if (feof(readerFile->file)) { 36 | RDB_reportError(readerFile->parser, RDB_ERR_FAILED_PARTIAL_READ_RDB_FILE, 37 | "Encountered an unexpected RDB end-of-file. Parsing halted."); 38 | } else if (ferror(readerFile->file)) { 39 | RDB_reportError(readerFile->parser, RDB_ERR_FAILED_READ_RDB_FILE, 40 | "An error occurred while attempting to read the RDB file (errno=%d).", errno); 41 | } else { /* readLen < len */ 42 | RDB_reportError(readerFile->parser, RDB_ERR_FAILED_READ_RDB_FILE, 43 | "The amount of data read from the RDB file was less than expected. Reached EOF."); 44 | } 45 | return RDB_STATUS_ERROR; 46 | } 47 | 48 | RdbxReaderFile *RDBX_createReaderFile(RdbParser *p, const char *filename) { 49 | FILE *f; 50 | 51 | if (filename == NULL) { 52 | RDB_reportError(p, RDB_ERR_FAILED_OPEN_RDB_FILE, "Filename is not provided"); 53 | return NULL; 54 | } 55 | 56 | if (!(f = fopen(filename, "rb"))) { 57 | RDB_reportError(p, RDB_ERR_FAILED_OPEN_RDB_FILE, 58 | "Failed to open RDB file `%s`: %s\n", filename, strerror(errno)); 59 | return NULL; 60 | } 61 | 62 | RDB_log(p, RDB_LOG_INF, "RDBX_createReaderFile: Initialized with file %s", filename); 63 | 64 | RdbxReaderFile *ctx = RDB_alloc(p, sizeof(RdbxReaderFile)); 65 | ctx->parser = p; 66 | ctx->file = f; 67 | ctx->filename = RDB_alloc(p, strlen(filename) + 1); 68 | strcpy(ctx->filename, filename); 69 | RDB_createReaderRdb(p, readFile, ctx, deleteReaderFile); 70 | return ctx; 71 | } 72 | -------------------------------------------------------------------------------- /src/ext/readerFileDesc.c: -------------------------------------------------------------------------------- 1 | #define _POSIX_C_SOURCE 1 /* Required in order to use file-descriptors */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "extCommon.h" 9 | 10 | 11 | struct RdbxReaderFileDesc { 12 | RdbParser *parser; 13 | int fdCloseWhenDone; 14 | int fd; 15 | FILE *file; 16 | }; 17 | 18 | static void deleteReaderFileDesc(RdbParser *p, void *rdata) { 19 | if (!rdata) return; 20 | 21 | RdbxReaderFileDesc *ctx = (RdbxReaderFileDesc *) rdata; 22 | if (ctx->file) 23 | fclose(ctx->file); 24 | 25 | if (ctx->fdCloseWhenDone) 26 | close(ctx->fd); 27 | RDB_free(p, ctx); 28 | } 29 | 30 | /* Attempts to read entire len, otherwise returns error */ 31 | static RdbStatus readFileDesc(void *data, void *buf, size_t len) { 32 | RdbxReaderFileDesc *ctx = (RdbxReaderFileDesc *)data; 33 | size_t totalBytesRead = 0; 34 | 35 | while (1) { 36 | 37 | totalBytesRead += fread((char *)buf + totalBytesRead, 1, len - totalBytesRead, ctx->file); 38 | 39 | if (totalBytesRead == len) { 40 | return RDB_STATUS_OK; 41 | } else { 42 | if (feof(ctx->file)) { 43 | RDB_reportError(ctx->parser, RDB_ERR_FAILED_READ_RDB_FILE, 44 | "readFileDesc(fd=%d): Reached EOF. Not all requested bytes were read", ctx->fd); 45 | return RDB_STATUS_ERROR; 46 | } else if (ferror(ctx->file)) { 47 | /* Wrongly configured to nonblocking mode (Not supported at the moment) */ 48 | if (errno == EAGAIN || errno == EWOULDBLOCK) { 49 | RDB_reportError(ctx->parser, RDB_ERR_NONBLOCKING_READ_FD, 50 | "readFileDesc(fd=%d): Unexpected EAGAIN|EWOULDBLOCK. The fd must be set to blocking mode", ctx->fd); 51 | return RDB_STATUS_ERROR; 52 | } 53 | 54 | RDB_reportError(ctx->parser, RDB_ERR_FAILED_READ_RDB_FILE, 55 | "readFileDesc(fd=%d): System errno %d : %s", ctx->fd, errno, strerror(errno)); 56 | return RDB_STATUS_ERROR; 57 | } 58 | } 59 | } 60 | } 61 | 62 | RdbxReaderFileDesc *RDBX_createReaderFileDesc(RdbParser *p, int fd, int fdCloseWhenDone) { 63 | 64 | int flags = fcntl(fd, F_GETFL); 65 | 66 | if (flags==-1) { 67 | 68 | RDB_reportError(p, RDB_ERR_FAILED_GET_FD_FLAGS, 69 | "RDBX_createReaderFileDesc(fd=%d): Failed to get fcntl(). Error:%s", fd, strerror(errno)); 70 | return NULL; 71 | } 72 | 73 | if (flags & O_NONBLOCK) { 74 | RDB_reportError(p, RDB_ERR_NONBLOCKING_FD, 75 | "RDBX_createReaderFileDesc(fd=%d): fd must be set to blocking mode", fd); 76 | return NULL; 77 | } 78 | 79 | /* Use fdopen and fread instead of read in order to enjoy read-ahead buffering and less syscalls. */ 80 | FILE *file = fdopen(fd, "r"); 81 | 82 | if (file == NULL) { 83 | RDB_reportError(p, RDB_ERR_FAILED_OPEN_FILE, 84 | "RDBX_createReaderFileDesc(fd=%d): failed on fdopen() with errno %d: %s\"", 85 | fd, errno, strerror(errno)); 86 | return NULL; 87 | } 88 | 89 | RdbxReaderFileDesc *ctx = (RdbxReaderFileDesc *) RDB_alloc(p, sizeof(RdbxReaderFileDesc)); 90 | ctx->parser = p; 91 | ctx->fd = fd; 92 | ctx->file = file; 93 | ctx->fdCloseWhenDone = fdCloseWhenDone; 94 | RDB_createReaderRdb(p, readFileDesc, ctx, deleteReaderFileDesc); 95 | return ctx; 96 | } 97 | -------------------------------------------------------------------------------- /src/ext/readerResp.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define MAX_RESP_REPLY_ERR_MSG 256 4 | 5 | typedef enum RespReplyRes { 6 | RESP_REPLY_OK=0, 7 | RESP_REPLY_PARTIAL, 8 | RESP_REPLY_ERR, 9 | } RespRes; 10 | 11 | typedef struct RespReplyBuff { 12 | const char *buff; 13 | int len; 14 | int at; 15 | } RespReplyBuff; 16 | 17 | /* cb to report on RESP error. Returns 1 to propagate. 0 to mask. */ 18 | typedef int (*OnRespErrorCb) (void *callerCtx, char *msg); 19 | 20 | typedef struct { 21 | 22 | /* PUBLIC: read-only */ 23 | size_t countReplies; 24 | char errorMsg[MAX_RESP_REPLY_ERR_MSG+1]; 25 | int errorMsgLen; 26 | 27 | /* PRIVATE: */ 28 | int type; 29 | int typeState; 30 | int typeArrayState; 31 | 32 | /* private bulk response state */ 33 | unsigned int bulkLen; 34 | unsigned int bulkAt; 35 | 36 | /* private bulk-array response state */ 37 | long long numBulksArray; 38 | 39 | /* On RESP error callback */ 40 | void *errCbCtx; 41 | OnRespErrorCb errCb; 42 | 43 | } RespReaderCtx; 44 | 45 | void readRespInit(RespReaderCtx *ctx); 46 | 47 | /* Can register cb to decide whether to ignore given error or propagate it */ 48 | void setErrorCb(RespReaderCtx *respReaderCtx, void *errorCbCtx, OnRespErrorCb cb); 49 | 50 | RespRes readRespReplies(RespReaderCtx *ctx, const char *buff, int buffLen); 51 | -------------------------------------------------------------------------------- /src/ext/respToFileWriter.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "extCommon.h" 3 | #include 4 | #include 5 | 6 | struct RdbxRespToFileWriter { 7 | long cmdCount; 8 | RdbParser *p; 9 | FILE *filePtr; /* either stdout or pointer to open file */ 10 | }; 11 | 12 | /* return 0 for success. 1 Otherwise. */ 13 | static int respFileWritev(void *context, struct iovec *iov, int count, 14 | RdbxRespWriterStartCmd *startCmd, int endCmd) 15 | { 16 | UNUSED(startCmd); 17 | struct RdbxRespToFileWriter *ctx = context; 18 | ctx->cmdCount += endCmd; 19 | 20 | /* not optimized code */ 21 | for (int i = 0 ; i < count ; ++i) { 22 | if (unlikely(fwrite(iov[i].iov_base, sizeof(char), iov[i].iov_len, ctx->filePtr) != iov[i].iov_len)) { 23 | RDB_reportError(ctx->p, (RdbRes) RDBX_ERR_RESP_WRITE, "Failed to write RESP to file: (errno=%d)", errno); 24 | return 1; 25 | } 26 | } 27 | 28 | return 0; 29 | } 30 | 31 | /* return 0 for success. 1 Otherwise. */ 32 | static int respFileFlush(void *context) { 33 | struct RdbxRespToFileWriter *ctx = context; 34 | return (EOF == fflush(ctx->filePtr)) ? 1 : 0; 35 | } 36 | 37 | static void respFileWriteDelete(void *context) { 38 | struct RdbxRespToFileWriter *ctx = context; 39 | if (ctx != NULL) { 40 | fflush(ctx->filePtr); 41 | if (ctx->filePtr != stdout) { 42 | fclose(ctx->filePtr); 43 | } 44 | RDB_free(ctx->p, ctx); 45 | } 46 | } 47 | 48 | RdbxRespToFileWriter *RDBX_createRespToFileWriter(RdbParser *p, RdbxToResp *rdbToResp, const char *filePath) { 49 | RdbxRespToFileWriter *ctx; 50 | FILE *filePtr; 51 | 52 | if (filePath == NULL) { 53 | filePtr = stdout; 54 | } else { 55 | filePtr = fopen(filePath, "wb"); 56 | if (filePtr == NULL) { 57 | RDB_reportError(p, RDB_ERR_FAILED_OPEN_FILE, "createRespWriter: Failed to open file: `%s`. errno:%d", 58 | filePath, errno); 59 | return NULL; 60 | } 61 | } 62 | 63 | if ((ctx = RDB_alloc(p, sizeof(RdbxRespToFileWriter))) == NULL) { 64 | fclose(filePtr); 65 | RDB_reportError(p, (RdbRes) RDBX_ERR_RESP_FAILED_ALLOC, "Failed to allocate struct RdbxRespToFileWriter"); 66 | return NULL; 67 | } 68 | 69 | ctx->cmdCount = 0; 70 | ctx->filePtr = filePtr; 71 | ctx->p = p; 72 | 73 | /* Attach this writer to rdbToResp */ 74 | RdbxRespWriter writer = {ctx, respFileWriteDelete, respFileWritev, respFileFlush}; 75 | RDBX_attachRespWriter(rdbToResp, &writer); 76 | return ctx; 77 | } 78 | -------------------------------------------------------------------------------- /src/lib/Makefile: -------------------------------------------------------------------------------- 1 | default: all 2 | 3 | LIB_DIR = ../../lib 4 | LIB_NAME = rdb 5 | LIBRDB_SONAME = lib$(LIB_NAME).so.${LIBRDB_VERSION} 6 | 7 | # Artifacts: 8 | TARGET_LIB = $(LIB_DIR)/${LIBRDB_SONAME} 9 | TARGET_LIB_STATIC = $(LIB_DIR)/lib$(LIB_NAME).a 10 | 11 | # Source files in the working directory 12 | SOURCES = $(notdir $(basename $(wildcard *.c))) 13 | OBJECTS = $(patsubst %,%.o,$(SOURCES)) 14 | 15 | # Source files in deps/redis directory. For now, librdb.so and librdb-ext.so, 16 | # each will have its own copy. Take care not to pass Redis structs from one lib 17 | # to another! 18 | REDIS_SOURCES = $(notdir $(basename $(wildcard ../../deps/redis/*.c))) 19 | REDIS_OBJECTS = $(patsubst %,../../deps/redis/%.o,$(REDIS_SOURCES)) 20 | 21 | OPTIMIZATION ?= -O3 22 | LIBRDB_DEBUG ?= 0 23 | 24 | STD = -std=c99 25 | STACK = -fstack-protector-all -Wstack-protector 26 | WARNS = -Wall -Wextra -pedantic -Werror 27 | CFLAGS = -fPIC $(OPTIMIZATION) $(STD) $(STACK) $(WARNS) -fvisibility=hidden 28 | DEBUG = -g3 29 | LIBS = 30 | 31 | ifeq ($(LIBRDB_DEBUG), 1) 32 | CFLAGS += -DLIBRDB_DEBUG=1 33 | else 34 | CFLAGS += -DNDEBUG=1 35 | endif 36 | 37 | # Platform-specific overrides 38 | uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') 39 | 40 | ifeq ($(uname_S),Darwin) 41 | SONAME_FLAG = -install_name 42 | SHARED_FLAG = -dynamiclib 43 | else 44 | SONAME_FLAG = -soname 45 | SHARED_FLAG = -shared 46 | endif 47 | 48 | ######################################### RULES ####################################### 49 | all: $(TARGET_LIB) $(TARGET_LIB_STATIC) 50 | @echo "Done."; 51 | 52 | $(TARGET_LIB): $(OBJECTS) $(REDIS_OBJECTS) 53 | $(CC) -o $@ $(SHARED_FLAG) -Wl,$(SONAME_FLAG),${LIBRDB_SONAME} ${LDFLAGS} $^ 54 | 55 | $(TARGET_LIB_STATIC): $(OBJECTS) $(REDIS_OBJECTS) 56 | ar rcs $@ $^ 57 | 58 | # Include object file dependencies 59 | -include $(OBJECTS:.o=.d) $(REDIS_OBJECTS:.o=.d) 60 | 61 | # Compile source files in the working directory to object files 62 | %.o: %.c 63 | $(CC) -fPIC $(CFLAGS) -c $*.c -o $*.o $(DEBUG) $(LIBS) 64 | $(CC) -MM $(CFLAGS) $*.c > $*.d 65 | 66 | clean: 67 | @rm -rvf $(TARGET_LIB) $(TARGET_LIB_STATIC) ./*.o ./*.d; 68 | 69 | .PHONY: all clean 70 | -------------------------------------------------------------------------------- /src/lib/bulkAlloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This API propose two ways to allocate and release bulks of memory: 3 | * 4 | * 1) Unmanaged RdbBulk allocation (aka. BulkUnmanaged) 5 | * 6 | * Unmanaged bulk allocation is a method of allocating memory where the parser 7 | * manages the allocation and deallocation of memory rather than relying on a data 8 | * structure like the bulk-pool (Gets flushed on each state transition. more below). 9 | * This method is useful when the application has RdbBulk allocations that needs 10 | * to live behind current state of the parser. 11 | * 12 | * 13 | * 2) Bulk-pool (aka. BulkPool) 14 | * 15 | * This customized data structure is useful in the context of RDBParser that support 16 | * asynchronous execution (but not only). In such cases, the parser might receive 17 | * only partial data and needs to preserve its last valid state and return. BulkPool 18 | * helps preserve the partial data already read from the RDB source, which cannot 19 | * be re-read such as in the case of streaming. The data can then be "replayed" 20 | * later once more data becomes available to complete the parsing-element state. 21 | * 22 | * The Bulk-Pool support 3 commands: 23 | * 24 | * a) Allocate - Allocates memory per caller request and store a reference 25 | * to the allocation in a sequential queue. 26 | * b) Rollback - The "Rollback" command rewinds the queue and allows the exact same 27 | * sequence of allocation requests to be "replayed" to the caller. 28 | * However, instead of creating new allocations, the allocator returns 29 | * the next item in the queue. 30 | * c) Flush - Clean the entire queue and deletes corresponding referenced buffers. 31 | * 32 | * The bulk-pool utilizes 3 distinct types of allocators: 33 | * 34 | * 1) STACK ALLOCATOR 35 | * The Stack Allocator is specifically designed to work in tandem with the BulkPool 36 | * and supports the Allocate, Rollback, and Flush commands. When the pool 37 | * receives small allocation requests and the application has not restricted 38 | * allocation to a specific type, it prefers to allocate from the stack. If 39 | * the parser fails to reach a new state, the stack will be rolled back in order 40 | * to replay. If the parser reaches a new state, then the stack will be flushed 41 | * along with the pool. 42 | * 43 | * 2) HEAP ALLOCATOR 44 | * The Heap Allocator allocates memory from the heap with refcount support. 45 | * 46 | * 3) EXTERNAL ALLOCATOR 47 | * The External Allocator is not mandatory and can be provided by the application 48 | * client to allocate only the buffers that will be passed to the application's 49 | * callbacks. These buffers are referred to as RQ_ALLOC_APP_BULK within this API. 50 | * 51 | * In addition, the pool supports Reference allocator of a Bulk. It expects to 52 | * receive pre-allocated memory and record it as a referenced bulk. The first use 53 | * case for it is when there is allocated memory that is already initialized with 54 | * data and the parser just want to optimize and pass it as RdbBulk to callbacks. 55 | * Another use case is when memory was allocated, but it is not loaded with data 56 | * yet by rdbLoad functions, then by registration to the pool it will be able to 57 | * load it safely with rdbLoad functions without worry from rollback flows. 58 | * 59 | */ 60 | 61 | #ifndef BULK_ALLOC_H 62 | #define BULK_ALLOC_H 63 | 64 | #include "parser.h" 65 | 66 | /*** BulkPool ***/ 67 | BulkPool *bulkPoolInit(RdbMemAlloc *mem); 68 | void bulkPoolRelease(RdbParser *p); 69 | BulkInfo *bulkPoolAlloc(RdbParser *p, size_t len, AllocTypeRq typeRq, char *refBuf); 70 | void bulkPoolFlush(RdbParser *p); 71 | void bulkPoolRollback(RdbParser *p); 72 | 73 | /*** BulkUnmanaged ***/ 74 | void bulkUnmanagedAlloc(RdbParser *p, size_t len, AllocUnmngTypeRq rq, char *refBuf, BulkInfo *bi); 75 | void bulkUnmanagedFree(RdbParser *p, BulkInfo *binfo); 76 | 77 | /* cloning RdbBulk */ 78 | RdbBulkCopy bulkClone(RdbParser *p, BulkInfo *binfo); 79 | 80 | /* debug */ 81 | void bulkPoolPrintDbg(RdbParser *p); 82 | int bulkPoolIsNewNextAllocDbg(RdbParser *p); 83 | void bulkPoolAssertFlushedDbg(RdbParser *p); 84 | 85 | #endif /*BULK_ALLOC_H*/ 86 | -------------------------------------------------------------------------------- /src/lib/defines.h: -------------------------------------------------------------------------------- 1 | #ifndef DEFINES_H 2 | #define DEFINES_H 3 | 4 | /* This file should include only RDB related defines. Might be read in the 5 | * future from Redis repo */ 6 | 7 | /* Map object types to RDB object types. Macros starting with OBJ_ are for 8 | * memory storage and may change. Instead RDB types must be fixed because 9 | * we store them on disk. */ 10 | #define RDB_TYPE_STRING 0 11 | #define RDB_TYPE_LIST 1 12 | #define RDB_TYPE_SET 2 13 | #define RDB_TYPE_ZSET 3 14 | #define RDB_TYPE_HASH 4 15 | #define RDB_TYPE_ZSET_2 5 /* ZSET version 2 with doubles stored in binary. */ 16 | #define RDB_TYPE_MODULE_PRE_GA 6 /* Used in 4.0 release candidates */ 17 | #define RDB_TYPE_MODULE_2 7 /* Module value with annotations for parsing without 18 | the generating module being loaded. */ 19 | 20 | /* Object types for encoded objects. */ 21 | #define RDB_TYPE_HASH_ZIPMAP 9 22 | #define RDB_TYPE_LIST_ZIPLIST 10 23 | #define RDB_TYPE_SET_INTSET 11 24 | #define RDB_TYPE_ZSET_ZIPLIST 12 25 | #define RDB_TYPE_HASH_ZIPLIST 13 26 | #define RDB_TYPE_LIST_QUICKLIST 14 27 | #define RDB_TYPE_STREAM_LISTPACKS 15 28 | #define RDB_TYPE_HASH_LISTPACK 16 29 | #define RDB_TYPE_ZSET_LISTPACK 17 30 | #define RDB_TYPE_LIST_QUICKLIST_2 18 31 | #define RDB_TYPE_STREAM_LISTPACKS_2 19 32 | #define RDB_TYPE_SET_LISTPACK 20 33 | #define RDB_TYPE_STREAM_LISTPACKS_3 21 34 | #define RDB_TYPE_HASH_METADATA_PRE_GA 22 /* Hash with HFEs. Doesn't attach min TTL at start (7.4 RC) */ 35 | #define RDB_TYPE_HASH_LISTPACK_EX_PRE_GA 23 /* Hash LP with HFEs. Doesn't attach min TTL at start (7.4 RC) */ 36 | #define RDB_TYPE_HASH_METADATA 24 /* Hash with HFEs. Attach min TTL at start */ 37 | #define RDB_TYPE_HASH_LISTPACK_EX 25 /* Hash LP with HFEs. Attach min TTL at start */ 38 | #define RDB_TYPE_MAX 26 39 | 40 | 41 | /* Special RDB opcodes (saved/loaded with rdbSaveType/rdbLoadType). */ 42 | #define RDB_OPCODE_SLOT_INFO 244 /* Individual slot info, such as slot id and size (cluster mode only). */ 43 | #define RDB_OPCODE_FUNCTION2 245 /* function library data */ 44 | #define RDB_OPCODE_FUNCTION 246 /* old function library data for 7.0 rc1 and rc2 */ 45 | #define RDB_OPCODE_MODULE_AUX 247 /* Module auxiliary data. */ 46 | #define RDB_OPCODE_IDLE 248 /* LRU idle time. */ 47 | #define RDB_OPCODE_FREQ 249 /* LFU frequency. */ 48 | #define RDB_OPCODE_AUX 250 /* RDB aux field. */ 49 | #define RDB_OPCODE_RESIZEDB 251 /* Hash table resize hint. */ 50 | #define RDB_OPCODE_EXPIRETIME_MS 252 /* Expire time in milliseconds. */ 51 | #define RDB_OPCODE_EXPIRETIME 253 /* Old expire time in seconds. */ 52 | #define RDB_OPCODE_SELECTDB 254 /* DB number of the following keys. */ 53 | #define RDB_OPCODE_EOF 255 /* End of the RDB file. */ 54 | 55 | /* Garantia V1002 RDB opcodes -- used to read older version RDB files. */ 56 | /*#define REDIS_RDB_2_OPCODE_GD_DICT 249*/ 57 | #define REDIS_RDB_2_OPCODE_GOPTIONS 250 58 | #define REDIS_RDB_2_OPCODE_GCAS 251 59 | #define REDIS_RDB_2_OPCODE_GFLAGS 252 60 | 61 | /* Garantia V1006 (current) opcodes */ 62 | /*#define RDB_OPCODE_GD_DICT 100*/ 63 | #define RDB_OPCODE_GCAS 101 64 | #define RDB_OPCODE_GFLAGS 102 65 | #define __RDB_OPCODE_RAM_LRU 107 /* Available only in Redis Enterprise */ 66 | 67 | /* Defines related to the dump file format. To store 32 bits lengths for short 68 | * keys requires a lot of space, so we check the most significant 2 bits of 69 | * the first byte to interpreter the length: 70 | * 71 | * 00|XXXXXX => if the two MSB are 00 the len is the 6 bits of this byte 72 | * 01|XXXXXX XXXXXXXX => 01, the len is 14 bits, 6 bits + 8 bits of next byte 73 | * 10|000000 [32 bit integer] => A full 32 bit len in net byte order will follow 74 | * 10|000001 [64 bit integer] => A full 64 bit len in net byte order will follow 75 | * 11|OBKIND this means: specially encoded object will follow. The six bits 76 | * number specify the kind of object that follows. 77 | * See the RDB_ENC_* defines. 78 | * 79 | * Lengths up to 63 are stored using a single byte, most DB keys, and may 80 | * values, will fit inside. */ 81 | #define RDB_6BITLEN 0 82 | #define RDB_14BITLEN 1 83 | #define RDB_32BITLEN 0x80 84 | #define RDB_64BITLEN 0x81 85 | #define RDB_ENCVAL 3 86 | #define RDB_LENERR UINT64_MAX 87 | 88 | /* When a length of a string object stored on disk has the first two bits 89 | * set, the remaining six bits specify a special encoding for the object 90 | * accordingly to the following defines: */ 91 | #define RDB_ENC_INT8 0 /* 8 bit signed integer */ 92 | #define RDB_ENC_INT16 1 /* 16 bit signed integer */ 93 | #define RDB_ENC_INT32 2 /* 32 bit signed integer */ 94 | #define RDB_ENC_LZF 3 /* string compressed with FASTLZ */ 95 | /*#define RDB_ENC_GD 4 string is a gdcompressed entry */ 96 | 97 | /* quicklist node container formats */ 98 | #define QUICKLIST_NODE_CONTAINER_PLAIN 1 99 | #define QUICKLIST_NODE_CONTAINER_PACKED 2 100 | 101 | /* Module serialized values sub opcodes */ 102 | #define RDB_MODULE_OPCODE_EOF 0 /* End of module value. */ 103 | #define RDB_MODULE_OPCODE_SINT 1 /* Signed integer. */ 104 | #define RDB_MODULE_OPCODE_UINT 2 /* Unsigned integer. */ 105 | #define RDB_MODULE_OPCODE_FLOAT 3 /* Float. */ 106 | #define RDB_MODULE_OPCODE_DOUBLE 4 /* Double. */ 107 | #define RDB_MODULE_OPCODE_STRING 5 /* String. */ 108 | 109 | #define UNINIT_STREAM_ENTRIES_READ (-2) 110 | #endif /*DEFINES_H*/ 111 | -------------------------------------------------------------------------------- /src/lib/version.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "version.h" 5 | 6 | #define STATIC_ASSERT(COND,MSG) typedef char static_assertion[(COND)?1:-1] 7 | 8 | #define STRINGIFY(x) #x 9 | #define TOSTRING(x) STRINGIFY(x) 10 | #define LIBRDB_COMPOSED_VERSION_STRING TOSTRING(LIBRDB_MAJOR_VERSION) "." \ 11 | TOSTRING(LIBRDB_MINOR_VERSION) "." \ 12 | TOSTRING(LIBRDB_PATCH_VERSION) 13 | 14 | /* Verify that the composed version string matches the individual version components */ 15 | STATIC_ASSERT( 16 | (sizeof(LIBRDB_VERSION_STRING) == sizeof(LIBRDB_COMPOSED_VERSION_STRING)) && 17 | (__builtin_strcmp(LIBRDB_VERSION_STRING, LIBRDB_COMPOSED_VERSION_STRING) == 0), 18 | "LIBRDB_VERSION_STRING does not match the individual version components" 19 | ); 20 | -------------------------------------------------------------------------------- /src/lib/version.h: -------------------------------------------------------------------------------- 1 | #define LIBRDB_MAJOR_VERSION 1 2 | #define LIBRDB_MINOR_VERSION 0 3 | #define LIBRDB_PATCH_VERSION 0 4 | 5 | /* Keep direct value for external readers */ 6 | #define LIBRDB_VERSION_STRING "1.0.0" 7 | 8 | /* Update Maximum supported RDB version */ 9 | #define LIBRDB_SUPPORT_MAX_RDB_VER 12 10 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | default: all 2 | 3 | LIB_DIR = ../lib 4 | LIB_NAME = rdb 5 | LIB_NAME_EXT = $(LIB_NAME)-ext 6 | LIBHIREDIS = ../deps/hiredis/libhiredis.a 7 | 8 | # Artifacts: 9 | TARGET_TEST = test_lib 10 | TARGET_TEST_STATIC = test_static_lib 11 | 12 | ######################################################################################### 13 | SOURCES = $(notdir $(basename $(wildcard *.c))) 14 | OBJECTS = $(patsubst %,%.o,$(SOURCES)) 15 | 16 | STD = -std=c99 17 | STACK = -fstack-protector-all -Wstack-protector 18 | WARNS = -Wall -Wextra -pedantic -Werror -Wno-unused-function 19 | 20 | OPTIMIZATION ?= -O0 21 | 22 | CFLAGS = -D_DEFAULT_SOURCE -fPIC $(OPTIMIZATION) $(STD) $(STACK) $(WARNS) 23 | DEBUG = -g3 -DDEBUG=1 24 | LIBS = -l cmocka -L $(LIB_DIR) -l $(LIB_NAME) -l $(LIB_NAME_EXT) $(LIBHIREDIS) 25 | LIBS_STATIC = -l cmocka -L $(LIB_DIR) $(LIB_DIR)/lib$(LIB_NAME).a $(LIB_DIR)/lib$(LIB_NAME_EXT).a $(LIBHIREDIS) 26 | 27 | ifeq ($(BUILD_TLS),yes) 28 | CFLAGS += -DUSE_OPENSSL=1 29 | LIBS += -lssl -lcrypto 30 | endif 31 | 32 | # Platform-specific overrides 33 | uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') 34 | 35 | ifeq ($(uname_S),Darwin) 36 | CFLAGS += -I$(shell brew --prefix)/include 37 | LIBS += -L$(shell brew --prefix)/lib 38 | LIBS_STATIC += -L$(shell brew --prefix)/lib 39 | endif 40 | 41 | ######################################### RULES ####################################### 42 | all: $(TARGET_TEST) $(TARGET_TEST_STATIC) 43 | @echo "Done."; 44 | 45 | $(TARGET_TEST): $(OBJECTS) 46 | $(CC) $(OBJECTS) -o $@ $(DEBUG) $(CFLAGS) $(LIBS) 47 | 48 | $(TARGET_TEST_STATIC): $(OBJECTS) 49 | $(CC) $(OBJECTS) -o $@ $(DEBUG) $(CFLAGS) $(LIBS_STATIC) 50 | 51 | -include $(OBJECTS:.o=.d) 52 | 53 | %.o: %.c 54 | $(CC) -c $*.c -o $*.o $(DEBUG) $(CFLAGS) 55 | $(CC) -MM $(CFLAGS) $*.c > $*.d 56 | 57 | clean: 58 | @rm -rvf $(TARGET_TEST) $(TARGET_TEST_STATIC) ./tmp/*.* ./*.o ./*.d ./log/*.log; 59 | 60 | .PHONY: all clean -------------------------------------------------------------------------------- /test/dumps/100_lists.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/100_lists.rdb -------------------------------------------------------------------------------- /test/dumps/cluster_slot_info.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1713005699", 5 | "used-mem":"2550192", 6 | "repl-stream-db":"0", 7 | "repl-id":"734638bff92ee423e11e46e417b47acbd2d9c896", 8 | "repl-offset":"390", 9 | "aof-base":"0" 10 | }, 11 | 12 | "__dbsize__": { 13 | "size": 1, 14 | "expires": 0 15 | }, 16 | 17 | "__slotinfo__": { 18 | "slotId": 7638, 19 | "slotSize": 1, 20 | "slotSExpiresSize": 0 21 | }, 22 | 23 | "abc":"abc" 24 | -------------------------------------------------------------------------------- /test/dumps/cluster_slot_info.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/cluster_slot_info.rdb -------------------------------------------------------------------------------- /test/dumps/empty.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/empty.rdb -------------------------------------------------------------------------------- /test/dumps/function.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/function.rdb -------------------------------------------------------------------------------- /test/dumps/function2.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1713086666", 5 | "used-mem":"966312", 6 | "aof-base":"0" 7 | }, 8 | 9 | "__func__": { 10 | "__Function_1":"#!lua name=mylib2\n\nlocal function my_hset2(keys, args)\n local hash = keys[1]\n local time = redis.call('TIME')[1]\n return redis.call('HSET', hash, '_last_modified_', time, unpack(args))\nend\n\nlocal function my_hgetall2(keys, args)\n redis.setresp(3)\n local hash = keys[1]\n local res = redis.call('HGETALL', hash)\n res['map']['_last_modified_'] = nil\n return res\nend\n\nlocal function my_hlastmodified2(keys, args)\n local hash = keys[1]\n return redis.call('HGET', hash, '_last_modified_')\nend\n\nredis.register_function('my_hset2', my_hset2)\nredis.register_function('my_hgetall2', my_hgetall2)\nredis.register_function('my_hlastmodified2', my_hlastmodified2)\n\n", 11 | "__Function_3":"#!lua name=mylib\n\nlocal function my_hset(keys, args)\n local hash = keys[1]\n local time = redis.call('TIME')[1]\n return redis.call('HSET', hash, '_last_modified_', time, unpack(args))\nend\n\nlocal function my_hgetall(keys, args)\n redis.setresp(3)\n local hash = keys[1]\n local res = redis.call('HGETALL', hash)\n res['map']['_last_modified_'] = nil\n return res\nend\n\nlocal function my_hlastmodified(keys, args)\n local hash = keys[1]\n return redis.call('HGET', hash, '_last_modified_')\nend\n\nredis.register_function('my_hset', my_hset)\nredis.register_function('my_hgetall', my_hgetall)\nredis.register_function('my_hlastmodified', my_hlastmodified)\n\n" 12 | }, 13 | 14 | "key_97":"value_97", 15 | "key_90":"value_90", 16 | "key_93":"value_93", 17 | "key_99":"value_99", 18 | "key_96":"value_96", 19 | "key_92":"value_92", 20 | "key_95":"value_95", 21 | "key_91":"value_91", 22 | "key_94":"value_94", 23 | "key_98":"value_98" -------------------------------------------------------------------------------- /test/dumps/function2.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/function2.rdb -------------------------------------------------------------------------------- /test/dumps/future_v19.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/future_v19.rdb -------------------------------------------------------------------------------- /test/dumps/hash_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"3.2.1", 3 | "redis-bits":"64", 4 | "ctime":"1689605183", 5 | "used-mem":"821904" 6 | }, 7 | 8 | "myhash1":{"5":"5","6":"6","10":"10","1":"1","2":"2","8":"8","4":"4","9":"9","3":"3","7":"7","11":"11"} 9 | -------------------------------------------------------------------------------- /test/dumps/hash_ex_v12_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1718101998", 5 | "used-mem":"1168904", 6 | "aof-base":"0" 7 | }, 8 | "myhash":{"field1":"value1","field3":"value3","field2":"value2"} 9 | -------------------------------------------------------------------------------- /test/dumps/hash_lp_ex_v12_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1718036120", 5 | "used-mem":"1191512", 6 | "aof-base":"0" 7 | }, 8 | 9 | "myhash":{"field2":"value2","field1":"value1","field3":"value3"} 10 | -------------------------------------------------------------------------------- /test/dumps/hash_lp_v11.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/hash_lp_v11.rdb -------------------------------------------------------------------------------- /test/dumps/hash_lp_v11_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1695280472", 5 | "used-mem":"1062024", 6 | "aof-base":"0" 7 | }, 8 | 9 | "hash2":{"field7":"value7","field8":"value8","9":"value9","field10":"value10","field11":"11","12":"12.0"}, 10 | "hash1":{"field2":"2","field3":"3","field4":"value4.0","field5":"5.0","6":"6"} 11 | -------------------------------------------------------------------------------- /test/dumps/hash_lp_v11_raw.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1695280472", 5 | "used-mem":"1062024", 6 | "aof-base":"0" 7 | }, 8 | 9 | "hash2":"\u0010\u00c3@C@V\u0013V\u0000\u0000\u0000\f\u0000\u0086field7\u0007\u0086value \u0007`\u000f\u00008\u00a0\u000f\u00038\u0007\t\u0001\u0080\u0019\u00029\u0007\u0087`\u0019\u000310\b\u0087`*@\b\u0080\u0011\f1\b\u000b\u0001\f\u0001\u008412.0\u0005\u00ff", 10 | "hash1":"\u0010\u00c35>\u000f>\u0000\u0000\u0000\n\u0000\u0086field2\u0007\u0002\u0001\u0080\t\u00023\u0007\u0003\u00a0\t\u000b4\u0007\u0088value4.0\t\u0080\u001b\u000b5\u0007\u00835.0\u0004\u0006\u0001\u0006\u0001\u00ff" 11 | -------------------------------------------------------------------------------- /test/dumps/hash_lp_v11_struct.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1695280472", 5 | "used-mem":"1062024", 6 | "aof-base":"0" 7 | }, 8 | 9 | "hash2":["V\u0000\u0000\u0000\f\u0000\u0086field7\u0007\u0086value7\u0007\u0086field8\u0007\u0086value8\u0007\t\u0001\u0086value9\u0007\u0087field10\b\u0087value10\b\u0087field11\b\u000b\u0001\f\u0001\u008412.0\u0005\u00ff"], 10 | "hash1":[">\u0000\u0000\u0000\n\u0000\u0086field2\u0007\u0002\u0001\u0086field3\u0007\u0003\u0001\u0086field4\u0007\u0088value4.0\t\u0086field5\u0007\u00835.0\u0004\u0006\u0001\u0006\u0001\u00ff"] 11 | -------------------------------------------------------------------------------- /test/dumps/hash_lp_with_hexpire_v12.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/hash_lp_with_hexpire_v12.rdb -------------------------------------------------------------------------------- /test/dumps/hash_raw.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver": "3.2.1", 3 | "redis-bits": "64", 4 | "ctime": "1689605183", 5 | "used-mem": "821904" 6 | }, 7 | 8 | "myhash1":"\u0004\u000b\u00c0\u0005\u00c0\u0005\u00c0\u0006\u00c0\u0006\u00c0\n\u00c0\n\u00c0\u0001\u00c0\u0001\u00c0\u0002\u00c0\u0002\u00c0\b\u00c0\b\u00c0\u0004\u00c0\u0004\u00c0\t\u00c0\t\u00c0\u0003\u00c0\u0003\u00c0\u0007\u00c0\u0007\u00c0\u000b\u00c0\u000b" -------------------------------------------------------------------------------- /test/dumps/hash_struct.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"3.2.1", 3 | "redis-bits":"64", 4 | "ctime":"1689605183", 5 | "used-mem":"821904" 6 | }, 7 | 8 | "myhash1":{"5":"5","6":"6","10":"10","1":"1","2":"2","8":"8","4":"4","9":"9","3":"3","7":"7","11":"11"} 9 | -------------------------------------------------------------------------------- /test/dumps/hash_v3.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/hash_v3.rdb -------------------------------------------------------------------------------- /test/dumps/hash_with_expire_v12.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/hash_with_expire_v12.rdb -------------------------------------------------------------------------------- /test/dumps/hash_zl_v6.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/hash_zl_v6.rdb -------------------------------------------------------------------------------- /test/dumps/hash_zl_v6_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"6.0.16", 3 | "redis-bits":"64", 4 | "ctime":"1690533464", 5 | "used-mem":"865216", 6 | "aof-preamble":"0" 7 | }, 8 | 9 | "myhash":{"1":"2","3":"4","5":"6","7.0":"8.0","str1":"str2","str3":"str4"} 10 | -------------------------------------------------------------------------------- /test/dumps/hash_zl_v6_raw.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"6.0.16", 3 | "redis-bits":"64", 4 | "ctime":"1690533464", 5 | "used-mem":"865216", 6 | "aof-preamble":"0" 7 | }, 8 | 9 | "myhash":"\r99\u0000\u0000\u00002\u0000\u0000\u0000\f\u0000\u0000\u00f2\u0002\u00f3\u0002\u00f4\u0002\u00f5\u0002\u00f6\u0002\u00f7\u0002\u00037.0\u0005\u00038.0\u0005\u0004str1\u0006\u0004str2\u0006\u0004str3\u0006\u0004str4\u00ff" -------------------------------------------------------------------------------- /test/dumps/hash_zl_v6_struct.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"6.0.16", 3 | "redis-bits":"64", 4 | "ctime":"1690533464", 5 | "used-mem":"865216", 6 | "aof-preamble":"0" 7 | }, 8 | 9 | "myhash":["9\u0000\u0000\u00002\u0000\u0000\u0000\f\u0000\u0000\u00f2\u0002\u00f3\u0002\u00f4\u0002\u00f5\u0002\u00f6\u0002\u00f7\u0002\u00037.0\u0005\u00038.0\u0005\u0004str1\u0006\u0004str2\u0006\u0004str3\u0006\u0004str4\u00ff"] 10 | -------------------------------------------------------------------------------- /test/dumps/hash_zm_v2.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/hash_zm_v2.rdb -------------------------------------------------------------------------------- /test/dumps/hash_zm_v2_data.json: -------------------------------------------------------------------------------- 1 | "myhash":{"1":"1","2":"2","3":"3","1.1":"1.1","1.2":"1.2","1.3":"1.3","aaa1":"aaa1","aaa2":"aaa2","aaa3":"aaa3"} 2 | -------------------------------------------------------------------------------- /test/dumps/hash_zm_v2_raw.json: -------------------------------------------------------------------------------- 1 | "myhash":"\t\u00c3@C@M\u0015\t\u00011\u0001\u00001\u00012\u0001\u00002\u00013\u0001\u00003\u00031.1\u0003\u0000@\u0004\u00021.2@\b\u00002 \b\u00003@\b\u00073\u0004aaa1\u0004\u0000`\u0005 \u0004\u00002`\n\u00002@\n\u00003`\n\u00013\u00ff" 2 | -------------------------------------------------------------------------------- /test/dumps/hash_zm_v2_struct.json: -------------------------------------------------------------------------------- 1 | "myhash":["\t\u00011\u0001\u00001\u00012\u0001\u00002\u00013\u0001\u00003\u00031.1\u0003\u00001.1\u00031.2\u0003\u00001.2\u00031.3\u0003\u00001.3\u0004aaa1\u0004\u0000aaa1\u0004aaa2\u0004\u0000aaa2\u0004aaa3\u0004\u0000aaa3\u00ff"] 2 | -------------------------------------------------------------------------------- /test/dumps/invalid_chksum_v8.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/invalid_chksum_v8.rdb -------------------------------------------------------------------------------- /test/dumps/mem_policy_lfu.json: -------------------------------------------------------------------------------- 1 | "abcdefghijk":"012345789abcdefghik" 2 | -------------------------------------------------------------------------------- /test/dumps/mem_policy_lfu.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/mem_policy_lfu.rdb -------------------------------------------------------------------------------- /test/dumps/mem_policy_lru.json: -------------------------------------------------------------------------------- 1 | "abcdefghijk":"012345789abcdefghik" 2 | -------------------------------------------------------------------------------- /test/dumps/mem_policy_lru.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/mem_policy_lru.rdb -------------------------------------------------------------------------------- /test/dumps/misc_with_stream.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/misc_with_stream.rdb -------------------------------------------------------------------------------- /test/dumps/module.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/module.rdb -------------------------------------------------------------------------------- /test/dumps/module_aux.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/module_aux.rdb -------------------------------------------------------------------------------- /test/dumps/module_aux_data.json: -------------------------------------------------------------------------------- 1 | "x":"1" 2 | -------------------------------------------------------------------------------- /test/dumps/module_aux_empty.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/module_aux_empty.rdb -------------------------------------------------------------------------------- /test/dumps/module_data.json: -------------------------------------------------------------------------------- 1 | "key1":"" -------------------------------------------------------------------------------- /test/dumps/module_raw.json: -------------------------------------------------------------------------------- 1 | "key1":"\u0007\u0081\u00b5\u00eb-\u00ff\u00fa\u00ddl\u0001\u0005\u0006value1\u0000" 2 | -------------------------------------------------------------------------------- /test/dumps/multiple_dbs.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/multiple_dbs.rdb -------------------------------------------------------------------------------- /test/dumps/multiple_dbs_data.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "x":"0" 3 | },{ 4 | "y":"1" 5 | },{ 6 | "z":"2" 7 | }] 8 | -------------------------------------------------------------------------------- /test/dumps/multiple_lists_strings.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/multiple_lists_strings.rdb -------------------------------------------------------------------------------- /test/dumps/multiple_lists_strings_2filters.json: -------------------------------------------------------------------------------- 1 | "mylist1":["v1"], 2 | "mylist3":["v3","v2","v1"], 3 | "mylist2":["v2","v1"] 4 | -------------------------------------------------------------------------------- /test/dumps/multiple_lists_strings_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1677580558", 5 | "used-mem":"937464", 6 | "aof-base":"0" 7 | }, 8 | 9 | "string2":"Hi there!", 10 | "mylist1":["v1"], 11 | "mylist3":["v3","v2","v1"], 12 | "lzf_compressed":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", 13 | "string1":"blaa", 14 | "mylist2":["v2","v1"] 15 | -------------------------------------------------------------------------------- /test/dumps/multiple_lists_strings_no_aux.json: -------------------------------------------------------------------------------- 1 | "string2":"Hi there!", 2 | "lzf_compressed":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", 3 | "mylist3":["v3","v2","v1"], 4 | "mylist2":["v2","v1"], 5 | "mylist1":["v1"], 6 | "string1":"blaa" 7 | -------------------------------------------------------------------------------- /test/dumps/multiple_lists_strings_raw.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1677580558", 5 | "used-mem":"937464", 6 | "aof-base":"0" 7 | }, 8 | 9 | "string2":"\u0000\tHi there!", 10 | "mylist1":"\u0012\u0001\u0002\u000b\u000b\u0000\u0000\u0000\u0001\u0000\u0082v1\u0003\u00ff", 11 | "mylist3":"\u0012\u0001\u0002\u0013\u0013\u0000\u0000\u0000\u0003\u0000\u0082v3\u0003\u0082v2\u0003\u0082v1\u0003\u00ff", 12 | "lzf_compressed":"\u0000\u00c3\t@v\u0001cc\u00e0i\u0000\u0001cc", 13 | "string1":"\u0000\u0004blaa", 14 | "mylist2":"\u0012\u0001\u0002\u000f\u000f\u0000\u0000\u0000\u0002\u0000\u0082v2\u0003\u0082v1\u0003\u00ff" 15 | -------------------------------------------------------------------------------- /test/dumps/multiple_lists_strings_struct.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1677580558", 5 | "used-mem":"937464", 6 | "aof-base":"0" 7 | }, 8 | 9 | "string2":"Hi there!", 10 | "mylist1":["\u000b\u0000\u0000\u0000\u0001\u0000\u0082v1\u0003\u00ff"], 11 | "mylist3":["\u0013\u0000\u0000\u0000\u0003\u0000\u0082v3\u0003\u0082v2\u0003\u0082v1\u0003\u00ff"], 12 | "lzf_compressed":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", 13 | "string1":"blaa", 14 | "mylist2":["\u000f\u0000\u0000\u0000\u0002\u0000\u0082v2\u0003\u0082v1\u0003\u00ff"] 15 | -------------------------------------------------------------------------------- /test/dumps/multiple_lists_strings_subset_list.json: -------------------------------------------------------------------------------- 1 | "mylist1":["v1"], 2 | "mylist3":["v3","v2","v1"], 3 | "mylist2":["v2","v1"] -------------------------------------------------------------------------------- /test/dumps/multiple_lists_strings_subset_str.json: -------------------------------------------------------------------------------- 1 | "string2":"\u0000\tHi there!", 2 | "lzf_compressed":"\u0000\u00c3\t@v\u0001cc\u00e0i\u0000\u0001cc", 3 | "string1":"\u0000\u0004blaa" 4 | -------------------------------------------------------------------------------- /test/dumps/plain_hash_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"3.2.1", 3 | "redis-bits":"64", 4 | "ctime":"1689605183", 5 | "used-mem":"821904" 6 | }, 7 | 8 | "myhash1":{"5":"5","6":"6","10":"10","1":"1","2":"2","8":"8","4":"4","9":"9","3":"3","7":"7","11":"11"} 9 | -------------------------------------------------------------------------------- /test/dumps/plain_hash_struct.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"3.2.1", 3 | "redis-bits":"64", 4 | "ctime":"1689605183", 5 | "used-mem":"821904" 6 | }, 7 | 8 | "myhash1":{"5":"5","6":"6","10":"10","1":"1","2":"2","8":"8","4":"4","9":"9","3":"3","7":"7","11":"11"} 9 | -------------------------------------------------------------------------------- /test/dumps/plain_list_v6.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/plain_list_v6.rdb -------------------------------------------------------------------------------- /test/dumps/plain_list_v6_data.json: -------------------------------------------------------------------------------- 1 | "ll":["1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1","1"] 2 | -------------------------------------------------------------------------------- /test/dumps/plain_list_v6_raw.json: -------------------------------------------------------------------------------- 1 | "ll":"\u0001B\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001" 2 | -------------------------------------------------------------------------------- /test/dumps/plain_set_v6.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/plain_set_v6.rdb -------------------------------------------------------------------------------- /test/dumps/plain_set_v6_data.json: -------------------------------------------------------------------------------- 1 | "myset":["a1","1.3","b2","2","3","1.1","1.2","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","c3","1"] 2 | -------------------------------------------------------------------------------- /test/dumps/plain_set_v6_raw.json: -------------------------------------------------------------------------------- 1 | "myset":"\u0002\n\u0002a1\u00031.3\u0002b2\u00c0\u0002\u00c0\u0003\u00031.1\u00031.2\u00c3\t@Q\u0001xx\u00e0D\u0000\u0001xx\u0002c3\u00c0\u0001" 2 | -------------------------------------------------------------------------------- /test/dumps/plain_set_v6_struct.json: -------------------------------------------------------------------------------- 1 | "myset":["a1","1.3","b2","2","3","1.1","1.2","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","c3","1"] 2 | -------------------------------------------------------------------------------- /test/dumps/plain_zset_2_v11.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/plain_zset_2_v11.rdb -------------------------------------------------------------------------------- /test/dumps/plain_zset_2_v11_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1695705520", 5 | "used-mem":"967352", 6 | "aof-base":"0" 7 | }, 8 | 9 | "myzset":{"a9":"inf","a8":"inf","a23":"1.000033e+25","a11":"9007199254740992","a21":"1125899906842624","a17":"65536","a15":"255","a13":"8.888888","a7":"2.2","a6":"0","a5":"0","a4":"0","a3":"0","a2":"0","a1":"0","a19":"-1","a20":"-1.1","a14":"-9.99999","a16":"-255","a18":"-65536","a22":"-1125899906842624","a12":"-9007199254740992","a24":"-4.329000123123131e+28","a10":"-inf"} 10 | -------------------------------------------------------------------------------- /test/dumps/plain_zset_2_v11_raw.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1695705520", 5 | "used-mem":"967352", 6 | "aof-base":"0" 7 | }, 8 | 9 | "myzset":"\u0005\u0018\u0002a9\u0000\u0000\u0000\u0000\u0000\u0000\u00f0\u007f\u0002a8\u0000\u0000\u0000\u0000\u0000\u0000\u00f0\u007f\u0003a23\u00bc\t\u007f\u00f3M\u008b E\u0003a11\u0000\u0000\u0000\u0000\u0000\u0000@C\u0003a21\u0000\u0000\u0000\u0000\u0000\u0000\u0010C\u0003a17\u0000\u0000\u0000\u0000\u0000\u0000\u00f0@\u0003a15\u0000\u0000\u0000\u0000\u0000\u00e0o@\u0003a13\u001b\u009d\u00f3S\u001c\u00c7!@\u0002a7\u009a\u0099\u0099\u0099\u0099\u0099\u0001@\u0002a6\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002a5\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002a4\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0080\u0002a3\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0080\u0002a2\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002a1\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0003a19\u0000\u0000\u0000\u0000\u0000\u0000\u00f0\u00bf\u0003a20\u009a\u0099\u0099\u0099\u0099\u0099\u00f1\u00bf\u0003a14r\u00a7t\u00b0\u00fe\u00ff#\u00c0\u0003a16\u0000\u0000\u0000\u0000\u0000\u00e0o\u00c0\u0003a18\u0000\u0000\u0000\u0000\u0000\u0000\u00f0\u00c0\u0003a22\u0000\u0000\u0000\u0000\u0000\u0000\u0010\u00c3\u0003a12\u0000\u0000\u0000\u0000\u0000\u0000@\u00c3\u0003a24\u00c0\u00e1\u00a2\u00ca\u0014|\u00e1\u00c5\u0003a10\u0000\u0000\u0000\u0000\u0000\u0000\u00f0\u00ff" 10 | -------------------------------------------------------------------------------- /test/dumps/plain_zset_2_v11_struct.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1695705520", 5 | "used-mem":"967352", 6 | "aof-base":"0" 7 | }, 8 | 9 | "myzset":{"a9":"inf","a8":"inf","a23":"1.000033e+25","a11":"9007199254740992","a21":"1125899906842624","a17":"65536","a15":"255","a13":"8.888888","a7":"2.2","a6":"0","a5":"0","a4":"0","a3":"0","a2":"0","a1":"0","a19":"-1","a20":"-1.1","a14":"-9.99999","a16":"-255","a18":"-65536","a22":"-1125899906842624","a12":"-9007199254740992","a24":"-4.329000123123131e+28","a10":"-inf"} 10 | -------------------------------------------------------------------------------- /test/dumps/plain_zset_v6.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/plain_zset_v6.rdb -------------------------------------------------------------------------------- /test/dumps/plain_zset_v6_data.json: -------------------------------------------------------------------------------- 1 | "myzset": { 2 | "a23": "1.000033e+25", 3 | "a19": "-1", 4 | "a9": "inf", 5 | "a24": "-4.329000123123131e+28", 6 | "a12": "-9007199254740992", 7 | "a7": "2.2", 8 | "a13": "8.888888", 9 | "a17": "65536", 10 | "a21": "1125899906842624", 11 | "a20": "-1.1", 12 | "a22": "-1125899906842624", 13 | "a3": "0", 14 | "a2": "0", 15 | "a15": "255", 16 | "a8": "inf", 17 | "a11": "9007199254740992", 18 | "a10": "-inf", 19 | "a5": "0", 20 | "a14": "-9.99999", 21 | "a6": "0", 22 | "a16": "-255", 23 | "a4": "0", 24 | "a1": "0", 25 | "a18": "-65536" 26 | } 27 | 28 | -------------------------------------------------------------------------------- /test/dumps/plain_zset_v6_raw.json: -------------------------------------------------------------------------------- 1 | "myzset": "\u0003\u0018\u0003a23\f1.000033e+25\u0003a19\u0002-1\u0002a9þ\u0003a24\u0017-4.3290001231231309e+28\u0003a12\u0011-9007199254740992\u0002a7\u00122.2000000000000002\u0003a13\u00128.8888879999999997\u0003a17\u000565536\u0003a21\u00101125899906842624\u0003a20\u0013-1.1000000000000001\u0003a22\u0011-1125899906842624\u0002a3\u0002-0\u0002a2\u00010\u0003a15\u0003255\u0002a8þ\u0003a11\u00109007199254740992\u0003a10ÿ\u0002a5\u00010\u0003a14\u0013-9.9999900000000004\u0002a6\u00010\u0003a16\u0004-255\u0002a4\u0002-0\u0002a1\u00010\u0003a18\u0006-65536" 2 | -------------------------------------------------------------------------------- /test/dumps/plain_zset_v6_struct.json: -------------------------------------------------------------------------------- 1 | "myzset": { 2 | "a23": "1.000033e+25", 3 | "a19": "-1", 4 | "a9": "inf", 5 | "a24": "-4.329000123123131e+28", 6 | "a12": "-9007199254740992", 7 | "a7": "2.2", 8 | "a13": "8.888888", 9 | "a17": "65536", 10 | "a21": "1125899906842624", 11 | "a20": "-1.1", 12 | "a22": "-1125899906842624", 13 | "a3": "0", 14 | "a2": "0", 15 | "a15": "255", 16 | "a8": "inf", 17 | "a11": "9007199254740992", 18 | "a10": "-inf", 19 | "a5": "0", 20 | "a14": "-9.99999", 21 | "a6": "0", 22 | "a16": "-255", 23 | "a4": "0", 24 | "a1": "0", 25 | "a18": "-65536" 26 | } 27 | -------------------------------------------------------------------------------- /test/dumps/quicklist.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/quicklist.rdb -------------------------------------------------------------------------------- /test/dumps/quicklist2_v11.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/quicklist2_v11.rdb -------------------------------------------------------------------------------- /test/dumps/quicklist_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"4.0.9", 3 | "redis-bits":"64", 4 | "ctime":"1629882015", 5 | "used-mem":"496256", 6 | "aof-preamble":"0" 7 | }, 8 | 9 | "list":["7"], 10 | "x":"7" 11 | -------------------------------------------------------------------------------- /test/dumps/quicklist_raw.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"4.0.9", 3 | "redis-bits":"64", 4 | "ctime":"1629882015", 5 | "used-mem":"496256", 6 | "aof-preamble":"0" 7 | }, 8 | 9 | "list":"\u000e\u0001\r\r\u0000\u0000\u0000\n\u0000\u0000\u0000\u0001\u0000\u0000\u00f8\u00ff", 10 | "x":"\u0000\u00c0\u0007" 11 | -------------------------------------------------------------------------------- /test/dumps/quicklist_struct.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"4.0.9", 3 | "redis-bits":"64", 4 | "ctime":"1629882015", 5 | "used-mem":"496256", 6 | "aof-preamble":"0" 7 | }, 8 | 9 | "list":["\r\u0000\u0000\u0000\n\u0000\u0000\u0000\u0001\u0000\u0000\u00f8\u00ff"], 10 | "x":"7" 11 | -------------------------------------------------------------------------------- /test/dumps/redis_ent_opcode_ram_lru.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/redis_ent_opcode_ram_lru.rdb -------------------------------------------------------------------------------- /test/dumps/set_expired.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/set_expired.json -------------------------------------------------------------------------------- /test/dumps/set_expired_v11.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/set_expired_v11.rdb -------------------------------------------------------------------------------- /test/dumps/set_is_v11.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/set_is_v11.rdb -------------------------------------------------------------------------------- /test/dumps/set_is_v11_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1691304897", 5 | "used-mem":"978520", 6 | "aof-base":"0" 7 | }, 8 | 9 | "myintest":["1","2","3","4","5","1234567890"] -------------------------------------------------------------------------------- /test/dumps/set_is_v11_raw.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1691304897", 5 | "used-mem":"978520", 6 | "aof-base":"0" 7 | }, 8 | 9 | "myintest":["\u0004\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0001\u0000\u0000\u0000\u0002\u0000\u0000\u0000\u0003\u0000\u0000\u0000\u0004\u0000\u0000\u0000\u0005\u0000\u0000\u0000\u00d2\u0002\u0096I"] 10 | -------------------------------------------------------------------------------- /test/dumps/set_is_v11_struct.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1691304897", 5 | "used-mem":"978520", 6 | "aof-base":"0" 7 | }, 8 | 9 | "myintest":["\u0004\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0001\u0000\u0000\u0000\u0002\u0000\u0000\u0000\u0003\u0000\u0000\u0000\u0004\u0000\u0000\u0000\u0005\u0000\u0000\u0000\u00d2\u0002\u0096I"] 10 | -------------------------------------------------------------------------------- /test/dumps/set_lp_v11.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/set_lp_v11.rdb -------------------------------------------------------------------------------- /test/dumps/set_lp_v11_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1691481599", 5 | "used-mem":"866040", 6 | "aof-base":"0" 7 | }, 8 | 9 | "myset":["1","2","3","1.1","1.2","1.3","a","b","c"] 10 | -------------------------------------------------------------------------------- /test/dumps/set_lp_v11_raw.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1691481599", 5 | "used-mem":"866040", 6 | "aof-base":"0" 7 | }, 8 | 9 | "myset":["%\u0000\u0000\u0000\t\u0000\u0001\u0001\u0002\u0001\u0003\u0001\u00831.1\u0004\u00831.2\u0004\u00831.3\u0004\u0081a\u0002\u0081b\u0002\u0081c\u0002\u00ff"] 10 | -------------------------------------------------------------------------------- /test/dumps/set_lp_v11_struct.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1691481599", 5 | "used-mem":"866040", 6 | "aof-base":"0" 7 | }, 8 | 9 | "myset":["%\u0000\u0000\u0000\t\u0000\u0001\u0001\u0002\u0001\u0003\u0001\u00831.1\u0004\u00831.2\u0004\u00831.3\u0004\u0081a\u0002\u0081b\u0002\u0081c\u0002\u00ff"] -------------------------------------------------------------------------------- /test/dumps/set_not_expired.json: -------------------------------------------------------------------------------- 1 | "mykey":"myval" -------------------------------------------------------------------------------- /test/dumps/set_not_expired_v11.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/set_not_expired_v11.rdb -------------------------------------------------------------------------------- /test/dumps/single_key.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/single_key.rdb -------------------------------------------------------------------------------- /test/dumps/single_key_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1672087814", 5 | "used-mem":"972952", 6 | "repl-stream-db":"0", 7 | "repl-id":"67ebe8f627f436e2630eef8661a697fa33563a8f", 8 | "repl-offset":"162341903", 9 | "aof-base":"0" 10 | }, 11 | 12 | "xxx":"111" 13 | -------------------------------------------------------------------------------- /test/dumps/single_key_raw.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver": "255.255.255", 3 | "redis-bits": "64", 4 | "ctime": "1672087814", 5 | "used-mem": "972952", 6 | "repl-stream-db": "0", 7 | "repl-id": "67ebe8f627f436e2630eef8661a697fa33563a8f", 8 | "repl-offset": "162341903", 9 | "aof-base": "0" 10 | }, 11 | 12 | "xxx":"\u0000\u00c0o" 13 | -------------------------------------------------------------------------------- /test/dumps/single_key_struct.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver": "255.255.255", 3 | "redis-bits": "64", 4 | "ctime": "1672087814", 5 | "used-mem": "972952", 6 | "repl-stream-db": "0", 7 | "repl-id": "67ebe8f627f436e2630eef8661a697fa33563a8f", 8 | "repl-offset": "162341903", 9 | "aof-base": "0" 10 | }, 11 | 12 | "xxx":"111" 13 | -------------------------------------------------------------------------------- /test/dumps/single_list_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver": "255.255.255", 3 | "redis-bits": "64", 4 | "ctime": "1677071222", 5 | "used-mem": "982208", 6 | "repl-stream-db": "0", 7 | "repl-id": "f42ea6b158e5926941d08bde6b9ecb6ae88dcd45", 8 | "repl-offset": "162395634", 9 | "aof-base": "0" 10 | }, 11 | 12 | "mylist":["val3","val2","val1"] 13 | -------------------------------------------------------------------------------- /test/dumps/single_list_raw.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1677071222", 5 | "used-mem":"982208", 6 | "repl-stream-db":"0", 7 | "repl-id":"f42ea6b158e5926941d08bde6b9ecb6ae88dcd45", 8 | "repl-offset":"162395634", 9 | "aof-base":"0" 10 | }, 11 | 12 | "mylist":"\u0012\u0001\u0002\u0019\u0019\u0000\u0000\u0000\u0003\u0000\u0084val3\u0005\u0084val2\u0005\u0084val1\u0005\u00ff" -------------------------------------------------------------------------------- /test/dumps/single_list_struct.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1677071222", 5 | "used-mem":"982208", 6 | "repl-stream-db":"0", 7 | "repl-id":"f42ea6b158e5926941d08bde6b9ecb6ae88dcd45", 8 | "repl-offset":"162395634", 9 | "aof-base":"0" 10 | }, 11 | 12 | "mylist":["\u0019\u0000\u0000\u0000\u0003\u0000\u0084val3\u0005\u0084val2\u0005\u0084val1\u0005\u00ff"] 13 | -------------------------------------------------------------------------------- /test/dumps/stream_data.json: -------------------------------------------------------------------------------- 1 | "mystream":{ 2 | "entries":[ 3 | { "id":"1695649068107-0", "items":{"message":"Message1"} }, 4 | { "id":"1695649068110-0", "items":{"message":"Message2"} }, 5 | { "id":"1695649069139-0", "items":{"message":"Message3"} }, 6 | { "id":"1695649446276-0", "items":{"message":"Message4"} }, 7 | { "id":"1695649456516-0", "items":{"message":"Message5"} }, 8 | { "id":"1695893015933-0", "items":{"field1":"value1", "field2":"value2", "field3":"value3"} } 9 | ]} 10 | -------------------------------------------------------------------------------- /test/dumps/stream_data_with_meta.json: -------------------------------------------------------------------------------- 1 | "mystream":{ 2 | "entries":[ 3 | { "id":"1695649068107-0", "items":{"message":"Message1"} }, 4 | { "id":"1695649068110-0", "items":{"message":"Message2"} }, 5 | { "id":"1695649069139-0", "items":{"message":"Message3"} }, 6 | { "id":"1695649446276-0", "items":{"message":"Message4"} }, 7 | { "id":"1695649456516-0", "items":{"message":"Message5"} }, 8 | { "id":"1695893015933-0", "items":{"field1":"value1", "field2":"value2", "field3":"value3"} }], 9 | "length": 6, 10 | "entriesAdded": 6, 11 | "firstID": "1695649068107-0", 12 | "lastID": "1695893015933-0", 13 | "maxDelEntryID": "0-0", 14 | "groups": [ 15 | {"name": "groupA", "lastid": "1695649446276-0", "entriesRead": 4, 16 | "pending": [ 17 | { "sent": 1695649446276, "id":"1695649446276-0", "count": 1 }], 18 | "consumers": [ 19 | { "name": "consumerA1", "activeTime": 1696679585023, "seenTime": 1696679585023}, 20 | { "name": "consumerA2", "activeTime": 1696679585024, "seenTime": 1696679585024, 21 | "pending": [ 22 | {"id":"1695649446276-0"}]}]}, 23 | {"name": "groupB", "lastid": "1695649069139-0", "entriesRead": 3, 24 | "pending": [ 25 | { "sent": 1695649069139, "id":"1695649069139-0", "count": 1 }], 26 | "consumers": [ 27 | { "name": "consumerB1", "activeTime": 1696679585026, "seenTime": 1696679585026, 28 | "pending": [ 29 | {"id":"1695649069139-0"}]}]}]} 30 | -------------------------------------------------------------------------------- /test/dumps/stream_v11.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/stream_v11.rdb -------------------------------------------------------------------------------- /test/dumps/stream_v11_target_ver_6.2.resp: -------------------------------------------------------------------------------- 1 | *5 2 | $4 3 | XADD 4 | $8 5 | mystream 6 | $15 7 | 1695649068107-0 8 | $7 9 | message 10 | $8 11 | Message1 12 | *5 13 | $4 14 | XADD 15 | $8 16 | mystream 17 | $15 18 | 1695649068110-0 19 | $7 20 | message 21 | $8 22 | Message2 23 | *5 24 | $4 25 | XADD 26 | $8 27 | mystream 28 | $15 29 | 1695649069139-0 30 | $7 31 | message 32 | $8 33 | Message3 34 | *5 35 | $4 36 | XADD 37 | $8 38 | mystream 39 | $15 40 | 1695649446276-0 41 | $7 42 | message 43 | $8 44 | Message4 45 | *5 46 | $4 47 | XADD 48 | $8 49 | mystream 50 | $15 51 | 1695649456516-0 52 | $7 53 | message 54 | $8 55 | Message5 56 | *9 57 | $4 58 | XADD 59 | $8 60 | mystream 61 | $15 62 | 1695893015933-0 63 | $6 64 | field1 65 | $6 66 | value1 67 | $6 68 | field2 69 | $6 70 | value2 71 | $6 72 | field3 73 | $6 74 | value3 75 | *3 76 | $6 77 | XSETID 78 | $8 79 | mystream 80 | $15 81 | 1695893015933-0 82 | *5 83 | $6 84 | XGROUP 85 | $6 86 | CREATE 87 | $8 88 | mystream 89 | $6 90 | groupA 91 | $15 92 | 1695649446276-0 93 | *12 94 | $6 95 | XCLAIM 96 | $8 97 | mystream 98 | $6 99 | groupA 100 | $10 101 | consumerA2 102 | $1 103 | 0 104 | $15 105 | 1695649446276-0 106 | $4 107 | TIME 108 | $13 109 | 1695649446276 110 | $10 111 | RETRYCOUNT 112 | $1 113 | 1 114 | $6 115 | JUSTID 116 | $5 117 | FORCE 118 | *5 119 | $6 120 | XGROUP 121 | $6 122 | CREATE 123 | $8 124 | mystream 125 | $6 126 | groupB 127 | $15 128 | 1695649069139-0 129 | *12 130 | $6 131 | XCLAIM 132 | $8 133 | mystream 134 | $6 135 | groupB 136 | $10 137 | consumerB1 138 | $1 139 | 0 140 | $15 141 | 1695649069139-0 142 | $4 143 | TIME 144 | $13 145 | 1695649069139 146 | $10 147 | RETRYCOUNT 148 | $1 149 | 1 150 | $6 151 | JUSTID 152 | $5 153 | FORCE 154 | -------------------------------------------------------------------------------- /test/dumps/stream_v11_target_ver_7.2.resp: -------------------------------------------------------------------------------- 1 | *5 2 | $4 3 | XADD 4 | $8 5 | mystream 6 | $15 7 | 1695649068107-0 8 | $7 9 | message 10 | $8 11 | Message1 12 | *5 13 | $4 14 | XADD 15 | $8 16 | mystream 17 | $15 18 | 1695649068110-0 19 | $7 20 | message 21 | $8 22 | Message2 23 | *5 24 | $4 25 | XADD 26 | $8 27 | mystream 28 | $15 29 | 1695649069139-0 30 | $7 31 | message 32 | $8 33 | Message3 34 | *5 35 | $4 36 | XADD 37 | $8 38 | mystream 39 | $15 40 | 1695649446276-0 41 | $7 42 | message 43 | $8 44 | Message4 45 | *5 46 | $4 47 | XADD 48 | $8 49 | mystream 50 | $15 51 | 1695649456516-0 52 | $7 53 | message 54 | $8 55 | Message5 56 | *9 57 | $4 58 | XADD 59 | $8 60 | mystream 61 | $15 62 | 1695893015933-0 63 | $6 64 | field1 65 | $6 66 | value1 67 | $6 68 | field2 69 | $6 70 | value2 71 | $6 72 | field3 73 | $6 74 | value3 75 | *7 76 | $6 77 | XSETID 78 | $8 79 | mystream 80 | $15 81 | 1695893015933-0 82 | $12 83 | ENTRIESADDED 84 | $1 85 | 6 86 | $12 87 | MAXDELETEDID 88 | $3 89 | 0-0 90 | *7 91 | $6 92 | XGROUP 93 | $6 94 | CREATE 95 | $8 96 | mystream 97 | $6 98 | groupA 99 | $15 100 | 1695649446276-0 101 | $11 102 | ENTRIESREAD 103 | $1 104 | 4 105 | *12 106 | $6 107 | XCLAIM 108 | $8 109 | mystream 110 | $6 111 | groupA 112 | $10 113 | consumerA2 114 | $1 115 | 0 116 | $15 117 | 1695649446276-0 118 | $4 119 | TIME 120 | $13 121 | 1695649446276 122 | $10 123 | RETRYCOUNT 124 | $1 125 | 1 126 | $6 127 | JUSTID 128 | $5 129 | FORCE 130 | *7 131 | $6 132 | XGROUP 133 | $6 134 | CREATE 135 | $8 136 | mystream 137 | $6 138 | groupB 139 | $15 140 | 1695649069139-0 141 | $11 142 | ENTRIESREAD 143 | $1 144 | 3 145 | *12 146 | $6 147 | XCLAIM 148 | $8 149 | mystream 150 | $6 151 | groupB 152 | $10 153 | consumerB1 154 | $1 155 | 0 156 | $15 157 | 1695649069139-0 158 | $4 159 | TIME 160 | $13 161 | 1695649069139 162 | $10 163 | RETRYCOUNT 164 | $1 165 | 1 166 | $6 167 | JUSTID 168 | $5 169 | FORCE 170 | -------------------------------------------------------------------------------- /test/dumps/string_int_encoded.json: -------------------------------------------------------------------------------- 1 | "str::-4294967295":"-4294967295", 2 | "str::255":"255", 3 | "str::-16777217":"-16777217", 4 | "str::16777218":"16777218", 5 | "str::-4294967297":"-4294967297", 6 | "str::257":"257", 7 | "str::2147483649":"2147483649", 8 | "str::-16777215":"-16777215", 9 | "str::3":"3", 10 | "str::-281474976710656":"-281474976710656", 11 | "str::-16777214":"-16777214", 12 | "str::-65534":"-65534", 13 | "str::256":"256", 14 | "str::65535":"65535", 15 | "str::-258":"-258", 16 | "str::-256":"-256", 17 | "str::254":"254", 18 | "str::-4294967294":"-4294967294", 19 | "str::16777217":"16777217", 20 | "str::-281474976710655":"-281474976710655", 21 | "str::16777216":"16777216", 22 | "str::-255":"-255", 23 | "str::-4294967298":"-4294967298", 24 | "str::-1":"-1", 25 | "str::281474976710655":"281474976710655", 26 | "str::1":"1", 27 | "str::0":"0", 28 | "str::-281474976710654":"-281474976710654", 29 | "str::-65538":"-65538", 30 | "str::-254":"-254", 31 | "str::-16777216":"-16777216", 32 | "str::281474976710654":"281474976710654", 33 | "str::281474976710657":"281474976710657", 34 | "str::-281474976710657":"-281474976710657", 35 | "str::258":"258", 36 | "str::9223372036854780000":"9223372036854780000", 37 | "str::16777214":"16777214", 38 | "str::-257":"-257", 39 | "str::2":"2", 40 | "str::2147483650":"2147483650", 41 | "str::16777215":"16777215", 42 | "str::-65537":"-65537", 43 | "str::65537":"65537", 44 | "str::-65536":"-65536", 45 | "str::-16777218":"-16777218", 46 | "str::65534":"65534", 47 | "str::-4294967296":"-4294967296", 48 | "str::65538":"65538", 49 | "str::2147483646":"2147483646", 50 | "str::281474976710658":"281474976710658", 51 | "str::2147483648":"2147483648", 52 | "str::281474976710656":"281474976710656", 53 | "str::-9223372036854780000":"-9223372036854780000", 54 | "str::-65535":"-65535", 55 | "str::65536":"65536", 56 | "str::2147483647":"2147483647", 57 | "str::-281474976710658":"-281474976710658" 58 | -------------------------------------------------------------------------------- /test/dumps/string_int_encoded.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/string_int_encoded.rdb -------------------------------------------------------------------------------- /test/dumps/string_lzf.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/string_lzf.rdb -------------------------------------------------------------------------------- /test/dumps/validate_all_json_files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for unwrap_json_file in *.json; do 4 | tmp_file=wrapped_$unwrap_json_file 5 | # Wrap the unwrapped JSON file with curly braces to make it valid JSON 6 | echo '{' > $tmp_file 7 | cat "$unwrap_json_file" >> $tmp_file 8 | echo '}' >> $tmp_file 9 | 10 | # Use jq to check if the JSON is valid 11 | if jq empty $tmp_file &> /dev/null; then 12 | echo "Validation succeeded for $unwrap_json_file" 13 | else 14 | echo "Validation failed for $unwrap_json_file" 15 | exit 1 16 | fi 17 | 18 | # Clean up the temporary wrapped file 19 | rm $tmp_file 20 | done 21 | exit 0 -------------------------------------------------------------------------------- /test/dumps/ziplist_data.json: -------------------------------------------------------------------------------- 1 | "ziplist_compresses_easily":["aaaaaa","aaaaaaaaaaaa","aaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"] -------------------------------------------------------------------------------- /test/dumps/ziplist_raw.json: -------------------------------------------------------------------------------- 1 | "ziplist_compresses_easily":"\n\u00c3<@\u0095\u0004\u0095\u0000\u0000\u0000n \u0003\u0000\u0006 \u0002\u0000a`\u0000\u0001\b\f`\u0006\u00a0\u0000\u0001\u000e\u0012\u00a0\b\u00e0\u0002\u0000\u0001\u0014\u0018\u00e0\u0002\f\u00e0\u0004\u0000\u0001\u001a\u001e\u00e0\u0004\u000e\u00e0\b\u0000\u0001 $\u00e0\b\u0012\u00e0\n\u0000\u0000\u00ff" -------------------------------------------------------------------------------- /test/dumps/ziplist_struct.json: -------------------------------------------------------------------------------- 1 | "ziplist_compresses_easily":["\u0095\u0000\u0000\u0000n\u0000\u0000\u0000\u0006\u0000\u0000\u0006aaaaaa\b\faaaaaaaaaaaa\u000e\u0012aaaaaaaaaaaaaaaaaa\u0014\u0018aaaaaaaaaaaaaaaaaaaaaaaa\u001a\u001eaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa $aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\u00ff"] -------------------------------------------------------------------------------- /test/dumps/ziplist_v3.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/ziplist_v3.rdb -------------------------------------------------------------------------------- /test/dumps/zset_lp_v11.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/zset_lp_v11.rdb -------------------------------------------------------------------------------- /test/dumps/zset_lp_v11_data.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1695704816", 5 | "used-mem":"969032", 6 | "aof-base":"0" 7 | }, 8 | 9 | "myzset":{"a10":"-inf","a24":"-4.329000123123131e+28","a12":"-9007199254740992","a22":"-1125899906842624","a18":"-65536","a16":"-255","a14":"-9.99999","a20":"-1.1","a19":"-1","a1":"0","a2":"0","a3":"0","a4":"0","a5":"0","a6":"0","a7":"2.2","a13":"8.888888","a15":"255","a17":"65536","a21":"1125899906842624","a11":"9007199254740992","a23":"1.000033e+25","a8":"inf","a9":"inf"} 10 | -------------------------------------------------------------------------------- /test/dumps/zset_lp_v11_raw.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1695704816", 5 | "used-mem":"969032", 6 | "aof-base":"0" 7 | }, 8 | 9 | "myzset":"\u0011\u00c3@\u00e6A\u0012\u001f\u0012\u0001\u0000\u00000\u0000\u0083a10\u0004\u0084-inf\u0005\u0083a24\u0004\u0096-4.329000\u0002123@\u0002\u000631e+28\u0017 '\u00032\u0004\u00f4\u0000`\u0000\u0002\u00e0\u00ff\t +\u00e0\u0000\u000e\u0000\u00fc@\u000e\u000718\u0004\u00f2\u0000\u0000\u00ff\u0004 \t\u00046\u0004\u00df\u0001\u0002 \u0007\u00064\u0004\u0088-9.9@\u0000@/@f\u00021.1 f\u000e19\u0004\u00df\u00ff\u0002\u0082a1\u0003\u0000\u0001\u0082a2`\u0005\u00003`\u0005\u00004`\u0005\u00005`\u0005\u00006`\u0005\u00057\u0003\u00832.2@V\u00053\u0004\u00888.8`\u0000 N\u000415\u0004\u00c0\u00ff@e\u00007@w\u0000\u0001 \u000121\u00c0\u009f\u0001\u0004\u0000@ \u00e0\u0000\u000e\u0000 @\u000e\u000523\u0004\u008c1. \u00d6\u0002033 \u00d0\u00065\r\u0082a8\u0003\u0083 \u00f6\u0003\u0004\u0082a9`\b\u0001\u0004\u00ff" 10 | -------------------------------------------------------------------------------- /test/dumps/zset_lp_v11_struct.json: -------------------------------------------------------------------------------- 1 | "__aux__" : { 2 | "redis-ver":"255.255.255", 3 | "redis-bits":"64", 4 | "ctime":"1695704816", 5 | "used-mem":"969032", 6 | "aof-base":"0" 7 | }, 8 | 9 | "myzset":["\u0012\u0001\u0000\u00000\u0000\u0083a10\u0004\u0084-inf\u0005\u0083a24\u0004\u0096-4.329000123123131e+28\u0017\u0083a12\u0004\u00f4\u0000\u0000\u0000\u0000\u0000\u0000\u00e0\u00ff\t\u0083a22\u0004\u00f4\u0000\u0000\u0000\u0000\u0000\u0000\u00fc\u00ff\t\u0083a18\u0004\u00f2\u0000\u0000\u00ff\u0004\u0083a16\u0004\u00df\u0001\u0002\u0083a14\u0004\u0088-9.99999\t\u0083a20\u0004\u0084-1.1\u0005\u0083a19\u0004\u00df\u00ff\u0002\u0082a1\u0003\u0000\u0001\u0082a2\u0003\u0000\u0001\u0082a3\u0003\u0000\u0001\u0082a4\u0003\u0000\u0001\u0082a5\u0003\u0000\u0001\u0082a6\u0003\u0000\u0001\u0082a7\u0003\u00832.2\u0004\u0083a13\u0004\u00888.888888\t\u0083a15\u0004\u00c0\u00ff\u0002\u0083a17\u0004\u00f2\u0000\u0000\u0001\u0004\u0083a21\u0004\u00f4\u0000\u0000\u0000\u0000\u0000\u0000\u0004\u0000\t\u0083a11\u0004\u00f4\u0000\u0000\u0000\u0000\u0000\u0000 \u0000\t\u0083a23\u0004\u008c1.000033e+25\r\u0082a8\u0003\u0083inf\u0004\u0082a9\u0003\u0083inf\u0004\u00ff"] 10 | -------------------------------------------------------------------------------- /test/dumps/zset_zl_v6.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/dumps/zset_zl_v6.rdb -------------------------------------------------------------------------------- /test/dumps/zset_zl_v6_data.json: -------------------------------------------------------------------------------- 1 | "myzset":{"a10":"-inf","a24":"-4.329000123123131e+28","a12":"-9007199254740992","a22":"-1125899906842624","a18":"-65536","a16":"-255","a14":"-9.99999","a20":"-1.1","a19":"-1","a1":"0","a2":"0","a3":"0","a4":"0","a5":"0","a6":"0","a7":"2.2","a13":"8.888888","a15":"255","a17":"65536","a21":"1125899906842624","a11":"9007199254740992","a23":"1.000033e+25","a8":"inf","a9":"inf"} 2 | -------------------------------------------------------------------------------- /test/dumps/zset_zl_v6_raw.json: -------------------------------------------------------------------------------- 1 | "myzset":"\f\u00c3A\u000fAP\u0004P\u0001\u0000\u0000J \u0003\u001f0\u0000\u0000\u0003a10\u0005\u0004-inf\u0006\u0003a24\u0005\u0017-4.329000123@\u0002\u0007309e+28\u0019 (\u00032\u0005\u00e0\u0000`\u0000\u0002\u00e0\u00ff\n ,\u00e0\u0000\u000e\u0000\u00fc@\u000e\u000718\u0005\u00f0\u0000\u0000\u00ff\u0005 \t\u00056\u0005\u00c0\u0001\u00ff\u0004 \b\u00064\u0005\u0013-9.9@\u0000 P\u00a0\u0000\u00014\u0015 ;\u00000 \u0019\u00021.1\u00a0\u0012\u00a0\u0000\u00001 \u0019\u000e19\u0005\u00fe\u00ff\u0003\u0002a1\u0004\u00f1\u0002\u0002a2`\u0005\b3\u0004\u0002-0\u0004\u0002a4\u00a0\u0007\u00005`\u0015\u00006`\u0005\u00057\u0004\u00122.2\u00a0@\u00a0\u0000\u00012\u0014 G\u00053\u0005\u00128.8@\u0000\u00007@\u007f`\u0000\u00007@\u0018\u00045\u0005\u00c0\u00ff\u0000@\u009d\u00007@\u00b0\u0000\u0001 \u00b0\u000121\u00c0\u00d8\u0001\u0004\u0000 \u00d8\u00001\u00e0\u0000\u000e\u0000 @\u000e\u000523\u0005\f1.@Z\u000133!\t\u00065\u000e\u0002a8\u0004\u0003!0\u0003\u0005\u0002a9@\b\u0001f\u00ff" 2 | -------------------------------------------------------------------------------- /test/dumps/zset_zl_v6_struct.json: -------------------------------------------------------------------------------- 1 | "myzset":["P\u0001\u0000\u0000J\u0001\u0000\u00000\u0000\u0000\u0003a10\u0005\u0004-inf\u0006\u0003a24\u0005\u0017-4.3290001231231309e+28\u0019\u0003a12\u0005\u00e0\u0000\u0000\u0000\u0000\u0000\u0000\u00e0\u00ff\n\u0003a22\u0005\u00e0\u0000\u0000\u0000\u0000\u0000\u0000\u00fc\u00ff\n\u0003a18\u0005\u00f0\u0000\u0000\u00ff\u0005\u0003a16\u0005\u00c0\u0001\u00ff\u0004\u0003a14\u0005\u0013-9.9999900000000004\u0015\u0003a20\u0005\u0013-1.1000000000000001\u0015\u0003a19\u0005\u00fe\u00ff\u0003\u0002a1\u0004\u00f1\u0002\u0002a2\u0004\u00f1\u0002\u0002a3\u0004\u0002-0\u0004\u0002a4\u0004\u0002-0\u0004\u0002a5\u0004\u00f1\u0002\u0002a6\u0004\u00f1\u0002\u0002a7\u0004\u00122.2000000000000002\u0014\u0003a13\u0005\u00128.8888879999999997\u0014\u0003a15\u0005\u00c0\u00ff\u0000\u0004\u0003a17\u0005\u00f0\u0000\u0000\u0001\u0005\u0003a21\u0005\u00e0\u0000\u0000\u0000\u0000\u0000\u0000\u0004\u0000\n\u0003a11\u0005\u00e0\u0000\u0000\u0000\u0000\u0000\u0000 \u0000\n\u0003a23\u0005\f1.000033e+25\u000e\u0002a8\u0004\u0003inf\u0005\u0002a9\u0004\u0003inf\u00ff"] -------------------------------------------------------------------------------- /test/json_signature_generator.py: -------------------------------------------------------------------------------- 1 | """ 2 | JSON Signature Generator Service 3 | 4 | This script reads a JSON file path from its STDIN, generates its signature, ignoring 5 | elements order, and print result to STDOUT. It run as a service. The file test_common.c 6 | will start this service and will send filenames to it through pipe. 7 | 8 | It is optimized as a service since it is being used extensively in the test suite. 9 | """ 10 | import json 11 | import hashlib 12 | import sys 13 | import logging 14 | 15 | logging.getLogger().disabled = True 16 | # logging.basicConfig(filename='./json_signature_generator.log', level=logging.INFO, 17 | # format='%(asctime)s - %(levelname)s - %(message)s') 18 | 19 | def load_json(file_path): 20 | try: 21 | with open(file_path, 'r') as file: 22 | file_content = file.read() 23 | 24 | file_content = file_content.rstrip(",\r\n") 25 | 26 | # rdb-cli doesn't produce valid JSON. It requires few adaptations 27 | # [ ... ] ==> { "dbs": [ ... ] } 28 | # "a":"b" .... "y":"z" ==> { "a":"b" .... "y":"z" } 29 | if file_content.startswith('['): 30 | file_content = '{ "dbs":' + file_content + '}' 31 | elif not file_content.startswith('{'): 32 | file_content = '{' + file_content + '}' 33 | 34 | data = json.loads(file_content) 35 | return data 36 | except Exception as e: 37 | logging.error(f"Error loading JSON file {file_path}: {str(e)}") 38 | raise 39 | 40 | def sort_json(data): 41 | if isinstance(data, dict): 42 | sorted_dict = {key: sort_json(data[key]) for key in sorted(data)} 43 | return sorted_dict 44 | elif isinstance(data, list): 45 | return sorted((sort_json(item) for item in data), key=lambda x: json.dumps(x)) 46 | else: 47 | return data 48 | 49 | def json_to_string(data): 50 | return json.dumps(data, separators=(',', ':'), ensure_ascii=False) 51 | 52 | def generate_signature(data_string): 53 | return hashlib.sha256(data_string.encode('utf-8')).hexdigest() 54 | 55 | def service(): 56 | logging.info(f"Starting JSON Signature Generator Service") 57 | while True: 58 | try: 59 | # Read file path from standard input 60 | file_path = sys.stdin.readline().strip() 61 | 62 | if not file_path: 63 | break 64 | 65 | # Process the file 66 | json_data = load_json(file_path) 67 | sorted_json_data = sort_json(json_data) 68 | sorted_json_string = json_to_string(sorted_json_data) 69 | signature = generate_signature(sorted_json_string) 70 | 71 | # Return the signature 72 | print(signature) 73 | logging.info(f"Signature generated for file: {file_path}") 74 | sys.stdout.flush() # Flush STDOUT, ensure it's sent immediately 75 | 76 | except Exception as e: 77 | logging.error(f"Error processing file: {file_path}, Error: {str(e)}") 78 | print(f"Error: {str(e)}", file=sys.stderr) 79 | sys.stderr.flush() 80 | continue 81 | 82 | if __name__ == "__main__": 83 | service() 84 | -------------------------------------------------------------------------------- /test/log/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/log/.gitkeep -------------------------------------------------------------------------------- /test/test_bulk_ops.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "test_common.h" 3 | 4 | RdbMemAlloc mem = {xmalloc, xrealloc, xfree, 5 | RDB_BULK_ALLOC_MAX, /* << change each iteration */ 6 | { xmalloc, xclone, xfree } 7 | }; 8 | 9 | void loggerCb(RdbLogLevel l, const char *msg) { 10 | UNUSED(l, msg); 11 | /* mask simulated errors */ 12 | } 13 | 14 | void reportErrorCb(RdbRes errorID, const char *errorMsg) { 15 | UNUSED(errorID, errorMsg); 16 | } 17 | 18 | void testBulkOps(RdbParser *p, RdbBulk b, int strlenCheck) { 19 | 20 | /*** test clone, and free ***/ 21 | 22 | RdbBulkCopy bcopy = RDB_bulkClone(p, b); 23 | 24 | if (RDB_isRefBulk(p, b)) { 25 | assert_ptr_not_equal(b, bcopy); 26 | assert_int_not_equal(mem.bulkAllocType, RDB_BULK_ALLOC_EXTERN); 27 | } else if (mem.bulkAllocType == RDB_BULK_ALLOC_HEAP) 28 | assert_ptr_equal(b, bcopy); /* heap clone uses refcount */ 29 | else if (mem.bulkAllocType == RDB_BULK_ALLOC_EXTERN) 30 | assert_ptr_not_equal(b, bcopy); /* xclone imp creates a new copy */ 31 | 32 | assert_string_equal(b, bcopy); 33 | RDB_bulkCopyFree(p, bcopy); 34 | 35 | /* Try clone non exist bulk */ 36 | RdbBulk nonExistBulk = "NON EXIST BULK"; 37 | assert_null(RDB_bulkClone(p, nonExistBulk)); 38 | RdbRes err = RDB_getErrorCode(p); 39 | assert_int_equal(err, RDB_ERR_INVALID_BULK_CLONE_REQUEST); 40 | 41 | /*** test bulk len ***/ 42 | 43 | /* enabled this check only if for sure bulk cannot have the char `\0' */ 44 | if (strlenCheck) 45 | assert_int_equal(strlen(b), RDB_bulkLen(p, b)); 46 | assert_true(0 != RDB_bulkLen(p, b)); 47 | } 48 | 49 | RdbRes handle_aux_field(RdbParser *p, void *userData, RdbBulk auxkey, RdbBulk auxval) { 50 | UNUSED(userData); 51 | testBulkOps(p, auxkey, 1); 52 | testBulkOps(p, auxval, 1); 53 | return RDB_OK; 54 | } 55 | 56 | RdbRes handle_new_key(RdbParser *p, void *userData, RdbBulk key, RdbKeyInfo *info) { 57 | UNUSED(userData, info); 58 | testBulkOps(p, key, 1); 59 | return RDB_OK; 60 | } 61 | 62 | RdbRes handle_raw_begin(RdbParser *p, void *userData, size_t size) { 63 | UNUSED(p); 64 | /* init rawObjSizeLeft with declared size. Verified by handle_raw_end */ 65 | size_t *rawObjSizeLeft = (size_t *)userData; 66 | *rawObjSizeLeft = size; 67 | return RDB_OK; 68 | } 69 | 70 | RdbRes handle_raw_frag(RdbParser *p, void *userData, RdbBulk frag) { 71 | size_t *rawObjSizeLeft = (size_t *)userData; 72 | 73 | *rawObjSizeLeft -= RDB_bulkLen(p, frag); 74 | testBulkOps(p, frag, 0); 75 | return RDB_OK; 76 | } 77 | 78 | RdbRes handle_raw_end(RdbParser *p, void *userData) { 79 | UNUSED(p); 80 | size_t *rawObjSizeLeft = (size_t *)userData; 81 | 82 | /* Verify reported size by handle_raw_begin == total received bulks */ 83 | assert_int_equal(*rawObjSizeLeft, 0); 84 | return RDB_OK; 85 | } 86 | 87 | RdbRes handle_string_value(RdbParser *p, void *userData, RdbBulk str) { 88 | UNUSED(userData); 89 | testBulkOps(p, str, 0); 90 | return RDB_OK; 91 | } 92 | 93 | RdbRes handle_list_element(RdbParser *p, void *userData, RdbBulk b) { 94 | UNUSED(userData); 95 | testBulkOps(p, b, 0); 96 | return RDB_OK; 97 | } 98 | 99 | static void test_raw_handlers_callbacks_bulk_ops (void **state) { 100 | UNUSED(state); 101 | RdbStatus status; 102 | size_t rawObjSizeLeft; 103 | void *user_data =&rawObjSizeLeft; 104 | 105 | for (mem.bulkAllocType = 0 ; mem.bulkAllocType < RDB_BULK_ALLOC_MAX ; ++mem.bulkAllocType) { 106 | 107 | RdbHandlersRawCallbacks callbacks = { 108 | .handleAuxField = handle_aux_field, 109 | .handleNewKey = handle_new_key, 110 | .handleBegin = handle_raw_begin, 111 | .handleFrag = handle_raw_frag, 112 | .handleEnd = handle_raw_end, 113 | }; 114 | 115 | RdbParser *parser = RDB_createParserRdb(&mem); 116 | RDB_setLogger(parser, loggerCb); 117 | assert_non_null(RDBX_createReaderFile(parser, DUMP_FOLDER("multiple_lists_strings.rdb"))); 118 | assert_non_null(RDB_createHandlersRaw(parser, &callbacks, user_data, NULL)); 119 | while ((status = RDB_parse(parser)) == RDB_STATUS_WAIT_MORE_DATA); 120 | assert_int_equal( status, RDB_STATUS_OK); 121 | RDB_deleteParser(parser); 122 | } 123 | } 124 | 125 | static void test_struct_handlers_callbacks_bulk_ops (void **state) { 126 | UNUSED(state); 127 | RdbStatus status; 128 | size_t rawObjSizeLeft; 129 | void *user_data =&rawObjSizeLeft; 130 | 131 | for (mem.bulkAllocType = 0 ; mem.bulkAllocType < RDB_BULK_ALLOC_MAX ; ++mem.bulkAllocType) { 132 | 133 | RdbHandlersStructCallbacks callbacks = { 134 | .handleAuxField = handle_aux_field, 135 | .handleNewKey = handle_new_key, 136 | .handleString = handle_string_value, 137 | .handleListPlain = handle_list_element, 138 | .handleListLP = handle_list_element, 139 | 140 | }; 141 | 142 | RdbParser *parser = RDB_createParserRdb(&mem); 143 | RDB_setLogger(parser, loggerCb); 144 | assert_non_null(RDBX_createReaderFile(parser, DUMP_FOLDER("multiple_lists_strings.rdb"))); 145 | assert_non_null(RDB_createHandlersStruct(parser, &callbacks, user_data, NULL)); 146 | while ((status = RDB_parse(parser)) == RDB_STATUS_WAIT_MORE_DATA); 147 | assert_int_equal( status, RDB_STATUS_OK); 148 | RDB_deleteParser(parser); 149 | } 150 | } 151 | 152 | static void test_data_handlers_callbacks_bulk_ops (void **state) { 153 | UNUSED(state); 154 | RdbStatus status; 155 | size_t rawObjSizeLeft; 156 | void *user_data =&rawObjSizeLeft; 157 | 158 | for (mem.bulkAllocType = 0 ; mem.bulkAllocType < RDB_BULK_ALLOC_MAX ; ++mem.bulkAllocType) { 159 | 160 | RdbHandlersDataCallbacks callbacks = { 161 | .handleAuxField = handle_aux_field, 162 | .handleNewKey = handle_new_key, 163 | .handleStringValue = handle_string_value, 164 | .handleListItem = handle_list_element, 165 | }; 166 | 167 | RdbParser *parser = RDB_createParserRdb(&mem); 168 | RDB_setLogger(parser, loggerCb); 169 | assert_non_null(RDBX_createReaderFile(parser, DUMP_FOLDER("multiple_lists_strings.rdb"))); 170 | assert_non_null(RDB_createHandlersData(parser, &callbacks, user_data, NULL)); 171 | while ((status = RDB_parse(parser)) == RDB_STATUS_WAIT_MORE_DATA); 172 | assert_int_equal( status, RDB_STATUS_OK); 173 | RDB_deleteParser(parser); 174 | } 175 | } 176 | 177 | /*************************** group_rdb_to_json *******************************/ 178 | int group_bulk_ops(void) { 179 | const struct CMUnitTest tests[] = { 180 | cmocka_unit_test(test_raw_handlers_callbacks_bulk_ops), 181 | cmocka_unit_test(test_struct_handlers_callbacks_bulk_ops), 182 | cmocka_unit_test(test_data_handlers_callbacks_bulk_ops), 183 | }; 184 | return cmocka_run_group_tests(tests, NULL, NULL); 185 | } 186 | -------------------------------------------------------------------------------- /test/test_common.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../deps/hiredis/hiredis.h" 9 | #include "../api/librdb-api.h" /* RDB library header */ 10 | #include "../api/librdb-ext-api.h" /* RDB library extension header */ 11 | 12 | #define MAX_SUPPORTED_REDIS_VERSION "7.4" 13 | 14 | #define UNUSED(...) unused( (void *) NULL, __VA_ARGS__); 15 | static inline void unused(void *dummy, ...) { (void)(dummy);} 16 | 17 | #define DUMP_FOLDER(file) "./test/dumps/"file 18 | #define TMP_FOLDER(file) "./test/tmp/"file 19 | 20 | #define STR_AND_SIZE(str) str, (sizeof(str)-1) 21 | 22 | #define ASSERT_TRUE(exp, format, ...) \ 23 | do { \ 24 | if (!(exp)) { \ 25 | fprintf(stderr, "Assertion failed: %s\n", #exp); \ 26 | fprintf(stderr, "Error: " format "\n", __VA_ARGS__); \ 27 | assert_true(0); \ 28 | } \ 29 | } while (0) 30 | 31 | typedef enum MatchType { 32 | M_PREFIX, 33 | M_ENTIRE, 34 | M_SUFFIX, 35 | M_SUBSTR 36 | } MatchType; 37 | 38 | /* system() commands */ 39 | char *runSystemCmd(const char *cmdFormat, ...); 40 | 41 | /* assert */ 42 | void assert_json_equal(const char *f1, const char *f2, int ignoreListOrder); 43 | 44 | /* Test against Redis Server */ 45 | void setRedisInstallFolder(const char *path); 46 | int getRedisPort(void); 47 | void setValgrind(void); 48 | void setupRedisServer(const char *extraArgs); 49 | const char *getTargetRedisVersion(int *major, int *minor); /* call only after setupRedisServer() */ 50 | void teardownRedisServer(void); 51 | void cleanup_json_sign_service(void); 52 | int isSetRedisServer(void); 53 | char *sendRedisCmd(const char *cmd, int expRetType, char *expRsp); 54 | int isSupportRestoreModuleAux(void); 55 | 56 | /* test groups */ 57 | int group_rdb_to_redis(void); 58 | int group_test_rdb_cli(void); 59 | int group_rdb_to_resp(void); 60 | int group_examples(void); 61 | int group_main(void); 62 | int group_rdb_to_json(void); 63 | int group_mem_management(void); 64 | int group_pause(void); 65 | int group_bulk_ops(void); 66 | int group_test_resp_reader(void); 67 | 68 | /* simulate external malloc */ 69 | void *xmalloc(size_t size); 70 | void *xclone(void *str, size_t len); 71 | void xfree(void *ptr); 72 | void *xrealloc(void *ptr, size_t size); 73 | 74 | char *readFile(const char *filename, size_t *len, char *ignoredCh); 75 | void cleanTmpFolder(void); 76 | void setEnvVar(const char *name, const char *val); 77 | char *substring(char *str, size_t len, char *substr); 78 | void assert_file_payload(const char *filename, char *expData, int expLen, MatchType matchType, int expMatch); 79 | 80 | void dummyLogger(RdbLogLevel l, const char *msg); 81 | 82 | int printHexDump(const char *addr, size_t len, char *obuf, int obuflen); 83 | -------------------------------------------------------------------------------- /test/test_malloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "test_common.h" 4 | 5 | enum { 6 | CNT_CLONE_BULK, 7 | CNT_MALLOC_BULK, 8 | CNT_FREE_BULK, 9 | CNT_MALLOC_WRAPPER, 10 | CNT_REALLOC_WRAPPER, 11 | CNT_FREE_WRAPPER, 12 | CNT_MAX 13 | }; 14 | 15 | int counters[CNT_MAX]; 16 | 17 | void *myCloneBulk(void *str, size_t len) {++counters[CNT_CLONE_BULK]; return xclone(str, len); } 18 | void *myMallocBulk(size_t size) { ++counters[CNT_MALLOC_BULK]; return xmalloc(size); } 19 | void myFreeBulk(void *ptr) { ++counters[CNT_FREE_BULK]; xfree(ptr); } 20 | 21 | void *myMalloc (size_t size) { ++counters[CNT_MALLOC_WRAPPER]; return xmalloc(size); } 22 | void *myRealloc (void *ptr, size_t size) { ++counters[CNT_REALLOC_WRAPPER]; return xrealloc(ptr, size); } 23 | void myFree (void *ptr) { ++counters[CNT_FREE_WRAPPER]; xfree(ptr); } 24 | 25 | static void test_extern_alloc(void **state) { 26 | UNUSED(state); 27 | RdbStatus status; 28 | 29 | for (int bulkAllocType = 0 ; bulkAllocType < RDB_BULK_ALLOC_MAX ; ++bulkAllocType) { 30 | memset(counters, 0, sizeof(counters)); 31 | 32 | RdbMemAlloc mem = {myMalloc, myRealloc, myFree, 33 | bulkAllocType, /* << change each iteration */ 34 | { myMallocBulk, myCloneBulk, myFreeBulk } 35 | }; 36 | 37 | RdbParser *parser = RDB_createParserRdb(&mem); 38 | RDB_setLogLevel(parser, RDB_LOG_ERR); 39 | 40 | assert_non_null(RDBX_createReaderFile(parser, DUMP_FOLDER("single_key.rdb"))); 41 | RdbxToJsonConf r2jConf = { 42 | .level = RDB_LEVEL_DATA, 43 | .encoding = RDBX_CONV_JSON_ENC_PLAIN, 44 | .includeAuxField = 1, 45 | .includeFunc = 0, 46 | .includeStreamMeta = 0, 47 | .flatten = 1, 48 | }; 49 | assert_non_null(RDBX_createHandlersToJson(parser, 50 | TMP_FOLDER("single_key.json"), 51 | &r2jConf)); 52 | while ((status = RDB_parse(parser)) == RDB_STATUS_WAIT_MORE_DATA); 53 | assert_int_equal(status, RDB_STATUS_OK); 54 | RDB_deleteParser(parser); 55 | assert_json_equal(TMP_FOLDER("single_key.json"), DUMP_FOLDER("single_key_data.json"), 0); 56 | 57 | switch (bulkAllocType) { 58 | case RDB_BULK_ALLOC_STACK: 59 | assert_int_equal(0, counters[CNT_MALLOC_BULK]); 60 | assert_int_equal(0, counters[CNT_CLONE_BULK]); 61 | break; 62 | case RDB_BULK_ALLOC_HEAP: 63 | assert_int_equal(0, counters[CNT_MALLOC_BULK]); 64 | assert_int_equal(0, counters[CNT_CLONE_BULK]); 65 | break; 66 | case RDB_BULK_ALLOC_EXTERN: 67 | case RDB_BULK_ALLOC_EXTERN_OPT: 68 | /* Exactly 8 pairs of auxiliary fields and 1 pair of key-value should be created 69 | * by provided "external" Bulk allocator. 18 calls in total */ 70 | assert_int_equal(18, counters[CNT_MALLOC_BULK]); 71 | /* Exactly 1 key need to be cloned externally by rdb2json */ 72 | assert_int_equal(1, counters[CNT_CLONE_BULK]); 73 | break; 74 | } 75 | 76 | assert_int_not_equal(0, counters[CNT_MALLOC_WRAPPER]); 77 | assert_int_not_equal(0, counters[CNT_FREE_WRAPPER]); 78 | } 79 | } 80 | 81 | /*************************** group_rdb_to_json *******************************/ 82 | int group_mem_management(void) { 83 | const struct CMUnitTest tests[] = { 84 | cmocka_unit_test(test_extern_alloc), 85 | }; 86 | return cmocka_run_group_tests(tests, NULL, NULL); 87 | } 88 | -------------------------------------------------------------------------------- /test/test_pause.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "test_common.h" 3 | 4 | int aux_fields_counter; 5 | RdbRes handle_pause_aux_field_pause(RdbParser *p, void *userData, RdbBulk auxkey, RdbBulk auxval) { 6 | UNUSED(userData, auxkey, auxval); 7 | ++aux_fields_counter; 8 | RDB_pauseParser(p); 9 | return RDB_OK; 10 | } 11 | 12 | static void test_pause_by_handlers_callback(void **state) { 13 | UNUSED(state); 14 | RdbStatus status; 15 | int pause_counter = 0; 16 | void *user_data = NULL; 17 | aux_fields_counter = 0; 18 | 19 | RdbHandlersRawCallbacks cb = { .handleAuxField = handle_pause_aux_field_pause }; 20 | RdbParser *parser = RDB_createParserRdb(NULL); 21 | RDB_setLogLevel(parser, RDB_LOG_ERR); 22 | assert_non_null(RDBX_createReaderFile(parser, "./test/dumps/quicklist2_v11.rdb")); 23 | assert_non_null(RDB_createHandlersRaw(parser, &cb, user_data, NULL)); 24 | 25 | while ((status = RDB_parse(parser)) != RDB_STATUS_OK) { 26 | if (status == RDB_STATUS_PAUSED) ++pause_counter; 27 | } 28 | assert_int_equal( status, RDB_STATUS_OK); 29 | assert_int_equal( pause_counter, aux_fields_counter); 30 | 31 | RDB_deleteParser(parser); 32 | } 33 | 34 | /*************************** group_rdb_to_json *******************************/ 35 | int group_pause(void) { 36 | const struct CMUnitTest tests[] = { 37 | cmocka_unit_test(test_pause_by_handlers_callback), 38 | }; 39 | return cmocka_run_group_tests(tests, NULL, NULL); 40 | } 41 | -------------------------------------------------------------------------------- /test/test_resp_reader.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "test_common.h" 3 | 4 | #include "../src/ext/readerResp.c" 5 | 6 | #define STR_AND_SIZE(str) str, (sizeof(str)-1) 7 | 8 | static void test_resp_reader_common(RespReaderCtx *ctx, 9 | char *payload, 10 | int payloadSize, 11 | int initCtx, 12 | RespRes expRes, 13 | int expReplies) 14 | { 15 | RespReaderCtx alterCtx; 16 | if (!ctx) ctx = &alterCtx; 17 | if (initCtx) readRespInit(ctx); 18 | 19 | RespRes res = readRespReplies(ctx, payload, payloadSize); 20 | assert_int_equal(res, expRes); 21 | assert_int_equal(ctx->countReplies, expReplies); 22 | } 23 | 24 | static void test_single_status(void **state) { 25 | UNUSED(state); 26 | test_resp_reader_common(NULL, STR_AND_SIZE("+OK\r\n"), 27 | 1, RESP_REPLY_OK, 1); 28 | } 29 | 30 | static void test_empty_array(void **state) { 31 | UNUSED(state); 32 | test_resp_reader_common(NULL, STR_AND_SIZE("*0\r\n"), 33 | 1, RESP_REPLY_OK, 1); 34 | } 35 | 36 | static void test_empty_bulk(void **state) { 37 | UNUSED(state); 38 | test_resp_reader_common(NULL, STR_AND_SIZE("$0\r\n"), 39 | 1, RESP_REPLY_OK, 1); 40 | } 41 | 42 | static void test_single_int(void **state) { 43 | UNUSED(state); 44 | test_resp_reader_common(NULL, STR_AND_SIZE(":1\r\n"), 45 | 1, RESP_REPLY_OK, 1); 46 | } 47 | 48 | static void test_array_3_bulks(void **state) { 49 | UNUSED(state); 50 | test_resp_reader_common(NULL, STR_AND_SIZE("*3\r\n$2\r\n12\r\n$1\r\nA\r\n$3\r\nABC\r\n"), 51 | 1, RESP_REPLY_OK, 1); 52 | } 53 | 54 | void test_array_single_bulk(void **state) { 55 | UNUSED(state); 56 | test_resp_reader_common(NULL, STR_AND_SIZE("*1\r\n$15\r\n1695649446276-0\r\n"), 57 | 1, RESP_REPLY_OK, 1); 58 | } 59 | 60 | static void test_two_statuses_and_partial_reply(void **state) { 61 | UNUSED(state); 62 | test_resp_reader_common(NULL, STR_AND_SIZE("+OK\r\n+OK\r\n+OK\r"), 63 | 1, RESP_REPLY_PARTIAL, 2); 64 | } 65 | 66 | static void test_reply_fragmented(void **state) { 67 | UNUSED(state); 68 | RespReaderCtx ctx; 69 | test_resp_reader_common(&ctx, STR_AND_SIZE("+OK\r"), 70 | 1, RESP_REPLY_PARTIAL, 0); 71 | test_resp_reader_common(&ctx, STR_AND_SIZE("\n"), 72 | 0, RESP_REPLY_OK, 1); 73 | } 74 | 75 | static void test_reply_error(void **state) { 76 | UNUSED(state); 77 | RespReaderCtx ctx; 78 | test_resp_reader_common(&ctx, STR_AND_SIZE("+OK\r\n-ERR This is an error1\r\n+OK\r\n"), 79 | 1, RESP_REPLY_ERR, 1); 80 | assert_string_equal(ctx.errorMsg, "ERR This is an error1"); 81 | 82 | test_resp_reader_common(&ctx, 83 | STR_AND_SIZE("+OK\r\n-ERR This is an error2\r\n-Any data afterward won't get processed"), 84 | 1, RESP_REPLY_ERR, 1); 85 | assert_string_equal(ctx.errorMsg, "ERR This is an error2"); 86 | } 87 | 88 | static void test_single_bulk(void **state) { 89 | UNUSED(state); 90 | char bulk[] = "$5\r\nmylib\r\n"; 91 | RespReaderCtx ctx; 92 | test_resp_reader_common(&ctx, bulk, sizeof(bulk)-1, 1, RESP_REPLY_OK, 1); 93 | } 94 | 95 | static void test_three_bulks(void **state) { 96 | UNUSED(state); 97 | test_resp_reader_common(NULL, STR_AND_SIZE("$5\r\nmylib\r\n$4\r\nm\rib\r\n$8\r\nm123ylib\r\n"), 1, RESP_REPLY_OK, 3); 98 | } 99 | 100 | static void test_reply_error_fragmented(void **state) { 101 | UNUSED(state); 102 | RespReaderCtx ctx; 103 | test_resp_reader_common(&ctx, STR_AND_SIZE("+OK\r\n-ERR This "), 1, RESP_REPLY_PARTIAL, 1); 104 | test_resp_reader_common(&ctx, STR_AND_SIZE("is an "), 0, RESP_REPLY_PARTIAL, 1); 105 | test_resp_reader_common(&ctx, STR_AND_SIZE("error message\r"), 0, RESP_REPLY_PARTIAL, 1); 106 | test_resp_reader_common(&ctx, STR_AND_SIZE("\n"), 0, RESP_REPLY_ERR, 1); 107 | assert_string_equal(ctx.errorMsg, "ERR This is an error message"); 108 | } 109 | 110 | 111 | static void test_reply_long_err_trimmed_by_report(void **state) { 112 | UNUSED(state); 113 | RespReaderCtx ctx; 114 | int errMsgLen = MAX_RESP_REPLY_ERR_MSG + 7; /* overflow */ 115 | char errMsg[MAX_RESP_REPLY_ERR_MSG + 7]; 116 | const char errorChunk[] = "0123456789ABCDEF"; 117 | 118 | /* build error message */ 119 | for (int i = 0 ; i < errMsgLen ; ++i) 120 | errMsg[i] = errorChunk[i%16]; 121 | 122 | test_resp_reader_common(&ctx, STR_AND_SIZE("+OK\r\n-"), 1, RESP_REPLY_PARTIAL, 1); 123 | test_resp_reader_common(&ctx, errMsg, errMsgLen, 0, RESP_REPLY_PARTIAL, 1); 124 | test_resp_reader_common(&ctx, STR_AND_SIZE("\r\n-"), 0, RESP_REPLY_ERR, 1); 125 | errMsg[MAX_RESP_REPLY_ERR_MSG-1] = '\0'; /* reported error is trimmed */ 126 | assert_string_equal(ctx.errorMsg, errMsg); 127 | 128 | } 129 | 130 | static void test_mixture_and_fragmented(void **state) { 131 | UNUSED(state); 132 | RespRes res; 133 | int expReplies = 5; 134 | char bulk[] = "*3\r\n$2\r\n12\r\n$1\r\nA\r\n$3\r\nABC\r\n" 135 | "+OK\r\n$5\r\nmylib\r\n+OK\r\n+OK\r\n"; 136 | RespReaderCtx ctx; 137 | 138 | /* all responses in one bulk */ 139 | test_resp_reader_common(&ctx, STR_AND_SIZE(bulk), 1, RESP_REPLY_OK, expReplies); 140 | 141 | /* split stream to two bulks */ 142 | for (size_t firstFragLen = 1 ; firstFragLen < sizeof(bulk) - 1 ; ++firstFragLen) { 143 | readRespInit(&ctx); 144 | res = readRespReplies(&ctx, bulk, firstFragLen); 145 | assert_int_not_equal(res, RESP_REPLY_ERR); 146 | res = readRespReplies(&ctx, bulk + firstFragLen, (sizeof(bulk) - 1) - firstFragLen); 147 | assert_int_equal(res, RESP_REPLY_OK); 148 | assert_int_equal(ctx.countReplies, expReplies); 149 | } 150 | } 151 | 152 | static void test_reply_array_misc_data_types (void **state) { 153 | UNUSED(state); 154 | RespReaderCtx ctx; 155 | test_resp_reader_common(&ctx, STR_AND_SIZE("*6\r\n(34928903284"), 156 | 1, RESP_REPLY_PARTIAL, 0); 157 | test_resp_reader_common(&ctx, STR_AND_SIZE("0923850932485094385094"), 158 | 0, RESP_REPLY_PARTIAL, 0); 159 | test_resp_reader_common(&ctx, STR_AND_SIZE("3825024385\r\n#t\r"), 160 | 0, RESP_REPLY_PARTIAL, 0); 161 | test_resp_reader_common(&ctx, STR_AND_SIZE("\n_\r\n,1.23\r\n:1\r\n:1\r\n"), 162 | 0, RESP_REPLY_OK, 1); 163 | } 164 | 165 | /* Masked error should be counted as valid response */ 166 | const char *ignoreThisRespErr = "ERR Oopsie Daisy!"; 167 | int onRespErrorCb(void *callerCtx, char *msg) { 168 | UNUSED(callerCtx); 169 | return (strcmp(msg, ignoreThisRespErr)==0) ? 0 /*mask*/ : 1 /*propagate*/; 170 | } 171 | static void test_masked_errors (void **state) { 172 | UNUSED(state); 173 | /* Ignore "ERR Oopsie Daisy" */ 174 | char *payload = "$5\r\nmylib\r\n$4\r\nm\rib\r\n-ERR Oopsie Daisy!\r\n$8\r\n" 175 | "m123ylib\r\n-ERR reported error\r\n-ERR never reached\r\n"; 176 | RespReaderCtx ctx; 177 | readRespInit(&ctx); 178 | setErrorCb(&ctx, NULL, onRespErrorCb); 179 | RespRes res = readRespReplies(&ctx, payload, strlen(payload)); 180 | assert_int_equal(res, RESP_REPLY_ERR); 181 | assert_int_equal(ctx.countReplies, 4); 182 | assert_string_equal(ctx.errorMsg, "ERR reported error"); 183 | } 184 | 185 | /*************************** group_test_resp_reader *******************************/ 186 | int group_test_resp_reader(void) { 187 | const struct CMUnitTest tests[] = { 188 | cmocka_unit_test(test_single_status), 189 | cmocka_unit_test(test_empty_array), 190 | cmocka_unit_test(test_empty_bulk), 191 | cmocka_unit_test(test_single_int), 192 | cmocka_unit_test(test_array_single_bulk), 193 | cmocka_unit_test(test_array_3_bulks), 194 | cmocka_unit_test(test_two_statuses_and_partial_reply), 195 | cmocka_unit_test(test_reply_fragmented), 196 | cmocka_unit_test(test_reply_error), 197 | cmocka_unit_test(test_reply_long_err_trimmed_by_report), 198 | cmocka_unit_test(test_reply_error_fragmented), 199 | cmocka_unit_test(test_single_bulk), 200 | cmocka_unit_test(test_three_bulks), 201 | cmocka_unit_test(test_mixture_and_fragmented), 202 | cmocka_unit_test(test_reply_array_misc_data_types), 203 | cmocka_unit_test(test_masked_errors), 204 | }; 205 | 206 | return cmocka_run_group_tests(tests, NULL, NULL); 207 | } 208 | -------------------------------------------------------------------------------- /test/tmp/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redis/librdb/b0e6b98f5da7864c2669cbffa747ec652b57a155/test/tmp/.gitkeep --------------------------------------------------------------------------------