diff --git a/libvalkey/CMakeLists.txt b/libvalkey/CMakeLists.txt index d613f818..9cbe2b55 100644 --- a/libvalkey/CMakeLists.txt +++ b/libvalkey/CMakeLists.txt @@ -2,151 +2,151 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.0.0) MACRO(getVersionBit name) SET(VERSION_REGEX "^#define ${name} (.+)$") - FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/hiredis.h" + FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/valkey.h" VERSION_BIT REGEX ${VERSION_REGEX}) STRING(REGEX REPLACE ${VERSION_REGEX} "\\1" ${name} "${VERSION_BIT}") ENDMACRO(getVersionBit) -getVersionBit(HIREDIS_MAJOR) -getVersionBit(HIREDIS_MINOR) -getVersionBit(HIREDIS_PATCH) -getVersionBit(HIREDIS_SONAME) -SET(VERSION "${HIREDIS_MAJOR}.${HIREDIS_MINOR}.${HIREDIS_PATCH}") +getVersionBit(LIBVALKEY_MAJOR) +getVersionBit(LIBVALKEY_MINOR) +getVersionBit(LIBVALKEY_PATCH) +getVersionBit(LIBVALKEY_SONAME) +SET(VERSION "${LIBVALKEY_MAJOR}.${LIBVALKEY_MINOR}.${LIBVALKEY_PATCH}") MESSAGE("Detected version: ${VERSION}") -PROJECT(hiredis LANGUAGES "C" VERSION "${VERSION}") +PROJECT(valkey LANGUAGES "C" VERSION "${VERSION}") INCLUDE(GNUInstallDirs) OPTION(BUILD_SHARED_LIBS "Build shared libraries" ON) -OPTION(ENABLE_SSL "Build hiredis_ssl for SSL support" OFF) +OPTION(ENABLE_SSL "Build valkey_ssl for SSL support" OFF) OPTION(DISABLE_TESTS "If tests should be compiled or not" OFF) OPTION(ENABLE_SSL_TESTS "Should we test SSL connections" OFF) -OPTION(ENABLE_EXAMPLES "Enable building hiredis examples" OFF) +OPTION(ENABLE_EXAMPLES "Enable building valkey examples" OFF) OPTION(ENABLE_ASYNC_TESTS "Should we run all asynchronous API tests" OFF) # Historically, the NuGet file was always install; default # to ON for those who rely on that historical behaviour. OPTION(ENABLE_NUGET "Install NuGET packaging details" ON) -# Hiredis requires C99 +# valkey requires C99 SET(CMAKE_C_STANDARD 99) SET(CMAKE_DEBUG_POSTFIX d) -SET(hiredis_sources +SET(valkey_sources alloc.c async.c - hiredis.c + valkey.c net.c read.c sds.c sockcompat.c) -SET(hiredis_sources ${hiredis_sources}) +SET(valkey_sources ${valkey_sources}) IF(WIN32) ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -DWIN32_LEAN_AND_MEAN) ENDIF() -ADD_LIBRARY(hiredis ${hiredis_sources}) -ADD_LIBRARY(hiredis::hiredis ALIAS hiredis) -set(hiredis_export_name hiredis CACHE STRING "Name of the exported target") -set_target_properties(hiredis PROPERTIES EXPORT_NAME ${hiredis_export_name}) +ADD_LIBRARY(valkey ${valkey_sources}) +ADD_LIBRARY(valkey::valkey ALIAS valkey) +set(valkey_export_name valkey CACHE STRING "Name of the exported target") +set_target_properties(valkey PROPERTIES EXPORT_NAME ${valkey_export_name}) -SET_TARGET_PROPERTIES(hiredis +SET_TARGET_PROPERTIES(valkey PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE - VERSION "${HIREDIS_SONAME}") + VERSION "${LIBVALKEY_SONAME}") IF(MSVC) - SET_TARGET_PROPERTIES(hiredis + SET_TARGET_PROPERTIES(valkey PROPERTIES COMPILE_FLAGS /Z7) ENDIF() IF(WIN32) - TARGET_LINK_LIBRARIES(hiredis PUBLIC ws2_32 crypt32) + TARGET_LINK_LIBRARIES(valkey PUBLIC ws2_32 crypt32) ELSEIF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") - TARGET_LINK_LIBRARIES(hiredis PUBLIC m) + TARGET_LINK_LIBRARIES(valkey PUBLIC m) ELSEIF(CMAKE_SYSTEM_NAME MATCHES "SunOS") - TARGET_LINK_LIBRARIES(hiredis PUBLIC socket) + TARGET_LINK_LIBRARIES(valkey PUBLIC socket) ENDIF() -TARGET_INCLUDE_DIRECTORIES(hiredis PUBLIC $ $) +TARGET_INCLUDE_DIRECTORIES(valkey PUBLIC $ $) -CONFIGURE_FILE(hiredis.pc.in hiredis.pc @ONLY) +CONFIGURE_FILE(valkey.pc.in valkey.pc @ONLY) -set(CPACK_PACKAGE_VENDOR "Redis") +set(CPACK_PACKAGE_VENDOR "Valkey") set(CPACK_PACKAGE_DESCRIPTION "\ -Hiredis is a minimalistic C client library for the Redis database. +Libvalkey is a minimalistic C client library for the Valkey, KeyDB, and Redis databases It is minimalistic because it just adds minimal support for the protocol, \ but at the same time it uses a high level printf-alike API in order to make \ it much higher level than otherwise suggested by its minimal code base and the \ -lack of explicit bindings for every Redis command. +lack of explicit bindings for every server command. Apart from supporting sending commands and receiving replies, it comes with a \ reply parser that is decoupled from the I/O layer. It is a stream parser designed \ for easy reusability, which can for instance be used in higher level language bindings \ for efficient reply parsing. -Hiredis only supports the binary-safe Redis protocol, so you can use it with any Redis \ -version >= 1.2.0. +valkey only supports the binary-safe RESP protocol, so you can use it with any Redis \ +compatible server >= 1.2.0. The library comes with multiple APIs. There is the synchronous API, the asynchronous API \ and the reply parsing API.") -set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/redis/hiredis") +set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/valkey-io/libvalkey") set(CPACK_PACKAGE_CONTACT "michael dot grunder at gmail dot com") set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) set(CPACK_RPM_PACKAGE_AUTOREQPROV ON) include(CPack) -INSTALL(TARGETS hiredis - EXPORT hiredis-targets +INSTALL(TARGETS valkey + EXPORT valkey-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) if (MSVC AND BUILD_SHARED_LIBS) - INSTALL(FILES $ + INSTALL(FILES $ DESTINATION ${CMAKE_INSTALL_BINDIR} CONFIGURATIONS Debug RelWithDebInfo) endif() if (ENABLE_NUGET) # For NuGet packages - INSTALL(FILES hiredis.targets + INSTALL(FILES valkey.targets DESTINATION build/native) endif() -INSTALL(FILES hiredis.h read.h sds.h async.h alloc.h sockcompat.h - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis) +INSTALL(FILES valkey.h read.h sds.h async.h alloc.h sockcompat.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/valkey) INSTALL(DIRECTORY adapters - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis) + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/valkey) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis.pc +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/valkey.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) -export(EXPORT hiredis-targets - FILE "${CMAKE_CURRENT_BINARY_DIR}/hiredis-targets.cmake" - NAMESPACE hiredis::) +export(EXPORT valkey-targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/valkey-targets.cmake" + NAMESPACE valkey::) if(WIN32) - SET(CMAKE_CONF_INSTALL_DIR share/hiredis) + SET(CMAKE_CONF_INSTALL_DIR share/valkey) else() - SET(CMAKE_CONF_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/hiredis) + SET(CMAKE_CONF_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/valkey) endif() SET(INCLUDE_INSTALL_DIR include) include(CMakePackageConfigHelpers) -write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/hiredis-config-version.cmake" +write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/valkey-config-version.cmake" COMPATIBILITY SameMajorVersion) -configure_package_config_file(hiredis-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/hiredis-config.cmake +configure_package_config_file(valkey-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/valkey-config.cmake INSTALL_DESTINATION ${CMAKE_CONF_INSTALL_DIR} PATH_VARS INCLUDE_INSTALL_DIR) -INSTALL(EXPORT hiredis-targets - FILE hiredis-targets.cmake - NAMESPACE hiredis:: +INSTALL(EXPORT valkey-targets + FILE valkey-targets.cmake + NAMESPACE valkey:: DESTINATION ${CMAKE_CONF_INSTALL_DIR}) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis-config.cmake - ${CMAKE_CURRENT_BINARY_DIR}/hiredis-config-version.cmake +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/valkey-config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/valkey-config-version.cmake DESTINATION ${CMAKE_CONF_INSTALL_DIR}) @@ -157,82 +157,82 @@ IF(ENABLE_SSL) ENDIF() ENDIF() FIND_PACKAGE(OpenSSL REQUIRED) - SET(hiredis_ssl_sources + SET(valkey_ssl_sources ssl.c) - ADD_LIBRARY(hiredis_ssl ${hiredis_ssl_sources}) - ADD_LIBRARY(hiredis::hiredis_ssl ALIAS hiredis_ssl) + ADD_LIBRARY(valkey_ssl ${valkey_ssl_sources}) + ADD_LIBRARY(valkey::valkey_ssl ALIAS valkey_ssl) IF (APPLE AND BUILD_SHARED_LIBS) - SET_PROPERTY(TARGET hiredis_ssl PROPERTY LINK_FLAGS "-Wl,-undefined -Wl,dynamic_lookup") + SET_PROPERTY(TARGET valkey_ssl PROPERTY LINK_FLAGS "-Wl,-undefined -Wl,dynamic_lookup") ENDIF() - SET_TARGET_PROPERTIES(hiredis_ssl + SET_TARGET_PROPERTIES(valkey_ssl PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE - VERSION "${HIREDIS_SONAME}") + VERSION "${LIBVALKEY_SONAME}") IF(MSVC) - SET_TARGET_PROPERTIES(hiredis_ssl + SET_TARGET_PROPERTIES(valkey_ssl PROPERTIES COMPILE_FLAGS /Z7) ENDIF() - TARGET_LINK_LIBRARIES(hiredis_ssl PRIVATE OpenSSL::SSL) + TARGET_LINK_LIBRARIES(valkey_ssl PRIVATE OpenSSL::SSL) IF(WIN32) - TARGET_LINK_LIBRARIES(hiredis_ssl PRIVATE hiredis) + TARGET_LINK_LIBRARIES(valkey_ssl PRIVATE valkey) ENDIF() - CONFIGURE_FILE(hiredis_ssl.pc.in hiredis_ssl.pc @ONLY) + CONFIGURE_FILE(valkey_ssl.pc.in valkey_ssl.pc @ONLY) - INSTALL(TARGETS hiredis_ssl - EXPORT hiredis_ssl-targets + INSTALL(TARGETS valkey_ssl + EXPORT valkey_ssl-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) if (MSVC AND BUILD_SHARED_LIBS) - INSTALL(FILES $ + INSTALL(FILES $ DESTINATION ${CMAKE_INSTALL_BINDIR} CONFIGURATIONS Debug RelWithDebInfo) endif() - INSTALL(FILES hiredis_ssl.h - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis) + INSTALL(FILES valkey_ssl.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/valkey) - INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis_ssl.pc + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/valkey_ssl.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) - export(EXPORT hiredis_ssl-targets - FILE "${CMAKE_CURRENT_BINARY_DIR}/hiredis_ssl-targets.cmake" - NAMESPACE hiredis::) + export(EXPORT valkey_ssl-targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/valkey_ssl-targets.cmake" + NAMESPACE valkey::) if(WIN32) - SET(CMAKE_CONF_INSTALL_DIR share/hiredis_ssl) + SET(CMAKE_CONF_INSTALL_DIR share/valkey_ssl) else() - SET(CMAKE_CONF_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/hiredis_ssl) + SET(CMAKE_CONF_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/valkey_ssl) endif() - configure_package_config_file(hiredis_ssl-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/hiredis_ssl-config.cmake + configure_package_config_file(valkey_ssl-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/valkey_ssl-config.cmake INSTALL_DESTINATION ${CMAKE_CONF_INSTALL_DIR} PATH_VARS INCLUDE_INSTALL_DIR) - INSTALL(EXPORT hiredis_ssl-targets - FILE hiredis_ssl-targets.cmake - NAMESPACE hiredis:: + INSTALL(EXPORT valkey_ssl-targets + FILE valkey_ssl-targets.cmake + NAMESPACE valkey:: DESTINATION ${CMAKE_CONF_INSTALL_DIR}) - INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis_ssl-config.cmake + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/valkey_ssl-config.cmake DESTINATION ${CMAKE_CONF_INSTALL_DIR}) ENDIF() IF(NOT DISABLE_TESTS) ENABLE_TESTING() - ADD_EXECUTABLE(hiredis-test test.c) - TARGET_LINK_LIBRARIES(hiredis-test hiredis) + ADD_EXECUTABLE(libvalkey-test test.c) + TARGET_LINK_LIBRARIES(libvalkey-test valkey) IF(ENABLE_SSL_TESTS) - ADD_DEFINITIONS(-DHIREDIS_TEST_SSL=1) - TARGET_LINK_LIBRARIES(hiredis-test hiredis_ssl) + ADD_DEFINITIONS(-DVALKEY_TEST_SSL=1) + TARGET_LINK_LIBRARIES(libvalkey-test valkey_ssl) ENDIF() IF(ENABLE_ASYNC_TESTS) - ADD_DEFINITIONS(-DHIREDIS_TEST_ASYNC=1) - TARGET_LINK_LIBRARIES(hiredis-test event) + ADD_DEFINITIONS(-DVALKEY_TEST_ASYNC=1) + TARGET_LINK_LIBRARIES(libvalkey-test event) ENDIF() - ADD_TEST(NAME hiredis-test + ADD_TEST(NAME libvalkey-test COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/test.sh) ENDIF() diff --git a/libvalkey/Makefile b/libvalkey/Makefile index 56e3d59b..af861c0f 100644 --- a/libvalkey/Makefile +++ b/libvalkey/Makefile @@ -1,39 +1,39 @@ -# Hiredis Makefile +# Libvalkey Makefile # Copyright (C) 2010-2011 Salvatore Sanfilippo # Copyright (C) 2010-2011 Pieter Noordhuis # This file is released under the BSD license, see the COPYING file -OBJ=alloc.o net.o hiredis.o sds.o async.o read.o sockcompat.o -EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib hiredis-example-push hiredis-example-poll -TESTS=hiredis-test -LIBNAME=libhiredis -PKGCONFNAME=hiredis.pc +OBJ=alloc.o net.o valkey.o sds.o async.o read.o sockcompat.o +EXAMPLES=valkey-example valkey-example-libevent valkey-example-libev valkey-example-glib valkey-example-push valkey-example-poll +TESTS=libvalkey-test +LIBNAME=libvalkey +PKGCONFNAME=valkey.pc -HIREDIS_MAJOR=$(shell grep HIREDIS_MAJOR hiredis.h | awk '{print $$3}') -HIREDIS_MINOR=$(shell grep HIREDIS_MINOR hiredis.h | awk '{print $$3}') -HIREDIS_PATCH=$(shell grep HIREDIS_PATCH hiredis.h | awk '{print $$3}') -HIREDIS_SONAME=$(shell grep HIREDIS_SONAME hiredis.h | awk '{print $$3}') +LIBVALKEY_MAJOR=$(shell grep LIBVALKEY_MAJOR valkey.h | awk '{print $$3}') +LIBVALKEY_MINOR=$(shell grep LIBVALKEY_MINOR valkey.h | awk '{print $$3}') +LIBVALKEY_PATCH=$(shell grep LIBVALKEY_PATCH valkey.h | awk '{print $$3}') +LIBVALKEY_SONAME=$(shell grep LIBVALKEY_SONAME valkey.h | awk '{print $$3}') # Installation related variables and target PREFIX?=/usr/local -INCLUDE_PATH?=include/hiredis +INCLUDE_PATH?=include/valkey LIBRARY_PATH?=lib PKGCONF_PATH?=pkgconfig INSTALL_INCLUDE_PATH= $(DESTDIR)$(PREFIX)/$(INCLUDE_PATH) INSTALL_LIBRARY_PATH= $(DESTDIR)$(PREFIX)/$(LIBRARY_PATH) INSTALL_PKGCONF_PATH= $(INSTALL_LIBRARY_PATH)/$(PKGCONF_PATH) -# redis-server configuration used for testing -REDIS_PORT=56379 -REDIS_SERVER=redis-server -define REDIS_TEST_CONFIG +# valkey-server configuration used for testing +VALKEY_PORT=56379 +VALKEY_SERVER=valkey-server +define VALKEY_TEST_CONFIG daemonize yes - pidfile /tmp/hiredis-test-redis.pid - port $(REDIS_PORT) + pidfile /tmp/valkey-test-valkey.pid + port $(VALKEY_PORT) bind 127.0.0.1 - unixsocket /tmp/hiredis-test-redis.sock + unixsocket /tmp/valkey-test-valkey.sock endef -export REDIS_TEST_CONFIG +export VALKEY_TEST_CONFIG # Fallback to gcc when $CC is not in $PATH. CC:=$(shell sh -c 'type $${CC%% *} >/dev/null 2>/dev/null && echo $(CC) || echo gcc') @@ -50,8 +50,8 @@ REAL_LDFLAGS=$(LDFLAGS) DYLIBSUFFIX=so STLIBSUFFIX=a -DYLIB_MINOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_SONAME) -DYLIB_MAJOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_MAJOR) +DYLIB_MINOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(LIBVALKEY_SONAME) +DYLIB_MAJOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(LIBVALKEY_MAJOR) DYLIBNAME=$(LIBNAME).$(DYLIBSUFFIX) DYLIB_MAKE_CMD=$(CC) $(PLATFORM_FLAGS) -shared -Wl,-soname,$(DYLIB_MINOR_NAME) @@ -60,11 +60,11 @@ STLIB_MAKE_CMD=$(AR) rcs #################### SSL variables start #################### SSL_OBJ=ssl.o -SSL_LIBNAME=libhiredis_ssl -SSL_PKGCONFNAME=hiredis_ssl.pc +SSL_LIBNAME=libvalkey_ssl +SSL_PKGCONFNAME=valkey_ssl.pc SSL_INSTALLNAME=install-ssl -SSL_DYLIB_MINOR_NAME=$(SSL_LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_SONAME) -SSL_DYLIB_MAJOR_NAME=$(SSL_LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_MAJOR) +SSL_DYLIB_MINOR_NAME=$(SSL_LIBNAME).$(DYLIBSUFFIX).$(LIBVALKEY_SONAME) +SSL_DYLIB_MAJOR_NAME=$(SSL_LIBNAME).$(DYLIBSUFFIX).$(LIBVALKEY_MAJOR) SSL_DYLIBNAME=$(SSL_LIBNAME).$(DYLIBSUFFIX) SSL_STLIBNAME=$(SSL_LIBNAME).$(STLIBSUFFIX) SSL_DYLIB_MAKE_CMD=$(CC) $(PLATFORM_FLAGS) -shared -Wl,-soname,$(SSL_DYLIB_MINOR_NAME) @@ -72,8 +72,8 @@ SSL_DYLIB_MAKE_CMD=$(CC) $(PLATFORM_FLAGS) -shared -Wl,-soname,$(SSL_DYLIB_MINOR USE_SSL?=0 ifeq ($(USE_SSL),1) # This is required for test.c only - CFLAGS+=-DHIREDIS_TEST_SSL - EXAMPLES+=hiredis-example-ssl hiredis-example-libevent-ssl + CFLAGS+=-DVALKEY_TEST_SSL + EXAMPLES+=valkey-example-ssl valkey-example-libevent-ssl SSL_STLIB=$(SSL_STLIBNAME) SSL_DYLIB=$(SSL_DYLIBNAME) SSL_PKGCONF=$(SSL_PKGCONFNAME) @@ -92,7 +92,7 @@ uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') # This is required for test.c only ifeq ($(TEST_ASYNC),1) - export CFLAGS+=-DHIREDIS_TEST_ASYNC + export CFLAGS+=-DVALKEY_TEST_ASYNC endif ifeq ($(USE_SSL),1) @@ -140,13 +140,13 @@ ifeq ($(uname_S),SunOS) endif ifeq ($(uname_S),Darwin) DYLIBSUFFIX=dylib - DYLIB_MINOR_NAME=$(LIBNAME).$(HIREDIS_SONAME).$(DYLIBSUFFIX) + DYLIB_MINOR_NAME=$(LIBNAME).$(LIBVALKEY_SONAME).$(DYLIBSUFFIX) DYLIB_MAKE_CMD=$(CC) -dynamiclib -Wl,-install_name,$(PREFIX)/$(LIBRARY_PATH)/$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS) SSL_DYLIB_MAKE_CMD=$(CC) -dynamiclib -Wl,-install_name,$(PREFIX)/$(LIBRARY_PATH)/$(SSL_DYLIB_MINOR_NAME) -o $(SSL_DYLIBNAME) $(LDFLAGS) $(SSL_LDFLAGS) DYLIB_PLUGIN=-Wl,-undefined -Wl,dynamic_lookup endif -all: dynamic static hiredis-test pkgconfig +all: dynamic static libvalkey-test pkgconfig dynamic: $(DYLIBNAME) $(SSL_DYLIB) @@ -156,14 +156,14 @@ pkgconfig: $(PKGCONFNAME) $(SSL_PKGCONF) # Deps (use make dep to generate this) alloc.o: alloc.c fmacros.h alloc.h -async.o: async.c fmacros.h alloc.h async.h hiredis.h read.h sds.h net.h dict.c dict.h win32.h async_private.h +async.o: async.c fmacros.h alloc.h async.h valkey.h read.h sds.h net.h dict.c dict.h win32.h async_private.h dict.o: dict.c fmacros.h alloc.h dict.h -hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h alloc.h net.h async.h win32.h -net.o: net.c fmacros.h net.h hiredis.h read.h sds.h alloc.h sockcompat.h win32.h +valkey.o: valkey.c fmacros.h valkey.h read.h sds.h alloc.h net.h async.h win32.h +net.o: net.c fmacros.h net.h valkey.h read.h sds.h alloc.h sockcompat.h win32.h read.o: read.c fmacros.h alloc.h read.h sds.h win32.h sds.o: sds.c sds.h sdsalloc.h alloc.h sockcompat.o: sockcompat.c sockcompat.h -test.o: test.c fmacros.h hiredis.h read.h sds.h alloc.h net.h sockcompat.h win32.h +test.o: test.c fmacros.h valkey.h read.h sds.h alloc.h net.h sockcompat.h win32.h $(DYLIBNAME): $(OBJ) $(DYLIB_MAKE_CMD) -o $(DYLIBNAME) $(OBJ) $(REAL_LDFLAGS) @@ -178,62 +178,62 @@ $(SSL_DYLIBNAME): $(SSL_OBJ) $(SSL_STLIBNAME): $(SSL_OBJ) $(STLIB_MAKE_CMD) $(SSL_STLIBNAME) $(SSL_OBJ) -$(SSL_OBJ): ssl.c hiredis.h read.h sds.h alloc.h async.h win32.h async_private.h +$(SSL_OBJ): ssl.c valkey.h read.h sds.h alloc.h async.h win32.h async_private.h #################### SSL building rules end #################### # Binaries: -hiredis-example-libevent: examples/example-libevent.c adapters/libevent.h $(STLIBNAME) +valkey-example-libevent: examples/example-libevent.c adapters/libevent.h $(STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -levent $(STLIBNAME) $(REAL_LDFLAGS) -hiredis-example-libevent-ssl: examples/example-libevent-ssl.c adapters/libevent.h $(STLIBNAME) $(SSL_STLIBNAME) +valkey-example-libevent-ssl: examples/example-libevent-ssl.c adapters/libevent.h $(STLIBNAME) $(SSL_STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -levent $(STLIBNAME) $(SSL_STLIBNAME) $(REAL_LDFLAGS) $(SSL_LDFLAGS) -hiredis-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME) +valkey-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -lev $(STLIBNAME) $(REAL_LDFLAGS) -hiredis-example-libhv: examples/example-libhv.c adapters/libhv.h $(STLIBNAME) +valkey-example-libhv: examples/example-libhv.c adapters/libhv.h $(STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -lhv $(STLIBNAME) $(REAL_LDFLAGS) -hiredis-example-glib: examples/example-glib.c adapters/glib.h $(STLIBNAME) +valkey-example-glib: examples/example-glib.c adapters/glib.h $(STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(shell pkg-config --cflags --libs glib-2.0) $(STLIBNAME) $(REAL_LDFLAGS) -hiredis-example-ivykis: examples/example-ivykis.c adapters/ivykis.h $(STLIBNAME) +valkey-example-ivykis: examples/example-ivykis.c adapters/ivykis.h $(STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -livykis $(STLIBNAME) $(REAL_LDFLAGS) -hiredis-example-macosx: examples/example-macosx.c adapters/macosx.h $(STLIBNAME) +valkey-example-macosx: examples/example-macosx.c adapters/macosx.h $(STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -framework CoreFoundation $(STLIBNAME) $(REAL_LDFLAGS) -hiredis-example-ssl: examples/example-ssl.c $(STLIBNAME) $(SSL_STLIBNAME) +valkey-example-ssl: examples/example-ssl.c $(STLIBNAME) $(SSL_STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(SSL_STLIBNAME) $(REAL_LDFLAGS) $(SSL_LDFLAGS) -hiredis-example-poll: examples/example-poll.c adapters/poll.h $(STLIBNAME) +valkey-example-poll: examples/example-poll.c adapters/poll.h $(STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(REAL_LDFLAGS) ifndef AE_DIR -hiredis-example-ae: - @echo "Please specify AE_DIR (e.g. /src)" +valkey-example-ae: + @echo "Please specify AE_DIR (e.g. /src)" @false else -hiredis-example-ae: examples/example-ae.c adapters/ae.h $(STLIBNAME) +valkey-example-ae: examples/example-ae.c adapters/ae.h $(STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(AE_DIR) $< $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o $(AE_DIR)/../deps/jemalloc/lib/libjemalloc.a -pthread $(STLIBNAME) endif ifndef LIBUV_DIR # dynamic link libuv.so -hiredis-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME) +valkey-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) -I. -I$(LIBUV_DIR)/include $< -luv -lpthread -lrt $(STLIBNAME) $(REAL_LDFLAGS) else # use user provided static lib -hiredis-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME) +valkey-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) -I. -I$(LIBUV_DIR)/include $< $(LIBUV_DIR)/.libs/libuv.a -lpthread -lrt $(STLIBNAME) $(REAL_LDFLAGS) endif ifeq ($(and $(QT_MOC),$(QT_INCLUDE_DIR),$(QT_LIBRARY_DIR)),) -hiredis-example-qt: +valkey-example-qt: @echo "Please specify QT_MOC, QT_INCLUDE_DIR AND QT_LIBRARY_DIR" @false else -hiredis-example-qt: examples/example-qt.cpp adapters/qt.h $(STLIBNAME) +valkey-example-qt: examples/example-qt.cpp adapters/qt.h $(STLIBNAME) $(QT_MOC) adapters/qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \ $(CXX) -x c++ -o qt-adapter-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore $(QT_MOC) examples/example-qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \ @@ -241,10 +241,10 @@ hiredis-example-qt: examples/example-qt.cpp adapters/qt.h $(STLIBNAME) $(CXX) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore -L$(QT_LIBRARY_DIR) qt-adapter-moc.o qt-example-moc.o $< -pthread $(STLIBNAME) -lQtCore endif -hiredis-example: examples/example.c $(STLIBNAME) +valkey-example: examples/example.c $(STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(REAL_LDFLAGS) -hiredis-example-push: examples/example-push.c $(STLIBNAME) +valkey-example-push: examples/example-push.c $(STLIBNAME) $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(REAL_LDFLAGS) examples: $(EXAMPLES) @@ -258,30 +258,30 @@ ifeq ($(TEST_ASYNC),1) TEST_LDFLAGS += -levent endif -hiredis-test: test.o $(TEST_LIBS) +libvalkey-test: test.o $(TEST_LIBS) $(CC) -o $@ $(REAL_CFLAGS) -I. $^ $(REAL_LDFLAGS) $(TEST_LDFLAGS) -hiredis-%: %.o $(STLIBNAME) +valkey-%: %.o $(STLIBNAME) $(CC) $(REAL_CFLAGS) -o $@ $< $(TEST_LIBS) $(REAL_LDFLAGS) -test: hiredis-test - ./hiredis-test +test: libvalkey-test + ./libvalkey-test -check: hiredis-test +check: libvalkey-test TEST_SSL=$(USE_SSL) ./test.sh .c.o: $(CC) -std=c99 -c $(REAL_CFLAGS) $< clean: - rm -rf $(DYLIBNAME) $(STLIBNAME) $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(TESTS) $(PKGCONFNAME) examples/hiredis-example* *.o *.gcda *.gcno *.gcov + rm -rf $(DYLIBNAME) $(STLIBNAME) $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(TESTS) $(PKGCONFNAME) examples/valkey-example* *.o *.gcda *.gcno *.gcov dep: $(CC) $(CPPFLAGS) $(CFLAGS) -MM *.c INSTALL?= cp -pPR -$(PKGCONFNAME): hiredis.h +$(PKGCONFNAME): valkey.h @echo "Generating $@ for pkgconfig..." @echo prefix=$(PREFIX) > $@ @echo exec_prefix=\$${prefix} >> $@ @@ -289,13 +289,13 @@ $(PKGCONFNAME): hiredis.h @echo includedir=$(PREFIX)/include >> $@ @echo pkgincludedir=$(PREFIX)/$(INCLUDE_PATH) >> $@ @echo >> $@ - @echo Name: hiredis >> $@ - @echo Description: Minimalistic C client library for Redis. >> $@ - @echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@ - @echo Libs: -L\$${libdir} -lhiredis >> $@ + @echo Name: valkey >> $@ + @echo Description: C client library for Valkey. >> $@ + @echo Version: $(LIBVALKEY_MAJOR).$(LIBVALKEY_MINOR).$(LIBVALKEY_PATCH) >> $@ + @echo Libs: -L\$${libdir} -lvalkey >> $@ @echo Cflags: -I\$${pkgincludedir} -I\$${includedir} -D_FILE_OFFSET_BITS=64 >> $@ -$(SSL_PKGCONFNAME): hiredis_ssl.h +$(SSL_PKGCONFNAME): valkey_ssl.h @echo "Generating $@ for pkgconfig..." @echo prefix=$(PREFIX) > $@ @echo exec_prefix=\$${prefix} >> $@ @@ -303,16 +303,16 @@ $(SSL_PKGCONFNAME): hiredis_ssl.h @echo includedir=$(PREFIX)/include >> $@ @echo pkgincludedir=$(PREFIX)/$(INCLUDE_PATH) >> $@ @echo >> $@ - @echo Name: hiredis_ssl >> $@ - @echo Description: SSL Support for hiredis. >> $@ - @echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@ - @echo Requires: hiredis >> $@ - @echo Libs: -L\$${libdir} -lhiredis_ssl >> $@ + @echo Name: valkey_ssl >> $@ + @echo Description: SSL Support for valkey. >> $@ + @echo Version: $(LIBVALKEY_MAJOR).$(LIBVALKEY_MINOR).$(LIBVALKEY_PATCH) >> $@ + @echo Requires: valkey >> $@ + @echo Libs: -L\$${libdir} -lvalkey_ssl >> $@ @echo Libs.private: -lssl -lcrypto >> $@ install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME) $(SSL_INSTALL) mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_INCLUDE_PATH)/adapters $(INSTALL_LIBRARY_PATH) - $(INSTALL) hiredis.h async.h read.h sds.h alloc.h sockcompat.h $(INSTALL_INCLUDE_PATH) + $(INSTALL) valkey.h async.h read.h sds.h alloc.h sockcompat.h $(INSTALL_INCLUDE_PATH) $(INSTALL) adapters/*.h $(INSTALL_INCLUDE_PATH)/adapters $(INSTALL) $(DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(DYLIB_MINOR_NAME) cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIBNAME) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIB_MAJOR_NAME) @@ -322,7 +322,7 @@ install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME) $(SSL_INSTALL) install-ssl: $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(SSL_PKGCONFNAME) mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_LIBRARY_PATH) - $(INSTALL) hiredis_ssl.h $(INSTALL_INCLUDE_PATH) + $(INSTALL) valkey_ssl.h $(INSTALL_INCLUDE_PATH) $(INSTALL) $(SSL_DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(SSL_DYLIB_MINOR_NAME) cd $(INSTALL_LIBRARY_PATH) && ln -sf $(SSL_DYLIB_MINOR_NAME) $(SSL_DYLIBNAME) && ln -sf $(SSL_DYLIB_MINOR_NAME) $(SSL_DYLIB_MAJOR_NAME) $(INSTALL) $(SSL_STLIBNAME) $(INSTALL_LIBRARY_PATH) @@ -348,9 +348,9 @@ gcov: coverage: gcov make check mkdir -p tmp/lcov - lcov -d . -c --exclude '/usr*' -o tmp/lcov/hiredis.info - lcov -q -l tmp/lcov/hiredis.info - genhtml --legend -q -o tmp/lcov/report tmp/lcov/hiredis.info + lcov -d . -c --exclude '/usr*' -o tmp/lcov/valkey.info + lcov -q -l tmp/lcov/valkey.info + genhtml --legend -q -o tmp/lcov/report tmp/lcov/valkey.info noopt: $(MAKE) OPTIMIZATION="" diff --git a/libvalkey/README.md b/libvalkey/README.md index 7090455e..bb59cec4 100644 --- a/libvalkey/README.md +++ b/libvalkey/README.md @@ -3,166 +3,108 @@ **This Readme reflects the latest changed in the master branch. See [v1.0.0](https://github.com/redis/hiredis/tree/v1.0.0) for the Readme and documentation for the latest release ([API/ABI history](https://abi-laboratory.pro/?view=timeline&l=hiredis)).** -# HIREDIS +# LIBVALKEY -Hiredis is a minimalistic C client library for the [Redis](https://redis.io/) database. +Libvalkey is a minimalistic C client library for the [Valkey](https://valkey.io/) database. It is minimalistic because it just adds minimal support for the protocol, but at the same time it uses a high level printf-alike API in order to make it much higher level than otherwise suggested by its minimal code base and the -lack of explicit bindings for every Redis command. +lack of explicit bindings for every Valkey command. Apart from supporting sending commands and receiving replies, it comes with a reply parser that is decoupled from the I/O layer. It is a stream parser designed for easy reusability, which can for instance be used in higher level language bindings for efficient reply parsing. -Hiredis only supports the binary-safe Redis protocol, so you can use it with any -Redis version >= 1.2.0. +Libvalkey only supports the binary-safe RESP protocol, so you can use it with any +server that uses it. The library comes with multiple APIs. There is the *synchronous API*, the *asynchronous API* and the *reply parsing API*. -## Upgrading to > 1.2.0 (**PRERELEASE**) - -* After v1.2.0 we modified how we invoke `poll(2)` to wait for connections to complete, such that we will now retry - the call if it is interrupted by a signal until: - - a) The connection succeeds or fails. - b) The overall connection timeout is reached. - - In previous versions, an interrupted `poll(2)` call would cause the connection to fail - with `c->err` set to `REDIS_ERR_IO` and `c->errstr` set to `poll(2): Interrupted system call`. - -## Upgrading to `1.1.0` - -Almost all users will simply need to recompile their applications against the newer version of hiredis. - -**NOTE**: Hiredis can now return `nan` in addition to `-inf` and `inf` in a `REDIS_REPLY_DOUBLE`. - Applications that deal with `RESP3` doubles should make sure to account for this. - -## Upgrading to `1.0.2` - -NOTE: v1.0.1 erroneously bumped SONAME, which is why it is skipped here. - -Version 1.0.2 is simply 1.0.0 with a fix for [CVE-2021-32765](https://github.com/redis/hiredis/security/advisories/GHSA-hfm9-39pp-55p2). They are otherwise identical. - -## Upgrading to `1.0.0` - -Version 1.0.0 marks the first stable release of Hiredis. -It includes some minor breaking changes, mostly to make the exposed API more uniform and self-explanatory. -It also bundles the updated `sds` library, to sync up with upstream and Redis. -For code changes see the [Changelog](CHANGELOG.md). - -_Note: As described below, a few member names have been changed but most applications should be able to upgrade with minor code changes and recompiling._ - -## IMPORTANT: Breaking changes from `0.14.1` -> `1.0.0` - -* `redisContext` has two additional members (`free_privdata`, and `privctx`). -* `redisOptions.timeout` has been renamed to `redisOptions.connect_timeout`, and we've added `redisOptions.command_timeout`. -* `redisReplyObjectFunctions.createArray` now takes `size_t` instead of `int` for its length parameter. - -## IMPORTANT: Breaking changes when upgrading from 0.13.x -> 0.14.x - -Bulk and multi-bulk lengths less than -1 or greater than `LLONG_MAX` are now -protocol errors. This is consistent with the RESP specification. On 32-bit -platforms, the upper bound is lowered to `SIZE_MAX`. - -Change `redisReply.len` to `size_t`, as it denotes the the size of a string - -User code should compare this to `size_t` values as well. If it was used to -compare to other values, casting might be necessary or can be removed, if -casting was applied before. - -## Upgrading from `<0.9.0` - -Version 0.9.0 is a major overhaul of hiredis in every aspect. However, upgrading existing -code using hiredis should not be a big pain. The key thing to keep in mind when -upgrading is that hiredis >= 0.9.0 uses a `redisContext*` to keep state, in contrast to -the stateless 0.0.1 that only has a file descriptor to work with. - ## Synchronous API To consume the synchronous API, there are only a few function calls that need to be introduced: ```c -redisContext *redisConnect(const char *ip, int port); -void *redisCommand(redisContext *c, const char *format, ...); +valkeyContext *valkeyConnect(const char *ip, int port); +void *valkeyCommand(valkeyContext *c, const char *format, ...); void freeReplyObject(void *reply); ``` ### Connecting -The function `redisConnect` is used to create a so-called `redisContext`. The -context is where Hiredis holds state for a connection. The `redisContext` +The function `valkeyConnect` is used to create a so-called `valkeyContext`. The +context is where Libvalkey holds state for a connection. The `valkeyContext` struct has an integer `err` field that is non-zero when the connection is in an error state. The field `errstr` will contain a string with a description of the error. More information on errors can be found in the **Errors** section. -After trying to connect to Redis using `redisConnect` you should +After trying to connect to Valkey using `valkeyConnect` you should check the `err` field to see if establishing the connection was successful: ```c -redisContext *c = redisConnect("127.0.0.1", 6379); +valkeyContext *c = valkeyConnect("127.0.0.1", 6379); if (c == NULL || c->err) { if (c) { printf("Error: %s\n", c->errstr); // handle error } else { - printf("Can't allocate redis context\n"); + printf("Can't allocate valkey context\n"); } } ``` -One can also use `redisConnectWithOptions` which takes a `redisOptions` argument +One can also use `valkeyConnectWithOptions` which takes a `valkeyOptions` argument that can be configured with endpoint information as well as many different flags -to change how the `redisContext` will be configured. +to change how the `valkeyContext` will be configured. ```c -redisOptions opt = {0}; +valkeyOptions opt = {0}; /* One can set the endpoint with one of our helper macros */ if (tcp) { - REDIS_OPTIONS_SET_TCP(&opt, "localhost", 6379); + VALKEY_OPTIONS_SET_TCP(&opt, "localhost", 6379); } else { - REDIS_OPTIONS_SET_UNIX(&opt, "/tmp/redis.sock"); + VALKEY_OPTIONS_SET_UNIX(&opt, "/tmp/valkey.sock"); } /* And privdata can be specified with another helper */ -REDIS_OPTIONS_SET_PRIVDATA(&opt, myPrivData, myPrivDataDtor); +VALKEY_OPTIONS_SET_PRIVDATA(&opt, myPrivData, myPrivDataDtor); /* Finally various options may be set via the `options` member, as described below */ -opt->options |= REDIS_OPT_PREFER_IPV4; +opt->options |= VALKEY_OPT_PREFER_IPV4; ``` -If a connection is lost, `int redisReconnect(redisContext *c)` can be used to restore the connection using the same endpoint and options as the given context. +If a connection is lost, `int valkeyReconnect(valkeyContext *c)` can be used to restore the connection using the same endpoint and options as the given context. -### Configurable redisOptions flags +### Configurable valkeyOptions flags -There are several flags you may set in the `redisOptions` struct to change default behavior. You can specify the flags via the `redisOptions->options` member. +There are several flags you may set in the `valkeyOptions` struct to change default behavior. You can specify the flags via the `valkeyOptions->options` member. | Flag | Description | | --- | --- | -| REDIS\_OPT\_NONBLOCK | Tells hiredis to make a non-blocking connection. | -| REDIS\_OPT\_REUSEADDR | Tells hiredis to set the [SO_REUSEADDR](https://man7.org/linux/man-pages/man7/socket.7.html) socket option | -| REDIS\_OPT\_PREFER\_IPV4
REDIS\_OPT\_PREFER_IPV6
REDIS\_OPT\_PREFER\_IP\_UNSPEC | Informs hiredis to either prefer IPv4 or IPv6 when invoking [getaddrinfo](https://man7.org/linux/man-pages/man3/gai_strerror.3.html). `REDIS_OPT_PREFER_IP_UNSPEC` will cause hiredis to specify `AF_UNSPEC` in the getaddrinfo call, which means both IPv4 and IPv6 addresses will be searched simultaneously.
Hiredis prefers IPv4 by default. | -| REDIS\_OPT\_NO\_PUSH\_AUTOFREE | Tells hiredis to not install the default RESP3 PUSH handler (which just intercepts and frees the replies). This is useful in situations where you want to process these messages in-band. | -| REDIS\_OPT\_NOAUTOFREEREPLIES | **ASYNC**: tells hiredis not to automatically invoke `freeReplyObject` after executing the reply callback. | -| REDIS\_OPT\_NOAUTOFREE | **ASYNC**: Tells hiredis not to automatically free the `redisAsyncContext` on connection/communication failure, but only if the user makes an explicit call to `redisAsyncDisconnect` or `redisAsyncFree` | +| VALKEY\_OPT\_NONBLOCK | Tells libvalkey to make a non-blocking connection. | +| VALKEY\_OPT\_REUSEADDR | Tells libvalkey to set the [SO_REUSEADDR](https://man7.org/linux/man-pages/man7/socket.7.html) socket option | +| VALKEY\_OPT\_PREFER\_IPV4
VALKEY\_OPT\_PREFER_IPV6
VALKEY\_OPT\_PREFER\_IP\_UNSPEC | Informs libvalkey to either prefer IPv4 or IPv6 when invoking [getaddrinfo](https://man7.org/linux/man-pages/man3/gai_strerror.3.html). `VALKEY_OPT_PREFER_IP_UNSPEC` will cause libvalkey to specify `AF_UNSPEC` in the getaddrinfo call, which means both IPv4 and IPv6 addresses will be searched simultaneously.
Libvalkey prefers IPv4 by default. | +| VALKEY\_OPT\_NO\_PUSH\_AUTOFREE | Tells libvalkey to not install the default RESP3 PUSH handler (which just intercepts and frees the replies). This is useful in situations where you want to process these messages in-band. | +| VALKEY\_OPT\_NOAUTOFREEREPLIES | **ASYNC**: tells libvalkey not to automatically invoke `freeReplyObject` after executing the reply callback. | +| VALKEY\_OPT\_NOAUTOFREE | **ASYNC**: Tells libvalkey not to automatically free the `valkeyAsyncContext` on connection/communication failure, but only if the user makes an explicit call to `valkeyAsyncDisconnect` or `valkeyAsyncFree` | -*Note: A `redisContext` is not thread-safe.* +*Note: A `valkeyContext` is not thread-safe.* ### Other configuration using socket options The following socket options are applied directly to the underlying socket. -The values are not stored in the `redisContext`, so they are not automatically applied when reconnecting using `redisReconnect()`. -These functions return `REDIS_OK` on success. -On failure, `REDIS_ERR` is returned and the underlying connection is closed. +The values are not stored in the `valkeyContext`, so they are not automatically applied when reconnecting using `valkeyReconnect()`. +These functions return `VALKEY_OK` on success. +On failure, `VALKEY_ERR` is returned and the underlying connection is closed. -To configure these for an asynchronous context (see *Asynchronous API* below), use `ac->c` to get the redisContext out of an asyncRedisContext. +To configure these for an asynchronous context (see *Asynchronous API* below), use `ac->c` to get the valkeyContext out of an valkeyAsyncContext. ```C -int redisEnableKeepAlive(redisContext *c); -int redisEnableKeepAliveWithInterval(redisContext *c, int interval); +int valkeyEnableKeepAlive(valkeyContext *c); +int valkeyEnableKeepAliveWithInterval(valkeyContext *c, int interval); ``` Enables TCP keepalive by setting the following socket options (with some variations depending on OS): @@ -173,7 +115,7 @@ Enables TCP keepalive by setting the following socket options (with some variati * `TCP_KEEPCNT` set to 3. ```C -int redisSetTcpUserTimeout(redisContext *c, unsigned int timeout); +int valkeySetTcpUserTimeout(valkeyContext *c, unsigned int timeout); ``` Set the `TCP_USER_TIMEOUT` Linux-specific socket option which is as described in the `tcp` man page: @@ -183,103 +125,102 @@ Set the `TCP_USER_TIMEOUT` Linux-specific socket option which is as described in ### Sending commands -There are several ways to issue commands to Redis. The first that will be introduced is -`redisCommand`. This function takes a format similar to printf. In the simplest form, +There are several ways to issue commands to Valkey. The first that will be introduced is +`valkeyCommand`. This function takes a format similar to printf. In the simplest form, it is used like this: ```c -reply = redisCommand(context, "SET foo bar"); +reply = valkeyCommand(context, "SET foo bar"); ``` The specifier `%s` interpolates a string in the command, and uses `strlen` to determine the length of the string: ```c -reply = redisCommand(context, "SET foo %s", value); +reply = valkeyCommand(context, "SET foo %s", value); ``` When you need to pass binary safe strings in a command, the `%b` specifier can be used. Together with a pointer to the string, it requires a `size_t` length argument of the string: ```c -reply = redisCommand(context, "SET foo %b", value, (size_t) valuelen); +reply = valkeyCommand(context, "SET foo %b", value, (size_t) valuelen); ``` -Internally, Hiredis splits the command in different arguments and will -convert it to the protocol used to communicate with Redis. +Internally, Libvalkey splits the command in different arguments and will +convert it to the protocol used to communicate with Valkey. One or more spaces separates arguments, so you can use the specifiers anywhere in an argument: ```c -reply = redisCommand(context, "SET key:%s %s", myid, value); +reply = valkeyCommand(context, "SET key:%s %s", myid, value); ``` ### Using replies -The return value of `redisCommand` holds a reply when the command was +The return value of `valkeyCommand` holds a reply when the command was successfully executed. When an error occurs, the return value is `NULL` and the `err` field in the context will be set (see section on **Errors**). Once an error is returned the context cannot be reused and you should set up a new connection. -The standard replies that `redisCommand` are of the type `redisReply`. The -`type` field in the `redisReply` should be used to test what kind of reply +The standard replies that `valkeyCommand` are of the type `valkeyReply`. The +`type` field in the `valkeyReply` should be used to test what kind of reply was received: ### RESP2 -* **`REDIS_REPLY_STATUS`**: +* **`VALKEY_REPLY_STATUS`**: * The command replied with a status reply. The status string can be accessed using `reply->str`. The length of this string can be accessed using `reply->len`. -* **`REDIS_REPLY_ERROR`**: - * The command replied with an error. The error string can be accessed identical to `REDIS_REPLY_STATUS`. +* **`VALKEY_REPLY_ERROR`**: + * The command replied with an error. The error string can be accessed identical to `VALKEY_REPLY_STATUS`. -* **`REDIS_REPLY_INTEGER`**: +* **`VALKEY_REPLY_INTEGER`**: * The command replied with an integer. The integer value can be accessed using the `reply->integer` field of type `long long`. -* **`REDIS_REPLY_NIL`**: +* **`VALKEY_REPLY_NIL`**: * The command replied with a **nil** object. There is no data to access. -* **`REDIS_REPLY_STRING`**: +* **`VALKEY_REPLY_STRING`**: * A bulk (string) reply. The value of the reply can be accessed using `reply->str`. The length of this string can be accessed using `reply->len`. -* **`REDIS_REPLY_ARRAY`**: +* **`VALKEY_REPLY_ARRAY`**: * A multi bulk reply. The number of elements in the multi bulk reply is stored in - `reply->elements`. Every element in the multi bulk reply is a `redisReply` object as well + `reply->elements`. Every element in the multi bulk reply is a `valkeyReply` object as well and can be accessed via `reply->element[..index..]`. - Redis may reply with nested arrays but this is fully supported. + Valkey may reply with nested arrays but this is fully supported. ### RESP3 -Hiredis also supports every new `RESP3` data type which are as follows. For more information about the protocol see the `RESP3` [specification.](https://github.com/antirez/RESP3/blob/master/spec.md) +Libvalkey also supports every new `RESP3` data type which are as follows. For more information about the protocol see the `RESP3` [specification.](https://github.com/antirez/RESP3/blob/master/spec.md) -* **`REDIS_REPLY_DOUBLE`**: +* **`VALKEY_REPLY_DOUBLE`**: * The command replied with a double-precision floating point number. The value is stored as a string in the `str` member, and can be converted with `strtod` or similar. -* **`REDIS_REPLY_BOOL`**: +* **`VALKEY_REPLY_BOOL`**: * A boolean true/false reply. The value is stored in the `integer` member and will be either `0` or `1`. -* **`REDIS_REPLY_MAP`**: +* **`VALKEY_REPLY_MAP`**: * An array with the added invariant that there will always be an even number of elements. - The MAP is functionally equivalent to `REDIS_REPLY_ARRAY` except for the previously mentioned invariant. + The MAP is functionally equivalent to `VALKEY_REPLY_ARRAY` except for the previously mentioned invariant. -* **`REDIS_REPLY_SET`**: +* **`VALKEY_REPLY_SET`**: * An array response where each entry is unique. Like the MAP type, the data is identical to an array response except there are no duplicate values. -* **`REDIS_REPLY_PUSH`**: - * An array that can be generated spontaneously by Redis. +* **`VALKEY_REPLY_PUSH`**: + * An array that can be generated spontaneously by Valkey. This array response will always contain at least two subelements. The first contains the type of `PUSH` message (e.g. `message`, or `invalidate`), and the second being a sub-array with the `PUSH` payload itself. -* **`REDIS_REPLY_ATTR`**: +* **`VALKEY_REPLY_ATTR`**: * An array structurally identical to a `MAP` but intended as meta-data about a reply. - _As of Redis 6.0.6 this reply type is not used in Redis_ -* **`REDIS_REPLY_BIGNUM`**: +* **`VALKEY_REPLY_BIGNUM`**: * A string representing an arbitrarily large signed or unsigned integer value. - The number will be encoded as a string in the `str` member of `redisReply`. + The number will be encoded as a string in the `str` member of `valkeyReply`. -* **`REDIS_REPLY_VERB`**: +* **`VALKEY_REPLY_VERB`**: * A verbatim string, intended to be presented to the user without modification. The string payload is stored in the `str` member, and type data is stored in the `vtype` member (e.g. `txt` for raw text or `md` for markdown). @@ -288,43 +229,43 @@ Note that this function will take care of freeing sub-reply objects contained in arrays and nested arrays, so there is no need for the user to free the sub replies (it is actually harmful and will corrupt the memory). -**Important:** the current version of hiredis (1.0.0) frees replies when the +**Important:** the current version of valkey (1.0.0) frees replies when the asynchronous API is used. This means you should not call `freeReplyObject` when -you use this API. The reply is cleaned up by hiredis _after_ the callback +you use this API. The reply is cleaned up by libvalkey _after_ the callback returns. We may introduce a flag to make this configurable in future versions of the library. ### Cleaning up To disconnect and free the context the following function can be used: ```c -void redisFree(redisContext *c); +void valkeyFree(valkeyContext *c); ``` This function immediately closes the socket and then frees the allocations done in creating the context. ### Sending commands (continued) -Together with `redisCommand`, the function `redisCommandArgv` can be used to issue commands. +Together with `valkeyCommand`, the function `valkeyCommandArgv` can be used to issue commands. It has the following prototype: ```c -void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); +void *valkeyCommandArgv(valkeyContext *c, int argc, const char **argv, const size_t *argvlen); ``` It takes the number of arguments `argc`, an array of strings `argv` and the lengths of the arguments `argvlen`. For convenience, `argvlen` may be set to `NULL` and the function will use `strlen(3)` on every argument to determine its length. Obviously, when any of the arguments need to be binary safe, the entire array of lengths `argvlen` should be provided. -The return value has the same semantic as `redisCommand`. +The return value has the same semantic as `valkeyCommand`. ### Pipelining -To explain how Hiredis supports pipelining in a blocking connection, there needs to be +To explain how Libvalkey supports pipelining in a blocking connection, there needs to be understanding of the internal execution flow. -When any of the functions in the `redisCommand` family is called, Hiredis first formats the -command according to the Redis protocol. The formatted command is then put in the output buffer +When any of the functions in the `valkeyCommand` family is called, Libvalkey first formats the +command according to the Valkey protocol. The formatted command is then put in the output buffer of the context. This output buffer is dynamic, so it can hold any number of commands. -After the command is put in the output buffer, `redisGetReply` is called. This function has the +After the command is put in the output buffer, `valkeyGetReply` is called. This function has the following two execution paths: 1. The input buffer is non-empty: @@ -334,58 +275,58 @@ following two execution paths: * Write the **entire** output buffer to the socket * Read from the socket until a single reply could be parsed -The function `redisGetReply` is exported as part of the Hiredis API and can be used when a reply +The function `valkeyGetReply` is exported as part of the Libvalkey API and can be used when a reply is expected on the socket. To pipeline commands, the only thing that needs to be done is filling up the output buffer. For this cause, two commands can be used that are identical -to the `redisCommand` family, apart from not returning a reply: +to the `valkeyCommand` family, apart from not returning a reply: ```c -void redisAppendCommand(redisContext *c, const char *format, ...); -void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); +void valkeyAppendCommand(valkeyContext *c, const char *format, ...); +void valkeyAppendCommandArgv(valkeyContext *c, int argc, const char **argv, const size_t *argvlen); ``` -After calling either function one or more times, `redisGetReply` can be used to receive the -subsequent replies. The return value for this function is either `REDIS_OK` or `REDIS_ERR`, where +After calling either function one or more times, `valkeyGetReply` can be used to receive the +subsequent replies. The return value for this function is either `VALKEY_OK` or `VALKEY_ERR`, where the latter means an error occurred while reading a reply. Just as with the other commands, the `err` field in the context can be used to find out what the cause of this error is. The following examples shows a simple pipeline (resulting in only a single call to `write(2)` and a single call to `read(2)`): ```c -redisReply *reply; -redisAppendCommand(context,"SET foo bar"); -redisAppendCommand(context,"GET foo"); -redisGetReply(context,(void**)&reply); // reply for SET +valkeyReply *reply; +valkeyAppendCommand(context,"SET foo bar"); +valkeyAppendCommand(context,"GET foo"); +valkeyGetReply(context,(void**)&reply); // reply for SET freeReplyObject(reply); -redisGetReply(context,(void**)&reply); // reply for GET +valkeyGetReply(context,(void**)&reply); // reply for GET freeReplyObject(reply); ``` This API can also be used to implement a blocking subscriber: ```c -reply = redisCommand(context,"SUBSCRIBE foo"); +reply = valkeyCommand(context,"SUBSCRIBE foo"); freeReplyObject(reply); -while(redisGetReply(context,(void *)&reply) == REDIS_OK) { +while(valkeyGetReply(context,(void *)&reply) == VALKEY_OK) { // consume message freeReplyObject(reply); } ``` ### Errors -When a function call is not successful, depending on the function either `NULL` or `REDIS_ERR` is +When a function call is not successful, depending on the function either `NULL` or `VALKEY_ERR` is returned. The `err` field inside the context will be non-zero and set to one of the following constants: -* **`REDIS_ERR_IO`**: +* **`VALKEY_ERR_IO`**: There was an I/O error while creating the connection, trying to write to the socket or read from the socket. If you included `errno.h` in your application, you can use the global `errno` variable to find out what is wrong. -* **`REDIS_ERR_EOF`**: +* **`VALKEY_ERR_EOF`**: The server closed the connection which resulted in an empty read. -* **`REDIS_ERR_PROTOCOL`**: +* **`VALKEY_ERR_PROTOCOL`**: There was an error while parsing the protocol. -* **`REDIS_ERR_OTHER`**: +* **`VALKEY_ERR_OTHER`**: Any other error. Currently, it is only used when a specified hostname to connect to cannot be resolved. @@ -394,38 +335,38 @@ of the error. ## Asynchronous API -Hiredis comes with an asynchronous API that works easily with any event library. -Examples are bundled that show using Hiredis with [libev](http://software.schmorp.de/pkg/libev.html) +Libvalkey comes with an asynchronous API that works easily with any event library. +Examples are bundled that show using Libvalkey with [libev](http://software.schmorp.de/pkg/libev.html) and [libevent](http://monkey.org/~provos/libevent/). ### Connecting -The function `redisAsyncConnect` can be used to establish a non-blocking connection to -Redis. It returns a pointer to the newly created `redisAsyncContext` struct. The `err` field +The function `valkeyAsyncConnect` can be used to establish a non-blocking connection to +Valkey. It returns a pointer to the newly created `valkeyAsyncContext` struct. The `err` field should be checked after creation to see if there were errors creating the connection. Because the connection that will be created is non-blocking, the kernel is not able to instantly return if the specified host and port is able to accept a connection. -In case of error, it is the caller's responsibility to free the context using `redisAsyncFree()` +In case of error, it is the caller's responsibility to free the context using `valkeyAsyncFree()` -*Note: A `redisAsyncContext` is not thread-safe.* +*Note: A `valkeyAsyncContext` is not thread-safe.* An application function creating a connection might look like this: ```c void appConnect(myAppData *appData) { - redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + valkeyAsyncContext *c = valkeyAsyncConnect("127.0.0.1", 6379); if (c->err) { printf("Error: %s\n", c->errstr); // handle error - redisAsyncFree(c); + valkeyAsyncFree(c); c = NULL; } else { appData->context = c; appData->connecting = 1; c->data = appData; /* store application pointer for the callbacks */ - redisAsyncSetConnectCallback(c, appOnConnect); - redisAsyncSetDisconnectCallback(c, appOnDisconnect); + valkeyAsyncSetConnectCallback(c, appOnConnect); + valkeyAsyncSetDisconnectCallback(c, appOnDisconnect); } } @@ -438,38 +379,38 @@ It _can_ also hold a *disconnect* callback function that is called when the connection is disconnected (either because of an error or per user request). Both callbacks should have the following prototype: ```c -void(const redisAsyncContext *c, int status); +void(const valkeyAsyncContext *c, int status); ``` -On a *connect*, the `status` argument is set to `REDIS_OK` if the connection attempt succeeded. In this -case, the context is ready to accept commands. If it is called with `REDIS_ERR` then the +On a *connect*, the `status` argument is set to `VALKEY_OK` if the connection attempt succeeded. In this +case, the context is ready to accept commands. If it is called with `VALKEY_ERR` then the connection attempt failed. The `err` field in the context can be accessed to find out the cause of the error. After a failed connection attempt, the context object is automatically freed by the library after calling the connect callback. This may be a good point to create a new context and retry the connection. -On a disconnect, the `status` argument is set to `REDIS_OK` when disconnection was initiated by the -user, or `REDIS_ERR` when the disconnection was caused by an error. When it is `REDIS_ERR`, the `err` +On a disconnect, the `status` argument is set to `VALKEY_OK` when disconnection was initiated by the +user, or `VALKEY_ERR` when the disconnection was caused by an error. When it is `VALKEY_ERR`, the `err` field in the context can be accessed to find out the cause of the error. The context object is always freed after the disconnect callback fired. When a reconnect is needed, the disconnect callback is a good point to do so. Setting the connect or disconnect callbacks can only be done once per context. For subsequent calls the -api will return `REDIS_ERR`. The function to set the callbacks have the following prototype: +api will return `VALKEY_ERR`. The function to set the callbacks have the following prototype: ```c -/* Alternatively you can use redisAsyncSetConnectCallbackNC which will be passed a non-const - redisAsyncContext* on invocation (e.g. allowing writes to the privdata member). */ -int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn); -int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); +/* Alternatively you can use valkeyAsyncSetConnectCallbackNC which will be passed a non-const + valkeyAsyncContext* on invocation (e.g. allowing writes to the privdata member). */ +int valkeyAsyncSetConnectCallback(valkeyAsyncContext *ac, valkeyConnectCallback *fn); +int valkeyAsyncSetDisconnectCallback(valkeyAsyncContext *ac, valkeyDisconnectCallback *fn); ``` `ac->data` may be used to pass user data to both callbacks. A typical implementation might look something like this: ```c -void appOnConnect(redisAsyncContext *c, int status) +void appOnConnect(valkeyAsyncContext *c, int status) { myAppData *appData = (myAppData*)c->data; /* get my application specific context*/ appData->connecting = 0; - if (status == REDIS_OK) { + if (status == VALKEY_OK) { appData->connected = 1; } else { appData->connected = 0; @@ -479,13 +420,13 @@ void appOnConnect(redisAsyncContext *c, int status) appAttemptReconnect(); } -void appOnDisconnect(redisAsyncContext *c, int status) +void appOnDisconnect(valkeyAsyncContext *c, int status) { myAppData *appData = (myAppData*)c->data; /* get my application specific context*/ appData->connected = 0; appData->err = c->err; appData->context = NULL; /* avoid stale pointer when callback returns */ - if (status == REDIS_OK) { + if (status == VALKEY_OK) { appNotifyDisconnectCompleted(mydata); } else { appNotifyUnexpectedDisconnect(mydata); @@ -498,27 +439,27 @@ void appOnDisconnect(redisAsyncContext *c, int status) In an asynchronous context, commands are automatically pipelined due to the nature of an event loop. Therefore, unlike the synchronous API, there is only a single way to send commands. -Because commands are sent to Redis asynchronously, issuing a command requires a callback function +Because commands are sent to Valkey asynchronously, issuing a command requires a callback function that is called when the reply is received. Reply callbacks should have the following prototype: ```c -void(redisAsyncContext *c, void *reply, void *privdata); +void(valkeyAsyncContext *c, void *reply, void *privdata); ``` The `privdata` argument can be used to curry arbitrary data to the callback from the point where the command is initially queued for execution. The functions that can be used to issue commands in an asynchronous context are: ```c -int redisAsyncCommand( - redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, +int valkeyAsyncCommand( + valkeyAsyncContext *ac, valkeyCallbackFn *fn, void *privdata, const char *format, ...); -int redisAsyncCommandArgv( - redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, +int valkeyAsyncCommandArgv( + valkeyAsyncContext *ac, valkeyCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen); ``` -Both functions work like their blocking counterparts. The return value is `REDIS_OK` when the command -was successfully added to the output buffer and `REDIS_ERR` otherwise. Example: when the connection -is being disconnected per user-request, no new commands may be added to the output buffer and `REDIS_ERR` is -returned on calls to the `redisAsyncCommand` family. +Both functions work like their blocking counterparts. The return value is `VALKEY_OK` when the command +was successfully added to the output buffer and `VALKEY_ERR` otherwise. Example: when the connection +is being disconnected per user-request, no new commands may be added to the output buffer and `VALKEY_ERR` is +returned on calls to the `valkeyAsyncCommand` family. If the reply for a command with a `NULL` callback is read, it is immediately freed. When the callback for a command is non-`NULL`, the memory is freed immediately following the callback: the reply is only @@ -538,20 +479,20 @@ may receive a final `NULL` reply instead. An asynchronous connection can be terminated using: ```c -void redisAsyncDisconnect(redisAsyncContext *ac); +void valkeyAsyncDisconnect(valkeyAsyncContext *ac); ``` When this function is called, the connection is **not** immediately terminated. Instead, new commands are no longer accepted and the connection is only terminated when all pending commands have been written to the socket, their respective replies have been read and their respective callbacks have been executed. After this, the disconnection callback is executed with the -`REDIS_OK` status and the context object is freed. +`VALKEY_OK` status and the context object is freed. The connection can be forcefully disconnected using ```c -void redisAsyncFree(redisAsyncContext *ac); +void valkeyAsyncFree(valkeyAsyncContext *ac); ``` In this case, nothing more is written to the socket, all pending callbacks are called with a `NULL` -reply and the disconnection callback is called with `REDIS_OK`, after which the context object +reply and the disconnection callback is called with `VALKEY_OK`, after which the context object is freed. @@ -562,31 +503,31 @@ See the `adapters/` directory for bindings to *libev* and *libevent*. ## Reply parsing API -Hiredis comes with a reply parsing API that makes it easy for writing higher +Libvalkey comes with a reply parsing API that makes it easy for writing higher level language bindings. The reply parsing API consists of the following functions: ```c -redisReader *redisReaderCreate(void); -void redisReaderFree(redisReader *reader); -int redisReaderFeed(redisReader *reader, const char *buf, size_t len); -int redisReaderGetReply(redisReader *reader, void **reply); +valkeyReader *valkeyReaderCreate(void); +void valkeyReaderFree(valkeyReader *reader); +int valkeyReaderFeed(valkeyReader *reader, const char *buf, size_t len); +int valkeyReaderGetReply(valkeyReader *reader, void **reply); ``` -The same set of functions are used internally by hiredis when creating a -normal Redis context, the above API just exposes it to the user for a direct +The same set of functions are used internally by libvalkey when creating a +normal Valkey context, the above API just exposes it to the user for a direct usage. ### Usage -The function `redisReaderCreate` creates a `redisReader` structure that holds a +The function `valkeyReaderCreate` creates a `valkeyReader` structure that holds a buffer with unparsed data and state for the protocol parser. Incoming data -- most likely from a socket -- can be placed in the internal -buffer of the `redisReader` using `redisReaderFeed`. This function will make a +buffer of the `valkeyReader` using `valkeyReaderFeed`. This function will make a copy of the buffer pointed to by `buf` for `len` bytes. This data is parsed -when `redisReaderGetReply` is called. This function returns an integer status +when `valkeyReaderGetReply` is called. This function returns an integer status and a reply object (as described above) via `void **reply`. The returned status -can be either `REDIS_OK` or `REDIS_ERR`, where the latter means something went +can be either `VALKEY_OK` or `VALKEY_ERR`, where the latter means something went wrong (either a protocol error, or an out of memory error). The parser limits the level of nesting for multi bulk payloads to 7. If the @@ -594,13 +535,13 @@ multi bulk nesting level is higher than this, the parser returns an error. ### Customizing replies -The function `redisReaderGetReply` creates `redisReply` and makes the function -argument `reply` point to the created `redisReply` variable. For instance, if -the response of type `REDIS_REPLY_STATUS` then the `str` field of `redisReply` +The function `valkeyReaderGetReply` creates `valkeyReply` and makes the function +argument `reply` point to the created `valkeyReply` variable. For instance, if +the response of type `VALKEY_REPLY_STATUS` then the `str` field of `valkeyReply` will hold the status as a vanilla C string. However, the functions that are -responsible for creating instances of the `redisReply` can be customized by -setting the `fn` field on the `redisReader` struct. This should be done -immediately after creating the `redisReader`. +responsible for creating instances of the `valkeyReply` can be customized by +setting the `fn` field on the `valkeyReader` struct. This should be done +immediately after creating the `valkeyReader`. For example, [hiredis-rb](https://github.com/pietern/hiredis-rb/blob/master/ext/hiredis_ext/reader.c) uses customized reply object functions to create Ruby objects. @@ -608,7 +549,7 @@ uses customized reply object functions to create Ruby objects. ### Reader max buffer Both when using the Reader API directly or when using it indirectly via a -normal Redis context, the redisReader structure uses a buffer in order to +normal Valkey context, the valkeyReader structure uses a buffer in order to accumulate data from the server. Usually this buffer is destroyed when it is empty and is larger than 16 KiB in order to avoid wasting memory in unused buffers @@ -619,18 +560,18 @@ an idle buffer changing the value of the `maxbuf` field of the reader structure to the desired value. The special value of 0 means that there is no maximum value for an idle buffer, so the buffer will never get freed. -For instance if you have a normal Redis context you can set the maximum idle +For instance if you have a normal Valkey context you can set the maximum idle buffer to zero (unlimited) just with: ```c context->reader->maxbuf = 0; ``` This should be done only in order to maximize performances when working with -large payloads. The context should be set back to `REDIS_READER_MAX_BUF` again +large payloads. The context should be set back to `VALKEY_READER_MAX_BUF` again as soon as possible in order to prevent allocation of useless memory. ### Reader max array elements -By default the hiredis reply parser sets the maximum number of multi-bulk elements +By default the libvalkey reply parser sets the maximum number of multi-bulk elements to 2^32 - 1 or 4,294,967,295 entries. If you need to process multi-bulk replies with more than this many elements you can set the value higher or to zero, meaning unlimited with: @@ -649,8 +590,8 @@ SSL/TLS support is not built by default and requires an explicit flag: This requires OpenSSL development package (e.g. including header files to be available. -When enabled, SSL/TLS support is built into extra `libhiredis_ssl.a` and -`libhiredis_ssl.so` static/dynamic libraries. This leaves the original libraries +When enabled, SSL/TLS support is built into extra `libvalkey_ssl.a` and +`libvalkey_ssl.so` static/dynamic libraries. This leaves the original libraries unaffected so no additional dependencies are introduced. ### Using it @@ -658,88 +599,88 @@ unaffected so no additional dependencies are introduced. First, you'll need to make sure you include the SSL header file: ```c -#include -#include +#include +#include ``` -You will also need to link against `libhiredis_ssl`, **in addition** to -`libhiredis` and add `-lssl -lcrypto` to satisfy its dependencies. +You will also need to link against `libhivalkey_ssl`, **in addition** to +`libvalkey` and add `-lssl -lcrypto` to satisfy its dependencies. -Hiredis implements SSL/TLS on top of its normal `redisContext` or -`redisAsyncContext`, so you will need to establish a connection first and then +Libvalkey implements SSL/TLS on top of its normal `valkeyContext` or +`valkeyAsyncContext`, so you will need to establish a connection first and then initiate an SSL/TLS handshake. -#### Hiredis OpenSSL Wrappers +#### Libvalkey OpenSSL Wrappers -Before Hiredis can negotiate an SSL/TLS connection, it is necessary to +Before Libvalkey can negotiate an SSL/TLS connection, it is necessary to initialize OpenSSL and create a context. You can do that in two ways: 1. Work directly with the OpenSSL API to initialize the library's global context and create `SSL_CTX *` and `SSL *` contexts. With an `SSL *` object you can - call `redisInitiateSSL()`. -2. Work with a set of Hiredis-provided wrappers around OpenSSL, create a - `redisSSLContext` object to hold configuration and use - `redisInitiateSSLWithContext()` to initiate the SSL/TLS handshake. + call `valkeyInitiateSSL()`. +2. Work with a set of Libvalkey-provided wrappers around OpenSSL, create a + `valkeySSLContext` object to hold configuration and use + `valkeyInitiateSSLWithContext()` to initiate the SSL/TLS handshake. ```c -/* An Hiredis SSL context. It holds SSL configuration and can be reused across +/* An Libvalkey SSL context. It holds SSL configuration and can be reused across * many contexts. */ -redisSSLContext *ssl_context; +valkeySSLContext *ssl_context; /* An error variable to indicate what went wrong, if the context fails to * initialize. */ -redisSSLContextError ssl_error = REDIS_SSL_CTX_NONE; +valkeySSLContextError ssl_error = VALKEY_SSL_CTX_NONE; /* Initialize global OpenSSL state. * * You should call this only once when your app initializes, and only if * you don't explicitly or implicitly initialize OpenSSL it elsewhere. */ -redisInitOpenSSL(); +valkeyInitOpenSSL(); /* Create SSL context */ -ssl_context = redisCreateSSLContext( +ssl_context = valkeyCreateSSLContext( "cacertbundle.crt", /* File name of trusted CA/ca bundle file, optional */ "/path/to/certs", /* Path of trusted certificates, optional */ "client_cert.pem", /* File name of client certificate file, optional */ "client_key.pem", /* File name of client private key, optional */ - "redis.mydomain.com", /* Server name to request (SNI), optional */ + "valkey.mydomain.com", /* Server name to request (SNI), optional */ &ssl_error); -if(ssl_context == NULL || ssl_error != REDIS_SSL_CTX_NONE) { +if(ssl_context == NULL || ssl_error != VALKEY_SSL_CTX_NONE) { /* Handle error and abort... */ /* e.g. printf("SSL error: %s\n", - (ssl_error != REDIS_SSL_CTX_NONE) ? - redisSSLContextGetError(ssl_error) : "Unknown error"); + (ssl_error != VALKEY_SSL_CTX_NONE) ? + valkeySSLContextGetError(ssl_error) : "Unknown error"); // Abort */ } -/* Create Redis context and establish connection */ -c = redisConnect("localhost", 6443); +/* Create Valkey context and establish connection */ +c = valkeyConnect("localhost", 6443); if (c == NULL || c->err) { /* Handle error and abort... */ } /* Negotiate SSL/TLS */ -if (redisInitiateSSLWithContext(c, ssl_context) != REDIS_OK) { +if (valkeyInitiateSSLWithContext(c, ssl_context) != VALKEY_OK) { /* Handle error, in c->err / c->errstr */ } ``` ## RESP3 PUSH replies -Redis 6.0 introduced PUSH replies with the reply-type `>`. These messages are generated spontaneously and can arrive at any time, so must be handled using callbacks. +`RESP3` introduced PUSH replies with the reply-type `>`. These messages are generated spontaneously and can arrive at any time, so must be handled using callbacks. ### Default behavior -Hiredis installs handlers on `redisContext` and `redisAsyncContext` by default, which will intercept and free any PUSH replies detected. This means existing code will work as-is after upgrading to Redis 6 and switching to `RESP3`. +Libvalkey installs handlers on `valkeyContext` and `valkeyAsyncContext` by default, which will intercept and free any PUSH replies detected. This means existing code will work as-is after upgrading to to `RESP3`. ### Custom PUSH handler prototypes -The callback prototypes differ between `redisContext` and `redisAsyncContext`. +The callback prototypes differ between `valkeyContext` and `valkeyAsyncContext`. -#### redisContext +#### valkeyContext ```c void my_push_handler(void *privdata, void *reply) { /* Handle the reply */ @@ -751,12 +692,12 @@ void my_push_handler(void *privdata, void *reply) { } ``` -#### redisAsyncContext +#### valkeyAsyncContext ```c -void my_async_push_handler(redisAsyncContext *ac, void *reply) { +void my_async_push_handler(valkeyAsyncContext *ac, void *reply) { /* Handle the reply */ - /* Note: Because async hiredis always frees replies, you should + /* Note: Because async libvalkey always frees replies, you should not call freeReplyObject in an async push callback. */ } ``` @@ -764,48 +705,48 @@ void my_async_push_handler(redisAsyncContext *ac, void *reply) { ### Installing a custom handler There are two ways to set your own PUSH handlers. -1. Set `push_cb` or `async_push_cb` in the `redisOptions` struct and connect with `redisConnectWithOptions` or `redisAsyncConnectWithOptions`. +1. Set `push_cb` or `async_push_cb` in the `valkeyOptions` struct and connect with `valkeyConnectWithOptions` or `valkeyAsyncConnectWithOptions`. ```c - redisOptions = {0}; - REDIS_OPTIONS_SET_TCP(&options, "127.0.0.1", 6379); + valkeyOptions = {0}; + VALKEY_OPTIONS_SET_TCP(&options, "127.0.0.1", 6379); options->push_cb = my_push_handler; - redisContext *context = redisConnectWithOptions(&options); + valkeyContext *context = valkeyConnectWithOptions(&options); ``` -2. Call `redisSetPushCallback` or `redisAsyncSetPushCallback` on a connected context. +2. Call `valkeySetPushCallback` or `valkeyAsyncSetPushCallback` on a connected context. ```c - redisContext *context = redisConnect("127.0.0.1", 6379); - redisSetPushCallback(context, my_push_handler); + valkeyContext *context = valkeyConnect("127.0.0.1", 6379); + valkeySetPushCallback(context, my_push_handler); ``` - _Note `redisSetPushCallback` and `redisAsyncSetPushCallback` both return any currently configured handler, making it easy to override and then return to the old value._ + _Note `valkeySetPushCallback` and `valkeyAsyncSetPushCallback` both return any currently configured handler, making it easy to override and then return to the old value._ ### Specifying no handler -If you have a unique use-case where you don't want hiredis to automatically intercept and free PUSH replies, you will want to configure no handler at all. This can be done in two ways. -1. Set the `REDIS_OPT_NO_PUSH_AUTOFREE` flag in `redisOptions` and leave the callback function pointer `NULL`. +If you have a unique use-case where you don't want libvalkey to automatically intercept and free PUSH replies, you will want to configure no handler at all. This can be done in two ways. +1. Set the `VALKEY_OPT_NO_PUSH_AUTOFREE` flag in `valkeyOptions` and leave the callback function pointer `NULL`. ```c - redisOptions = {0}; - REDIS_OPTIONS_SET_TCP(&options, "127.0.0.1", 6379); - options->options |= REDIS_OPT_NO_PUSH_AUTOFREE; - redisContext *context = redisConnectWithOptions(&options); + valkeyOptions = {0}; + VALKEY_OPTIONS_SET_TCP(&options, "127.0.0.1", 6379); + options->options |= VALKEY_OPT_NO_PUSH_AUTOFREE; + valkeyContext *context = valkeyConnectWithOptions(&options); ``` -3. Call `redisSetPushCallback` with `NULL` once connected. +3. Call `valkeySetPushCallback` with `NULL` once connected. ```c - redisContext *context = redisConnect("127.0.0.1", 6379); - redisSetPushCallback(context, NULL); + valkeyContext *context = valkeyConnect("127.0.0.1", 6379); + valkeySetPushCallback(context, NULL); ``` - _Note: With no handler configured, calls to `redisCommand` may generate more than one reply, so this strategy is only applicable when there's some kind of blocking `redisGetReply()` loop (e.g. `MONITOR` or `SUBSCRIBE` workloads)._ + _Note: With no handler configured, calls to `valkeyCommand` may generate more than one reply, so this strategy is only applicable when there's some kind of blocking `valkeyGetReply()` loop (e.g. `MONITOR` or `SUBSCRIBE` workloads)._ ## Allocator injection -Hiredis uses a pass-thru structure of function pointers defined in [alloc.h](https://github.com/redis/hiredis/blob/f5d25850/alloc.h#L41) that contain the currently configured allocation and deallocation functions. By default they just point to libc (`malloc`, `calloc`, `realloc`, etc). +Libvalkey uses a pass-thru structure of function pointers defined in [alloc.h](https://github.com/valkey-io/libvalkey/blob/main/alloc.h) that contain the currently configured allocation and deallocation functions. By default they just point to libc (`malloc`, `calloc`, `realloc`, and `strdup`). ### Overriding One can override the allocators like so: ```c -hiredisAllocFuncs myfuncs = { +valkeyAllocFuncs myfuncs = { .mallocFn = my_malloc, .callocFn = my_calloc, .reallocFn = my_realloc, @@ -814,13 +755,13 @@ hiredisAllocFuncs myfuncs = { }; // Override allocators (function returns current allocators if needed) -hiredisAllocFuncs orig = hiredisSetAllocators(&myfuncs); +valkeyAllocFuncs orig = valkeyAllocators(&myfuncs); ``` To reset the allocators to their default libc function simply call: ```c -hiredisResetAllocators(); +valkeyResetAllocators(); ``` ## AUTHORS @@ -829,4 +770,4 @@ Salvatore Sanfilippo (antirez at gmail),\ Pieter Noordhuis (pcnoordhuis at gmail)\ Michael Grunder (michael dot grunder at gmail) -_Hiredis is released under the BSD license._ +_Libvalkey is released under the BSD license._ diff --git a/libvalkey/adapters/ae.h b/libvalkey/adapters/ae.h deleted file mode 100644 index 660d82eb..00000000 --- a/libvalkey/adapters/ae.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2010-2011, Pieter Noordhuis - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __HIREDIS_AE_H__ -#define __HIREDIS_AE_H__ -#include -#include -#include "../hiredis.h" -#include "../async.h" - -typedef struct redisAeEvents { - redisAsyncContext *context; - aeEventLoop *loop; - int fd; - int reading, writing; -} redisAeEvents; - -static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) { - ((void)el); ((void)fd); ((void)mask); - - redisAeEvents *e = (redisAeEvents*)privdata; - redisAsyncHandleRead(e->context); -} - -static void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) { - ((void)el); ((void)fd); ((void)mask); - - redisAeEvents *e = (redisAeEvents*)privdata; - redisAsyncHandleWrite(e->context); -} - -static void redisAeAddRead(void *privdata) { - redisAeEvents *e = (redisAeEvents*)privdata; - aeEventLoop *loop = e->loop; - if (!e->reading) { - e->reading = 1; - aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e); - } -} - -static void redisAeDelRead(void *privdata) { - redisAeEvents *e = (redisAeEvents*)privdata; - aeEventLoop *loop = e->loop; - if (e->reading) { - e->reading = 0; - aeDeleteFileEvent(loop,e->fd,AE_READABLE); - } -} - -static void redisAeAddWrite(void *privdata) { - redisAeEvents *e = (redisAeEvents*)privdata; - aeEventLoop *loop = e->loop; - if (!e->writing) { - e->writing = 1; - aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e); - } -} - -static void redisAeDelWrite(void *privdata) { - redisAeEvents *e = (redisAeEvents*)privdata; - aeEventLoop *loop = e->loop; - if (e->writing) { - e->writing = 0; - aeDeleteFileEvent(loop,e->fd,AE_WRITABLE); - } -} - -static void redisAeCleanup(void *privdata) { - redisAeEvents *e = (redisAeEvents*)privdata; - redisAeDelRead(privdata); - redisAeDelWrite(privdata); - hi_free(e); -} - -static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) { - redisContext *c = &(ac->c); - redisAeEvents *e; - - /* Nothing should be attached when something is already attached */ - if (ac->ev.data != NULL) - return REDIS_ERR; - - /* Create container for context and r/w events */ - e = (redisAeEvents*)hi_malloc(sizeof(*e)); - if (e == NULL) - return REDIS_ERR; - - e->context = ac; - e->loop = loop; - e->fd = c->fd; - e->reading = e->writing = 0; - - /* Register functions to start/stop listening for events */ - ac->ev.addRead = redisAeAddRead; - ac->ev.delRead = redisAeDelRead; - ac->ev.addWrite = redisAeAddWrite; - ac->ev.delWrite = redisAeDelWrite; - ac->ev.cleanup = redisAeCleanup; - ac->ev.data = e; - - return REDIS_OK; -} -#endif diff --git a/libvalkey/adapters/glib.h b/libvalkey/adapters/glib.h deleted file mode 100644 index ad59dd14..00000000 --- a/libvalkey/adapters/glib.h +++ /dev/null @@ -1,156 +0,0 @@ -#ifndef __HIREDIS_GLIB_H__ -#define __HIREDIS_GLIB_H__ - -#include - -#include "../hiredis.h" -#include "../async.h" - -typedef struct -{ - GSource source; - redisAsyncContext *ac; - GPollFD poll_fd; -} RedisSource; - -static void -redis_source_add_read (gpointer data) -{ - RedisSource *source = (RedisSource *)data; - g_return_if_fail(source); - source->poll_fd.events |= G_IO_IN; - g_main_context_wakeup(g_source_get_context((GSource *)data)); -} - -static void -redis_source_del_read (gpointer data) -{ - RedisSource *source = (RedisSource *)data; - g_return_if_fail(source); - source->poll_fd.events &= ~G_IO_IN; - g_main_context_wakeup(g_source_get_context((GSource *)data)); -} - -static void -redis_source_add_write (gpointer data) -{ - RedisSource *source = (RedisSource *)data; - g_return_if_fail(source); - source->poll_fd.events |= G_IO_OUT; - g_main_context_wakeup(g_source_get_context((GSource *)data)); -} - -static void -redis_source_del_write (gpointer data) -{ - RedisSource *source = (RedisSource *)data; - g_return_if_fail(source); - source->poll_fd.events &= ~G_IO_OUT; - g_main_context_wakeup(g_source_get_context((GSource *)data)); -} - -static void -redis_source_cleanup (gpointer data) -{ - RedisSource *source = (RedisSource *)data; - - g_return_if_fail(source); - - redis_source_del_read(source); - redis_source_del_write(source); - /* - * It is not our responsibility to remove ourself from the - * current main loop. However, we will remove the GPollFD. - */ - if (source->poll_fd.fd >= 0) { - g_source_remove_poll((GSource *)data, &source->poll_fd); - source->poll_fd.fd = -1; - } -} - -static gboolean -redis_source_prepare (GSource *source, - gint *timeout_) -{ - RedisSource *redis = (RedisSource *)source; - *timeout_ = -1; - return !!(redis->poll_fd.events & redis->poll_fd.revents); -} - -static gboolean -redis_source_check (GSource *source) -{ - RedisSource *redis = (RedisSource *)source; - return !!(redis->poll_fd.events & redis->poll_fd.revents); -} - -static gboolean -redis_source_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data) -{ - RedisSource *redis = (RedisSource *)source; - - if ((redis->poll_fd.revents & G_IO_OUT)) { - redisAsyncHandleWrite(redis->ac); - redis->poll_fd.revents &= ~G_IO_OUT; - } - - if ((redis->poll_fd.revents & G_IO_IN)) { - redisAsyncHandleRead(redis->ac); - redis->poll_fd.revents &= ~G_IO_IN; - } - - if (callback) { - return callback(user_data); - } - - return TRUE; -} - -static void -redis_source_finalize (GSource *source) -{ - RedisSource *redis = (RedisSource *)source; - - if (redis->poll_fd.fd >= 0) { - g_source_remove_poll(source, &redis->poll_fd); - redis->poll_fd.fd = -1; - } -} - -static GSource * -redis_source_new (redisAsyncContext *ac) -{ - static GSourceFuncs source_funcs = { - .prepare = redis_source_prepare, - .check = redis_source_check, - .dispatch = redis_source_dispatch, - .finalize = redis_source_finalize, - }; - redisContext *c = &ac->c; - RedisSource *source; - - g_return_val_if_fail(ac != NULL, NULL); - - source = (RedisSource *)g_source_new(&source_funcs, sizeof *source); - if (source == NULL) - return NULL; - - source->ac = ac; - source->poll_fd.fd = c->fd; - source->poll_fd.events = 0; - source->poll_fd.revents = 0; - g_source_add_poll((GSource *)source, &source->poll_fd); - - ac->ev.addRead = redis_source_add_read; - ac->ev.delRead = redis_source_del_read; - ac->ev.addWrite = redis_source_add_write; - ac->ev.delWrite = redis_source_del_write; - ac->ev.cleanup = redis_source_cleanup; - ac->ev.data = source; - - return (GSource *)source; -} - -#endif /* __HIREDIS_GLIB_H__ */ diff --git a/libvalkey/adapters/ivykis.h b/libvalkey/adapters/ivykis.h deleted file mode 100644 index 179f6ab5..00000000 --- a/libvalkey/adapters/ivykis.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef __HIREDIS_IVYKIS_H__ -#define __HIREDIS_IVYKIS_H__ -#include -#include "../hiredis.h" -#include "../async.h" - -typedef struct redisIvykisEvents { - redisAsyncContext *context; - struct iv_fd fd; -} redisIvykisEvents; - -static void redisIvykisReadEvent(void *arg) { - redisAsyncContext *context = (redisAsyncContext *)arg; - redisAsyncHandleRead(context); -} - -static void redisIvykisWriteEvent(void *arg) { - redisAsyncContext *context = (redisAsyncContext *)arg; - redisAsyncHandleWrite(context); -} - -static void redisIvykisAddRead(void *privdata) { - redisIvykisEvents *e = (redisIvykisEvents*)privdata; - iv_fd_set_handler_in(&e->fd, redisIvykisReadEvent); -} - -static void redisIvykisDelRead(void *privdata) { - redisIvykisEvents *e = (redisIvykisEvents*)privdata; - iv_fd_set_handler_in(&e->fd, NULL); -} - -static void redisIvykisAddWrite(void *privdata) { - redisIvykisEvents *e = (redisIvykisEvents*)privdata; - iv_fd_set_handler_out(&e->fd, redisIvykisWriteEvent); -} - -static void redisIvykisDelWrite(void *privdata) { - redisIvykisEvents *e = (redisIvykisEvents*)privdata; - iv_fd_set_handler_out(&e->fd, NULL); -} - -static void redisIvykisCleanup(void *privdata) { - redisIvykisEvents *e = (redisIvykisEvents*)privdata; - - iv_fd_unregister(&e->fd); - hi_free(e); -} - -static int redisIvykisAttach(redisAsyncContext *ac) { - redisContext *c = &(ac->c); - redisIvykisEvents *e; - - /* Nothing should be attached when something is already attached */ - if (ac->ev.data != NULL) - return REDIS_ERR; - - /* Create container for context and r/w events */ - e = (redisIvykisEvents*)hi_malloc(sizeof(*e)); - if (e == NULL) - return REDIS_ERR; - - e->context = ac; - - /* Register functions to start/stop listening for events */ - ac->ev.addRead = redisIvykisAddRead; - ac->ev.delRead = redisIvykisDelRead; - ac->ev.addWrite = redisIvykisAddWrite; - ac->ev.delWrite = redisIvykisDelWrite; - ac->ev.cleanup = redisIvykisCleanup; - ac->ev.data = e; - - /* Initialize and install read/write events */ - IV_FD_INIT(&e->fd); - e->fd.fd = c->fd; - e->fd.handler_in = redisIvykisReadEvent; - e->fd.handler_out = redisIvykisWriteEvent; - e->fd.handler_err = NULL; - e->fd.cookie = e->context; - - iv_fd_register(&e->fd); - - return REDIS_OK; -} -#endif diff --git a/libvalkey/adapters/libev.h b/libvalkey/adapters/libev.h deleted file mode 100644 index c59d3da7..00000000 --- a/libvalkey/adapters/libev.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2010-2011, Pieter Noordhuis - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __HIREDIS_LIBEV_H__ -#define __HIREDIS_LIBEV_H__ -#include -#include -#include -#include "../hiredis.h" -#include "../async.h" - -typedef struct redisLibevEvents { - redisAsyncContext *context; - struct ev_loop *loop; - int reading, writing; - ev_io rev, wev; - ev_timer timer; -} redisLibevEvents; - -static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) { -#if EV_MULTIPLICITY - ((void)EV_A); -#endif - ((void)revents); - - redisLibevEvents *e = (redisLibevEvents*)watcher->data; - redisAsyncHandleRead(e->context); -} - -static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) { -#if EV_MULTIPLICITY - ((void)EV_A); -#endif - ((void)revents); - - redisLibevEvents *e = (redisLibevEvents*)watcher->data; - redisAsyncHandleWrite(e->context); -} - -static void redisLibevAddRead(void *privdata) { - redisLibevEvents *e = (redisLibevEvents*)privdata; -#if EV_MULTIPLICITY - struct ev_loop *loop = e->loop; -#endif - if (!e->reading) { - e->reading = 1; - ev_io_start(EV_A_ &e->rev); - } -} - -static void redisLibevDelRead(void *privdata) { - redisLibevEvents *e = (redisLibevEvents*)privdata; -#if EV_MULTIPLICITY - struct ev_loop *loop = e->loop; -#endif - if (e->reading) { - e->reading = 0; - ev_io_stop(EV_A_ &e->rev); - } -} - -static void redisLibevAddWrite(void *privdata) { - redisLibevEvents *e = (redisLibevEvents*)privdata; -#if EV_MULTIPLICITY - struct ev_loop *loop = e->loop; -#endif - if (!e->writing) { - e->writing = 1; - ev_io_start(EV_A_ &e->wev); - } -} - -static void redisLibevDelWrite(void *privdata) { - redisLibevEvents *e = (redisLibevEvents*)privdata; -#if EV_MULTIPLICITY - struct ev_loop *loop = e->loop; -#endif - if (e->writing) { - e->writing = 0; - ev_io_stop(EV_A_ &e->wev); - } -} - -static void redisLibevStopTimer(void *privdata) { - redisLibevEvents *e = (redisLibevEvents*)privdata; -#if EV_MULTIPLICITY - struct ev_loop *loop = e->loop; -#endif - ev_timer_stop(EV_A_ &e->timer); -} - -static void redisLibevCleanup(void *privdata) { - redisLibevEvents *e = (redisLibevEvents*)privdata; - redisLibevDelRead(privdata); - redisLibevDelWrite(privdata); - redisLibevStopTimer(privdata); - hi_free(e); -} - -static void redisLibevTimeout(EV_P_ ev_timer *timer, int revents) { -#if EV_MULTIPLICITY - ((void)EV_A); -#endif - ((void)revents); - redisLibevEvents *e = (redisLibevEvents*)timer->data; - redisAsyncHandleTimeout(e->context); -} - -static void redisLibevSetTimeout(void *privdata, struct timeval tv) { - redisLibevEvents *e = (redisLibevEvents*)privdata; -#if EV_MULTIPLICITY - struct ev_loop *loop = e->loop; -#endif - - if (!ev_is_active(&e->timer)) { - ev_init(&e->timer, redisLibevTimeout); - e->timer.data = e; - } - - e->timer.repeat = tv.tv_sec + tv.tv_usec / 1000000.00; - ev_timer_again(EV_A_ &e->timer); -} - -static int redisLibevAttach(EV_P_ redisAsyncContext *ac) { - redisContext *c = &(ac->c); - redisLibevEvents *e; - - /* Nothing should be attached when something is already attached */ - if (ac->ev.data != NULL) - return REDIS_ERR; - - /* Create container for context and r/w events */ - e = (redisLibevEvents*)hi_calloc(1, sizeof(*e)); - if (e == NULL) - return REDIS_ERR; - - e->context = ac; -#if EV_MULTIPLICITY - e->loop = EV_A; -#else - e->loop = NULL; -#endif - e->rev.data = e; - e->wev.data = e; - - /* Register functions to start/stop listening for events */ - ac->ev.addRead = redisLibevAddRead; - ac->ev.delRead = redisLibevDelRead; - ac->ev.addWrite = redisLibevAddWrite; - ac->ev.delWrite = redisLibevDelWrite; - ac->ev.cleanup = redisLibevCleanup; - ac->ev.scheduleTimer = redisLibevSetTimeout; - ac->ev.data = e; - - /* Initialize read/write events */ - ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ); - ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE); - return REDIS_OK; -} - -#endif diff --git a/libvalkey/adapters/libevent.h b/libvalkey/adapters/libevent.h deleted file mode 100644 index 73bb8ed7..00000000 --- a/libvalkey/adapters/libevent.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2010-2011, Pieter Noordhuis - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __HIREDIS_LIBEVENT_H__ -#define __HIREDIS_LIBEVENT_H__ -#include -#include "../hiredis.h" -#include "../async.h" - -#define REDIS_LIBEVENT_DELETED 0x01 -#define REDIS_LIBEVENT_ENTERED 0x02 - -typedef struct redisLibeventEvents { - redisAsyncContext *context; - struct event *ev; - struct event_base *base; - struct timeval tv; - short flags; - short state; -} redisLibeventEvents; - -static void redisLibeventDestroy(redisLibeventEvents *e) { - hi_free(e); -} - -static void redisLibeventHandler(evutil_socket_t fd, short event, void *arg) { - ((void)fd); - redisLibeventEvents *e = (redisLibeventEvents*)arg; - e->state |= REDIS_LIBEVENT_ENTERED; - - #define CHECK_DELETED() if (e->state & REDIS_LIBEVENT_DELETED) {\ - redisLibeventDestroy(e);\ - return; \ - } - - if ((event & EV_TIMEOUT) && (e->state & REDIS_LIBEVENT_DELETED) == 0) { - redisAsyncHandleTimeout(e->context); - CHECK_DELETED(); - } - - if ((event & EV_READ) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) { - redisAsyncHandleRead(e->context); - CHECK_DELETED(); - } - - if ((event & EV_WRITE) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) { - redisAsyncHandleWrite(e->context); - CHECK_DELETED(); - } - - e->state &= ~REDIS_LIBEVENT_ENTERED; - #undef CHECK_DELETED -} - -static void redisLibeventUpdate(void *privdata, short flag, int isRemove) { - redisLibeventEvents *e = (redisLibeventEvents *)privdata; - const struct timeval *tv = e->tv.tv_sec || e->tv.tv_usec ? &e->tv : NULL; - - if (isRemove) { - if ((e->flags & flag) == 0) { - return; - } else { - e->flags &= ~flag; - } - } else { - if (e->flags & flag) { - return; - } else { - e->flags |= flag; - } - } - - event_del(e->ev); - event_assign(e->ev, e->base, e->context->c.fd, e->flags | EV_PERSIST, - redisLibeventHandler, privdata); - event_add(e->ev, tv); -} - -static void redisLibeventAddRead(void *privdata) { - redisLibeventUpdate(privdata, EV_READ, 0); -} - -static void redisLibeventDelRead(void *privdata) { - redisLibeventUpdate(privdata, EV_READ, 1); -} - -static void redisLibeventAddWrite(void *privdata) { - redisLibeventUpdate(privdata, EV_WRITE, 0); -} - -static void redisLibeventDelWrite(void *privdata) { - redisLibeventUpdate(privdata, EV_WRITE, 1); -} - -static void redisLibeventCleanup(void *privdata) { - redisLibeventEvents *e = (redisLibeventEvents*)privdata; - if (!e) { - return; - } - event_del(e->ev); - event_free(e->ev); - e->ev = NULL; - - if (e->state & REDIS_LIBEVENT_ENTERED) { - e->state |= REDIS_LIBEVENT_DELETED; - } else { - redisLibeventDestroy(e); - } -} - -static void redisLibeventSetTimeout(void *privdata, struct timeval tv) { - redisLibeventEvents *e = (redisLibeventEvents *)privdata; - short flags = e->flags; - e->flags = 0; - e->tv = tv; - redisLibeventUpdate(e, flags, 0); -} - -static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) { - redisContext *c = &(ac->c); - redisLibeventEvents *e; - - /* Nothing should be attached when something is already attached */ - if (ac->ev.data != NULL) - return REDIS_ERR; - - /* Create container for context and r/w events */ - e = (redisLibeventEvents*)hi_calloc(1, sizeof(*e)); - if (e == NULL) - return REDIS_ERR; - - e->context = ac; - - /* Register functions to start/stop listening for events */ - ac->ev.addRead = redisLibeventAddRead; - ac->ev.delRead = redisLibeventDelRead; - ac->ev.addWrite = redisLibeventAddWrite; - ac->ev.delWrite = redisLibeventDelWrite; - ac->ev.cleanup = redisLibeventCleanup; - ac->ev.scheduleTimer = redisLibeventSetTimeout; - ac->ev.data = e; - - /* Initialize and install read/write events */ - e->ev = event_new(base, c->fd, EV_READ | EV_WRITE, redisLibeventHandler, e); - e->base = base; - return REDIS_OK; -} -#endif diff --git a/libvalkey/adapters/libhv.h b/libvalkey/adapters/libhv.h deleted file mode 100644 index 3b54c70f..00000000 --- a/libvalkey/adapters/libhv.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef __HIREDIS_LIBHV_H__ -#define __HIREDIS_LIBHV_H__ - -#include -#include "../hiredis.h" -#include "../async.h" - -typedef struct redisLibhvEvents { - hio_t *io; - htimer_t *timer; -} redisLibhvEvents; - -static void redisLibhvHandleEvents(hio_t* io) { - redisAsyncContext* context = (redisAsyncContext*)hevent_userdata(io); - int events = hio_events(io); - int revents = hio_revents(io); - if (context && (events & HV_READ) && (revents & HV_READ)) { - redisAsyncHandleRead(context); - } - if (context && (events & HV_WRITE) && (revents & HV_WRITE)) { - redisAsyncHandleWrite(context); - } -} - -static void redisLibhvAddRead(void *privdata) { - redisLibhvEvents* events = (redisLibhvEvents*)privdata; - hio_add(events->io, redisLibhvHandleEvents, HV_READ); -} - -static void redisLibhvDelRead(void *privdata) { - redisLibhvEvents* events = (redisLibhvEvents*)privdata; - hio_del(events->io, HV_READ); -} - -static void redisLibhvAddWrite(void *privdata) { - redisLibhvEvents* events = (redisLibhvEvents*)privdata; - hio_add(events->io, redisLibhvHandleEvents, HV_WRITE); -} - -static void redisLibhvDelWrite(void *privdata) { - redisLibhvEvents* events = (redisLibhvEvents*)privdata; - hio_del(events->io, HV_WRITE); -} - -static void redisLibhvCleanup(void *privdata) { - redisLibhvEvents* events = (redisLibhvEvents*)privdata; - - if (events->timer) - htimer_del(events->timer); - - hio_close(events->io); - hevent_set_userdata(events->io, NULL); - - hi_free(events); -} - -static void redisLibhvTimeout(htimer_t* timer) { - hio_t* io = (hio_t*)hevent_userdata(timer); - redisAsyncHandleTimeout((redisAsyncContext*)hevent_userdata(io)); -} - -static void redisLibhvSetTimeout(void *privdata, struct timeval tv) { - redisLibhvEvents* events; - uint32_t millis; - hloop_t* loop; - - events = (redisLibhvEvents*)privdata; - millis = tv.tv_sec * 1000 + tv.tv_usec / 1000; - - if (millis == 0) { - /* Libhv disallows zero'd timers so treat this as a delete or NO OP */ - if (events->timer) { - htimer_del(events->timer); - events->timer = NULL; - } - } else if (events->timer == NULL) { - /* Add new timer */ - loop = hevent_loop(events->io); - events->timer = htimer_add(loop, redisLibhvTimeout, millis, 1); - hevent_set_userdata(events->timer, events->io); - } else { - /* Update existing timer */ - htimer_reset(events->timer, millis); - } -} - -static int redisLibhvAttach(redisAsyncContext* ac, hloop_t* loop) { - redisContext *c = &(ac->c); - redisLibhvEvents *events; - hio_t* io = NULL; - - if (ac->ev.data != NULL) { - return REDIS_ERR; - } - - /* Create container struct to keep track of our io and any timer */ - events = (redisLibhvEvents*)hi_malloc(sizeof(*events)); - if (events == NULL) { - return REDIS_ERR; - } - - io = hio_get(loop, c->fd); - if (io == NULL) { - hi_free(events); - return REDIS_ERR; - } - - hevent_set_userdata(io, ac); - - events->io = io; - events->timer = NULL; - - ac->ev.addRead = redisLibhvAddRead; - ac->ev.delRead = redisLibhvDelRead; - ac->ev.addWrite = redisLibhvAddWrite; - ac->ev.delWrite = redisLibhvDelWrite; - ac->ev.cleanup = redisLibhvCleanup; - ac->ev.scheduleTimer = redisLibhvSetTimeout; - ac->ev.data = events; - - return REDIS_OK; -} -#endif diff --git a/libvalkey/adapters/libsdevent.h b/libvalkey/adapters/libsdevent.h deleted file mode 100644 index 1268ed9f..00000000 --- a/libvalkey/adapters/libsdevent.h +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef HIREDIS_LIBSDEVENT_H -#define HIREDIS_LIBSDEVENT_H -#include -#include "../hiredis.h" -#include "../async.h" - -#define REDIS_LIBSDEVENT_DELETED 0x01 -#define REDIS_LIBSDEVENT_ENTERED 0x02 - -typedef struct redisLibsdeventEvents { - redisAsyncContext *context; - struct sd_event *event; - struct sd_event_source *fdSource; - struct sd_event_source *timerSource; - int fd; - short flags; - short state; -} redisLibsdeventEvents; - -static void redisLibsdeventDestroy(redisLibsdeventEvents *e) { - if (e->fdSource) { - e->fdSource = sd_event_source_disable_unref(e->fdSource); - } - if (e->timerSource) { - e->timerSource = sd_event_source_disable_unref(e->timerSource); - } - sd_event_unref(e->event); - hi_free(e); -} - -static int redisLibsdeventTimeoutHandler(sd_event_source *s, uint64_t usec, void *userdata) { - ((void)s); - ((void)usec); - redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; - redisAsyncHandleTimeout(e->context); - return 0; -} - -static int redisLibsdeventHandler(sd_event_source *s, int fd, uint32_t event, void *userdata) { - ((void)s); - ((void)fd); - redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; - e->state |= REDIS_LIBSDEVENT_ENTERED; - -#define CHECK_DELETED() if (e->state & REDIS_LIBSDEVENT_DELETED) {\ - redisLibsdeventDestroy(e);\ - return 0; \ - } - - if ((event & EPOLLIN) && e->context && (e->state & REDIS_LIBSDEVENT_DELETED) == 0) { - redisAsyncHandleRead(e->context); - CHECK_DELETED(); - } - - if ((event & EPOLLOUT) && e->context && (e->state & REDIS_LIBSDEVENT_DELETED) == 0) { - redisAsyncHandleWrite(e->context); - CHECK_DELETED(); - } - - e->state &= ~REDIS_LIBSDEVENT_ENTERED; -#undef CHECK_DELETED - - return 0; -} - -static void redisLibsdeventAddRead(void *userdata) { - redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; - - if (e->flags & EPOLLIN) { - return; - } - - e->flags |= EPOLLIN; - - if (e->flags & EPOLLOUT) { - sd_event_source_set_io_events(e->fdSource, e->flags); - } else { - sd_event_add_io(e->event, &e->fdSource, e->fd, e->flags, redisLibsdeventHandler, e); - } -} - -static void redisLibsdeventDelRead(void *userdata) { - redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; - - e->flags &= ~EPOLLIN; - - if (e->flags) { - sd_event_source_set_io_events(e->fdSource, e->flags); - } else { - e->fdSource = sd_event_source_disable_unref(e->fdSource); - } -} - -static void redisLibsdeventAddWrite(void *userdata) { - redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; - - if (e->flags & EPOLLOUT) { - return; - } - - e->flags |= EPOLLOUT; - - if (e->flags & EPOLLIN) { - sd_event_source_set_io_events(e->fdSource, e->flags); - } else { - sd_event_add_io(e->event, &e->fdSource, e->fd, e->flags, redisLibsdeventHandler, e); - } -} - -static void redisLibsdeventDelWrite(void *userdata) { - redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; - - e->flags &= ~EPOLLOUT; - - if (e->flags) { - sd_event_source_set_io_events(e->fdSource, e->flags); - } else { - e->fdSource = sd_event_source_disable_unref(e->fdSource); - } -} - -static void redisLibsdeventCleanup(void *userdata) { - redisLibsdeventEvents *e = (redisLibsdeventEvents*)userdata; - - if (!e) { - return; - } - - if (e->state & REDIS_LIBSDEVENT_ENTERED) { - e->state |= REDIS_LIBSDEVENT_DELETED; - } else { - redisLibsdeventDestroy(e); - } -} - -static void redisLibsdeventSetTimeout(void *userdata, struct timeval tv) { - redisLibsdeventEvents *e = (redisLibsdeventEvents *)userdata; - - uint64_t usec = tv.tv_sec * 1000000 + tv.tv_usec; - if (!e->timerSource) { - sd_event_add_time_relative(e->event, &e->timerSource, CLOCK_MONOTONIC, usec, 1, redisLibsdeventTimeoutHandler, e); - } else { - sd_event_source_set_time_relative(e->timerSource, usec); - } -} - -static int redisLibsdeventAttach(redisAsyncContext *ac, struct sd_event *event) { - redisContext *c = &(ac->c); - redisLibsdeventEvents *e; - - /* Nothing should be attached when something is already attached */ - if (ac->ev.data != NULL) - return REDIS_ERR; - - /* Create container for context and r/w events */ - e = (redisLibsdeventEvents*)hi_calloc(1, sizeof(*e)); - if (e == NULL) - return REDIS_ERR; - - /* Initialize and increase event refcount */ - e->context = ac; - e->event = event; - e->fd = c->fd; - sd_event_ref(event); - - /* Register functions to start/stop listening for events */ - ac->ev.addRead = redisLibsdeventAddRead; - ac->ev.delRead = redisLibsdeventDelRead; - ac->ev.addWrite = redisLibsdeventAddWrite; - ac->ev.delWrite = redisLibsdeventDelWrite; - ac->ev.cleanup = redisLibsdeventCleanup; - ac->ev.scheduleTimer = redisLibsdeventSetTimeout; - ac->ev.data = e; - - return REDIS_OK; -} -#endif diff --git a/libvalkey/adapters/libuv.h b/libvalkey/adapters/libuv.h deleted file mode 100644 index ec67c15a..00000000 --- a/libvalkey/adapters/libuv.h +++ /dev/null @@ -1,172 +0,0 @@ -#ifndef __HIREDIS_LIBUV_H__ -#define __HIREDIS_LIBUV_H__ -#include -#include -#include "../hiredis.h" -#include "../async.h" -#include - -typedef struct redisLibuvEvents { - redisAsyncContext* context; - uv_poll_t handle; - uv_timer_t timer; - int events; -} redisLibuvEvents; - - -static void redisLibuvPoll(uv_poll_t* handle, int status, int events) { - redisLibuvEvents* p = (redisLibuvEvents*)handle->data; - int ev = (status ? p->events : events); - - if (p->context != NULL && (ev & UV_READABLE)) { - redisAsyncHandleRead(p->context); - } - if (p->context != NULL && (ev & UV_WRITABLE)) { - redisAsyncHandleWrite(p->context); - } -} - - -static void redisLibuvAddRead(void *privdata) { - redisLibuvEvents* p = (redisLibuvEvents*)privdata; - - if (p->events & UV_READABLE) { - return; - } - - p->events |= UV_READABLE; - - uv_poll_start(&p->handle, p->events, redisLibuvPoll); -} - - -static void redisLibuvDelRead(void *privdata) { - redisLibuvEvents* p = (redisLibuvEvents*)privdata; - - p->events &= ~UV_READABLE; - - if (p->events) { - uv_poll_start(&p->handle, p->events, redisLibuvPoll); - } else { - uv_poll_stop(&p->handle); - } -} - - -static void redisLibuvAddWrite(void *privdata) { - redisLibuvEvents* p = (redisLibuvEvents*)privdata; - - if (p->events & UV_WRITABLE) { - return; - } - - p->events |= UV_WRITABLE; - - uv_poll_start(&p->handle, p->events, redisLibuvPoll); -} - - -static void redisLibuvDelWrite(void *privdata) { - redisLibuvEvents* p = (redisLibuvEvents*)privdata; - - p->events &= ~UV_WRITABLE; - - if (p->events) { - uv_poll_start(&p->handle, p->events, redisLibuvPoll); - } else { - uv_poll_stop(&p->handle); - } -} - -static void on_timer_close(uv_handle_t *handle) { - redisLibuvEvents* p = (redisLibuvEvents*)handle->data; - p->timer.data = NULL; - if (!p->handle.data) { - // both timer and handle are closed - hi_free(p); - } - // else, wait for `on_handle_close` -} - -static void on_handle_close(uv_handle_t *handle) { - redisLibuvEvents* p = (redisLibuvEvents*)handle->data; - p->handle.data = NULL; - if (!p->timer.data) { - // timer never started, or timer already destroyed - hi_free(p); - } - // else, wait for `on_timer_close` -} - -// libuv removed `status` parameter since v0.11.23 -// see: https://github.com/libuv/libuv/blob/v0.11.23/include/uv.h -#if (UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR < 11) || \ - (UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR == 11 && UV_VERSION_PATCH < 23) -static void redisLibuvTimeout(uv_timer_t *timer, int status) { - (void)status; // unused -#else -static void redisLibuvTimeout(uv_timer_t *timer) { -#endif - redisLibuvEvents *e = (redisLibuvEvents*)timer->data; - redisAsyncHandleTimeout(e->context); -} - -static void redisLibuvSetTimeout(void *privdata, struct timeval tv) { - redisLibuvEvents* p = (redisLibuvEvents*)privdata; - - uint64_t millsec = tv.tv_sec * 1000 + tv.tv_usec / 1000.0; - if (!p->timer.data) { - // timer is uninitialized - if (uv_timer_init(p->handle.loop, &p->timer) != 0) { - return; - } - p->timer.data = p; - } - // updates the timeout if the timer has already started - // or start the timer - uv_timer_start(&p->timer, redisLibuvTimeout, millsec, 0); -} - -static void redisLibuvCleanup(void *privdata) { - redisLibuvEvents* p = (redisLibuvEvents*)privdata; - - p->context = NULL; // indicate that context might no longer exist - if (p->timer.data) { - uv_close((uv_handle_t*)&p->timer, on_timer_close); - } - uv_close((uv_handle_t*)&p->handle, on_handle_close); -} - - -static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) { - redisContext *c = &(ac->c); - - if (ac->ev.data != NULL) { - return REDIS_ERR; - } - - ac->ev.addRead = redisLibuvAddRead; - ac->ev.delRead = redisLibuvDelRead; - ac->ev.addWrite = redisLibuvAddWrite; - ac->ev.delWrite = redisLibuvDelWrite; - ac->ev.cleanup = redisLibuvCleanup; - ac->ev.scheduleTimer = redisLibuvSetTimeout; - - redisLibuvEvents* p = (redisLibuvEvents*)hi_malloc(sizeof(*p)); - if (p == NULL) - return REDIS_ERR; - - memset(p, 0, sizeof(*p)); - - if (uv_poll_init_socket(loop, &p->handle, c->fd) != 0) { - hi_free(p); - return REDIS_ERR; - } - - ac->ev.data = p; - p->handle.data = p; - p->context = ac; - - return REDIS_OK; -} -#endif diff --git a/libvalkey/adapters/macosx.h b/libvalkey/adapters/macosx.h deleted file mode 100644 index 3c87f1b2..00000000 --- a/libvalkey/adapters/macosx.h +++ /dev/null @@ -1,115 +0,0 @@ -// -// Created by Дмитрий Бахвалов on 13.07.15. -// Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved. -// - -#ifndef __HIREDIS_MACOSX_H__ -#define __HIREDIS_MACOSX_H__ - -#include - -#include "../hiredis.h" -#include "../async.h" - -typedef struct { - redisAsyncContext *context; - CFSocketRef socketRef; - CFRunLoopSourceRef sourceRef; -} RedisRunLoop; - -static int freeRedisRunLoop(RedisRunLoop* redisRunLoop) { - if( redisRunLoop != NULL ) { - if( redisRunLoop->sourceRef != NULL ) { - CFRunLoopSourceInvalidate(redisRunLoop->sourceRef); - CFRelease(redisRunLoop->sourceRef); - } - if( redisRunLoop->socketRef != NULL ) { - CFSocketInvalidate(redisRunLoop->socketRef); - CFRelease(redisRunLoop->socketRef); - } - hi_free(redisRunLoop); - } - return REDIS_ERR; -} - -static void redisMacOSAddRead(void *privdata) { - RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; - CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); -} - -static void redisMacOSDelRead(void *privdata) { - RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; - CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); -} - -static void redisMacOSAddWrite(void *privdata) { - RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; - CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); -} - -static void redisMacOSDelWrite(void *privdata) { - RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; - CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); -} - -static void redisMacOSCleanup(void *privdata) { - RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; - freeRedisRunLoop(redisRunLoop); -} - -static void redisMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) { - redisAsyncContext* context = (redisAsyncContext*) info; - - switch (callbackType) { - case kCFSocketReadCallBack: - redisAsyncHandleRead(context); - break; - - case kCFSocketWriteCallBack: - redisAsyncHandleWrite(context); - break; - - default: - break; - } -} - -static int redisMacOSAttach(redisAsyncContext *redisAsyncCtx, CFRunLoopRef runLoop) { - redisContext *redisCtx = &(redisAsyncCtx->c); - - /* Nothing should be attached when something is already attached */ - if( redisAsyncCtx->ev.data != NULL ) return REDIS_ERR; - - RedisRunLoop* redisRunLoop = (RedisRunLoop*) hi_calloc(1, sizeof(RedisRunLoop)); - if (redisRunLoop == NULL) - return REDIS_ERR; - - /* Setup redis stuff */ - redisRunLoop->context = redisAsyncCtx; - - redisAsyncCtx->ev.addRead = redisMacOSAddRead; - redisAsyncCtx->ev.delRead = redisMacOSDelRead; - redisAsyncCtx->ev.addWrite = redisMacOSAddWrite; - redisAsyncCtx->ev.delWrite = redisMacOSDelWrite; - redisAsyncCtx->ev.cleanup = redisMacOSCleanup; - redisAsyncCtx->ev.data = redisRunLoop; - - /* Initialize and install read/write events */ - CFSocketContext socketCtx = { 0, redisAsyncCtx, NULL, NULL, NULL }; - - redisRunLoop->socketRef = CFSocketCreateWithNative(NULL, redisCtx->fd, - kCFSocketReadCallBack | kCFSocketWriteCallBack, - redisMacOSAsyncCallback, - &socketCtx); - if( !redisRunLoop->socketRef ) return freeRedisRunLoop(redisRunLoop); - - redisRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redisRunLoop->socketRef, 0); - if( !redisRunLoop->sourceRef ) return freeRedisRunLoop(redisRunLoop); - - CFRunLoopAddSource(runLoop, redisRunLoop->sourceRef, kCFRunLoopDefaultMode); - - return REDIS_OK; -} - -#endif - diff --git a/libvalkey/adapters/redismoduleapi.h b/libvalkey/adapters/redismoduleapi.h deleted file mode 100644 index 8a076fe4..00000000 --- a/libvalkey/adapters/redismoduleapi.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef __HIREDIS_REDISMODULEAPI_H__ -#define __HIREDIS_REDISMODULEAPI_H__ - -#include "redismodule.h" - -#include "../async.h" -#include "../hiredis.h" - -#include - -typedef struct redisModuleEvents { - redisAsyncContext *context; - RedisModuleCtx *module_ctx; - int fd; - int reading, writing; - int timer_active; - RedisModuleTimerID timer_id; -} redisModuleEvents; - -static inline void redisModuleReadEvent(int fd, void *privdata, int mask) { - (void) fd; - (void) mask; - - redisModuleEvents *e = (redisModuleEvents*)privdata; - redisAsyncHandleRead(e->context); -} - -static inline void redisModuleWriteEvent(int fd, void *privdata, int mask) { - (void) fd; - (void) mask; - - redisModuleEvents *e = (redisModuleEvents*)privdata; - redisAsyncHandleWrite(e->context); -} - -static inline void redisModuleAddRead(void *privdata) { - redisModuleEvents *e = (redisModuleEvents*)privdata; - if (!e->reading) { - e->reading = 1; - RedisModule_EventLoopAdd(e->fd, REDISMODULE_EVENTLOOP_READABLE, redisModuleReadEvent, e); - } -} - -static inline void redisModuleDelRead(void *privdata) { - redisModuleEvents *e = (redisModuleEvents*)privdata; - if (e->reading) { - e->reading = 0; - RedisModule_EventLoopDel(e->fd, REDISMODULE_EVENTLOOP_READABLE); - } -} - -static inline void redisModuleAddWrite(void *privdata) { - redisModuleEvents *e = (redisModuleEvents*)privdata; - if (!e->writing) { - e->writing = 1; - RedisModule_EventLoopAdd(e->fd, REDISMODULE_EVENTLOOP_WRITABLE, redisModuleWriteEvent, e); - } -} - -static inline void redisModuleDelWrite(void *privdata) { - redisModuleEvents *e = (redisModuleEvents*)privdata; - if (e->writing) { - e->writing = 0; - RedisModule_EventLoopDel(e->fd, REDISMODULE_EVENTLOOP_WRITABLE); - } -} - -static inline void redisModuleStopTimer(void *privdata) { - redisModuleEvents *e = (redisModuleEvents*)privdata; - if (e->timer_active) { - RedisModule_StopTimer(e->module_ctx, e->timer_id, NULL); - } - e->timer_active = 0; -} - -static inline void redisModuleCleanup(void *privdata) { - redisModuleEvents *e = (redisModuleEvents*)privdata; - redisModuleDelRead(privdata); - redisModuleDelWrite(privdata); - redisModuleStopTimer(privdata); - hi_free(e); -} - -static inline void redisModuleTimeout(RedisModuleCtx *ctx, void *privdata) { - (void) ctx; - - redisModuleEvents *e = (redisModuleEvents*)privdata; - e->timer_active = 0; - redisAsyncHandleTimeout(e->context); -} - -static inline void redisModuleSetTimeout(void *privdata, struct timeval tv) { - redisModuleEvents* e = (redisModuleEvents*)privdata; - - redisModuleStopTimer(privdata); - - mstime_t millis = tv.tv_sec * 1000 + tv.tv_usec / 1000.0; - e->timer_id = RedisModule_CreateTimer(e->module_ctx, millis, redisModuleTimeout, e); - e->timer_active = 1; -} - -/* Check if Redis version is compatible with the adapter. */ -static inline int redisModuleCompatibilityCheck(void) { - if (!RedisModule_EventLoopAdd || - !RedisModule_EventLoopDel || - !RedisModule_CreateTimer || - !RedisModule_StopTimer) { - return REDIS_ERR; - } - return REDIS_OK; -} - -static inline int redisModuleAttach(redisAsyncContext *ac, RedisModuleCtx *module_ctx) { - redisContext *c = &(ac->c); - redisModuleEvents *e; - - /* Nothing should be attached when something is already attached */ - if (ac->ev.data != NULL) - return REDIS_ERR; - - /* Create container for context and r/w events */ - e = (redisModuleEvents*)hi_malloc(sizeof(*e)); - if (e == NULL) - return REDIS_ERR; - - e->context = ac; - e->module_ctx = module_ctx; - e->fd = c->fd; - e->reading = e->writing = 0; - e->timer_active = 0; - - /* Register functions to start/stop listening for events */ - ac->ev.addRead = redisModuleAddRead; - ac->ev.delRead = redisModuleDelRead; - ac->ev.addWrite = redisModuleAddWrite; - ac->ev.delWrite = redisModuleDelWrite; - ac->ev.cleanup = redisModuleCleanup; - ac->ev.scheduleTimer = redisModuleSetTimeout; - ac->ev.data = e; - - return REDIS_OK; -} - -#endif diff --git a/libvalkey/dict.c b/libvalkey/dict.c deleted file mode 100644 index ad571818..00000000 --- a/libvalkey/dict.c +++ /dev/null @@ -1,343 +0,0 @@ -/* Hash table implementation. - * - * This file implements in memory hash tables with insert/del/replace/find/ - * get-random-element operations. Hash tables will auto resize if needed - * tables of power of two in size are used, collisions are handled by - * chaining. See the source code for more information... :) - * - * Copyright (c) 2006-2010, Salvatore Sanfilippo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "fmacros.h" -#include "alloc.h" -#include -#include -#include -#include "dict.h" - -/* -------------------------- private prototypes ---------------------------- */ - -static int _dictExpandIfNeeded(dict *ht); -static unsigned long _dictNextPower(unsigned long size); -static int _dictKeyIndex(dict *ht, const void *key); -static int _dictInit(dict *ht, dictType *type, void *privDataPtr); - -/* -------------------------- hash functions -------------------------------- */ - -/* Generic hash function (a popular one from Bernstein). - * I tested a few and this was the best. */ -static unsigned int dictGenHashFunction(const unsigned char *buf, int len) { - unsigned int hash = 5381; - - while (len--) - hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */ - return hash; -} - -/* ----------------------------- API implementation ------------------------- */ - -/* Reset an hashtable already initialized with ht_init(). - * NOTE: This function should only called by ht_destroy(). */ -static void _dictReset(dict *ht) { - ht->table = NULL; - ht->size = 0; - ht->sizemask = 0; - ht->used = 0; -} - -/* Create a new hash table */ -static dict *dictCreate(dictType *type, void *privDataPtr) { - dict *ht = hi_malloc(sizeof(*ht)); - if (ht == NULL) - return NULL; - - _dictInit(ht,type,privDataPtr); - return ht; -} - -/* Initialize the hash table */ -static int _dictInit(dict *ht, dictType *type, void *privDataPtr) { - _dictReset(ht); - ht->type = type; - ht->privdata = privDataPtr; - return DICT_OK; -} - -/* Expand or create the hashtable */ -static int dictExpand(dict *ht, unsigned long size) { - dict n; /* the new hashtable */ - unsigned long realsize = _dictNextPower(size), i; - - /* the size is invalid if it is smaller than the number of - * elements already inside the hashtable */ - if (ht->used > size) - return DICT_ERR; - - _dictInit(&n, ht->type, ht->privdata); - n.size = realsize; - n.sizemask = realsize-1; - n.table = hi_calloc(realsize,sizeof(dictEntry*)); - if (n.table == NULL) - return DICT_ERR; - - /* Copy all the elements from the old to the new table: - * note that if the old hash table is empty ht->size is zero, - * so dictExpand just creates an hash table. */ - n.used = ht->used; - for (i = 0; i < ht->size && ht->used > 0; i++) { - dictEntry *he, *nextHe; - - if (ht->table[i] == NULL) continue; - - /* For each hash entry on this slot... */ - he = ht->table[i]; - while(he) { - unsigned int h; - - nextHe = he->next; - /* Get the new element index */ - h = dictHashKey(ht, he->key) & n.sizemask; - he->next = n.table[h]; - n.table[h] = he; - ht->used--; - /* Pass to the next element */ - he = nextHe; - } - } - assert(ht->used == 0); - hi_free(ht->table); - - /* Remap the new hashtable in the old */ - *ht = n; - return DICT_OK; -} - -/* Add an element to the target hash table */ -static int dictAdd(dict *ht, void *key, void *val) { - int index; - dictEntry *entry; - - /* Get the index of the new element, or -1 if - * the element already exists. */ - if ((index = _dictKeyIndex(ht, key)) == -1) - return DICT_ERR; - - /* Allocates the memory and stores key */ - entry = hi_malloc(sizeof(*entry)); - if (entry == NULL) - return DICT_ERR; - - entry->next = ht->table[index]; - ht->table[index] = entry; - - /* Set the hash entry fields. */ - dictSetHashKey(ht, entry, key); - dictSetHashVal(ht, entry, val); - ht->used++; - return DICT_OK; -} - -/* Add an element, discarding the old if the key already exists. - * Return 1 if the key was added from scratch, 0 if there was already an - * element with such key and dictReplace() just performed a value update - * operation. */ -static int dictReplace(dict *ht, void *key, void *val) { - dictEntry *entry, auxentry; - - /* Try to add the element. If the key - * does not exists dictAdd will succeed. */ - if (dictAdd(ht, key, val) == DICT_OK) - return 1; - /* It already exists, get the entry */ - entry = dictFind(ht, key); - if (entry == NULL) - return 0; - - /* Free the old value and set the new one */ - /* Set the new value and free the old one. Note that it is important - * to do that in this order, as the value may just be exactly the same - * as the previous one. In this context, think to reference counting, - * you want to increment (set), and then decrement (free), and not the - * reverse. */ - auxentry = *entry; - dictSetHashVal(ht, entry, val); - dictFreeEntryVal(ht, &auxentry); - return 0; -} - -/* Search and remove an element */ -static int dictDelete(dict *ht, const void *key) { - unsigned int h; - dictEntry *de, *prevde; - - if (ht->size == 0) - return DICT_ERR; - h = dictHashKey(ht, key) & ht->sizemask; - de = ht->table[h]; - - prevde = NULL; - while(de) { - if (dictCompareHashKeys(ht,key,de->key)) { - /* Unlink the element from the list */ - if (prevde) - prevde->next = de->next; - else - ht->table[h] = de->next; - - dictFreeEntryKey(ht,de); - dictFreeEntryVal(ht,de); - hi_free(de); - ht->used--; - return DICT_OK; - } - prevde = de; - de = de->next; - } - return DICT_ERR; /* not found */ -} - -/* Destroy an entire hash table */ -static int _dictClear(dict *ht) { - unsigned long i; - - /* Free all the elements */ - for (i = 0; i < ht->size && ht->used > 0; i++) { - dictEntry *he, *nextHe; - - if ((he = ht->table[i]) == NULL) continue; - while(he) { - nextHe = he->next; - dictFreeEntryKey(ht, he); - dictFreeEntryVal(ht, he); - hi_free(he); - ht->used--; - he = nextHe; - } - } - /* Free the table and the allocated cache structure */ - hi_free(ht->table); - /* Re-initialize the table */ - _dictReset(ht); - return DICT_OK; /* never fails */ -} - -/* Clear & Release the hash table */ -static void dictRelease(dict *ht) { - _dictClear(ht); - hi_free(ht); -} - -static dictEntry *dictFind(dict *ht, const void *key) { - dictEntry *he; - unsigned int h; - - if (ht->size == 0) return NULL; - h = dictHashKey(ht, key) & ht->sizemask; - he = ht->table[h]; - while(he) { - if (dictCompareHashKeys(ht, key, he->key)) - return he; - he = he->next; - } - return NULL; -} - -static void dictInitIterator(dictIterator *iter, dict *ht) { - iter->ht = ht; - iter->index = -1; - iter->entry = NULL; - iter->nextEntry = NULL; -} - -static dictEntry *dictNext(dictIterator *iter) { - while (1) { - if (iter->entry == NULL) { - iter->index++; - if (iter->index >= - (signed)iter->ht->size) break; - iter->entry = iter->ht->table[iter->index]; - } else { - iter->entry = iter->nextEntry; - } - if (iter->entry) { - /* We need to save the 'next' here, the iterator user - * may delete the entry we are returning. */ - iter->nextEntry = iter->entry->next; - return iter->entry; - } - } - return NULL; -} - -/* ------------------------- private functions ------------------------------ */ - -/* Expand the hash table if needed */ -static int _dictExpandIfNeeded(dict *ht) { - /* If the hash table is empty expand it to the initial size, - * if the table is "full" double its size. */ - if (ht->size == 0) - return dictExpand(ht, DICT_HT_INITIAL_SIZE); - if (ht->used == ht->size) - return dictExpand(ht, ht->size*2); - return DICT_OK; -} - -/* Our hash table capability is a power of two */ -static unsigned long _dictNextPower(unsigned long size) { - unsigned long i = DICT_HT_INITIAL_SIZE; - - if (size >= LONG_MAX) return LONG_MAX; - while(1) { - if (i >= size) - return i; - i *= 2; - } -} - -/* Returns the index of a free slot that can be populated with - * an hash entry for the given 'key'. - * If the key already exists, -1 is returned. */ -static int _dictKeyIndex(dict *ht, const void *key) { - unsigned int h; - dictEntry *he; - - /* Expand the hashtable if needed */ - if (_dictExpandIfNeeded(ht) == DICT_ERR) - return -1; - /* Compute the key hash value */ - h = dictHashKey(ht, key) & ht->sizemask; - /* Search if this slot does not already contain the given key */ - he = ht->table[h]; - while(he) { - if (dictCompareHashKeys(ht, key, he->key)) - return -1; - he = he->next; - } - return h; -} - diff --git a/libvalkey/dict.h b/libvalkey/dict.h deleted file mode 100644 index 6ad0acd8..00000000 --- a/libvalkey/dict.h +++ /dev/null @@ -1,125 +0,0 @@ -/* Hash table implementation. - * - * This file implements in memory hash tables with insert/del/replace/find/ - * get-random-element operations. Hash tables will auto resize if needed - * tables of power of two in size are used, collisions are handled by - * chaining. See the source code for more information... :) - * - * Copyright (c) 2006-2010, Salvatore Sanfilippo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __DICT_H -#define __DICT_H - -#define DICT_OK 0 -#define DICT_ERR 1 - -/* Unused arguments generate annoying warnings... */ -#define DICT_NOTUSED(V) ((void) V) - -typedef struct dictEntry { - void *key; - void *val; - struct dictEntry *next; -} dictEntry; - -typedef struct dictType { - unsigned int (*hashFunction)(const void *key); - void *(*keyDup)(void *privdata, const void *key); - void *(*valDup)(void *privdata, const void *obj); - int (*keyCompare)(void *privdata, const void *key1, const void *key2); - void (*keyDestructor)(void *privdata, void *key); - void (*valDestructor)(void *privdata, void *obj); -} dictType; - -typedef struct dict { - dictEntry **table; - dictType *type; - unsigned long size; - unsigned long sizemask; - unsigned long used; - void *privdata; -} dict; - -typedef struct dictIterator { - dict *ht; - int index; - dictEntry *entry, *nextEntry; -} dictIterator; - -/* This is the initial size of every hash table */ -#define DICT_HT_INITIAL_SIZE 4 - -/* ------------------------------- Macros ------------------------------------*/ -#define dictFreeEntryVal(ht, entry) \ - if ((ht)->type->valDestructor) \ - (ht)->type->valDestructor((ht)->privdata, (entry)->val) - -#define dictSetHashVal(ht, entry, _val_) do { \ - if ((ht)->type->valDup) \ - entry->val = (ht)->type->valDup((ht)->privdata, _val_); \ - else \ - entry->val = (_val_); \ -} while(0) - -#define dictFreeEntryKey(ht, entry) \ - if ((ht)->type->keyDestructor) \ - (ht)->type->keyDestructor((ht)->privdata, (entry)->key) - -#define dictSetHashKey(ht, entry, _key_) do { \ - if ((ht)->type->keyDup) \ - entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \ - else \ - entry->key = (_key_); \ -} while(0) - -#define dictCompareHashKeys(ht, key1, key2) \ - (((ht)->type->keyCompare) ? \ - (ht)->type->keyCompare((ht)->privdata, key1, key2) : \ - (key1) == (key2)) - -#define dictHashKey(ht, key) (ht)->type->hashFunction(key) - -#define dictGetEntryKey(he) ((he)->key) -#define dictGetEntryVal(he) ((he)->val) -#define dictSlots(ht) ((ht)->size) -#define dictSize(ht) ((ht)->used) - -/* API */ -static unsigned int dictGenHashFunction(const unsigned char *buf, int len); -static dict *dictCreate(dictType *type, void *privDataPtr); -static int dictExpand(dict *ht, unsigned long size); -static int dictAdd(dict *ht, void *key, void *val); -static int dictReplace(dict *ht, void *key, void *val); -static int dictDelete(dict *ht, const void *key); -static void dictRelease(dict *ht); -static dictEntry * dictFind(dict *ht, const void *key); -static void dictInitIterator(dictIterator *iter, dict *ht); -static dictEntry *dictNext(dictIterator *iter); - -#endif /* __DICT_H */ diff --git a/libvalkey/examples/CMakeLists.txt b/libvalkey/examples/CMakeLists.txt index 214898b0..49901ece 100644 --- a/libvalkey/examples/CMakeLists.txt +++ b/libvalkey/examples/CMakeLists.txt @@ -6,7 +6,7 @@ if (GLIB2_FOUND) INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) LINK_DIRECTORIES(${GLIB2_LIBRARY_DIRS}) ADD_EXECUTABLE(example-glib example-glib.c) - TARGET_LINK_LIBRARIES(example-glib hiredis ${GLIB2_LIBRARIES}) + TARGET_LINK_LIBRARIES(example-glib valkey ${GLIB2_LIBRARIES}) ENDIF(GLIB2_FOUND) FIND_PATH(LIBEV ev.h @@ -16,46 +16,46 @@ FIND_PATH(LIBEV ev.h if (LIBEV) # Just compile and link with libev ADD_EXECUTABLE(example-libev example-libev.c) - TARGET_LINK_LIBRARIES(example-libev hiredis ev) + TARGET_LINK_LIBRARIES(example-libev valkey ev) ENDIF() FIND_PATH(LIBEVENT event.h) if (LIBEVENT) ADD_EXECUTABLE(example-libevent example-libevent.c) - TARGET_LINK_LIBRARIES(example-libevent hiredis event) + TARGET_LINK_LIBRARIES(example-libevent valkey event) ENDIF() FIND_PATH(LIBHV hv/hv.h) IF (LIBHV) ADD_EXECUTABLE(example-libhv example-libhv.c) - TARGET_LINK_LIBRARIES(example-libhv hiredis hv) + TARGET_LINK_LIBRARIES(example-libhv valkey hv) ENDIF() FIND_PATH(LIBUV uv.h) IF (LIBUV) ADD_EXECUTABLE(example-libuv example-libuv.c) - TARGET_LINK_LIBRARIES(example-libuv hiredis uv) + TARGET_LINK_LIBRARIES(example-libuv valkey uv) ENDIF() FIND_PATH(LIBSDEVENT systemd/sd-event.h) IF (LIBSDEVENT) ADD_EXECUTABLE(example-libsdevent example-libsdevent.c) - TARGET_LINK_LIBRARIES(example-libsdevent hiredis systemd) + TARGET_LINK_LIBRARIES(example-libsdevent valkey systemd) ENDIF() IF (APPLE) FIND_LIBRARY(CF CoreFoundation) ADD_EXECUTABLE(example-macosx example-macosx.c) - TARGET_LINK_LIBRARIES(example-macosx hiredis ${CF}) + TARGET_LINK_LIBRARIES(example-macosx valkey ${CF}) ENDIF() IF (ENABLE_SSL) ADD_EXECUTABLE(example-ssl example-ssl.c) - TARGET_LINK_LIBRARIES(example-ssl hiredis hiredis_ssl) + TARGET_LINK_LIBRARIES(example-ssl valkey valkey_ssl) ENDIF() ADD_EXECUTABLE(example example.c) -TARGET_LINK_LIBRARIES(example hiredis) +TARGET_LINK_LIBRARIES(example valkey) ADD_EXECUTABLE(example-push example-push.c) -TARGET_LINK_LIBRARIES(example-push hiredis) +TARGET_LINK_LIBRARIES(example-push valkey) diff --git a/libvalkey/examples/example-ae.c b/libvalkey/examples/example-ae.c index 8efa7306..060f3e0a 100644 --- a/libvalkey/examples/example-ae.c +++ b/libvalkey/examples/example-ae.c @@ -3,24 +3,24 @@ #include #include -#include +#include #include #include /* Put event loop in the global scope, so it can be explicitly stopped */ static aeEventLoop *loop; -void getCallback(redisAsyncContext *c, void *r, void *privdata) { - redisReply *reply = r; +void getCallback(valkeyAsyncContext *c, void *r, void *privdata) { + valkeyReply *reply = r; if (reply == NULL) return; printf("argv[%s]: %s\n", (char*)privdata, reply->str); /* Disconnect after receiving the reply to GET */ - redisAsyncDisconnect(c); + valkeyAsyncDisconnect(c); } -void connectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void connectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); aeStop(loop); return; @@ -29,8 +29,8 @@ void connectCallback(const redisAsyncContext *c, int status) { printf("Connected...\n"); } -void disconnectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void disconnectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); aeStop(loop); return; @@ -43,7 +43,7 @@ void disconnectCallback(const redisAsyncContext *c, int status) { int main (int argc, char **argv) { signal(SIGPIPE, SIG_IGN); - redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + valkeyAsyncContext *c = valkeyAsyncConnect("127.0.0.1", 6379); if (c->err) { /* Let *c leak for now... */ printf("Error: %s\n", c->errstr); @@ -51,11 +51,11 @@ int main (int argc, char **argv) { } loop = aeCreateEventLoop(64); - redisAeAttach(loop, c); - redisAsyncSetConnectCallback(c,connectCallback); - redisAsyncSetDisconnectCallback(c,disconnectCallback); - redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); - redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + valkeyAeAttach(loop, c); + valkeyAsyncSetConnectCallback(c,connectCallback); + valkeyAsyncSetDisconnectCallback(c,disconnectCallback); + valkeyAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + valkeyAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); aeMain(loop); return 0; } diff --git a/libvalkey/examples/example-glib.c b/libvalkey/examples/example-glib.c index d6e10f8e..371a7330 100644 --- a/libvalkey/examples/example-glib.c +++ b/libvalkey/examples/example-glib.c @@ -1,16 +1,16 @@ #include -#include +#include #include #include static GMainLoop *mainloop; static void -connect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, +connect_cb (const valkeyAsyncContext *ac G_GNUC_UNUSED, int status) { - if (status != REDIS_OK) { + if (status != VALKEY_OK) { g_printerr("Failed to connect: %s\n", ac->errstr); g_main_loop_quit(mainloop); } else { @@ -19,10 +19,10 @@ connect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, } static void -disconnect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, +disconnect_cb (const valkeyAsyncContext *ac G_GNUC_UNUSED, int status) { - if (status != REDIS_OK) { + if (status != VALKEY_OK) { g_error("Failed to disconnect: %s", ac->errstr); } else { g_printerr("Disconnected...\n"); @@ -31,41 +31,41 @@ disconnect_cb (const redisAsyncContext *ac G_GNUC_UNUSED, } static void -command_cb(redisAsyncContext *ac, +command_cb(valkeyAsyncContext *ac, gpointer r, gpointer user_data G_GNUC_UNUSED) { - redisReply *reply = r; + valkeyReply *reply = r; if (reply) { g_print("REPLY: %s\n", reply->str); } - redisAsyncDisconnect(ac); + valkeyAsyncDisconnect(ac); } gint main (gint argc G_GNUC_UNUSED, gchar *argv[] G_GNUC_UNUSED) { - redisAsyncContext *ac; + valkeyAsyncContext *ac; GMainContext *context = NULL; GSource *source; - ac = redisAsyncConnect("127.0.0.1", 6379); + ac = valkeyAsyncConnect("127.0.0.1", 6379); if (ac->err) { g_printerr("%s\n", ac->errstr); exit(EXIT_FAILURE); } - source = redis_source_new(ac); + source = valkey_source_new(ac); mainloop = g_main_loop_new(context, FALSE); g_source_attach(source, context); - redisAsyncSetConnectCallback(ac, connect_cb); - redisAsyncSetDisconnectCallback(ac, disconnect_cb); - redisAsyncCommand(ac, command_cb, NULL, "SET key 1234"); - redisAsyncCommand(ac, command_cb, NULL, "GET key"); + valkeyAsyncSetConnectCallback(ac, connect_cb); + valkeyAsyncSetDisconnectCallback(ac, disconnect_cb); + valkeyAsyncCommand(ac, command_cb, NULL, "SET key 1234"); + valkeyAsyncCommand(ac, command_cb, NULL, "GET key"); g_main_loop_run(mainloop); diff --git a/libvalkey/examples/example-ivykis.c b/libvalkey/examples/example-ivykis.c index f57dc388..3a9e9dfd 100644 --- a/libvalkey/examples/example-ivykis.c +++ b/libvalkey/examples/example-ivykis.c @@ -3,29 +3,29 @@ #include #include -#include +#include #include #include -void getCallback(redisAsyncContext *c, void *r, void *privdata) { - redisReply *reply = r; +void getCallback(valkeyAsyncContext *c, void *r, void *privdata) { + valkeyReply *reply = r; if (reply == NULL) return; printf("argv[%s]: %s\n", (char*)privdata, reply->str); /* Disconnect after receiving the reply to GET */ - redisAsyncDisconnect(c); + valkeyAsyncDisconnect(c); } -void connectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void connectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } printf("Connected...\n"); } -void disconnectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void disconnectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } @@ -39,18 +39,18 @@ int main (int argc, char **argv) { iv_init(); - redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + valkeyAsyncContext *c = valkeyAsyncConnect("127.0.0.1", 6379); if (c->err) { /* Let *c leak for now... */ printf("Error: %s\n", c->errstr); return 1; } - redisIvykisAttach(c); - redisAsyncSetConnectCallback(c,connectCallback); - redisAsyncSetDisconnectCallback(c,disconnectCallback); - redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); - redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + valkeyIvykisAttach(c); + valkeyAsyncSetConnectCallback(c,connectCallback); + valkeyAsyncSetDisconnectCallback(c,disconnectCallback); + valkeyAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + valkeyAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); iv_main(); diff --git a/libvalkey/examples/example-libev.c b/libvalkey/examples/example-libev.c index ec474306..3d644b2d 100644 --- a/libvalkey/examples/example-libev.c +++ b/libvalkey/examples/example-libev.c @@ -3,29 +3,29 @@ #include #include -#include +#include #include #include -void getCallback(redisAsyncContext *c, void *r, void *privdata) { - redisReply *reply = r; +void getCallback(valkeyAsyncContext *c, void *r, void *privdata) { + valkeyReply *reply = r; if (reply == NULL) return; printf("argv[%s]: %s\n", (char*)privdata, reply->str); /* Disconnect after receiving the reply to GET */ - redisAsyncDisconnect(c); + valkeyAsyncDisconnect(c); } -void connectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void connectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } printf("Connected...\n"); } -void disconnectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void disconnectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } @@ -37,18 +37,18 @@ int main (int argc, char **argv) { signal(SIGPIPE, SIG_IGN); #endif - redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + valkeyAsyncContext *c = valkeyAsyncConnect("127.0.0.1", 6379); if (c->err) { /* Let *c leak for now... */ printf("Error: %s\n", c->errstr); return 1; } - redisLibevAttach(EV_DEFAULT_ c); - redisAsyncSetConnectCallback(c,connectCallback); - redisAsyncSetDisconnectCallback(c,disconnectCallback); - redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); - redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + valkeyLibevAttach(EV_DEFAULT_ c); + valkeyAsyncSetConnectCallback(c,connectCallback); + valkeyAsyncSetDisconnectCallback(c,disconnectCallback); + valkeyAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + valkeyAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); ev_loop(EV_DEFAULT_ 0); return 0; } diff --git a/libvalkey/examples/example-libevent-ssl.c b/libvalkey/examples/example-libevent-ssl.c index d0998bab..dd1bf44c 100644 --- a/libvalkey/examples/example-libevent-ssl.c +++ b/libvalkey/examples/example-libevent-ssl.c @@ -3,30 +3,30 @@ #include #include -#include -#include +#include +#include #include #include -void getCallback(redisAsyncContext *c, void *r, void *privdata) { - redisReply *reply = r; +void getCallback(valkeyAsyncContext *c, void *r, void *privdata) { + valkeyReply *reply = r; if (reply == NULL) return; printf("argv[%s]: %s\n", (char*)privdata, reply->str); /* Disconnect after receiving the reply to GET */ - redisAsyncDisconnect(c); + valkeyAsyncDisconnect(c); } -void connectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void connectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } printf("Connected...\n"); } -void disconnectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void disconnectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } @@ -55,36 +55,36 @@ int main (int argc, char **argv) { const char *certKey = argv[5]; const char *caCert = argc > 5 ? argv[6] : NULL; - redisSSLContext *ssl; - redisSSLContextError ssl_error = REDIS_SSL_CTX_NONE; + valkeySSLContext *ssl; + valkeySSLContextError ssl_error = VALKEY_SSL_CTX_NONE; - redisInitOpenSSL(); + valkeyInitOpenSSL(); - ssl = redisCreateSSLContext(caCert, NULL, + ssl = valkeyCreateSSLContext(caCert, NULL, cert, certKey, NULL, &ssl_error); if (!ssl) { - printf("Error: %s\n", redisSSLContextGetError(ssl_error)); + printf("Error: %s\n", valkeySSLContextGetError(ssl_error)); return 1; } - redisAsyncContext *c = redisAsyncConnect(hostname, port); + valkeyAsyncContext *c = valkeyAsyncConnect(hostname, port); if (c->err) { /* Let *c leak for now... */ printf("Error: %s\n", c->errstr); return 1; } - if (redisInitiateSSLWithContext(&c->c, ssl) != REDIS_OK) { + if (valkeyInitiateSSLWithContext(&c->c, ssl) != VALKEY_OK) { printf("SSL Error!\n"); exit(1); } - redisLibeventAttach(c,base); - redisAsyncSetConnectCallback(c,connectCallback); - redisAsyncSetDisconnectCallback(c,disconnectCallback); - redisAsyncCommand(c, NULL, NULL, "SET key %b", value, nvalue); - redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + valkeyLibeventAttach(c,base); + valkeyAsyncSetConnectCallback(c,connectCallback); + valkeyAsyncSetDisconnectCallback(c,disconnectCallback); + valkeyAsyncCommand(c, NULL, NULL, "SET key %b", value, nvalue); + valkeyAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); event_base_dispatch(base); - redisFreeSSLContext(ssl); + valkeyFreeSSLContext(ssl); return 0; } diff --git a/libvalkey/examples/example-libevent.c b/libvalkey/examples/example-libevent.c index 49bddd0c..6ac91678 100644 --- a/libvalkey/examples/example-libevent.c +++ b/libvalkey/examples/example-libevent.c @@ -3,12 +3,12 @@ #include #include -#include +#include #include #include -void getCallback(redisAsyncContext *c, void *r, void *privdata) { - redisReply *reply = r; +void getCallback(valkeyAsyncContext *c, void *r, void *privdata) { + valkeyReply *reply = r; if (reply == NULL) { if (c->errstr) { printf("errstr: %s\n", c->errstr); @@ -18,19 +18,19 @@ void getCallback(redisAsyncContext *c, void *r, void *privdata) { printf("argv[%s]: %s\n", (char*)privdata, reply->str); /* Disconnect after receiving the reply to GET */ - redisAsyncDisconnect(c); + valkeyAsyncDisconnect(c); } -void connectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void connectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } printf("Connected...\n"); } -void disconnectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void disconnectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } @@ -43,25 +43,25 @@ int main (int argc, char **argv) { #endif struct event_base *base = event_base_new(); - redisOptions options = {0}; - REDIS_OPTIONS_SET_TCP(&options, "127.0.0.1", 6379); + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_TCP(&options, "127.0.0.1", 6379); struct timeval tv = {0}; tv.tv_sec = 1; options.connect_timeout = &tv; - redisAsyncContext *c = redisAsyncConnectWithOptions(&options); + valkeyAsyncContext *c = valkeyAsyncConnectWithOptions(&options); if (c->err) { /* Let *c leak for now... */ printf("Error: %s\n", c->errstr); return 1; } - redisLibeventAttach(c,base); - redisAsyncSetConnectCallback(c,connectCallback); - redisAsyncSetDisconnectCallback(c,disconnectCallback); - redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); - redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + valkeyLibeventAttach(c,base); + valkeyAsyncSetConnectCallback(c,connectCallback); + valkeyAsyncSetDisconnectCallback(c,disconnectCallback); + valkeyAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + valkeyAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); event_base_dispatch(base); return 0; } diff --git a/libvalkey/examples/example-libhv.c b/libvalkey/examples/example-libhv.c index ac68b008..292eb434 100644 --- a/libvalkey/examples/example-libhv.c +++ b/libvalkey/examples/example-libhv.c @@ -3,41 +3,41 @@ #include #include -#include +#include #include #include -void getCallback(redisAsyncContext *c, void *r, void *privdata) { - redisReply *reply = r; +void getCallback(valkeyAsyncContext *c, void *r, void *privdata) { + valkeyReply *reply = r; if (reply == NULL) return; printf("argv[%s]: %s\n", (char*)privdata, reply->str); /* Disconnect after receiving the reply to GET */ - redisAsyncDisconnect(c); + valkeyAsyncDisconnect(c); } -void debugCallback(redisAsyncContext *c, void *r, void *privdata) { +void debugCallback(valkeyAsyncContext *c, void *r, void *privdata) { (void)privdata; - redisReply *reply = r; + valkeyReply *reply = r; if (reply == NULL) { printf("`DEBUG SLEEP` error: %s\n", c->errstr ? c->errstr : "unknown error"); return; } - redisAsyncDisconnect(c); + valkeyAsyncDisconnect(c); } -void connectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void connectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } printf("Connected...\n"); } -void disconnectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void disconnectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } @@ -49,7 +49,7 @@ int main (int argc, char **argv) { signal(SIGPIPE, SIG_IGN); #endif - redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + valkeyAsyncContext *c = valkeyAsyncConnect("127.0.0.1", 6379); if (c->err) { /* Let *c leak for now... */ printf("Error: %s\n", c->errstr); @@ -57,13 +57,13 @@ int main (int argc, char **argv) { } hloop_t* loop = hloop_new(HLOOP_FLAG_QUIT_WHEN_NO_ACTIVE_EVENTS); - redisLibhvAttach(c, loop); - redisAsyncSetTimeout(c, (struct timeval){.tv_sec = 0, .tv_usec = 500000}); - redisAsyncSetConnectCallback(c,connectCallback); - redisAsyncSetDisconnectCallback(c,disconnectCallback); - redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); - redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); - redisAsyncCommand(c, debugCallback, NULL, "DEBUG SLEEP %d", 1); + valkeyLibhvAttach(c, loop); + valkeyAsyncSetTimeout(c, (struct timeval){.tv_sec = 0, .tv_usec = 500000}); + valkeyAsyncSetConnectCallback(c,connectCallback); + valkeyAsyncSetDisconnectCallback(c,disconnectCallback); + valkeyAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + valkeyAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + valkeyAsyncCommand(c, debugCallback, NULL, "DEBUG SLEEP %d", 1); hloop_run(loop); hloop_free(&loop); return 0; diff --git a/libvalkey/examples/example-libsdevent.c b/libvalkey/examples/example-libsdevent.c index c3b902b4..d4f33579 100644 --- a/libvalkey/examples/example-libsdevent.c +++ b/libvalkey/examples/example-libsdevent.c @@ -3,24 +3,24 @@ #include #include -#include +#include #include #include -void debugCallback(redisAsyncContext *c, void *r, void *privdata) { +void debugCallback(valkeyAsyncContext *c, void *r, void *privdata) { (void)privdata; - redisReply *reply = r; + valkeyReply *reply = r; if (reply == NULL) { /* The DEBUG SLEEP command will almost always fail, because we have set a 1 second timeout */ printf("`DEBUG SLEEP` error: %s\n", c->errstr ? c->errstr : "unknown error"); return; } /* Disconnect after receiving the reply of DEBUG SLEEP (which will not)*/ - redisAsyncDisconnect(c); + valkeyAsyncDisconnect(c); } -void getCallback(redisAsyncContext *c, void *r, void *privdata) { - redisReply *reply = r; +void getCallback(valkeyAsyncContext *c, void *r, void *privdata) { + valkeyReply *reply = r; if (reply == NULL) { printf("`GET key` error: %s\n", c->errstr ? c->errstr : "unknown error"); return; @@ -28,19 +28,19 @@ void getCallback(redisAsyncContext *c, void *r, void *privdata) { printf("`GET key` result: argv[%s]: %s\n", (char*)privdata, reply->str); /* start another request that demonstrate timeout */ - redisAsyncCommand(c, debugCallback, NULL, "DEBUG SLEEP %f", 1.5); + valkeyAsyncCommand(c, debugCallback, NULL, "DEBUG SLEEP %f", 1.5); } -void connectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void connectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("connect error: %s\n", c->errstr); return; } printf("Connected...\n"); } -void disconnectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void disconnectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("disconnect because of error: %s\n", c->errstr); return; } @@ -53,17 +53,17 @@ int main (int argc, char **argv) { struct sd_event *event; sd_event_default(&event); - redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + valkeyAsyncContext *c = valkeyAsyncConnect("127.0.0.1", 6379); if (c->err) { printf("Error: %s\n", c->errstr); - redisAsyncFree(c); + valkeyAsyncFree(c); return 1; } - redisLibsdeventAttach(c,event); - redisAsyncSetConnectCallback(c,connectCallback); - redisAsyncSetDisconnectCallback(c,disconnectCallback); - redisAsyncSetTimeout(c, (struct timeval){ .tv_sec = 1, .tv_usec = 0}); + valkeyLibsdeventAttach(c,event); + valkeyAsyncSetConnectCallback(c,connectCallback); + valkeyAsyncSetDisconnectCallback(c,disconnectCallback); + valkeyAsyncSetTimeout(c, (struct timeval){ .tv_sec = 1, .tv_usec = 0}); /* In this demo, we first `set key`, then `get key` to demonstrate the basic usage of libsdevent adapter. @@ -72,8 +72,8 @@ int main (int argc, char **argv) { timeout error, which is shown in the `debugCallback`. */ - redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); - redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + valkeyAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + valkeyAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); /* sd-event does not quit when there are no handlers registered. Manually exit after 1.5 seconds */ sd_event_source *s; diff --git a/libvalkey/examples/example-libuv.c b/libvalkey/examples/example-libuv.c index 53fd04a8..cc31e46b 100644 --- a/libvalkey/examples/example-libuv.c +++ b/libvalkey/examples/example-libuv.c @@ -3,24 +3,24 @@ #include #include -#include +#include #include #include -void debugCallback(redisAsyncContext *c, void *r, void *privdata) { +void debugCallback(valkeyAsyncContext *c, void *r, void *privdata) { (void)privdata; //unused - redisReply *reply = r; + valkeyReply *reply = r; if (reply == NULL) { /* The DEBUG SLEEP command will almost always fail, because we have set a 1 second timeout */ printf("`DEBUG SLEEP` error: %s\n", c->errstr ? c->errstr : "unknown error"); return; } /* Disconnect after receiving the reply of DEBUG SLEEP (which will not)*/ - redisAsyncDisconnect(c); + valkeyAsyncDisconnect(c); } -void getCallback(redisAsyncContext *c, void *r, void *privdata) { - redisReply *reply = r; +void getCallback(valkeyAsyncContext *c, void *r, void *privdata) { + valkeyReply *reply = r; if (reply == NULL) { printf("`GET key` error: %s\n", c->errstr ? c->errstr : "unknown error"); return; @@ -28,19 +28,19 @@ void getCallback(redisAsyncContext *c, void *r, void *privdata) { printf("`GET key` result: argv[%s]: %s\n", (char*)privdata, reply->str); /* start another request that demonstrate timeout */ - redisAsyncCommand(c, debugCallback, NULL, "DEBUG SLEEP %f", 1.5); + valkeyAsyncCommand(c, debugCallback, NULL, "DEBUG SLEEP %f", 1.5); } -void connectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void connectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("connect error: %s\n", c->errstr); return; } printf("Connected...\n"); } -void disconnectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void disconnectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("disconnect because of error: %s\n", c->errstr); return; } @@ -54,17 +54,17 @@ int main (int argc, char **argv) { uv_loop_t* loop = uv_default_loop(); - redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + valkeyAsyncContext *c = valkeyAsyncConnect("127.0.0.1", 6379); if (c->err) { /* Let *c leak for now... */ printf("Error: %s\n", c->errstr); return 1; } - redisLibuvAttach(c,loop); - redisAsyncSetConnectCallback(c,connectCallback); - redisAsyncSetDisconnectCallback(c,disconnectCallback); - redisAsyncSetTimeout(c, (struct timeval){ .tv_sec = 1, .tv_usec = 0}); + valkeyLibuvAttach(c,loop); + valkeyAsyncSetConnectCallback(c,connectCallback); + valkeyAsyncSetDisconnectCallback(c,disconnectCallback); + valkeyAsyncSetTimeout(c, (struct timeval){ .tv_sec = 1, .tv_usec = 0}); /* In this demo, we first `set key`, then `get key` to demonstrate the basic usage of libuv adapter. @@ -73,8 +73,8 @@ int main (int argc, char **argv) { timeout error, which is shown in the `debugCallback`. */ - redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); - redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + valkeyAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + valkeyAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); uv_run(loop, UV_RUN_DEFAULT); return 0; diff --git a/libvalkey/examples/example-macosx.c b/libvalkey/examples/example-macosx.c index bc84ed5b..0e39fb94 100644 --- a/libvalkey/examples/example-macosx.c +++ b/libvalkey/examples/example-macosx.c @@ -5,29 +5,29 @@ #include -#include +#include #include #include -void getCallback(redisAsyncContext *c, void *r, void *privdata) { - redisReply *reply = r; +void getCallback(valkeyAsyncContext *c, void *r, void *privdata) { + valkeyReply *reply = r; if (reply == NULL) return; printf("argv[%s]: %s\n", (char*)privdata, reply->str); /* Disconnect after receiving the reply to GET */ - redisAsyncDisconnect(c); + valkeyAsyncDisconnect(c); } -void connectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void connectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } printf("Connected...\n"); } -void disconnectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void disconnectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } @@ -44,20 +44,20 @@ int main (int argc, char **argv) { return 1; } - redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + valkeyAsyncContext *c = valkeyAsyncConnect("127.0.0.1", 6379); if (c->err) { /* Let *c leak for now... */ printf("Error: %s\n", c->errstr); return 1; } - redisMacOSAttach(c, loop); + valkeyMacOSAttach(c, loop); - redisAsyncSetConnectCallback(c,connectCallback); - redisAsyncSetDisconnectCallback(c,disconnectCallback); + valkeyAsyncSetConnectCallback(c,connectCallback); + valkeyAsyncSetDisconnectCallback(c,disconnectCallback); - redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); - redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + valkeyAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + valkeyAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); CFRunLoopRun(); diff --git a/libvalkey/examples/example-poll.c b/libvalkey/examples/example-poll.c index 954673da..edc37205 100644 --- a/libvalkey/examples/example-poll.c +++ b/libvalkey/examples/example-poll.c @@ -10,17 +10,17 @@ /* Put in the global scope, so that loop can be explicitly stopped */ static int exit_loop = 0; -void getCallback(redisAsyncContext *c, void *r, void *privdata) { - redisReply *reply = r; +void getCallback(valkeyAsyncContext *c, void *r, void *privdata) { + valkeyReply *reply = r; if (reply == NULL) return; printf("argv[%s]: %s\n", (char*)privdata, reply->str); /* Disconnect after receiving the reply to GET */ - redisAsyncDisconnect(c); + valkeyAsyncDisconnect(c); } -void connectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void connectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); exit_loop = 1; return; @@ -29,9 +29,9 @@ void connectCallback(const redisAsyncContext *c, int status) { printf("Connected...\n"); } -void disconnectCallback(const redisAsyncContext *c, int status) { +void disconnectCallback(const valkeyAsyncContext *c, int status) { exit_loop = 1; - if (status != REDIS_OK) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } @@ -42,21 +42,21 @@ void disconnectCallback(const redisAsyncContext *c, int status) { int main (int argc, char **argv) { signal(SIGPIPE, SIG_IGN); - redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + valkeyAsyncContext *c = valkeyAsyncConnect("127.0.0.1", 6379); if (c->err) { /* Let *c leak for now... */ printf("Error: %s\n", c->errstr); return 1; } - redisPollAttach(c); - redisAsyncSetConnectCallback(c,connectCallback); - redisAsyncSetDisconnectCallback(c,disconnectCallback); - redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); - redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + valkeyPollAttach(c); + valkeyAsyncSetConnectCallback(c,connectCallback); + valkeyAsyncSetDisconnectCallback(c,disconnectCallback); + valkeyAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); + valkeyAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); while (!exit_loop) { - redisPollTick(c, 0.1); + valkeyPollTick(c, 0.1); } return 0; } diff --git a/libvalkey/examples/example-push.c b/libvalkey/examples/example-push.c index 6bc12055..3ecceb65 100644 --- a/libvalkey/examples/example-push.c +++ b/libvalkey/examples/example-push.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #define KEY_COUNT 5 @@ -40,13 +40,13 @@ exit(-1); \ } while (0) -static void assertReplyAndFree(redisContext *context, redisReply *reply, int type) { +static void assertReplyAndFree(valkeyContext *context, valkeyReply *reply, int type) { if (reply == NULL) panicAbort("NULL reply from server (error: %s)", context->errstr); if (reply->type != type) { - if (reply->type == REDIS_REPLY_ERROR) - fprintf(stderr, "Redis Error: %s\n", reply->str); + if (reply->type == VALKEY_REPLY_ERROR) + fprintf(stderr, "Server Error: %s\n", reply->str); panicAbort("Expected reply type %d but got type %d", type, reply->type); } @@ -55,34 +55,34 @@ static void assertReplyAndFree(redisContext *context, redisReply *reply, int typ } /* Switch to the RESP3 protocol and enable client tracking */ -static void enableClientTracking(redisContext *c) { - redisReply *reply = redisCommand(c, "HELLO 3"); +static void enableClientTracking(valkeyContext *c) { + valkeyReply *reply = valkeyCommand(c, "HELLO 3"); if (reply == NULL || c->err) { panicAbort("NULL reply or server error (error: %s)", c->errstr); } - if (reply->type != REDIS_REPLY_MAP) { + if (reply->type != VALKEY_REPLY_MAP) { fprintf(stderr, "Error: Can't send HELLO 3 command. Are you sure you're "); - fprintf(stderr, "connected to redis-server >= 6.0.0?\nRedis error: %s\n", - reply->type == REDIS_REPLY_ERROR ? reply->str : "(unknown)"); + fprintf(stderr, "connected to valkey-server >= 6.0.0?\Server error: %s\n", + reply->type == VALKEY_REPLY_ERROR ? reply->str : "(unknown)"); exit(-1); } freeReplyObject(reply); /* Enable client tracking */ - reply = redisCommand(c, "CLIENT TRACKING ON"); - assertReplyAndFree(c, reply, REDIS_REPLY_STATUS); + reply = valkeyCommand(c, "CLIENT TRACKING ON"); + assertReplyAndFree(c, reply, VALKEY_REPLY_STATUS); } void pushReplyHandler(void *privdata, void *r) { - redisReply *reply = r; + valkeyReply *reply = r; int *invalidations = privdata; /* Sanity check on the invalidation reply */ - if (reply->type != REDIS_REPLY_PUSH || reply->elements != 2 || - reply->element[1]->type != REDIS_REPLY_ARRAY || - reply->element[1]->element[0]->type != REDIS_REPLY_STRING) + if (reply->type != VALKEY_REPLY_PUSH || reply->elements != 2 || + reply->element[1]->type != VALKEY_REPLY_ARRAY || + reply->element[1]->element[0]->type != VALKEY_REPLY_STRING) { panicAbort("%s", "Can't parse PUSH message!"); } @@ -97,7 +97,7 @@ void pushReplyHandler(void *privdata, void *r) { } /* We aren't actually freeing anything here, but it is included to show that we can - * have hiredis call our data destructor when freeing the context */ + * have libvalkey call our data destructor when freeing the context */ void privdata_dtor(void *privdata) { unsigned int *icount = privdata; printf("privdata_dtor(): In context privdata dtor (invalidations: %u)\n", *icount); @@ -105,29 +105,29 @@ void privdata_dtor(void *privdata) { int main(int argc, char **argv) { unsigned int j, invalidations = 0; - redisContext *c; - redisReply *reply; + valkeyContext *c; + valkeyReply *reply; const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; int port = (argc > 2) ? atoi(argv[2]) : 6379; - redisOptions o = {0}; - REDIS_OPTIONS_SET_TCP(&o, hostname, port); + valkeyOptions o = {0}; + VALKEY_OPTIONS_SET_TCP(&o, hostname, port); /* Set our context privdata to the address of our invalidation counter. Each - * time our PUSH handler is called, hiredis will pass the privdata for context. + * time our PUSH handler is called, libvalkey will pass the privdata for context. * * This could also be done after we create the context like so: * * c->privdata = &invalidations; * c->free_privdata = privdata_dtor; */ - REDIS_OPTIONS_SET_PRIVDATA(&o, &invalidations, privdata_dtor); + VALKEY_OPTIONS_SET_PRIVDATA(&o, &invalidations, privdata_dtor); /* Set our custom PUSH message handler */ o.push_cb = pushReplyHandler; - c = redisConnectWithOptions(&o); + c = valkeyConnectWithOptions(&o); if (c == NULL || c->err) panicAbort("Connection error: %s", c ? c->errstr : "OOM"); @@ -137,23 +137,23 @@ int main(int argc, char **argv) { /* Set some keys and then read them back. Once we do that, Redis will deliver * invalidation push messages whenever the key is modified */ for (j = 0; j < KEY_COUNT; j++) { - reply = redisCommand(c, "SET key:%d initial:%d", j, j); - assertReplyAndFree(c, reply, REDIS_REPLY_STATUS); + reply = valkeyCommand(c, "SET key:%d initial:%d", j, j); + assertReplyAndFree(c, reply, VALKEY_REPLY_STATUS); - reply = redisCommand(c, "GET key:%d", j); - assertReplyAndFree(c, reply, REDIS_REPLY_STRING); + reply = valkeyCommand(c, "GET key:%d", j); + assertReplyAndFree(c, reply, VALKEY_REPLY_STRING); } /* Trigger invalidation messages by updating keys we just read */ for (j = 0; j < KEY_COUNT; j++) { printf(" main(): SET key:%d update:%d\n", j, j); - reply = redisCommand(c, "SET key:%d update:%d", j, j); - assertReplyAndFree(c, reply, REDIS_REPLY_STATUS); + reply = valkeyCommand(c, "SET key:%d update:%d", j, j); + assertReplyAndFree(c, reply, VALKEY_REPLY_STATUS); printf(" main(): SET REPLY OK\n"); } printf("\nTotal detected invalidations: %d, expected: %d\n", invalidations, KEY_COUNT); /* PING server */ - redisFree(c); + valkeyFree(c); } diff --git a/libvalkey/examples/example-qt.cpp b/libvalkey/examples/example-qt.cpp index f524c3f3..4c714823 100644 --- a/libvalkey/examples/example-qt.cpp +++ b/libvalkey/examples/example-qt.cpp @@ -6,9 +6,9 @@ using namespace std; #include "example-qt.h" -void getCallback(redisAsyncContext *, void * r, void * privdata) { +void getCallback(valkeyAsyncContext *, void * r, void * privdata) { - redisReply * reply = static_cast(r); + valkeyReply * reply = static_cast(r); ExampleQt * ex = static_cast(privdata); if (reply == nullptr || ex == nullptr) return; @@ -19,18 +19,18 @@ void getCallback(redisAsyncContext *, void * r, void * privdata) { void ExampleQt::run() { - m_ctx = redisAsyncConnect("localhost", 6379); + m_ctx = valkeyAsyncConnect("localhost", 6379); if (m_ctx->err) { cerr << "Error: " << m_ctx->errstr << endl; - redisAsyncFree(m_ctx); + valkeyAsyncFree(m_ctx); emit finished(); } m_adapter.setContext(m_ctx); - redisAsyncCommand(m_ctx, NULL, NULL, "SET key %s", m_value); - redisAsyncCommand(m_ctx, getCallback, this, "GET key"); + valkeyAsyncCommand(m_ctx, NULL, NULL, "SET key %s", m_value); + valkeyAsyncCommand(m_ctx, getCallback, this, "GET key"); } int main (int argc, char **argv) { diff --git a/libvalkey/examples/example-qt.h b/libvalkey/examples/example-qt.h index 374f4766..29f46c2c 100644 --- a/libvalkey/examples/example-qt.h +++ b/libvalkey/examples/example-qt.h @@ -1,5 +1,5 @@ -#ifndef __HIREDIS_EXAMPLE_QT_H -#define __HIREDIS_EXAMPLE_QT_H +#ifndef VALKEY_EXAMPLE_QT_H +#define VALKEY_EXAMPLE_QT_H #include @@ -22,11 +22,11 @@ class ExampleQt : public QObject { private: const char * m_value; - redisAsyncContext * m_ctx; - RedisQtAdapter m_adapter; + valkeyAsyncContext * m_ctx; + ValkeyQtAdapter m_adapter; friend - void getCallback(redisAsyncContext *, void *, void *); + void getCallback(valkeyAsyncContext *, void *, void *); }; -#endif /* !__HIREDIS_EXAMPLE_QT_H */ +#endif /* VALKEY_EXAMPLE_QT_H */ diff --git a/libvalkey/examples/example-redismoduleapi.c b/libvalkey/examples/example-redismoduleapi.c index 7d12f8a0..bc52cbe4 100644 --- a/libvalkey/examples/example-redismoduleapi.c +++ b/libvalkey/examples/example-redismoduleapi.c @@ -3,24 +3,24 @@ #include #include -#include +#include #include -#include +#include -void debugCallback(redisAsyncContext *c, void *r, void *privdata) { +void debugCallback(valkeyAsyncContext *c, void *r, void *privdata) { (void)privdata; //unused - redisReply *reply = r; + valkeyReply *reply = r; if (reply == NULL) { /* The DEBUG SLEEP command will almost always fail, because we have set a 1 second timeout */ printf("`DEBUG SLEEP` error: %s\n", c->errstr ? c->errstr : "unknown error"); return; } /* Disconnect after receiving the reply of DEBUG SLEEP (which will not)*/ - redisAsyncDisconnect(c); + valkeyAsyncDisconnect(c); } -void getCallback(redisAsyncContext *c, void *r, void *privdata) { - redisReply *reply = r; +void getCallback(valkeyAsyncContext *c, void *r, void *privdata) { + valkeyReply *reply = r; if (reply == NULL) { if (c->errstr) { printf("errstr: %s\n", c->errstr); @@ -30,19 +30,19 @@ void getCallback(redisAsyncContext *c, void *r, void *privdata) { printf("argv[%s]: %s\n", (char*)privdata, reply->str); /* start another request that demonstrate timeout */ - redisAsyncCommand(c, debugCallback, NULL, "DEBUG SLEEP %f", 1.5); + valkeyAsyncCommand(c, debugCallback, NULL, "DEBUG SLEEP %f", 1.5); } -void connectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void connectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } printf("Connected...\n"); } -void disconnectCallback(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +void disconnectCallback(const valkeyAsyncContext *c, int status) { + if (status != VALKEY_OK) { printf("Error: %s\n", c->errstr); return; } @@ -50,29 +50,21 @@ void disconnectCallback(const redisAsyncContext *c, int status) { } /* - * This example requires Redis 7.0 or above. - * - * 1- Compile this file as a shared library. Directory of "redismodule.h" must + * 1- Compile this file as a shared library. Directory of "valkeymodule.h" must * be in the include path. - * gcc -fPIC -shared -I../../redis/src/ -I.. example-redismoduleapi.c -o example-redismoduleapi.so + * gcc -fPIC -shared -I../../valkey/src/ -I.. example-valkeymoduleapi.c -o example-valkeymoduleapi.so * * 2- Load module: - * redis-server --loadmodule ./example-redismoduleapi.so value + * valkey-server --loadmodule ./example-valkeymoduleapi.so value */ -int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - - int ret = RedisModule_Init(ctx, "example-redismoduleapi", 1, REDISMODULE_APIVER_1); - if (ret != REDISMODULE_OK) { +int ValkeyModule_OnLoad(ValkeyModuleCtx *ctx, ValkeyModuleString **argv, int argc) { + int ret = ValkeyModule_Init(ctx, "example-valkeymoduleapi", 1, VALKEYMODULE_APIVER_1); + if (ret != VALKEYMODULE_OK) { printf("error module init \n"); - return REDISMODULE_ERR; - } - - if (redisModuleCompatibilityCheck() != REDIS_OK) { - printf("Redis 7.0 or above is required! \n"); - return REDISMODULE_ERR; + return VALKEYMODULE_ERR; } - redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); + valkeyAsyncContext *c = valkeyAsyncConnect("127.0.0.1", 6379); if (c->err) { /* Let *c leak for now... */ printf("Error: %s\n", c->errstr); @@ -80,13 +72,13 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) } size_t len; - const char *val = RedisModule_StringPtrLen(argv[argc-1], &len); + const char *val = ValkeyModule_StringPtrLen(argv[argc-1], &len); - RedisModuleCtx *module_ctx = RedisModule_GetDetachedThreadSafeContext(ctx); - redisModuleAttach(c, module_ctx); - redisAsyncSetConnectCallback(c,connectCallback); - redisAsyncSetDisconnectCallback(c,disconnectCallback); - redisAsyncSetTimeout(c, (struct timeval){ .tv_sec = 1, .tv_usec = 0}); + ValkeyModuleCtx *module_ctx = ValkeyModule_GetDetachedThreadSafeContext(ctx); + valkeyModuleAttach(c, module_ctx); + valkeyAsyncSetConnectCallback(c,connectCallback); + valkeyAsyncSetDisconnectCallback(c,disconnectCallback); + valkeyAsyncSetTimeout(c, (struct timeval){ .tv_sec = 1, .tv_usec = 0}); /* In this demo, we first `set key`, then `get key` to demonstrate the basic usage of the adapter. @@ -95,7 +87,7 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) timeout error, which is shown in the `debugCallback`. */ - redisAsyncCommand(c, NULL, NULL, "SET key %b", val, len); - redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); + valkeyAsyncCommand(c, NULL, NULL, "SET key %b", val, len); + valkeyAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); return 0; } diff --git a/libvalkey/examples/example-ssl.c b/libvalkey/examples/example-ssl.c index 6d1e32e7..47b5276c 100644 --- a/libvalkey/examples/example-ssl.c +++ b/libvalkey/examples/example-ssl.c @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #ifdef _MSC_VER #include /* For struct timeval */ @@ -11,10 +11,10 @@ int main(int argc, char **argv) { unsigned int j; - redisSSLContext *ssl; - redisSSLContextError ssl_error = REDIS_SSL_CTX_NONE; - redisContext *c; - redisReply *reply; + valkeySSLContext *ssl; + valkeySSLContextError ssl_error = VALKEY_SSL_CTX_NONE; + valkeyContext *c; + valkeyReply *reply; if (argc < 4) { printf("Usage: %s [ca]\n", argv[0]); exit(1); @@ -25,78 +25,78 @@ int main(int argc, char **argv) { const char *key = argv[4]; const char *ca = argc > 4 ? argv[5] : NULL; - redisInitOpenSSL(); - ssl = redisCreateSSLContext(ca, NULL, cert, key, NULL, &ssl_error); - if (!ssl || ssl_error != REDIS_SSL_CTX_NONE) { - printf("SSL Context error: %s\n", redisSSLContextGetError(ssl_error)); + valkeyInitOpenSSL(); + ssl = valkeyCreateSSLContext(ca, NULL, cert, key, NULL, &ssl_error); + if (!ssl || ssl_error != VALKEY_SSL_CTX_NONE) { + printf("SSL Context error: %s\n", valkeySSLContextGetError(ssl_error)); exit(1); } struct timeval tv = { 1, 500000 }; // 1.5 seconds - redisOptions options = {0}; - REDIS_OPTIONS_SET_TCP(&options, hostname, port); + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_TCP(&options, hostname, port); options.connect_timeout = &tv; - c = redisConnectWithOptions(&options); + c = valkeyConnectWithOptions(&options); if (c == NULL || c->err) { if (c) { printf("Connection error: %s\n", c->errstr); - redisFree(c); + valkeyFree(c); } else { - printf("Connection error: can't allocate redis context\n"); + printf("Connection error: can't allocate valkey context\n"); } exit(1); } - if (redisInitiateSSLWithContext(c, ssl) != REDIS_OK) { + if (valkeyInitiateSSLWithContext(c, ssl) != VALKEY_OK) { printf("Couldn't initialize SSL!\n"); printf("Error: %s\n", c->errstr); - redisFree(c); + valkeyFree(c); exit(1); } /* PING server */ - reply = redisCommand(c,"PING"); + reply = valkeyCommand(c,"PING"); printf("PING: %s\n", reply->str); freeReplyObject(reply); /* Set a key */ - reply = redisCommand(c,"SET %s %s", "foo", "hello world"); + reply = valkeyCommand(c,"SET %s %s", "foo", "hello world"); printf("SET: %s\n", reply->str); freeReplyObject(reply); /* Set a key using binary safe API */ - reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); + reply = valkeyCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); printf("SET (binary API): %s\n", reply->str); freeReplyObject(reply); /* Try a GET and two INCR */ - reply = redisCommand(c,"GET foo"); + reply = valkeyCommand(c,"GET foo"); printf("GET foo: %s\n", reply->str); freeReplyObject(reply); - reply = redisCommand(c,"INCR counter"); + reply = valkeyCommand(c,"INCR counter"); printf("INCR counter: %lld\n", reply->integer); freeReplyObject(reply); /* again ... */ - reply = redisCommand(c,"INCR counter"); + reply = valkeyCommand(c,"INCR counter"); printf("INCR counter: %lld\n", reply->integer); freeReplyObject(reply); /* Create a list of numbers, from 0 to 9 */ - reply = redisCommand(c,"DEL mylist"); + reply = valkeyCommand(c,"DEL mylist"); freeReplyObject(reply); for (j = 0; j < 10; j++) { char buf[64]; snprintf(buf,64,"%u",j); - reply = redisCommand(c,"LPUSH mylist element-%s", buf); + reply = valkeyCommand(c,"LPUSH mylist element-%s", buf); freeReplyObject(reply); } /* Let's check what we have inside the list */ - reply = redisCommand(c,"LRANGE mylist 0 -1"); - if (reply->type == REDIS_REPLY_ARRAY) { + reply = valkeyCommand(c,"LRANGE mylist 0 -1"); + if (reply->type == VALKEY_REPLY_ARRAY) { for (j = 0; j < reply->elements; j++) { printf("%u) %s\n", j, reply->element[j]->str); } @@ -104,9 +104,9 @@ int main(int argc, char **argv) { freeReplyObject(reply); /* Disconnects and frees the context */ - redisFree(c); + valkeyFree(c); - redisFreeSSLContext(ssl); + valkeyFreeSSLContext(ssl); return 0; } diff --git a/libvalkey/examples/example.c b/libvalkey/examples/example.c index c0a9bb73..ddd9715e 100644 --- a/libvalkey/examples/example.c +++ b/libvalkey/examples/example.c @@ -1,16 +1,16 @@ #include #include #include -#include +#include #ifdef _MSC_VER #include /* For struct timeval */ #endif -static void example_argv_command(redisContext *c, size_t n) { +static void example_argv_command(valkeyContext *c, size_t n) { char **argv, tmp[42]; size_t *argvlen; - redisReply *reply; + valkeyReply *reply; /* We're allocating two additional elements for command and key */ argv = malloc(sizeof(*argv) * (2 + n)); @@ -30,17 +30,17 @@ static void example_argv_command(redisContext *c, size_t n) { argv[i] = strdup(tmp); } - /* Execute the command using redisCommandArgv. We're sending the arguments with + /* Execute the command using valkeyCommandArgv. We're sending the arguments with * two explicit arrays. One for each argument's string, and the other for its * length. */ - reply = redisCommandArgv(c, n + 2, (const char **)argv, (const size_t*)argvlen); + reply = valkeyCommandArgv(c, n + 2, (const char **)argv, (const size_t*)argvlen); if (reply == NULL || c->err) { - fprintf(stderr, "Error: Couldn't execute redisCommandArgv\n"); + fprintf(stderr, "Error: Couldn't execute valkeyCommandArgv\n"); exit(1); } - if (reply->type == REDIS_REPLY_INTEGER) { + if (reply->type == VALKEY_REPLY_INTEGER) { printf("%s reply: %lld\n", argv[0], reply->integer); } @@ -57,8 +57,8 @@ static void example_argv_command(redisContext *c, size_t n) { int main(int argc, char **argv) { unsigned int j, isunix = 0; - redisContext *c; - redisReply *reply; + valkeyContext *c; + valkeyReply *reply; const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; if (argc > 2) { @@ -73,73 +73,73 @@ int main(int argc, char **argv) { struct timeval timeout = { 1, 500000 }; // 1.5 seconds if (isunix) { - c = redisConnectUnixWithTimeout(hostname, timeout); + c = valkeyConnectUnixWithTimeout(hostname, timeout); } else { - c = redisConnectWithTimeout(hostname, port, timeout); + c = valkeyConnectWithTimeout(hostname, port, timeout); } if (c == NULL || c->err) { if (c) { printf("Connection error: %s\n", c->errstr); - redisFree(c); + valkeyFree(c); } else { - printf("Connection error: can't allocate redis context\n"); + printf("Connection error: can't allocate valkey context\n"); } exit(1); } /* PING server */ - reply = redisCommand(c,"PING"); + reply = valkeyCommand(c,"PING"); printf("PING: %s\n", reply->str); freeReplyObject(reply); /* Set a key */ - reply = redisCommand(c,"SET %s %s", "foo", "hello world"); + reply = valkeyCommand(c,"SET %s %s", "foo", "hello world"); printf("SET: %s\n", reply->str); freeReplyObject(reply); /* Set a key using binary safe API */ - reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); + reply = valkeyCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); printf("SET (binary API): %s\n", reply->str); freeReplyObject(reply); /* Try a GET and two INCR */ - reply = redisCommand(c,"GET foo"); + reply = valkeyCommand(c,"GET foo"); printf("GET foo: %s\n", reply->str); freeReplyObject(reply); - reply = redisCommand(c,"INCR counter"); + reply = valkeyCommand(c,"INCR counter"); printf("INCR counter: %lld\n", reply->integer); freeReplyObject(reply); /* again ... */ - reply = redisCommand(c,"INCR counter"); + reply = valkeyCommand(c,"INCR counter"); printf("INCR counter: %lld\n", reply->integer); freeReplyObject(reply); /* Create a list of numbers, from 0 to 9 */ - reply = redisCommand(c,"DEL mylist"); + reply = valkeyCommand(c,"DEL mylist"); freeReplyObject(reply); for (j = 0; j < 10; j++) { char buf[64]; snprintf(buf,64,"%u",j); - reply = redisCommand(c,"LPUSH mylist element-%s", buf); + reply = valkeyCommand(c,"LPUSH mylist element-%s", buf); freeReplyObject(reply); } /* Let's check what we have inside the list */ - reply = redisCommand(c,"LRANGE mylist 0 -1"); - if (reply->type == REDIS_REPLY_ARRAY) { + reply = valkeyCommand(c,"LRANGE mylist 0 -1"); + if (reply->type == VALKEY_REPLY_ARRAY) { for (j = 0; j < reply->elements; j++) { printf("%u) %s\n", j, reply->element[j]->str); } } freeReplyObject(reply); - /* See function for an example of redisCommandArgv */ + /* See function for an example of valkeyCommandArgv */ example_argv_command(c, 10); /* Disconnects and frees the context */ - redisFree(c); + valkeyFree(c); return 0; } diff --git a/libvalkey/fuzzing/format_command_fuzzer.c b/libvalkey/fuzzing/format_command_fuzzer.c deleted file mode 100644 index de125e08..00000000 --- a/libvalkey/fuzzing/format_command_fuzzer.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2020, Salvatore Sanfilippo - * Copyright (c) 2020, Pieter Noordhuis - * Copyright (c) 2020, Matt Stancliff , - * Jan-Erik Rediger - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include "hiredis.h" - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - char *new_str, *cmd; - - if (size < 3) - return 0; - - new_str = malloc(size+1); - if (new_str == NULL) - return 0; - - memcpy(new_str, data, size); - new_str[size] = '\0'; - - if (redisFormatCommand(&cmd, new_str) != -1) - hi_free(cmd); - - free(new_str); - return 0; -} diff --git a/libvalkey/hiredis-config.cmake.in b/libvalkey/hiredis-config.cmake.in deleted file mode 100644 index 03398585..00000000 --- a/libvalkey/hiredis-config.cmake.in +++ /dev/null @@ -1,13 +0,0 @@ -@PACKAGE_INIT@ - -set_and_check(hiredis_INCLUDEDIR "@PACKAGE_INCLUDE_INSTALL_DIR@") - -IF (NOT TARGET hiredis::@hiredis_export_name@) - INCLUDE(${CMAKE_CURRENT_LIST_DIR}/hiredis-targets.cmake) -ENDIF() - -SET(hiredis_LIBRARIES hiredis::@hiredis_export_name@) -SET(hiredis_INCLUDE_DIRS ${hiredis_INCLUDEDIR}) - -check_required_components(hiredis) - diff --git a/libvalkey/hiredis_ssl-config.cmake.in b/libvalkey/hiredis_ssl-config.cmake.in deleted file mode 100644 index eeb19d1d..00000000 --- a/libvalkey/hiredis_ssl-config.cmake.in +++ /dev/null @@ -1,16 +0,0 @@ -@PACKAGE_INIT@ - -set_and_check(hiredis_ssl_INCLUDEDIR "@PACKAGE_INCLUDE_INSTALL_DIR@") - -include(CMakeFindDependencyMacro) -find_dependency(OpenSSL) - -IF (NOT TARGET hiredis::hiredis_ssl) - INCLUDE(${CMAKE_CURRENT_LIST_DIR}/hiredis_ssl-targets.cmake) -ENDIF() - -SET(hiredis_ssl_LIBRARIES hiredis::hiredis_ssl) -SET(hiredis_ssl_INCLUDE_DIRS ${hiredis_ssl_INCLUDEDIR}) - -check_required_components(hiredis_ssl) - diff --git a/libvalkey/test.sh b/libvalkey/test.sh index 0a1afb92..d4b47914 100755 --- a/libvalkey/test.sh +++ b/libvalkey/test.sh @@ -1,43 +1,43 @@ #!/bin/sh -ue -REDIS_SERVER=${REDIS_SERVER:-redis-server} -REDIS_PORT=${REDIS_PORT:-56379} -REDIS_SSL_PORT=${REDIS_SSL_PORT:-56443} +VALKEY_SERVER=${VALKEY_SERVER:-valkey-server} +VALKEY_PORT=${VALKEY_PORT:-56379} +VALKEY_SSL_PORT=${VALKEY_SSL_PORT:-56443} TEST_SSL=${TEST_SSL:-0} SKIPS_AS_FAILS=${SKIPS_AS_FAILS:-0} ENABLE_DEBUG_CMD= SSL_TEST_ARGS= SKIPS_ARG=${SKIPS_ARG:-} -REDIS_DOCKER=${REDIS_DOCKER:-} +VALKEY_DOCKER=${VALKEY_DOCKER:-} -# We need to enable the DEBUG command for redis-server >= 7.0.0 -REDIS_MAJOR_VERSION="$(redis-server --version|awk -F'[^0-9]+' '{ print $2 }')" -if [ "$REDIS_MAJOR_VERSION" -gt "6" ]; then +# Enable debug command for redis-server >= 7.0.0 or any version of valkey-server. +VALKEY_MAJOR_VERSION="$("$VALKEY_SERVER" --version|awk -F'[^0-9]+' '{ print $2 }')" +if [ "$VALKEY_MAJOR_VERSION" -gt "6" ]; then ENABLE_DEBUG_CMD="enable-debug-command local" fi tmpdir=$(mktemp -d) -PID_FILE=${tmpdir}/hiredis-test-redis.pid -SOCK_FILE=${tmpdir}/hiredis-test-redis.sock +PID_FILE=${tmpdir}/libvalkey-test-valkey.pid +SOCK_FILE=${tmpdir}/libvalkey-test-valkey.sock if [ "$TEST_SSL" = "1" ]; then SSL_CA_CERT=${tmpdir}/ca.crt SSL_CA_KEY=${tmpdir}/ca.key - SSL_CERT=${tmpdir}/redis.crt - SSL_KEY=${tmpdir}/redis.key + SSL_CERT=${tmpdir}/valkey.crt + SSL_KEY=${tmpdir}/valkey.key openssl genrsa -out ${tmpdir}/ca.key 4096 openssl req \ -x509 -new -nodes -sha256 \ -key ${SSL_CA_KEY} \ -days 3650 \ - -subj '/CN=Hiredis Test CA' \ + -subj '/CN=Libvalkey Test CA' \ -out ${SSL_CA_CERT} openssl genrsa -out ${SSL_KEY} 2048 openssl req \ -new -sha256 \ -key ${SSL_KEY} \ - -subj '/CN=Hiredis Test Cert' | \ + -subj '/CN=Libvalkey Test Cert' | \ openssl x509 \ -req -sha256 \ -CA ${SSL_CA_CERT} \ @@ -47,12 +47,12 @@ if [ "$TEST_SSL" = "1" ]; then -days 365 \ -out ${SSL_CERT} - SSL_TEST_ARGS="--ssl-host 127.0.0.1 --ssl-port ${REDIS_SSL_PORT} --ssl-ca-cert ${SSL_CA_CERT} --ssl-cert ${SSL_CERT} --ssl-key ${SSL_KEY}" + SSL_TEST_ARGS="--ssl-host 127.0.0.1 --ssl-port ${VALKEY_SSL_PORT} --ssl-ca-cert ${SSL_CA_CERT} --ssl-cert ${SSL_CERT} --ssl-key ${SSL_KEY}" fi cleanup() { - if [ -n "${REDIS_DOCKER}" ] ; then - docker kill redis-test-server + if [ -n "${VALKEY_DOCKER}" ] ; then + docker kill valkey-test-server else set +e kill $(cat ${PID_FILE}) @@ -62,16 +62,16 @@ cleanup() { trap cleanup INT TERM EXIT # base config -cat > ${tmpdir}/redis.conf < ${tmpdir}/valkey.comf <> ${tmpdir}/redis.conf <> ${tmpdir}/valkey.comf <> ${tmpdir}/redis.conf <> ${tmpdir}/valkey.comf < /* for struct timeval */ - -#ifndef inline -#define inline __inline -#endif - -#ifndef strcasecmp -#define strcasecmp stricmp -#endif - -#ifndef strncasecmp -#define strncasecmp strnicmp -#endif - -#ifndef va_copy -#define va_copy(d,s) ((d) = (s)) -#endif - -#ifndef snprintf -#define snprintf c99_snprintf - -__inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) -{ - int count = -1; - - if (size != 0) - count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); - if (count == -1) - count = _vscprintf(format, ap); - - return count; -} - -__inline int c99_snprintf(char* str, size_t size, const char* format, ...) -{ - int count; - va_list ap; - - va_start(ap, format); - count = c99_vsnprintf(str, size, format, ap); - va_end(ap); - - return count; -} -#endif -#endif /* _MSC_VER */ - -#ifdef _WIN32 -#define strerror_r(errno,buf,len) strerror_s(buf,len,errno) -#endif /* _WIN32 */ - -#endif /* _WIN32_HELPER_INCLUDE */ diff --git a/src/adapters/ae.h b/src/adapters/ae.h index 9e188802..861387b0 100644 --- a/src/adapters/ae.h +++ b/src/adapters/ae.h @@ -28,11 +28,106 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __VALKEYCLUSTER_AE_H__ -#define __VALKEYCLUSTER_AE_H__ - +#ifndef VALKEY_AE_H +#define VALKEY_AE_H +#include +#include +#include "../valkey.h" +#include "../async.h" #include "../valkeycluster.h" -#include + +typedef struct valkeyAeEvents { + valkeyAsyncContext *context; + aeEventLoop *loop; + int fd; + int reading, writing; +} valkeyAeEvents; + +static void valkeyAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) { + ((void)el); ((void)fd); ((void)mask); + + valkeyAeEvents *e = (valkeyAeEvents*)privdata; + valkeyAsyncHandleRead(e->context); +} + +static void valkeyAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) { + ((void)el); ((void)fd); ((void)mask); + + valkeyAeEvents *e = (valkeyAeEvents*)privdata; + valkeyAsyncHandleWrite(e->context); +} + +static void valkeyAeAddRead(void *privdata) { + valkeyAeEvents *e = (valkeyAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (!e->reading) { + e->reading = 1; + aeCreateFileEvent(loop,e->fd,AE_READABLE,valkeyAeReadEvent,e); + } +} + +static void valkeyAeDelRead(void *privdata) { + valkeyAeEvents *e = (valkeyAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (e->reading) { + e->reading = 0; + aeDeleteFileEvent(loop,e->fd,AE_READABLE); + } +} + +static void valkeyAeAddWrite(void *privdata) { + valkeyAeEvents *e = (valkeyAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (!e->writing) { + e->writing = 1; + aeCreateFileEvent(loop,e->fd,AE_WRITABLE,valkeyAeWriteEvent,e); + } +} + +static void valkeyAeDelWrite(void *privdata) { + valkeyAeEvents *e = (valkeyAeEvents*)privdata; + aeEventLoop *loop = e->loop; + if (e->writing) { + e->writing = 0; + aeDeleteFileEvent(loop,e->fd,AE_WRITABLE); + } +} + +static void valkeyAeCleanup(void *privdata) { + valkeyAeEvents *e = (valkeyAeEvents*)privdata; + valkeyAeDelRead(privdata); + valkeyAeDelWrite(privdata); + vk_free(e); +} + +static int valkeyAeAttach(aeEventLoop *loop, valkeyAsyncContext *ac) { + valkeyContext *c = &(ac->c); + valkeyAeEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return VALKEY_ERR; + + /* Create container for context and r/w events */ + e = (valkeyAeEvents*)vk_malloc(sizeof(*e)); + if (e == NULL) + return VALKEY_ERR; + + e->context = ac; + e->loop = loop; + e->fd = c->fd; + e->reading = e->writing = 0; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = valkeyAeAddRead; + ac->ev.delRead = valkeyAeDelRead; + ac->ev.addWrite = valkeyAeAddWrite; + ac->ev.delWrite = valkeyAeDelWrite; + ac->ev.cleanup = valkeyAeCleanup; + ac->ev.data = e; + + return VALKEY_OK; +} static int valkeyAeAttach_link(valkeyAsyncContext *ac, void *base) { return valkeyAeAttach((aeEventLoop *)base, ac); @@ -40,15 +135,12 @@ static int valkeyAeAttach_link(valkeyAsyncContext *ac, void *base) { static int valkeyClusterAeAttach(aeEventLoop *loop, valkeyClusterAsyncContext *acc) { - if (acc == NULL || loop == NULL) { return VALKEY_ERR; } acc->adapter = loop; acc->attach_fn = valkeyAeAttach_link; - return VALKEY_OK; } - #endif diff --git a/src/adapters/glib.h b/src/adapters/glib.h index 96eeeae9..51087282 100644 --- a/src/adapters/glib.h +++ b/src/adapters/glib.h @@ -1,38 +1,158 @@ -/* - * Copyright (c) 2021, Björn Svensson - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __VALKEYCLUSTER_GLIB_H__ -#define __VALKEYCLUSTER_GLIB_H__ +#ifndef VALKEY_GLIB_H +#define VALKEY_GLIB_H +#include + +#include "../valkey.h" +#include "../async.h" #include "../valkeycluster.h" -#include + +typedef struct +{ + GSource source; + valkeyAsyncContext *ac; + GPollFD poll_fd; +} ValkeySource; + +static void +valkey_source_add_read (gpointer data) +{ + ValkeySource *source = (ValkeySource *)data; + g_return_if_fail(source); + source->poll_fd.events |= G_IO_IN; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +valkey_source_del_read (gpointer data) +{ + ValkeySource *source = (ValkeySource *)data; + g_return_if_fail(source); + source->poll_fd.events &= ~G_IO_IN; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +valkey_source_add_write (gpointer data) +{ + ValkeySource *source = (ValkeySource *)data; + g_return_if_fail(source); + source->poll_fd.events |= G_IO_OUT; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +valkey_source_del_write (gpointer data) +{ + ValkeySource *source = (ValkeySource *)data; + g_return_if_fail(source); + source->poll_fd.events &= ~G_IO_OUT; + g_main_context_wakeup(g_source_get_context((GSource *)data)); +} + +static void +valkey_source_cleanup (gpointer data) +{ + ValkeySource *source = (ValkeySource *)data; + + g_return_if_fail(source); + + valkey_source_del_read(source); + valkey_source_del_write(source); + /* + * It is not our responsibility to remove ourself from the + * current main loop. However, we will remove the GPollFD. + */ + if (source->poll_fd.fd >= 0) { + g_source_remove_poll((GSource *)data, &source->poll_fd); + source->poll_fd.fd = -1; + } +} + +static gboolean +valkey_source_prepare (GSource *source, + gint *timeout_) +{ + ValkeySource *valkey = (ValkeySource *)source; + *timeout_ = -1; + return !!(valkey->poll_fd.events & valkey->poll_fd.revents); +} + +static gboolean +valkey_source_check (GSource *source) +{ + ValkeySource *valkey = (ValkeySource *)source; + return !!(valkey->poll_fd.events & valkey->poll_fd.revents); +} + +static gboolean +valkey_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + ValkeySource *valkey = (ValkeySource *)source; + + if ((valkey->poll_fd.revents & G_IO_OUT)) { + valkeyAsyncHandleWrite(valkey->ac); + valkey->poll_fd.revents &= ~G_IO_OUT; + } + + if ((valkey->poll_fd.revents & G_IO_IN)) { + valkeyAsyncHandleRead(valkey->ac); + valkey->poll_fd.revents &= ~G_IO_IN; + } + + if (callback) { + return callback(user_data); + } + + return TRUE; +} + +static void +valkey_source_finalize (GSource *source) +{ + ValkeySource *valkey = (ValkeySource *)source; + + if (valkey->poll_fd.fd >= 0) { + g_source_remove_poll(source, &valkey->poll_fd); + valkey->poll_fd.fd = -1; + } +} + +static GSource * +valkey_source_new (valkeyAsyncContext *ac) +{ + static GSourceFuncs source_funcs = { + .prepare = valkey_source_prepare, + .check = valkey_source_check, + .dispatch = valkey_source_dispatch, + .finalize = valkey_source_finalize, + }; + valkeyContext *c = &ac->c; + ValkeySource *source; + + g_return_val_if_fail(ac != NULL, NULL); + + source = (ValkeySource *)g_source_new(&source_funcs, sizeof *source); + if (source == NULL) + return NULL; + + source->ac = ac; + source->poll_fd.fd = c->fd; + source->poll_fd.events = 0; + source->poll_fd.revents = 0; + g_source_add_poll((GSource *)source, &source->poll_fd); + + ac->ev.addRead = valkey_source_add_read; + ac->ev.delRead = valkey_source_del_read; + ac->ev.addWrite = valkey_source_add_write; + ac->ev.delWrite = valkey_source_del_write; + ac->ev.cleanup = valkey_source_cleanup; + ac->ev.data = source; + + return (GSource *)source; +} typedef struct valkeyClusterGlibAdapter { GMainContext *context; @@ -54,8 +174,7 @@ static int valkeyClusterGlibAttach(valkeyClusterAsyncContext *acc, acc->adapter = adapter; acc->attach_fn = valkeyGlibAttach_link; - return VALKEY_OK; } -#endif +#endif /* VALKEY_GLIB_H */ diff --git a/src/adapters/ivykis.h b/src/adapters/ivykis.h new file mode 100644 index 00000000..fd5a0f24 --- /dev/null +++ b/src/adapters/ivykis.h @@ -0,0 +1,84 @@ +#ifndef VALKEY_IVYKIS_H +#define VALKEY_IVYKIS_H +#include +#include "../valkey.h" +#include "../async.h" + +typedef struct valkeyIvykisEvents { + valkeyAsyncContext *context; + struct iv_fd fd; +} valkeyIvykisEvents; + +static void valkeyIvykisReadEvent(void *arg) { + valkeyAsyncContext *context = (valkeyAsyncContext *)arg; + valkeyAsyncHandleRead(context); +} + +static void valkeyIvykisWriteEvent(void *arg) { + valkeyAsyncContext *context = (valkeyAsyncContext *)arg; + valkeyAsyncHandleWrite(context); +} + +static void valkeyIvykisAddRead(void *privdata) { + valkeyIvykisEvents *e = (valkeyIvykisEvents*)privdata; + iv_fd_set_handler_in(&e->fd, valkeyIvykisReadEvent); +} + +static void valkeyIvykisDelRead(void *privdata) { + valkeyIvykisEvents *e = (valkeyIvykisEvents*)privdata; + iv_fd_set_handler_in(&e->fd, NULL); +} + +static void valkeyIvykisAddWrite(void *privdata) { + valkeyIvykisEvents *e = (valkeyIvykisEvents*)privdata; + iv_fd_set_handler_out(&e->fd, valkeyIvykisWriteEvent); +} + +static void valkeyIvykisDelWrite(void *privdata) { + valkeyIvykisEvents *e = (valkeyIvykisEvents*)privdata; + iv_fd_set_handler_out(&e->fd, NULL); +} + +static void valkeyIvykisCleanup(void *privdata) { + valkeyIvykisEvents *e = (valkeyIvykisEvents*)privdata; + + iv_fd_unregister(&e->fd); + vk_free(e); +} + +static int valkeyIvykisAttach(valkeyAsyncContext *ac) { + valkeyContext *c = &(ac->c); + valkeyIvykisEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return VALKEY_ERR; + + /* Create container for context and r/w events */ + e = (valkeyIvykisEvents*)vk_malloc(sizeof(*e)); + if (e == NULL) + return VALKEY_ERR; + + e->context = ac; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = valkeyIvykisAddRead; + ac->ev.delRead = valkeyIvykisDelRead; + ac->ev.addWrite = valkeyIvykisAddWrite; + ac->ev.delWrite = valkeyIvykisDelWrite; + ac->ev.cleanup = valkeyIvykisCleanup; + ac->ev.data = e; + + /* Initialize and install read/write events */ + IV_FD_INIT(&e->fd); + e->fd.fd = c->fd; + e->fd.handler_in = valkeyIvykisReadEvent; + e->fd.handler_out = valkeyIvykisWriteEvent; + e->fd.handler_err = NULL; + e->fd.cookie = e->context; + + iv_fd_register(&e->fd); + + return VALKEY_OK; +} +#endif diff --git a/src/adapters/libev.h b/src/adapters/libev.h index 77d20141..b3ba2cc2 100644 --- a/src/adapters/libev.h +++ b/src/adapters/libev.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Björn Svensson + * Copyright (c) 2010-2011, Pieter Noordhuis * * All rights reserved. * @@ -28,11 +28,163 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __LIBVALKEYCLUSTER_LIBEV_H__ -#define __LIBVALKEYCLUSTER_LIBEV_H__ - +#ifndef VALKEY_LIBEV_H +#define VALKEY_LIBEV_H +#include +#include +#include +#include "../valkey.h" +#include "../async.h" #include "../valkeycluster.h" -#include + +typedef struct valkeyLibevEvents { + valkeyAsyncContext *context; + struct ev_loop *loop; + int reading, writing; + ev_io rev, wev; + ev_timer timer; +} valkeyLibevEvents; + +static void valkeyLibevReadEvent(EV_P_ ev_io *watcher, int revents) { +#if EV_MULTIPLICITY + ((void)EV_A); +#endif + ((void)revents); + + valkeyLibevEvents *e = (valkeyLibevEvents*)watcher->data; + valkeyAsyncHandleRead(e->context); +} + +static void valkeyLibevWriteEvent(EV_P_ ev_io *watcher, int revents) { +#if EV_MULTIPLICITY + ((void)EV_A); +#endif + ((void)revents); + + valkeyLibevEvents *e = (valkeyLibevEvents*)watcher->data; + valkeyAsyncHandleWrite(e->context); +} + +static void valkeyLibevAddRead(void *privdata) { + valkeyLibevEvents *e = (valkeyLibevEvents*)privdata; +#if EV_MULTIPLICITY + struct ev_loop *loop = e->loop; +#endif + if (!e->reading) { + e->reading = 1; + ev_io_start(EV_A_ &e->rev); + } +} + +static void valkeyLibevDelRead(void *privdata) { + valkeyLibevEvents *e = (valkeyLibevEvents*)privdata; +#if EV_MULTIPLICITY + struct ev_loop *loop = e->loop; +#endif + if (e->reading) { + e->reading = 0; + ev_io_stop(EV_A_ &e->rev); + } +} + +static void valkeyLibevAddWrite(void *privdata) { + valkeyLibevEvents *e = (valkeyLibevEvents*)privdata; +#if EV_MULTIPLICITY + struct ev_loop *loop = e->loop; +#endif + if (!e->writing) { + e->writing = 1; + ev_io_start(EV_A_ &e->wev); + } +} + +static void valkeyLibevDelWrite(void *privdata) { + valkeyLibevEvents *e = (valkeyLibevEvents*)privdata; +#if EV_MULTIPLICITY + struct ev_loop *loop = e->loop; +#endif + if (e->writing) { + e->writing = 0; + ev_io_stop(EV_A_ &e->wev); + } +} + +static void valkeyLibevStopTimer(void *privdata) { + valkeyLibevEvents *e = (valkeyLibevEvents*)privdata; +#if EV_MULTIPLICITY + struct ev_loop *loop = e->loop; +#endif + ev_timer_stop(EV_A_ &e->timer); +} + +static void valkeyLibevCleanup(void *privdata) { + valkeyLibevEvents *e = (valkeyLibevEvents*)privdata; + valkeyLibevDelRead(privdata); + valkeyLibevDelWrite(privdata); + valkeyLibevStopTimer(privdata); + vk_free(e); +} + +static void valkeyLibevTimeout(EV_P_ ev_timer *timer, int revents) { +#if EV_MULTIPLICITY + ((void)EV_A); +#endif + ((void)revents); + valkeyLibevEvents *e = (valkeyLibevEvents*)timer->data; + valkeyAsyncHandleTimeout(e->context); +} + +static void valkeyLibevSetTimeout(void *privdata, struct timeval tv) { + valkeyLibevEvents *e = (valkeyLibevEvents*)privdata; +#if EV_MULTIPLICITY + struct ev_loop *loop = e->loop; +#endif + + if (!ev_is_active(&e->timer)) { + ev_init(&e->timer, valkeyLibevTimeout); + e->timer.data = e; + } + + e->timer.repeat = tv.tv_sec + tv.tv_usec / 1000000.00; + ev_timer_again(EV_A_ &e->timer); +} + +static int valkeyLibevAttach(EV_P_ valkeyAsyncContext *ac) { + valkeyContext *c = &(ac->c); + valkeyLibevEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return VALKEY_ERR; + + /* Create container for context and r/w events */ + e = (valkeyLibevEvents*)vk_calloc(1, sizeof(*e)); + if (e == NULL) + return VALKEY_ERR; + + e->context = ac; +#if EV_MULTIPLICITY + e->loop = EV_A; +#else + e->loop = NULL; +#endif + e->rev.data = e; + e->wev.data = e; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = valkeyLibevAddRead; + ac->ev.delRead = valkeyLibevDelRead; + ac->ev.addWrite = valkeyLibevAddWrite; + ac->ev.delWrite = valkeyLibevDelWrite; + ac->ev.cleanup = valkeyLibevCleanup; + ac->ev.scheduleTimer = valkeyLibevSetTimeout; + ac->ev.data = e; + + /* Initialize read/write events */ + ev_io_init(&e->rev,valkeyLibevReadEvent,c->fd,EV_READ); + ev_io_init(&e->wev,valkeyLibevWriteEvent,c->fd,EV_WRITE); + return VALKEY_OK; +} static int valkeyLibevAttach_link(valkeyAsyncContext *ac, void *loop) { return valkeyLibevAttach((struct ev_loop *)loop, ac); @@ -46,7 +198,6 @@ static int valkeyClusterLibevAttach(valkeyClusterAsyncContext *acc, acc->adapter = loop; acc->attach_fn = valkeyLibevAttach_link; - return VALKEY_OK; } diff --git a/src/adapters/libevent.h b/src/adapters/libevent.h index 818eb7c0..a5f53e05 100644 --- a/src/adapters/libevent.h +++ b/src/adapters/libevent.h @@ -28,11 +28,151 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __LIBVALKEYCLUSTER_LIBEVENT_H__ -#define __LIBVALKEYCLUSTER_LIBEVENT_H__ - +#ifndef VALKEY_LIBEVENT_H +#define VALKEY_LIBEVENT_H +#include +#include "../valkey.h" +#include "../async.h" #include "../valkeycluster.h" -#include + +#define VALKEY_LIBEVENT_DELETED 0x01 +#define VALKEY_LIBEVENT_ENTERED 0x02 + +typedef struct valkeyLibeventEvents { + valkeyAsyncContext *context; + struct event *ev; + struct event_base *base; + struct timeval tv; + short flags; + short state; +} valkeyLibeventEvents; + +static void valkeyLibeventDestroy(valkeyLibeventEvents *e) { + vk_free(e); +} + +static void valkeyLibeventHandler(evutil_socket_t fd, short event, void *arg) { + ((void)fd); + valkeyLibeventEvents *e = (valkeyLibeventEvents*)arg; + e->state |= VALKEY_LIBEVENT_ENTERED; + + #define CHECK_DELETED() if (e->state & VALKEY_LIBEVENT_DELETED) {\ + valkeyLibeventDestroy(e);\ + return; \ + } + + if ((event & EV_TIMEOUT) && (e->state & VALKEY_LIBEVENT_DELETED) == 0) { + valkeyAsyncHandleTimeout(e->context); + CHECK_DELETED(); + } + + if ((event & EV_READ) && e->context && (e->state & VALKEY_LIBEVENT_DELETED) == 0) { + valkeyAsyncHandleRead(e->context); + CHECK_DELETED(); + } + + if ((event & EV_WRITE) && e->context && (e->state & VALKEY_LIBEVENT_DELETED) == 0) { + valkeyAsyncHandleWrite(e->context); + CHECK_DELETED(); + } + + e->state &= ~VALKEY_LIBEVENT_ENTERED; + #undef CHECK_DELETED +} + +static void valkeyLibeventUpdate(void *privdata, short flag, int isRemove) { + valkeyLibeventEvents *e = (valkeyLibeventEvents *)privdata; + const struct timeval *tv = e->tv.tv_sec || e->tv.tv_usec ? &e->tv : NULL; + + if (isRemove) { + if ((e->flags & flag) == 0) { + return; + } else { + e->flags &= ~flag; + } + } else { + if (e->flags & flag) { + return; + } else { + e->flags |= flag; + } + } + + event_del(e->ev); + event_assign(e->ev, e->base, e->context->c.fd, e->flags | EV_PERSIST, + valkeyLibeventHandler, privdata); + event_add(e->ev, tv); +} + +static void valkeyLibeventAddRead(void *privdata) { + valkeyLibeventUpdate(privdata, EV_READ, 0); +} + +static void valkeyLibeventDelRead(void *privdata) { + valkeyLibeventUpdate(privdata, EV_READ, 1); +} + +static void valkeyLibeventAddWrite(void *privdata) { + valkeyLibeventUpdate(privdata, EV_WRITE, 0); +} + +static void valkeyLibeventDelWrite(void *privdata) { + valkeyLibeventUpdate(privdata, EV_WRITE, 1); +} + +static void valkeyLibeventCleanup(void *privdata) { + valkeyLibeventEvents *e = (valkeyLibeventEvents*)privdata; + if (!e) { + return; + } + event_del(e->ev); + event_free(e->ev); + e->ev = NULL; + + if (e->state & VALKEY_LIBEVENT_ENTERED) { + e->state |= VALKEY_LIBEVENT_DELETED; + } else { + valkeyLibeventDestroy(e); + } +} + +static void valkeyLibeventSetTimeout(void *privdata, struct timeval tv) { + valkeyLibeventEvents *e = (valkeyLibeventEvents *)privdata; + short flags = e->flags; + e->flags = 0; + e->tv = tv; + valkeyLibeventUpdate(e, flags, 0); +} + +static int valkeyLibeventAttach(valkeyAsyncContext *ac, struct event_base *base) { + valkeyContext *c = &(ac->c); + valkeyLibeventEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return VALKEY_ERR; + + /* Create container for context and r/w events */ + e = (valkeyLibeventEvents*)vk_calloc(1, sizeof(*e)); + if (e == NULL) + return VALKEY_ERR; + + e->context = ac; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = valkeyLibeventAddRead; + ac->ev.delRead = valkeyLibeventDelRead; + ac->ev.addWrite = valkeyLibeventAddWrite; + ac->ev.delWrite = valkeyLibeventDelWrite; + ac->ev.cleanup = valkeyLibeventCleanup; + ac->ev.scheduleTimer = valkeyLibeventSetTimeout; + ac->ev.data = e; + + /* Initialize and install read/write events */ + e->ev = event_new(base, c->fd, EV_READ | EV_WRITE, valkeyLibeventHandler, e); + e->base = base; + return VALKEY_OK; +} static int valkeyLibeventAttach_link(valkeyAsyncContext *ac, void *base) { return valkeyLibeventAttach(ac, (struct event_base *)base); @@ -40,15 +180,12 @@ static int valkeyLibeventAttach_link(valkeyAsyncContext *ac, void *base) { static int valkeyClusterLibeventAttach(valkeyClusterAsyncContext *acc, struct event_base *base) { - if (acc == NULL || base == NULL) { return VALKEY_ERR; } acc->adapter = base; acc->attach_fn = valkeyLibeventAttach_link; - return VALKEY_OK; } - #endif diff --git a/src/adapters/libhv.h b/src/adapters/libhv.h new file mode 100644 index 00000000..04e2d7e5 --- /dev/null +++ b/src/adapters/libhv.h @@ -0,0 +1,123 @@ +#ifndef VALKEY_LIBHV_H +#define VALKEY_LIBHV_H + +#include +#include "../valkey.h" +#include "../async.h" + +typedef struct valkeyLibhvEvents { + hio_t *io; + htimer_t *timer; +} valkeyLibhvEvents; + +static void valkeyLibhvHandleEvents(hio_t* io) { + valkeyAsyncContext* context = (valkeyAsyncContext*)hevent_userdata(io); + int events = hio_events(io); + int revents = hio_revents(io); + if (context && (events & HV_READ) && (revents & HV_READ)) { + valkeyAsyncHandleRead(context); + } + if (context && (events & HV_WRITE) && (revents & HV_WRITE)) { + valkeyAsyncHandleWrite(context); + } +} + +static void valkeyLibhvAddRead(void *privdata) { + valkeyLibhvEvents* events = (valkeyLibhvEvents*)privdata; + hio_add(events->io, valkeyLibhvHandleEvents, HV_READ); +} + +static void valkeyLibhvDelRead(void *privdata) { + valkeyLibhvEvents* events = (valkeyLibhvEvents*)privdata; + hio_del(events->io, HV_READ); +} + +static void valkeyLibhvAddWrite(void *privdata) { + valkeyLibhvEvents* events = (valkeyLibhvEvents*)privdata; + hio_add(events->io, valkeyLibhvHandleEvents, HV_WRITE); +} + +static void valkeyLibhvDelWrite(void *privdata) { + valkeyLibhvEvents* events = (valkeyLibhvEvents*)privdata; + hio_del(events->io, HV_WRITE); +} + +static void valkeyLibhvCleanup(void *privdata) { + valkeyLibhvEvents* events = (valkeyLibhvEvents*)privdata; + + if (events->timer) + htimer_del(events->timer); + + hio_close(events->io); + hevent_set_userdata(events->io, NULL); + + vk_free(events); +} + +static void valkeyLibhvTimeout(htimer_t* timer) { + hio_t* io = (hio_t*)hevent_userdata(timer); + valkeyAsyncHandleTimeout((valkeyAsyncContext*)hevent_userdata(io)); +} + +static void valkeyLibhvSetTimeout(void *privdata, struct timeval tv) { + valkeyLibhvEvents* events; + uint32_t millis; + hloop_t* loop; + + events = (valkeyLibhvEvents*)privdata; + millis = tv.tv_sec * 1000 + tv.tv_usec / 1000; + + if (millis == 0) { + /* Libhv disallows zero'd timers so treat this as a delete or NO OP */ + if (events->timer) { + htimer_del(events->timer); + events->timer = NULL; + } + } else if (events->timer == NULL) { + /* Add new timer */ + loop = hevent_loop(events->io); + events->timer = htimer_add(loop, valkeyLibhvTimeout, millis, 1); + hevent_set_userdata(events->timer, events->io); + } else { + /* Update existing timer */ + htimer_reset(events->timer, millis); + } +} + +static int valkeyLibhvAttach(valkeyAsyncContext* ac, hloop_t* loop) { + valkeyContext *c = &(ac->c); + valkeyLibhvEvents *events; + hio_t* io = NULL; + + if (ac->ev.data != NULL) { + return VALKEY_ERR; + } + + /* Create container struct to keep track of our io and any timer */ + events = (valkeyLibhvEvents*)vk_malloc(sizeof(*events)); + if (events == NULL) { + return VALKEY_ERR; + } + + io = hio_get(loop, c->fd); + if (io == NULL) { + vk_free(events); + return VALKEY_ERR; + } + + hevent_set_userdata(io, ac); + + events->io = io; + events->timer = NULL; + + ac->ev.addRead = valkeyLibhvAddRead; + ac->ev.delRead = valkeyLibhvDelRead; + ac->ev.addWrite = valkeyLibhvAddWrite; + ac->ev.delWrite = valkeyLibhvDelWrite; + ac->ev.cleanup = valkeyLibhvCleanup; + ac->ev.scheduleTimer = valkeyLibhvSetTimeout; + ac->ev.data = events; + + return VALKEY_OK; +} +#endif diff --git a/src/adapters/libsdevent.h b/src/adapters/libsdevent.h new file mode 100644 index 00000000..36e3f29b --- /dev/null +++ b/src/adapters/libsdevent.h @@ -0,0 +1,177 @@ +#ifndef VALKEY_LIBSDEVENT_H +#define VALKEY_LIBSDEVENT_H +#include +#include "../valkey.h" +#include "../async.h" + +#define VALKEY_LIBSDEVENT_DELETED 0x01 +#define VALKEY_LIBSDEVENT_ENTERED 0x02 + +typedef struct valkeyLibsdeventEvents { + valkeyAsyncContext *context; + struct sd_event *event; + struct sd_event_source *fdSource; + struct sd_event_source *timerSource; + int fd; + short flags; + short state; +} valkeyLibsdeventEvents; + +static void valkeyLibsdeventDestroy(valkeyLibsdeventEvents *e) { + if (e->fdSource) { + e->fdSource = sd_event_source_disable_unref(e->fdSource); + } + if (e->timerSource) { + e->timerSource = sd_event_source_disable_unref(e->timerSource); + } + sd_event_unref(e->event); + vk_free(e); +} + +static int valkeyLibsdeventTimeoutHandler(sd_event_source *s, uint64_t usec, void *userdata) { + ((void)s); + ((void)usec); + valkeyLibsdeventEvents *e = (valkeyLibsdeventEvents*)userdata; + valkeyAsyncHandleTimeout(e->context); + return 0; +} + +static int valkeyLibsdeventHandler(sd_event_source *s, int fd, uint32_t event, void *userdata) { + ((void)s); + ((void)fd); + valkeyLibsdeventEvents *e = (valkeyLibsdeventEvents*)userdata; + e->state |= VALKEY_LIBSDEVENT_ENTERED; + +#define CHECK_DELETED() if (e->state & VALKEY_LIBSDEVENT_DELETED) {\ + valkeyLibsdeventDestroy(e);\ + return 0; \ + } + + if ((event & EPOLLIN) && e->context && (e->state & VALKEY_LIBSDEVENT_DELETED) == 0) { + valkeyAsyncHandleRead(e->context); + CHECK_DELETED(); + } + + if ((event & EPOLLOUT) && e->context && (e->state & VALKEY_LIBSDEVENT_DELETED) == 0) { + valkeyAsyncHandleWrite(e->context); + CHECK_DELETED(); + } + + e->state &= ~VALKEY_LIBSDEVENT_ENTERED; +#undef CHECK_DELETED + + return 0; +} + +static void valkeyLibsdeventAddRead(void *userdata) { + valkeyLibsdeventEvents *e = (valkeyLibsdeventEvents*)userdata; + + if (e->flags & EPOLLIN) { + return; + } + + e->flags |= EPOLLIN; + + if (e->flags & EPOLLOUT) { + sd_event_source_set_io_events(e->fdSource, e->flags); + } else { + sd_event_add_io(e->event, &e->fdSource, e->fd, e->flags, valkeyLibsdeventHandler, e); + } +} + +static void valkeyLibsdeventDelRead(void *userdata) { + valkeyLibsdeventEvents *e = (valkeyLibsdeventEvents*)userdata; + + e->flags &= ~EPOLLIN; + + if (e->flags) { + sd_event_source_set_io_events(e->fdSource, e->flags); + } else { + e->fdSource = sd_event_source_disable_unref(e->fdSource); + } +} + +static void valkeyLibsdeventAddWrite(void *userdata) { + valkeyLibsdeventEvents *e = (valkeyLibsdeventEvents*)userdata; + + if (e->flags & EPOLLOUT) { + return; + } + + e->flags |= EPOLLOUT; + + if (e->flags & EPOLLIN) { + sd_event_source_set_io_events(e->fdSource, e->flags); + } else { + sd_event_add_io(e->event, &e->fdSource, e->fd, e->flags, valkeyLibsdeventHandler, e); + } +} + +static void valkeyLibsdeventDelWrite(void *userdata) { + valkeyLibsdeventEvents *e = (valkeyLibsdeventEvents*)userdata; + + e->flags &= ~EPOLLOUT; + + if (e->flags) { + sd_event_source_set_io_events(e->fdSource, e->flags); + } else { + e->fdSource = sd_event_source_disable_unref(e->fdSource); + } +} + +static void valkeyLibsdeventCleanup(void *userdata) { + valkeyLibsdeventEvents *e = (valkeyLibsdeventEvents*)userdata; + + if (!e) { + return; + } + + if (e->state & VALKEY_LIBSDEVENT_ENTERED) { + e->state |= VALKEY_LIBSDEVENT_DELETED; + } else { + valkeyLibsdeventDestroy(e); + } +} + +static void valkeyLibsdeventSetTimeout(void *userdata, struct timeval tv) { + valkeyLibsdeventEvents *e = (valkeyLibsdeventEvents *)userdata; + + uint64_t usec = tv.tv_sec * 1000000 + tv.tv_usec; + if (!e->timerSource) { + sd_event_add_time_relative(e->event, &e->timerSource, CLOCK_MONOTONIC, usec, 1, valkeyLibsdeventTimeoutHandler, e); + } else { + sd_event_source_set_time_relative(e->timerSource, usec); + } +} + +static int valkeyLibsdeventAttach(valkeyAsyncContext *ac, struct sd_event *event) { + valkeyContext *c = &(ac->c); + valkeyLibsdeventEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return VALKEY_ERR; + + /* Create container for context and r/w events */ + e = (valkeyLibsdeventEvents*)vk_calloc(1, sizeof(*e)); + if (e == NULL) + return VALKEY_ERR; + + /* Initialize and increase event refcount */ + e->context = ac; + e->event = event; + e->fd = c->fd; + sd_event_ref(event); + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = valkeyLibsdeventAddRead; + ac->ev.delRead = valkeyLibsdeventDelRead; + ac->ev.addWrite = valkeyLibsdeventAddWrite; + ac->ev.delWrite = valkeyLibsdeventDelWrite; + ac->ev.cleanup = valkeyLibsdeventCleanup; + ac->ev.scheduleTimer = valkeyLibsdeventSetTimeout; + ac->ev.data = e; + + return VALKEY_OK; +} +#endif diff --git a/src/adapters/libuv.h b/src/adapters/libuv.h index 2150f9e4..082d2f6d 100644 --- a/src/adapters/libuv.h +++ b/src/adapters/libuv.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2013, Erik Dubbelboer * Copyright (c) 2021, Red Hat * * All rights reserved. @@ -28,11 +29,178 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __LIBVALKEYCLUSTER_LIBUV_H__ -#define __LIBVALKEYCLUSTER_LIBUV_H__ - +#ifndef VALKEY_LIBUV_H +#define VALKEY_LIBUV_H +#include +#include +#include "../valkey.h" +#include "../async.h" #include "../valkeycluster.h" -#include +#include + +typedef struct valkeyLibuvEvents { + valkeyAsyncContext* context; + uv_poll_t handle; + uv_timer_t timer; + int events; +} valkeyLibuvEvents; + + +static void valkeyLibuvPoll(uv_poll_t* handle, int status, int events) { + valkeyLibuvEvents* p = (valkeyLibuvEvents*)handle->data; + int ev = (status ? p->events : events); + + if (p->context != NULL && (ev & UV_READABLE)) { + valkeyAsyncHandleRead(p->context); + } + if (p->context != NULL && (ev & UV_WRITABLE)) { + valkeyAsyncHandleWrite(p->context); + } +} + + +static void valkeyLibuvAddRead(void *privdata) { + valkeyLibuvEvents* p = (valkeyLibuvEvents*)privdata; + + if (p->events & UV_READABLE) { + return; + } + + p->events |= UV_READABLE; + + uv_poll_start(&p->handle, p->events, valkeyLibuvPoll); +} + + +static void valkeyLibuvDelRead(void *privdata) { + valkeyLibuvEvents* p = (valkeyLibuvEvents*)privdata; + + p->events &= ~UV_READABLE; + + if (p->events) { + uv_poll_start(&p->handle, p->events, valkeyLibuvPoll); + } else { + uv_poll_stop(&p->handle); + } +} + + +static void valkeyLibuvAddWrite(void *privdata) { + valkeyLibuvEvents* p = (valkeyLibuvEvents*)privdata; + + if (p->events & UV_WRITABLE) { + return; + } + + p->events |= UV_WRITABLE; + + uv_poll_start(&p->handle, p->events, valkeyLibuvPoll); +} + + +static void valkeyLibuvDelWrite(void *privdata) { + valkeyLibuvEvents* p = (valkeyLibuvEvents*)privdata; + + p->events &= ~UV_WRITABLE; + + if (p->events) { + uv_poll_start(&p->handle, p->events, valkeyLibuvPoll); + } else { + uv_poll_stop(&p->handle); + } +} + +static void on_timer_close(uv_handle_t *handle) { + valkeyLibuvEvents* p = (valkeyLibuvEvents*)handle->data; + p->timer.data = NULL; + if (!p->handle.data) { + // both timer and handle are closed + vk_free(p); + } + // else, wait for `on_handle_close` +} + +static void on_handle_close(uv_handle_t *handle) { + valkeyLibuvEvents* p = (valkeyLibuvEvents*)handle->data; + p->handle.data = NULL; + if (!p->timer.data) { + // timer never started, or timer already destroyed + vk_free(p); + } + // else, wait for `on_timer_close` +} + +// libuv removed `status` parameter since v0.11.23 +// see: https://github.com/libuv/libuv/blob/v0.11.23/include/uv.h +#if (UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR < 11) || \ + (UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR == 11 && UV_VERSION_PATCH < 23) +static void valkeyLibuvTimeout(uv_timer_t *timer, int status) { + (void)status; // unused +#else +static void valkeyLibuvTimeout(uv_timer_t *timer) { +#endif + valkeyLibuvEvents *e = (valkeyLibuvEvents*)timer->data; + valkeyAsyncHandleTimeout(e->context); +} + +static void valkeyLibuvSetTimeout(void *privdata, struct timeval tv) { + valkeyLibuvEvents* p = (valkeyLibuvEvents*)privdata; + + uint64_t millsec = tv.tv_sec * 1000 + tv.tv_usec / 1000.0; + if (!p->timer.data) { + // timer is uninitialized + if (uv_timer_init(p->handle.loop, &p->timer) != 0) { + return; + } + p->timer.data = p; + } + // updates the timeout if the timer has already started + // or start the timer + uv_timer_start(&p->timer, valkeyLibuvTimeout, millsec, 0); +} + +static void valkeyLibuvCleanup(void *privdata) { + valkeyLibuvEvents* p = (valkeyLibuvEvents*)privdata; + + p->context = NULL; // indicate that context might no longer exist + if (p->timer.data) { + uv_close((uv_handle_t*)&p->timer, on_timer_close); + } + uv_close((uv_handle_t*)&p->handle, on_handle_close); +} + + +static int valkeyLibuvAttach(valkeyAsyncContext* ac, uv_loop_t* loop) { + valkeyContext *c = &(ac->c); + + if (ac->ev.data != NULL) { + return VALKEY_ERR; + } + + ac->ev.addRead = valkeyLibuvAddRead; + ac->ev.delRead = valkeyLibuvDelRead; + ac->ev.addWrite = valkeyLibuvAddWrite; + ac->ev.delWrite = valkeyLibuvDelWrite; + ac->ev.cleanup = valkeyLibuvCleanup; + ac->ev.scheduleTimer = valkeyLibuvSetTimeout; + + valkeyLibuvEvents* p = (valkeyLibuvEvents*)vk_malloc(sizeof(*p)); + if (p == NULL) + return VALKEY_ERR; + + memset(p, 0, sizeof(*p)); + + if (uv_poll_init_socket(loop, &p->handle, c->fd) != 0) { + vk_free(p); + return VALKEY_ERR; + } + + ac->ev.data = p; + p->handle.data = p; + p->context = ac; + + return VALKEY_OK; +} static int valkeyLibuvAttach_link(valkeyAsyncContext *ac, void *loop) { return valkeyLibuvAttach(ac, (uv_loop_t *)loop); @@ -40,15 +208,12 @@ static int valkeyLibuvAttach_link(valkeyAsyncContext *ac, void *loop) { static int valkeyClusterLibuvAttach(valkeyClusterAsyncContext *acc, uv_loop_t *loop) { - if (acc == NULL || loop == NULL) { return VALKEY_ERR; } acc->adapter = loop; acc->attach_fn = valkeyLibuvAttach_link; - return VALKEY_OK; } - #endif diff --git a/src/adapters/macosx.h b/src/adapters/macosx.h new file mode 100644 index 00000000..5f34a22b --- /dev/null +++ b/src/adapters/macosx.h @@ -0,0 +1,115 @@ +// +// Created by Дмитрий Бахвалов on 13.07.15. +// Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved. +// + +#ifndef VALKEY_MACOSX_H +#define VALKEY_MACOSX_H + +#include + +#include "../valkey.h" +#include "../async.h" + +typedef struct { + valkeyAsyncContext *context; + CFSocketRef socketRef; + CFRunLoopSourceRef sourceRef; +} ValkeyRunLoop; + +static int freeValkeyRunLoop(ValkeyRunLoop* valkeyRunLoop) { + if( valkeyRunLoop != NULL ) { + if( valkeyRunLoop->sourceRef != NULL ) { + CFRunLoopSourceInvalidate(valkeyRunLoop->sourceRef); + CFRelease(valkeyRunLoop->sourceRef); + } + if( valkeyRunLoop->socketRef != NULL ) { + CFSocketInvalidate(valkeyRunLoop->socketRef); + CFRelease(valkeyRunLoop->socketRef); + } + vk_free(valkeyRunLoop); + } + return VALKEY_ERR; +} + +static void valkeyMacOSAddRead(void *privdata) { + ValkeyRunLoop *valkeyRunLoop = (ValkeyRunLoop*)privdata; + CFSocketEnableCallBacks(valkeyRunLoop->socketRef, kCFSocketReadCallBack); +} + +static void valkeyMacOSDelRead(void *privdata) { + ValkeyRunLoop *valkeyRunLoop = (ValkeyRunLoop*)privdata; + CFSocketDisableCallBacks(valkeyRunLoop->socketRef, kCFSocketReadCallBack); +} + +static void valkeyMacOSAddWrite(void *privdata) { + ValkeyRunLoop *valkeyRunLoop = (ValkeyRunLoop*)privdata; + CFSocketEnableCallBacks(valkeyRunLoop->socketRef, kCFSocketWriteCallBack); +} + +static void valkeyMacOSDelWrite(void *privdata) { + ValkeyRunLoop *valkeyRunLoop = (ValkeyRunLoop*)privdata; + CFSocketDisableCallBacks(valkeyRunLoop->socketRef, kCFSocketWriteCallBack); +} + +static void valkeyMacOSCleanup(void *privdata) { + ValkeyRunLoop *valkeyRunLoop = (ValkeyRunLoop*)privdata; + freeValkeyRunLoop(valkeyRunLoop); +} + +static void valkeyMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) { + valkeyAsyncContext* context = (valkeyAsyncContext*) info; + + switch (callbackType) { + case kCFSocketReadCallBack: + valkeyAsyncHandleRead(context); + break; + + case kCFSocketWriteCallBack: + valkeyAsyncHandleWrite(context); + break; + + default: + break; + } +} + +static int valkeyMacOSAttach(valkeyAsyncContext *valkeyAsyncCtx, CFRunLoopRef runLoop) { + valkeyContext *valkeyCtx = &(valkeyAsyncCtx->c); + + /* Nothing should be attached when something is already attached */ + if( valkeyAsyncCtx->ev.data != NULL ) return VALKEY_ERR; + + ValkeyRunLoop* valkeyRunLoop = (ValkeyRunLoop*) vk_calloc(1, sizeof(ValkeyRunLoop)); + if (valkeyRunLoop == NULL) + return VALKEY_ERR; + + /* Setup valkey stuff */ + valkeyRunLoop->context = valkeyAsyncCtx; + + valkeyAsyncCtx->ev.addRead = valkeyMacOSAddRead; + valkeyAsyncCtx->ev.delRead = valkeyMacOSDelRead; + valkeyAsyncCtx->ev.addWrite = valkeyMacOSAddWrite; + valkeyAsyncCtx->ev.delWrite = valkeyMacOSDelWrite; + valkeyAsyncCtx->ev.cleanup = valkeyMacOSCleanup; + valkeyAsyncCtx->ev.data = valkeyRunLoop; + + /* Initialize and install read/write events */ + CFSocketContext socketCtx = { 0, valkeyAsyncCtx, NULL, NULL, NULL }; + + valkeyRunLoop->socketRef = CFSocketCreateWithNative(NULL, valkeyCtx->fd, + kCFSocketReadCallBack | kCFSocketWriteCallBack, + valkeyMacOSAsyncCallback, + &socketCtx); + if( !valkeyRunLoop->socketRef ) return freeValkeyRunLoop(valkeyRunLoop); + + valkeyRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, valkeyRunLoop->socketRef, 0); + if( !valkeyRunLoop->sourceRef ) return freeValkeyRunLoop(valkeyRunLoop); + + CFRunLoopAddSource(runLoop, valkeyRunLoop->sourceRef, kCFRunLoopDefaultMode); + + return VALKEY_OK; +} + +#endif + diff --git a/libvalkey/adapters/poll.h b/src/adapters/poll.h similarity index 57% rename from libvalkey/adapters/poll.h rename to src/adapters/poll.h index f138650f..ecee5244 100644 --- a/libvalkey/adapters/poll.h +++ b/src/adapters/poll.h @@ -1,41 +1,41 @@ -#ifndef HIREDIS_POLL_H -#define HIREDIS_POLL_H +#ifndef VALKEY_POLL_H +#define VALKEY_POLL_H #include "../async.h" #include "../sockcompat.h" #include // for memset #include -/* Values to return from redisPollTick */ -#define REDIS_POLL_HANDLED_READ 1 -#define REDIS_POLL_HANDLED_WRITE 2 -#define REDIS_POLL_HANDLED_TIMEOUT 4 +/* Values to return from valkeyPollTick */ +#define VALKEY_POLL_HANDLED_READ 1 +#define VALKEY_POLL_HANDLED_WRITE 2 +#define VALKEY_POLL_HANDLED_TIMEOUT 4 /* An adapter to allow manual polling of the async context by checking the state * of the underlying file descriptor. Useful in cases where there is no formal * IO event loop but regular ticking can be used, such as in game engines. */ -typedef struct redisPollEvents { - redisAsyncContext *context; - redisFD fd; +typedef struct valkeyPollEvents { + valkeyAsyncContext *context; + valkeyFD fd; char reading, writing; char in_tick; char deleted; double deadline; -} redisPollEvents; +} valkeyPollEvents; -static double redisPollTimevalToDouble(struct timeval *tv) { +static double valkeyPollTimevalToDouble(struct timeval *tv) { if (tv == NULL) return 0.0; return tv->tv_sec + tv->tv_usec / 1000000.00; } -static double redisPollGetNow(void) { +static double valkeyPollGetNow(void) { #ifndef _MSC_VER struct timeval tv; gettimeofday(&tv,NULL); - return redisPollTimevalToDouble(&tv); + return valkeyPollTimevalToDouble(&tv); #else FILETIME ft; ULARGE_INTEGER li; @@ -49,14 +49,14 @@ static double redisPollGetNow(void) { /* Poll for io, handling any pending callbacks. The timeout argument can be * positive to wait for a maximum given time for IO, zero to poll, or negative * to wait forever */ -static int redisPollTick(redisAsyncContext *ac, double timeout) { +static int valkeyPollTick(valkeyAsyncContext *ac, double timeout) { int reading, writing; struct pollfd pfd; int handled; int ns; int itimeout; - redisPollEvents *e = (redisPollEvents*)ac->ev.data; + valkeyPollEvents *e = (valkeyPollEvents*)ac->ev.data; if (!e) return 0; @@ -69,7 +69,7 @@ static int redisPollTick(redisAsyncContext *ac, double timeout) { pfd.fd = e->fd; pfd.events = 0; if (reading) - pfd.events = POLLIN; + pfd.events = POLLIN; if (writing) pfd.events |= POLLOUT; @@ -86,95 +86,95 @@ static int redisPollTick(redisAsyncContext *ac, double timeout) { return ns; ns = 0; } - + handled = 0; e->in_tick = 1; if (ns) { if (reading && (pfd.revents & POLLIN)) { - redisAsyncHandleRead(ac); - handled |= REDIS_POLL_HANDLED_READ; + valkeyAsyncHandleRead(ac); + handled |= VALKEY_POLL_HANDLED_READ; } /* on Windows, connection failure is indicated with the Exception fdset. * handle it the same as writable. */ if (writing && (pfd.revents & (POLLOUT | POLLERR))) { /* context Read callback may have caused context to be deleted, e.g. - by doing an redisAsyncDisconnect() */ + by doing an valkeyAsyncDisconnect() */ if (!e->deleted) { - redisAsyncHandleWrite(ac); - handled |= REDIS_POLL_HANDLED_WRITE; + valkeyAsyncHandleWrite(ac); + handled |= VALKEY_POLL_HANDLED_WRITE; } } } /* perform timeouts */ if (!e->deleted && e->deadline != 0.0) { - double now = redisPollGetNow(); + double now = valkeyPollGetNow(); if (now >= e->deadline) { /* deadline has passed. disable timeout and perform callback */ e->deadline = 0.0; - redisAsyncHandleTimeout(ac); - handled |= REDIS_POLL_HANDLED_TIMEOUT; + valkeyAsyncHandleTimeout(ac); + handled |= VALKEY_POLL_HANDLED_TIMEOUT; } } /* do a delayed cleanup if required */ if (e->deleted) - hi_free(e); + vk_free(e); else e->in_tick = 0; return handled; } -static void redisPollAddRead(void *data) { - redisPollEvents *e = (redisPollEvents*)data; +static void valkeyPollAddRead(void *data) { + valkeyPollEvents *e = (valkeyPollEvents*)data; e->reading = 1; } -static void redisPollDelRead(void *data) { - redisPollEvents *e = (redisPollEvents*)data; +static void valkeyPollDelRead(void *data) { + valkeyPollEvents *e = (valkeyPollEvents*)data; e->reading = 0; } -static void redisPollAddWrite(void *data) { - redisPollEvents *e = (redisPollEvents*)data; +static void valkeyPollAddWrite(void *data) { + valkeyPollEvents *e = (valkeyPollEvents*)data; e->writing = 1; } -static void redisPollDelWrite(void *data) { - redisPollEvents *e = (redisPollEvents*)data; +static void valkeyPollDelWrite(void *data) { + valkeyPollEvents *e = (valkeyPollEvents*)data; e->writing = 0; } -static void redisPollCleanup(void *data) { - redisPollEvents *e = (redisPollEvents*)data; +static void valkeyPollCleanup(void *data) { + valkeyPollEvents *e = (valkeyPollEvents*)data; /* if we are currently processing a tick, postpone deletion */ if (e->in_tick) e->deleted = 1; else - hi_free(e); + vk_free(e); } -static void redisPollScheduleTimer(void *data, struct timeval tv) +static void valkeyPollScheduleTimer(void *data, struct timeval tv) { - redisPollEvents *e = (redisPollEvents*)data; - double now = redisPollGetNow(); - e->deadline = now + redisPollTimevalToDouble(&tv); + valkeyPollEvents *e = (valkeyPollEvents*)data; + double now = valkeyPollGetNow(); + e->deadline = now + valkeyPollTimevalToDouble(&tv); } -static int redisPollAttach(redisAsyncContext *ac) { - redisContext *c = &(ac->c); - redisPollEvents *e; +static int valkeyPollAttach(valkeyAsyncContext *ac) { + valkeyContext *c = &(ac->c); + valkeyPollEvents *e; /* Nothing should be attached when something is already attached */ if (ac->ev.data != NULL) - return REDIS_ERR; + return VALKEY_ERR; /* Create container for context and r/w events */ - e = (redisPollEvents*)hi_malloc(sizeof(*e)); + e = (valkeyPollEvents*)vk_malloc(sizeof(*e)); if (e == NULL) - return REDIS_ERR; + return VALKEY_ERR; memset(e, 0, sizeof(*e)); e->context = ac; @@ -184,14 +184,14 @@ static int redisPollAttach(redisAsyncContext *ac) { e->deadline = 0.0; /* Register functions to start/stop listening for events */ - ac->ev.addRead = redisPollAddRead; - ac->ev.delRead = redisPollDelRead; - ac->ev.addWrite = redisPollAddWrite; - ac->ev.delWrite = redisPollDelWrite; - ac->ev.scheduleTimer = redisPollScheduleTimer; - ac->ev.cleanup = redisPollCleanup; + ac->ev.addRead = valkeyPollAddRead; + ac->ev.delRead = valkeyPollDelRead; + ac->ev.addWrite = valkeyPollAddWrite; + ac->ev.delWrite = valkeyPollDelWrite; + ac->ev.scheduleTimer = valkeyPollScheduleTimer; + ac->ev.cleanup = valkeyPollCleanup; ac->ev.data = e; - return REDIS_OK; + return VALKEY_OK; } -#endif /* HIREDIS_POLL_H */ +#endif /* VALKEY_POLL_H */ diff --git a/libvalkey/adapters/qt.h b/src/adapters/qt.h similarity index 65% rename from libvalkey/adapters/qt.h rename to src/adapters/qt.h index 5cc02e6c..7641f72e 100644 --- a/libvalkey/adapters/qt.h +++ b/src/adapters/qt.h @@ -23,73 +23,73 @@ * SUCH DAMAGE. */ -#ifndef __HIREDIS_QT_H__ -#define __HIREDIS_QT_H__ +#ifndef VALKEY_QT_H +#define VALKEY_QT_H #include #include "../async.h" -static void RedisQtAddRead(void *); -static void RedisQtDelRead(void *); -static void RedisQtAddWrite(void *); -static void RedisQtDelWrite(void *); -static void RedisQtCleanup(void *); +static void ValkeyQtAddRead(void *); +static void ValkeyQtDelRead(void *); +static void ValkeyQtAddWrite(void *); +static void ValkeyQtDelWrite(void *); +static void ValkeyQtCleanup(void *); -class RedisQtAdapter : public QObject { +class ValkeyQtAdapter : public QObject { Q_OBJECT friend - void RedisQtAddRead(void * adapter) { - RedisQtAdapter * a = static_cast(adapter); + void ValkeyQtAddRead(void * adapter) { + ValkeyQtAdapter * a = static_cast(adapter); a->addRead(); } friend - void RedisQtDelRead(void * adapter) { - RedisQtAdapter * a = static_cast(adapter); + void ValkeyQtDelRead(void * adapter) { + ValkeyQtAdapter * a = static_cast(adapter); a->delRead(); } friend - void RedisQtAddWrite(void * adapter) { - RedisQtAdapter * a = static_cast(adapter); + void ValkeyQtAddWrite(void * adapter) { + ValkeyQtAdapter * a = static_cast(adapter); a->addWrite(); } friend - void RedisQtDelWrite(void * adapter) { - RedisQtAdapter * a = static_cast(adapter); + void ValkeyQtDelWrite(void * adapter) { + ValkeyQtAdapter * a = static_cast(adapter); a->delWrite(); } friend - void RedisQtCleanup(void * adapter) { - RedisQtAdapter * a = static_cast(adapter); + void ValkeyQtCleanup(void * adapter) { + ValkeyQtAdapter * a = static_cast(adapter); a->cleanup(); } public: - RedisQtAdapter(QObject * parent = 0) + ValkeyQtAdapter(QObject * parent = 0) : QObject(parent), m_ctx(0), m_read(0), m_write(0) { } - ~RedisQtAdapter() { + ~ValkeyQtAdapter() { if (m_ctx != 0) { m_ctx->ev.data = NULL; } } - int setContext(redisAsyncContext * ac) { + int setContext(valkeyAsyncContext * ac) { if (ac->ev.data != NULL) { - return REDIS_ERR; + return VALKEY_ERR; } m_ctx = ac; m_ctx->ev.data = this; - m_ctx->ev.addRead = RedisQtAddRead; - m_ctx->ev.delRead = RedisQtDelRead; - m_ctx->ev.addWrite = RedisQtAddWrite; - m_ctx->ev.delWrite = RedisQtDelWrite; - m_ctx->ev.cleanup = RedisQtCleanup; - return REDIS_OK; + m_ctx->ev.addRead = ValkeyQtAddRead; + m_ctx->ev.delRead = ValkeyQtDelRead; + m_ctx->ev.addWrite = ValkeyQtAddWrite; + m_ctx->ev.delWrite = ValkeyQtDelWrite; + m_ctx->ev.cleanup = ValkeyQtCleanup; + return VALKEY_OK; } private: @@ -123,13 +123,13 @@ class RedisQtAdapter : public QObject { } private slots: - void read() { redisAsyncHandleRead(m_ctx); } - void write() { redisAsyncHandleWrite(m_ctx); } + void read() { valkeyAsyncHandleRead(m_ctx); } + void write() { valkeyAsyncHandleWrite(m_ctx); } private: - redisAsyncContext * m_ctx; + valkeyAsyncContext * m_ctx; QSocketNotifier * m_read; QSocketNotifier * m_write; }; -#endif /* !__HIREDIS_QT_H__ */ +#endif /* !VALKEY_QT_H */ diff --git a/src/adapters/valkeymoduleapi.h b/src/adapters/valkeymoduleapi.h new file mode 100644 index 00000000..f72daa74 --- /dev/null +++ b/src/adapters/valkeymoduleapi.h @@ -0,0 +1,144 @@ +#ifndef VALKEY_VALKEYMODULEAPI_H +#define VALKEY_VALKEYMODULEAPI_H + +#include "valkeymodule.h" + +#include "../async.h" +#include "../valkey.h" + +#include + +typedef struct valkeyModuleEvents { + valkeyAsyncContext *context; + ValkeyModuleCtx *module_ctx; + int fd; + int reading, writing; + int timer_active; + ValkeyModuleTimerID timer_id; +} valkeyModuleEvents; + +static inline void valkeyModuleReadEvent(int fd, void *privdata, int mask) { + (void) fd; + (void) mask; + + valkeyModuleEvents *e = (valkeyModuleEvents*)privdata; + valkeyAsyncHandleRead(e->context); +} + +static inline void valkeyModuleWriteEvent(int fd, void *privdata, int mask) { + (void) fd; + (void) mask; + + valkeyModuleEvents *e = (valkeyModuleEvents*)privdata; + valkeyAsyncHandleWrite(e->context); +} + +static inline void valkeyModuleAddRead(void *privdata) { + valkeyModuleEvents *e = (valkeyModuleEvents*)privdata; + if (!e->reading) { + e->reading = 1; + ValkeyModule_EventLoopAdd(e->fd, VALKEYMODULE_EVENTLOOP_READABLE, valkeyModuleReadEvent, e); + } +} + +static inline void valkeyModuleDelRead(void *privdata) { + valkeyModuleEvents *e = (valkeyModuleEvents*)privdata; + if (e->reading) { + e->reading = 0; + ValkeyModule_EventLoopDel(e->fd, VALKEYMODULE_EVENTLOOP_READABLE); + } +} + +static inline void valkeyModuleAddWrite(void *privdata) { + valkeyModuleEvents *e = (valkeyModuleEvents*)privdata; + if (!e->writing) { + e->writing = 1; + ValkeyModule_EventLoopAdd(e->fd, VALKEYMODULE_EVENTLOOP_WRITABLE, valkeyModuleWriteEvent, e); + } +} + +static inline void valkeyModuleDelWrite(void *privdata) { + valkeyModuleEvents *e = (valkeyModuleEvents*)privdata; + if (e->writing) { + e->writing = 0; + ValkeyModule_EventLoopDel(e->fd, VALKEYMODULE_EVENTLOOP_WRITABLE); + } +} + +static inline void valkeyModuleStopTimer(void *privdata) { + valkeyModuleEvents *e = (valkeyModuleEvents*)privdata; + if (e->timer_active) { + ValkeyModule_StopTimer(e->module_ctx, e->timer_id, NULL); + } + e->timer_active = 0; +} + +static inline void valkeyModuleCleanup(void *privdata) { + valkeyModuleEvents *e = (valkeyModuleEvents*)privdata; + valkeyModuleDelRead(privdata); + valkeyModuleDelWrite(privdata); + valkeyModuleStopTimer(privdata); + vk_free(e); +} + +static inline void valkeyModuleTimeout(ValkeyModuleCtx *ctx, void *privdata) { + (void) ctx; + + valkeyModuleEvents *e = (valkeyModuleEvents*)privdata; + e->timer_active = 0; + valkeyAsyncHandleTimeout(e->context); +} + +static inline void valkeyModuleSetTimeout(void *privdata, struct timeval tv) { + valkeyModuleEvents* e = (valkeyModuleEvents*)privdata; + + valkeyModuleStopTimer(privdata); + + mstime_t millis = tv.tv_sec * 1000 + tv.tv_usec / 1000.0; + e->timer_id = ValkeyModule_CreateTimer(e->module_ctx, millis, valkeyModuleTimeout, e); + e->timer_active = 1; +} + +/* Check if Redis version is compatible with the adapter. */ +static inline int valkeyModuleCompatibilityCheck(void) { + if (!ValkeyModule_EventLoopAdd || + !ValkeyModule_EventLoopDel || + !ValkeyModule_CreateTimer || + !ValkeyModule_StopTimer) { + return VALKEY_ERR; + } + return VALKEY_OK; +} + +static inline int valkeyModuleAttach(valkeyAsyncContext *ac, ValkeyModuleCtx *module_ctx) { + valkeyContext *c = &(ac->c); + valkeyModuleEvents *e; + + /* Nothing should be attached when something is already attached */ + if (ac->ev.data != NULL) + return VALKEY_ERR; + + /* Create container for context and r/w events */ + e = (valkeyModuleEvents*)vk_malloc(sizeof(*e)); + if (e == NULL) + return VALKEY_ERR; + + e->context = ac; + e->module_ctx = module_ctx; + e->fd = c->fd; + e->reading = e->writing = 0; + e->timer_active = 0; + + /* Register functions to start/stop listening for events */ + ac->ev.addRead = valkeyModuleAddRead; + ac->ev.delRead = valkeyModuleDelRead; + ac->ev.addWrite = valkeyModuleAddWrite; + ac->ev.delWrite = valkeyModuleDelWrite; + ac->ev.cleanup = valkeyModuleCleanup; + ac->ev.scheduleTimer = valkeyModuleSetTimeout; + ac->ev.data = e; + + return VALKEY_OK; +} + +#endif diff --git a/libvalkey/alloc.c b/src/alloc.c similarity index 75% rename from libvalkey/alloc.c rename to src/alloc.c index 0902286c..dd50c691 100644 --- a/libvalkey/alloc.c +++ b/src/alloc.c @@ -33,7 +33,7 @@ #include #include -hiredisAllocFuncs hiredisAllocFns = { +valkeyAllocFuncs valkeyAllocFns = { .mallocFn = malloc, .callocFn = calloc, .reallocFn = realloc, @@ -41,18 +41,18 @@ hiredisAllocFuncs hiredisAllocFns = { .freeFn = free, }; -/* Override hiredis' allocators with ones supplied by the user */ -hiredisAllocFuncs hiredisSetAllocators(hiredisAllocFuncs *override) { - hiredisAllocFuncs orig = hiredisAllocFns; +/* Override valkey' allocators with ones supplied by the user */ +valkeyAllocFuncs valkeySetAllocators(valkeyAllocFuncs *override) { + valkeyAllocFuncs orig = valkeyAllocFns; - hiredisAllocFns = *override; + valkeyAllocFns = *override; return orig; } /* Reset allocators to use libc defaults */ -void hiredisResetAllocators(void) { - hiredisAllocFns = (hiredisAllocFuncs) { +void valkeyResetAllocators(void) { + valkeyAllocFns = (valkeyAllocFuncs) { .mallocFn = malloc, .callocFn = calloc, .reallocFn = realloc, @@ -63,28 +63,28 @@ void hiredisResetAllocators(void) { #ifdef _WIN32 -void *hi_malloc(size_t size) { - return hiredisAllocFns.mallocFn(size); +void *vk_malloc(size_t size) { + return valkeyAllocFns.mallocFn(size); } -void *hi_calloc(size_t nmemb, size_t size) { +void *vk_calloc(size_t nmemb, size_t size) { /* Overflow check as the user can specify any arbitrary allocator */ if (SIZE_MAX / size < nmemb) return NULL; - return hiredisAllocFns.callocFn(nmemb, size); + return valkeyAllocFns.callocFn(nmemb, size); } -void *hi_realloc(void *ptr, size_t size) { - return hiredisAllocFns.reallocFn(ptr, size); +void *vk_realloc(void *ptr, size_t size) { + return valkeyAllocFns.reallocFn(ptr, size); } -char *hi_strdup(const char *str) { - return hiredisAllocFns.strdupFn(str); +char *vk_strdup(const char *str) { + return valkeyAllocFns.strdupFn(str); } -void hi_free(void *ptr) { - hiredisAllocFns.freeFn(ptr); +void vk_free(void *ptr) { + valkeyAllocFns.freeFn(ptr); } #endif diff --git a/libvalkey/alloc.h b/src/alloc.h similarity index 68% rename from libvalkey/alloc.h rename to src/alloc.h index 771f9fee..395c6197 100644 --- a/libvalkey/alloc.h +++ b/src/alloc.h @@ -28,8 +28,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef HIREDIS_ALLOC_H -#define HIREDIS_ALLOC_H +#ifndef VALKEY_ALLOC_H +#define VALKEY_ALLOC_H #include /* for size_t */ #include @@ -39,53 +39,53 @@ extern "C" { #endif /* Structure pointing to our actually configured allocators */ -typedef struct hiredisAllocFuncs { +typedef struct valkeyAllocFuncs { void *(*mallocFn)(size_t); void *(*callocFn)(size_t,size_t); void *(*reallocFn)(void*,size_t); char *(*strdupFn)(const char*); void (*freeFn)(void*); -} hiredisAllocFuncs; +} valkeyAllocFuncs; -hiredisAllocFuncs hiredisSetAllocators(hiredisAllocFuncs *ha); -void hiredisResetAllocators(void); +valkeyAllocFuncs valkeySetAllocators(valkeyAllocFuncs *fns); +void valkeyResetAllocators(void); #ifndef _WIN32 -/* Hiredis' configured allocator function pointer struct */ -extern hiredisAllocFuncs hiredisAllocFns; +/* valkey' configured allocator function pointer struct */ +extern valkeyAllocFuncs valkeyAllocFns; -static inline void *hi_malloc(size_t size) { - return hiredisAllocFns.mallocFn(size); +static inline void *vk_malloc(size_t size) { + return valkeyAllocFns.mallocFn(size); } -static inline void *hi_calloc(size_t nmemb, size_t size) { +static inline void *vk_calloc(size_t nmemb, size_t size) { /* Overflow check as the user can specify any arbitrary allocator */ if (SIZE_MAX / size < nmemb) return NULL; - return hiredisAllocFns.callocFn(nmemb, size); + return valkeyAllocFns.callocFn(nmemb, size); } -static inline void *hi_realloc(void *ptr, size_t size) { - return hiredisAllocFns.reallocFn(ptr, size); +static inline void *vk_realloc(void *ptr, size_t size) { + return valkeyAllocFns.reallocFn(ptr, size); } -static inline char *hi_strdup(const char *str) { - return hiredisAllocFns.strdupFn(str); +static inline char *vk_strdup(const char *str) { + return valkeyAllocFns.strdupFn(str); } -static inline void hi_free(void *ptr) { - hiredisAllocFns.freeFn(ptr); +static inline void vk_free(void *ptr) { + valkeyAllocFns.freeFn(ptr); } #else -void *hi_malloc(size_t size); -void *hi_calloc(size_t nmemb, size_t size); -void *hi_realloc(void *ptr, size_t size); -char *hi_strdup(const char *str); -void hi_free(void *ptr); +void *vk_malloc(size_t size); +void *vk_calloc(size_t nmemb, size_t size); +void *vk_realloc(void *ptr, size_t size); +char *vk_strdup(const char *str); +void vk_free(void *ptr); #endif @@ -93,4 +93,4 @@ void hi_free(void *ptr); } #endif -#endif /* HIREDIS_ALLOC_H */ +#endif /* VALKEY_ALLOC_H */ diff --git a/libvalkey/async.c b/src/async.c similarity index 60% rename from libvalkey/async.c rename to src/async.c index f82f567f..a18ce8a6 100644 --- a/libvalkey/async.c +++ b/src/async.c @@ -52,9 +52,9 @@ #define assert(e) (void)(e) #endif -/* Forward declarations of hiredis.c functions */ -int __redisAppendCommand(redisContext *c, const char *cmd, size_t len); -void __redisSetError(redisContext *c, int type, const char *str); +/* Forward declarations of valkey.c functions */ +int valkeyAppendCmdLen(valkeyContext *c, const char *cmd, size_t len); +void valkeySetError(valkeyContext *c, int type, const char *str); /* Functions managing dictionary of callbacks for pub/sub. */ static unsigned int callbackHash(const void *key) { @@ -64,9 +64,9 @@ static unsigned int callbackHash(const void *key) { static void *callbackValDup(void *privdata, const void *src) { ((void) privdata); - redisCallback *dup; + valkeyCallback *dup; - dup = hi_malloc(sizeof(*dup)); + dup = vk_malloc(sizeof(*dup)); if (dup == NULL) return NULL; @@ -91,7 +91,7 @@ static void callbackKeyDestructor(void *privdata, void *key) { static void callbackValDestructor(void *privdata, void *val) { ((void) privdata); - hi_free(val); + vk_free(val); } static dictType callbackDict = { @@ -103,8 +103,8 @@ static dictType callbackDict = { callbackValDestructor }; -static redisAsyncContext *redisAsyncInitialize(redisContext *c) { - redisAsyncContext *ac; +static valkeyAsyncContext *valkeyAsyncInitialize(valkeyContext *c) { + valkeyAsyncContext *ac; dict *channels = NULL, *patterns = NULL; channels = dictCreate(&callbackDict,NULL); @@ -115,16 +115,16 @@ static redisAsyncContext *redisAsyncInitialize(redisContext *c) { if (patterns == NULL) goto oom; - ac = hi_realloc(c,sizeof(redisAsyncContext)); + ac = vk_realloc(c,sizeof(valkeyAsyncContext)); if (ac == NULL) goto oom; c = &(ac->c); - /* The regular connect functions will always set the flag REDIS_CONNECTED. + /* The regular connect functions will always set the flag VALKEY_CONNECTED. * For the async API, we want to wait until the first write event is * received up before setting this flag, so reset it here. */ - c->flags &= ~REDIS_CONNECTED; + c->flags &= ~VALKEY_CONNECTED; ac->err = 0; ac->errstr = NULL; @@ -159,81 +159,81 @@ static redisAsyncContext *redisAsyncInitialize(redisContext *c) { } /* We want the error field to be accessible directly instead of requiring - * an indirection to the redisContext struct. */ -static void __redisAsyncCopyError(redisAsyncContext *ac) { + * an indirection to the valkeyContext struct. */ +static void valkeyAsyncCopyError(valkeyAsyncContext *ac) { if (!ac) return; - redisContext *c = &(ac->c); + valkeyContext *c = &(ac->c); ac->err = c->err; ac->errstr = c->errstr; } -redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options) { - redisOptions myOptions = *options; - redisContext *c; - redisAsyncContext *ac; +valkeyAsyncContext *valkeyAsyncConnectWithOptions(const valkeyOptions *options) { + valkeyOptions myOptions = *options; + valkeyContext *c; + valkeyAsyncContext *ac; /* Clear any erroneously set sync callback and flag that we don't want to * use freeReplyObject by default. */ myOptions.push_cb = NULL; - myOptions.options |= REDIS_OPT_NO_PUSH_AUTOFREE; + myOptions.options |= VALKEY_OPT_NO_PUSH_AUTOFREE; - myOptions.options |= REDIS_OPT_NONBLOCK; - c = redisConnectWithOptions(&myOptions); + myOptions.options |= VALKEY_OPT_NONBLOCK; + c = valkeyConnectWithOptions(&myOptions); if (c == NULL) { return NULL; } - ac = redisAsyncInitialize(c); + ac = valkeyAsyncInitialize(c); if (ac == NULL) { - redisFree(c); + valkeyFree(c); return NULL; } /* Set any configured async push handler */ - redisAsyncSetPushCallback(ac, myOptions.async_push_cb); + valkeyAsyncSetPushCallback(ac, myOptions.async_push_cb); - __redisAsyncCopyError(ac); + valkeyAsyncCopyError(ac); return ac; } -redisAsyncContext *redisAsyncConnect(const char *ip, int port) { - redisOptions options = {0}; - REDIS_OPTIONS_SET_TCP(&options, ip, port); - return redisAsyncConnectWithOptions(&options); +valkeyAsyncContext *valkeyAsyncConnect(const char *ip, int port) { + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_TCP(&options, ip, port); + return valkeyAsyncConnectWithOptions(&options); } -redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, - const char *source_addr) { - redisOptions options = {0}; - REDIS_OPTIONS_SET_TCP(&options, ip, port); +valkeyAsyncContext *valkeyAsyncConnectBind(const char *ip, int port, + const char *source_addr) { + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_TCP(&options, ip, port); options.endpoint.tcp.source_addr = source_addr; - return redisAsyncConnectWithOptions(&options); + return valkeyAsyncConnectWithOptions(&options); } -redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, - const char *source_addr) { - redisOptions options = {0}; - REDIS_OPTIONS_SET_TCP(&options, ip, port); - options.options |= REDIS_OPT_REUSEADDR; +valkeyAsyncContext *valkeyAsyncConnectBindWithReuse(const char *ip, int port, + const char *source_addr) { + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_TCP(&options, ip, port); + options.options |= VALKEY_OPT_REUSEADDR; options.endpoint.tcp.source_addr = source_addr; - return redisAsyncConnectWithOptions(&options); + return valkeyAsyncConnectWithOptions(&options); } -redisAsyncContext *redisAsyncConnectUnix(const char *path) { - redisOptions options = {0}; - REDIS_OPTIONS_SET_UNIX(&options, path); - return redisAsyncConnectWithOptions(&options); +valkeyAsyncContext *valkeyAsyncConnectUnix(const char *path) { + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_UNIX(&options, path); + return valkeyAsyncConnectWithOptions(&options); } static int -redisAsyncSetConnectCallbackImpl(redisAsyncContext *ac, redisConnectCallback *fn, - redisConnectCallbackNC *fn_nc) +valkeyAsyncSetConnectCallbackImpl(valkeyAsyncContext *ac, valkeyConnectCallback *fn, + valkeyConnectCallbackNC *fn_nc) { /* If either are already set, this is an error */ if (ac->onConnect || ac->onConnectNC) - return REDIS_ERR; + return VALKEY_ERR; if (fn) { ac->onConnect = fn; @@ -246,33 +246,33 @@ redisAsyncSetConnectCallbackImpl(redisAsyncContext *ac, redisConnectCallback *fn * library functions are already set. */ _EL_ADD_WRITE(ac); - return REDIS_OK; + return VALKEY_OK; } -int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn) { - return redisAsyncSetConnectCallbackImpl(ac, fn, NULL); +int valkeyAsyncSetConnectCallback(valkeyAsyncContext *ac, valkeyConnectCallback *fn) { + return valkeyAsyncSetConnectCallbackImpl(ac, fn, NULL); } -int redisAsyncSetConnectCallbackNC(redisAsyncContext *ac, redisConnectCallbackNC *fn) { - return redisAsyncSetConnectCallbackImpl(ac, NULL, fn); +int valkeyAsyncSetConnectCallbackNC(valkeyAsyncContext *ac, valkeyConnectCallbackNC *fn) { + return valkeyAsyncSetConnectCallbackImpl(ac, NULL, fn); } -int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn) { +int valkeyAsyncSetDisconnectCallback(valkeyAsyncContext *ac, valkeyDisconnectCallback *fn) { if (ac->onDisconnect == NULL) { ac->onDisconnect = fn; - return REDIS_OK; + return VALKEY_OK; } - return REDIS_ERR; + return VALKEY_ERR; } /* Helper functions to push/shift callbacks */ -static int __redisPushCallback(redisCallbackList *list, redisCallback *source) { - redisCallback *cb; +static int valkeyPushCallback(valkeyCallbackList *list, valkeyCallback *source) { + valkeyCallback *cb; /* Copy callback from stack to heap */ - cb = hi_malloc(sizeof(*cb)); + cb = vk_malloc(sizeof(*cb)); if (cb == NULL) - return REDIS_ERR_OOM; + return VALKEY_ERR_OOM; if (source != NULL) { memcpy(cb,source,sizeof(*cb)); @@ -285,11 +285,11 @@ static int __redisPushCallback(redisCallbackList *list, redisCallback *source) { if (list->tail != NULL) list->tail->next = cb; list->tail = cb; - return REDIS_OK; + return VALKEY_OK; } -static int __redisShiftCallback(redisCallbackList *list, redisCallback *target) { - redisCallback *cb = list->head; +static int valkeyShiftCallback(valkeyCallbackList *list, valkeyCallback *target) { + valkeyCallback *cb = list->head; if (cb != NULL) { list->head = cb->next; if (cb == list->tail) @@ -298,42 +298,42 @@ static int __redisShiftCallback(redisCallbackList *list, redisCallback *target) /* Copy callback from heap to stack */ if (target != NULL) memcpy(target,cb,sizeof(*cb)); - hi_free(cb); - return REDIS_OK; + vk_free(cb); + return VALKEY_OK; } - return REDIS_ERR; + return VALKEY_ERR; } -static void __redisRunCallback(redisAsyncContext *ac, redisCallback *cb, redisReply *reply) { - redisContext *c = &(ac->c); +static void valkeyRunCallback(valkeyAsyncContext *ac, valkeyCallback *cb, valkeyReply *reply) { + valkeyContext *c = &(ac->c); if (cb->fn != NULL) { - c->flags |= REDIS_IN_CALLBACK; + c->flags |= VALKEY_IN_CALLBACK; cb->fn(ac,reply,cb->privdata); - c->flags &= ~REDIS_IN_CALLBACK; + c->flags &= ~VALKEY_IN_CALLBACK; } } -static void __redisRunPushCallback(redisAsyncContext *ac, redisReply *reply) { +static void valkeyRunPushCallback(valkeyAsyncContext *ac, valkeyReply *reply) { if (ac->push_cb != NULL) { - ac->c.flags |= REDIS_IN_CALLBACK; + ac->c.flags |= VALKEY_IN_CALLBACK; ac->push_cb(ac, reply); - ac->c.flags &= ~REDIS_IN_CALLBACK; + ac->c.flags &= ~VALKEY_IN_CALLBACK; } } -static void __redisRunConnectCallback(redisAsyncContext *ac, int status) +static void valkeyRunConnectCallback(valkeyAsyncContext *ac, int status) { if (ac->onConnect == NULL && ac->onConnectNC == NULL) return; - if (!(ac->c.flags & REDIS_IN_CALLBACK)) { - ac->c.flags |= REDIS_IN_CALLBACK; + if (!(ac->c.flags & VALKEY_IN_CALLBACK)) { + ac->c.flags |= VALKEY_IN_CALLBACK; if (ac->onConnect) { ac->onConnect(ac, status); } else { ac->onConnectNC(ac, status); } - ac->c.flags &= ~REDIS_IN_CALLBACK; + ac->c.flags &= ~VALKEY_IN_CALLBACK; } else { /* already in callback */ if (ac->onConnect) { @@ -344,13 +344,13 @@ static void __redisRunConnectCallback(redisAsyncContext *ac, int status) } } -static void __redisRunDisconnectCallback(redisAsyncContext *ac, int status) +static void valkeyRunDisconnectCallback(valkeyAsyncContext *ac, int status) { if (ac->onDisconnect) { - if (!(ac->c.flags & REDIS_IN_CALLBACK)) { - ac->c.flags |= REDIS_IN_CALLBACK; + if (!(ac->c.flags & VALKEY_IN_CALLBACK)) { + ac->c.flags |= VALKEY_IN_CALLBACK; ac->onDisconnect(ac, status); - ac->c.flags &= ~REDIS_IN_CALLBACK; + ac->c.flags &= ~VALKEY_IN_CALLBACK; } else { /* already in callback */ ac->onDisconnect(ac, status); @@ -359,23 +359,23 @@ static void __redisRunDisconnectCallback(redisAsyncContext *ac, int status) } /* Helper function to free the context. */ -static void __redisAsyncFree(redisAsyncContext *ac) { - redisContext *c = &(ac->c); - redisCallback cb; +static void valkeyAsyncFreeInternal(valkeyAsyncContext *ac) { + valkeyContext *c = &(ac->c); + valkeyCallback cb; dictIterator it; dictEntry *de; /* Execute pending callbacks with NULL reply. */ - while (__redisShiftCallback(&ac->replies,&cb) == REDIS_OK) - __redisRunCallback(ac,&cb,NULL); - while (__redisShiftCallback(&ac->sub.replies,&cb) == REDIS_OK) - __redisRunCallback(ac,&cb,NULL); + while (valkeyShiftCallback(&ac->replies,&cb) == VALKEY_OK) + valkeyRunCallback(ac,&cb,NULL); + while (valkeyShiftCallback(&ac->sub.replies,&cb) == VALKEY_OK) + valkeyRunCallback(ac,&cb,NULL); /* Run subscription callbacks with NULL reply */ if (ac->sub.channels) { dictInitIterator(&it,ac->sub.channels); while ((de = dictNext(&it)) != NULL) - __redisRunCallback(ac,dictGetEntryVal(de),NULL); + valkeyRunCallback(ac,dictGetEntryVal(de),NULL); dictRelease(ac->sub.channels); } @@ -383,7 +383,7 @@ static void __redisAsyncFree(redisAsyncContext *ac) { if (ac->sub.patterns) { dictInitIterator(&it,ac->sub.patterns); while ((de = dictNext(&it)) != NULL) - __redisRunCallback(ac,dictGetEntryVal(de),NULL); + valkeyRunCallback(ac,dictGetEntryVal(de),NULL); dictRelease(ac->sub.patterns); } @@ -391,13 +391,13 @@ static void __redisAsyncFree(redisAsyncContext *ac) { /* Signal event lib to clean up */ _EL_CLEANUP(ac); - /* Execute disconnect callback. When redisAsyncFree() initiated destroying - * this context, the status will always be REDIS_OK. */ - if (c->flags & REDIS_CONNECTED) { - int status = ac->err == 0 ? REDIS_OK : REDIS_ERR; - if (c->flags & REDIS_FREEING) - status = REDIS_OK; - __redisRunDisconnectCallback(ac, status); + /* Execute disconnect callback. When valkeyAsyncFree() initiated destroying + * this context, the status will always be VALKEY_OK. */ + if (c->flags & VALKEY_CONNECTED) { + int status = ac->err == 0 ? VALKEY_OK : VALKEY_ERR; + if (c->flags & VALKEY_FREEING) + status = VALKEY_OK; + valkeyRunDisconnectCallback(ac, status); } if (ac->dataCleanup) { @@ -405,72 +405,72 @@ static void __redisAsyncFree(redisAsyncContext *ac) { } /* Cleanup self */ - redisFree(c); + valkeyFree(c); } /* Free the async context. When this function is called from a callback, - * control needs to be returned to redisProcessCallbacks() before actual + * control needs to be returned to valkeyProcessCallbacks() before actual * free'ing. To do so, a flag is set on the context which is picked up by - * redisProcessCallbacks(). Otherwise, the context is immediately free'd. */ -void redisAsyncFree(redisAsyncContext *ac) { + * valkeyProcessCallbacks(). Otherwise, the context is immediately free'd. */ +void valkeyAsyncFree(valkeyAsyncContext *ac) { if (ac == NULL) return; - redisContext *c = &(ac->c); + valkeyContext *c = &(ac->c); - c->flags |= REDIS_FREEING; - if (!(c->flags & REDIS_IN_CALLBACK)) - __redisAsyncFree(ac); + c->flags |= VALKEY_FREEING; + if (!(c->flags & VALKEY_IN_CALLBACK)) + valkeyAsyncFreeInternal(ac); } /* Helper function to make the disconnect happen and clean up. */ -void __redisAsyncDisconnect(redisAsyncContext *ac) { - redisContext *c = &(ac->c); +void valkeyAsyncDisconnectInternal(valkeyAsyncContext *ac) { + valkeyContext *c = &(ac->c); /* Make sure error is accessible if there is any */ - __redisAsyncCopyError(ac); + valkeyAsyncCopyError(ac); if (ac->err == 0) { /* For clean disconnects, there should be no pending callbacks. */ - int ret = __redisShiftCallback(&ac->replies,NULL); - assert(ret == REDIS_ERR); + int ret = valkeyShiftCallback(&ac->replies,NULL); + assert(ret == VALKEY_ERR); } else { /* Disconnection is caused by an error, make sure that pending * callbacks cannot call new commands. */ - c->flags |= REDIS_DISCONNECTING; + c->flags |= VALKEY_DISCONNECTING; } /* cleanup event library on disconnect. * this is safe to call multiple times */ _EL_CLEANUP(ac); - /* For non-clean disconnects, __redisAsyncFree() will execute pending + /* For non-clean disconnects, valkeyAsyncFreeInternal() will execute pending * callbacks with a NULL-reply. */ - if (!(c->flags & REDIS_NO_AUTO_FREE)) { - __redisAsyncFree(ac); + if (!(c->flags & VALKEY_NO_AUTO_FREE)) { + valkeyAsyncFreeInternal(ac); } } -/* Tries to do a clean disconnect from Redis, meaning it stops new commands +/* Tries to do a clean disconnect from the server, meaning it stops new commands * from being issued, but tries to flush the output buffer and execute * callbacks for all remaining replies. When this function is called from a * callback, there might be more replies and we can safely defer disconnecting - * to redisProcessCallbacks(). Otherwise, we can only disconnect immediately + * to valkeyProcessCallbacks(). Otherwise, we can only disconnect immediately * when there are no pending callbacks. */ -void redisAsyncDisconnect(redisAsyncContext *ac) { - redisContext *c = &(ac->c); - c->flags |= REDIS_DISCONNECTING; +void valkeyAsyncDisconnect(valkeyAsyncContext *ac) { + valkeyContext *c = &(ac->c); + c->flags |= VALKEY_DISCONNECTING; /** unset the auto-free flag here, because disconnect undoes this */ - c->flags &= ~REDIS_NO_AUTO_FREE; - if (!(c->flags & REDIS_IN_CALLBACK) && ac->replies.head == NULL) - __redisAsyncDisconnect(ac); + c->flags &= ~VALKEY_NO_AUTO_FREE; + if (!(c->flags & VALKEY_IN_CALLBACK) && ac->replies.head == NULL) + valkeyAsyncDisconnectInternal(ac); } -static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply, redisCallback *dstcb) { - redisContext *c = &(ac->c); +static int valkeyGetSubscribeCallback(valkeyAsyncContext *ac, valkeyReply *reply, valkeyCallback *dstcb) { + valkeyContext *c = &(ac->c); dict *callbacks; - redisCallback *cb = NULL; + valkeyCallback *cb = NULL; dictEntry *de; int pvariant; char *stype; @@ -478,10 +478,10 @@ static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply, /* Match reply with the expected format of a pushed message. * The type and number of elements (3 to 4) are specified at: - * https://redis.io/topics/pubsub#format-of-pushed-messages */ - if ((reply->type == REDIS_REPLY_ARRAY && !(c->flags & REDIS_SUPPORTS_PUSH) && reply->elements >= 3) || - reply->type == REDIS_REPLY_PUSH) { - assert(reply->element[0]->type == REDIS_REPLY_STRING); + * https://valkey.io/docs/topics/pubsub/#format-of-pushed-messages */ + if ((reply->type == VALKEY_REPLY_ARRAY && !(c->flags & VALKEY_SUPPORTS_PUSH) && reply->elements >= 3) || + reply->type == VALKEY_REPLY_PUSH) { + assert(reply->element[0]->type == VALKEY_REPLY_STRING); stype = reply->element[0]->str; pvariant = (tolower(stype[0]) == 'p') ? 1 : 0; @@ -491,7 +491,7 @@ static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply, callbacks = ac->sub.channels; /* Locate the right callback */ - if (reply->element[1]->type == REDIS_REPLY_STRING) { + if (reply->element[1]->type == VALKEY_REPLY_STRING) { sname = sdsnewlen(reply->element[1]->str,reply->element[1]->len); if (sname == NULL) goto oom; @@ -514,7 +514,7 @@ static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply, /* If this was the last unsubscribe message, revert to * non-subscribe mode. */ - assert(reply->element[2]->type == REDIS_REPLY_INTEGER); + assert(reply->element[2]->type == VALKEY_REPLY_INTEGER); /* Unset subscribed flag only when no pipelined pending subscribe * or pending unsubscribe replies. */ @@ -522,36 +522,36 @@ static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply, && dictSize(ac->sub.channels) == 0 && dictSize(ac->sub.patterns) == 0 && ac->sub.pending_unsubs == 0) { - c->flags &= ~REDIS_SUBSCRIBED; + c->flags &= ~VALKEY_SUBSCRIBED; /* Move ongoing regular command callbacks. */ - redisCallback cb; - while (__redisShiftCallback(&ac->sub.replies,&cb) == REDIS_OK) { - __redisPushCallback(&ac->replies,&cb); + valkeyCallback cb; + while (valkeyShiftCallback(&ac->sub.replies,&cb) == VALKEY_OK) { + valkeyPushCallback(&ac->replies,&cb); } } } sdsfree(sname); } else { /* Shift callback for pending command in subscribed context. */ - __redisShiftCallback(&ac->sub.replies,dstcb); + valkeyShiftCallback(&ac->sub.replies,dstcb); } - return REDIS_OK; + return VALKEY_OK; oom: - __redisSetError(&(ac->c), REDIS_ERR_OOM, "Out of memory"); - __redisAsyncCopyError(ac); - return REDIS_ERR; + valkeySetError(&(ac->c), VALKEY_ERR_OOM, "Out of memory"); + valkeyAsyncCopyError(ac); + return VALKEY_ERR; } -#define redisIsSpontaneousPushReply(r) \ - (redisIsPushReply(r) && !redisIsSubscribeReply(r)) +#define valkeyIsSpontaneousPushReply(r) \ + (valkeyIsPushReply(r) && !valkeyIsSubscribeReply(r)) -static int redisIsSubscribeReply(redisReply *reply) { +static int valkeyIsSubscribeReply(valkeyReply *reply) { char *str; size_t len, off; /* We will always have at least one string with the subscribe/message type */ - if (reply->elements < 1 || reply->element[0]->type != REDIS_REPLY_STRING || + if (reply->elements < 1 || reply->element[0]->type != VALKEY_REPLY_STRING || reply->element[0]->len < sizeof("message") - 1) { return 0; @@ -567,18 +567,18 @@ static int redisIsSubscribeReply(redisReply *reply) { !strncasecmp(str, "unsubscribe", len); } -void redisProcessCallbacks(redisAsyncContext *ac) { - redisContext *c = &(ac->c); +void valkeyProcessCallbacks(valkeyAsyncContext *ac) { + valkeyContext *c = &(ac->c); void *reply = NULL; int status; - while((status = redisGetReply(c,&reply)) == REDIS_OK) { + while((status = valkeyGetReply(c,&reply)) == VALKEY_OK) { if (reply == NULL) { /* When the connection is being disconnected and there are * no more replies, this is the cue to really disconnect. */ - if (c->flags & REDIS_DISCONNECTING && sdslen(c->obuf) == 0 + if (c->flags & VALKEY_DISCONNECTING && sdslen(c->obuf) == 0 && ac->replies.head == NULL) { - __redisAsyncDisconnect(ac); + valkeyAsyncDisconnectInternal(ac); return; } /* When the connection is not being disconnected, simply stop @@ -587,22 +587,22 @@ void redisProcessCallbacks(redisAsyncContext *ac) { } /* Keep track of push message support for subscribe handling */ - if (redisIsPushReply(reply)) c->flags |= REDIS_SUPPORTS_PUSH; + if (valkeyIsPushReply(reply)) c->flags |= VALKEY_SUPPORTS_PUSH; /* Send any non-subscribe related PUSH messages to our PUSH handler * while allowing subscribe related PUSH messages to pass through. * This allows existing code to be backward compatible and work in * either RESP2 or RESP3 mode. */ - if (redisIsSpontaneousPushReply(reply)) { - __redisRunPushCallback(ac, reply); + if (valkeyIsSpontaneousPushReply(reply)) { + valkeyRunPushCallback(ac, reply); c->reader->fn->freeObject(reply); continue; } /* Even if the context is subscribed, pending regular * callbacks will get a reply before pub/sub messages arrive. */ - redisCallback cb = {NULL, NULL, 0, 0, NULL}; - if (__redisShiftCallback(&ac->replies,&cb) != REDIS_OK) { + valkeyCallback cb = {NULL, NULL, 0, 0, NULL}; + if (valkeyShiftCallback(&ac->replies,&cb) != VALKEY_OK) { /* * A spontaneous reply in a not-subscribed context can be the error * reply that is sent when a new connection exceeds the maximum @@ -618,28 +618,28 @@ void redisProcessCallbacks(redisAsyncContext *ac) { * In this case we also want to close the connection, and have the * user wait until the server is ready to take our request. */ - if (((redisReply*)reply)->type == REDIS_REPLY_ERROR) { - c->err = REDIS_ERR_OTHER; - snprintf(c->errstr,sizeof(c->errstr),"%s",((redisReply*)reply)->str); + if (((valkeyReply*)reply)->type == VALKEY_REPLY_ERROR) { + c->err = VALKEY_ERR_OTHER; + snprintf(c->errstr,sizeof(c->errstr),"%s",((valkeyReply*)reply)->str); c->reader->fn->freeObject(reply); - __redisAsyncDisconnect(ac); + valkeyAsyncDisconnectInternal(ac); return; } /* No more regular callbacks and no errors, the context *must* be subscribed. */ - assert(c->flags & REDIS_SUBSCRIBED); - if (c->flags & REDIS_SUBSCRIBED) - __redisGetSubscribeCallback(ac,reply,&cb); + assert(c->flags & VALKEY_SUBSCRIBED); + if (c->flags & VALKEY_SUBSCRIBED) + valkeyGetSubscribeCallback(ac,reply,&cb); } if (cb.fn != NULL) { - __redisRunCallback(ac,&cb,reply); - if (!(c->flags & REDIS_NO_AUTO_FREE_REPLIES)){ + valkeyRunCallback(ac,&cb,reply); + if (!(c->flags & VALKEY_NO_AUTO_FREE_REPLIES)){ c->reader->fn->freeObject(reply); } - /* Proceed with free'ing when redisAsyncFree() was called. */ - if (c->flags & REDIS_FREEING) { - __redisAsyncFree(ac); + /* Proceed with free'ing when valkeyAsyncFree() was called. */ + if (c->flags & VALKEY_FREEING) { + valkeyAsyncFreeInternal(ac); return; } } else { @@ -651,99 +651,99 @@ void redisProcessCallbacks(redisAsyncContext *ac) { } /* If in monitor mode, repush the callback */ - if (c->flags & REDIS_MONITORING) { - __redisPushCallback(&ac->replies,&cb); + if (c->flags & VALKEY_MONITORING) { + valkeyPushCallback(&ac->replies,&cb); } } /* Disconnect when there was an error reading the reply */ - if (status != REDIS_OK) - __redisAsyncDisconnect(ac); + if (status != VALKEY_OK) + valkeyAsyncDisconnectInternal(ac); } -static void __redisAsyncHandleConnectFailure(redisAsyncContext *ac) { - __redisRunConnectCallback(ac, REDIS_ERR); - __redisAsyncDisconnect(ac); +static void valkeyAsyncHandleConnectFailure(valkeyAsyncContext *ac) { + valkeyRunConnectCallback(ac, VALKEY_ERR); + valkeyAsyncDisconnectInternal(ac); } /* Internal helper function to detect socket status the first time a read or * write event fires. When connecting was not successful, the connect callback - * is called with a REDIS_ERR status and the context is free'd. */ -static int __redisAsyncHandleConnect(redisAsyncContext *ac) { + * is called with a VALKEY_ERR status and the context is free'd. */ +static int valkeyAsyncHandleConnect(valkeyAsyncContext *ac) { int completed = 0; - redisContext *c = &(ac->c); + valkeyContext *c = &(ac->c); - if (redisCheckConnectDone(c, &completed) == REDIS_ERR) { + if (valkeyCheckConnectDone(c, &completed) == VALKEY_ERR) { /* Error! */ - if (redisCheckSocketError(c) == REDIS_ERR) - __redisAsyncCopyError(ac); - __redisAsyncHandleConnectFailure(ac); - return REDIS_ERR; + if (valkeyCheckSocketError(c) == VALKEY_ERR) + valkeyAsyncCopyError(ac); + valkeyAsyncHandleConnectFailure(ac); + return VALKEY_ERR; } else if (completed == 1) { /* connected! */ - if (c->connection_type == REDIS_CONN_TCP && - redisSetTcpNoDelay(c) == REDIS_ERR) { - __redisAsyncHandleConnectFailure(ac); - return REDIS_ERR; + if (c->connection_type == VALKEY_CONN_TCP && + valkeySetTcpNoDelay(c) == VALKEY_ERR) { + valkeyAsyncHandleConnectFailure(ac); + return VALKEY_ERR; } /* flag us as fully connect, but allow the callback * to disconnect. For that reason, permit the function * to delete the context here after callback return. */ - c->flags |= REDIS_CONNECTED; - __redisRunConnectCallback(ac, REDIS_OK); - if ((ac->c.flags & REDIS_DISCONNECTING)) { - redisAsyncDisconnect(ac); - return REDIS_ERR; - } else if ((ac->c.flags & REDIS_FREEING)) { - redisAsyncFree(ac); - return REDIS_ERR; + c->flags |= VALKEY_CONNECTED; + valkeyRunConnectCallback(ac, VALKEY_OK); + if ((ac->c.flags & VALKEY_DISCONNECTING)) { + valkeyAsyncDisconnect(ac); + return VALKEY_ERR; + } else if ((ac->c.flags & VALKEY_FREEING)) { + valkeyAsyncFree(ac); + return VALKEY_ERR; } - return REDIS_OK; + return VALKEY_OK; } else { - return REDIS_OK; + return VALKEY_OK; } } -void redisAsyncRead(redisAsyncContext *ac) { - redisContext *c = &(ac->c); +void valkeyAsyncRead(valkeyAsyncContext *ac) { + valkeyContext *c = &(ac->c); - if (redisBufferRead(c) == REDIS_ERR) { - __redisAsyncDisconnect(ac); + if (valkeyBufferRead(c) == VALKEY_ERR) { + valkeyAsyncDisconnectInternal(ac); } else { /* Always re-schedule reads */ _EL_ADD_READ(ac); - redisProcessCallbacks(ac); + valkeyProcessCallbacks(ac); } } /* This function should be called when the socket is readable. * It processes all replies that can be read and executes their callbacks. */ -void redisAsyncHandleRead(redisAsyncContext *ac) { - redisContext *c = &(ac->c); +void valkeyAsyncHandleRead(valkeyAsyncContext *ac) { + valkeyContext *c = &(ac->c); /* must not be called from a callback */ - assert(!(c->flags & REDIS_IN_CALLBACK)); + assert(!(c->flags & VALKEY_IN_CALLBACK)); - if (!(c->flags & REDIS_CONNECTED)) { + if (!(c->flags & VALKEY_CONNECTED)) { /* Abort connect was not successful. */ - if (__redisAsyncHandleConnect(ac) != REDIS_OK) + if (valkeyAsyncHandleConnect(ac) != VALKEY_OK) return; /* Try again later when the context is still not connected. */ - if (!(c->flags & REDIS_CONNECTED)) + if (!(c->flags & VALKEY_CONNECTED)) return; } c->funcs->async_read(ac); } -void redisAsyncWrite(redisAsyncContext *ac) { - redisContext *c = &(ac->c); +void valkeyAsyncWrite(valkeyAsyncContext *ac) { + valkeyContext *c = &(ac->c); int done = 0; - if (redisBufferWrite(c,&done) == REDIS_ERR) { - __redisAsyncDisconnect(ac); + if (valkeyBufferWrite(c,&done) == VALKEY_ERR) { + valkeyAsyncDisconnectInternal(ac); } else { /* Continue writing when not done, stop writing otherwise */ if (!done) @@ -756,30 +756,30 @@ void redisAsyncWrite(redisAsyncContext *ac) { } } -void redisAsyncHandleWrite(redisAsyncContext *ac) { - redisContext *c = &(ac->c); +void valkeyAsyncHandleWrite(valkeyAsyncContext *ac) { + valkeyContext *c = &(ac->c); /* must not be called from a callback */ - assert(!(c->flags & REDIS_IN_CALLBACK)); + assert(!(c->flags & VALKEY_IN_CALLBACK)); - if (!(c->flags & REDIS_CONNECTED)) { + if (!(c->flags & VALKEY_CONNECTED)) { /* Abort connect was not successful. */ - if (__redisAsyncHandleConnect(ac) != REDIS_OK) + if (valkeyAsyncHandleConnect(ac) != VALKEY_OK) return; /* Try again later when the context is still not connected. */ - if (!(c->flags & REDIS_CONNECTED)) + if (!(c->flags & VALKEY_CONNECTED)) return; } c->funcs->async_write(ac); } -void redisAsyncHandleTimeout(redisAsyncContext *ac) { - redisContext *c = &(ac->c); - redisCallback cb; +void valkeyAsyncHandleTimeout(valkeyAsyncContext *ac) { + valkeyContext *c = &(ac->c); + valkeyCallback cb; /* must not be called from a callback */ - assert(!(c->flags & REDIS_IN_CALLBACK)); + assert(!(c->flags & VALKEY_IN_CALLBACK)); - if ((c->flags & REDIS_CONNECTED)) { + if ((c->flags & VALKEY_CONNECTED)) { if (ac->replies.head == NULL && ac->sub.replies.head == NULL) { /* Nothing to do - just an idle timeout */ return; @@ -793,23 +793,23 @@ void redisAsyncHandleTimeout(redisAsyncContext *ac) { } if (!c->err) { - __redisSetError(c, REDIS_ERR_TIMEOUT, "Timeout"); - __redisAsyncCopyError(ac); + valkeySetError(c, VALKEY_ERR_TIMEOUT, "Timeout"); + valkeyAsyncCopyError(ac); } - if (!(c->flags & REDIS_CONNECTED)) { - __redisRunConnectCallback(ac, REDIS_ERR); + if (!(c->flags & VALKEY_CONNECTED)) { + valkeyRunConnectCallback(ac, VALKEY_ERR); } - while (__redisShiftCallback(&ac->replies, &cb) == REDIS_OK) { - __redisRunCallback(ac, &cb, NULL); + while (valkeyShiftCallback(&ac->replies, &cb) == VALKEY_OK) { + valkeyRunCallback(ac, &cb, NULL); } /** * TODO: Don't automatically sever the connection, * rather, allow to ignore responses before the queue is clear */ - __redisAsyncDisconnect(ac); + valkeyAsyncDisconnectInternal(ac); } /* Sets a pointer to the first argument and its length starting at p. Returns @@ -828,16 +828,16 @@ static const char *nextArgument(const char *start, const char **str, size_t *len return p+2+(*len)+2; } -/* Helper function for the redisAsyncCommand* family of functions. Writes a +/* Helper function for the valkeyAsyncCommand* family of functions. Writes a * formatted command to the output buffer and registers the provided callback * function with the context. */ -static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) { - redisContext *c = &(ac->c); - redisCallback cb; +static int valkeyAsyncAppendCmdLen(valkeyAsyncContext *ac, valkeyCallbackFn *fn, void *privdata, const char *cmd, size_t len) { + valkeyContext *c = &(ac->c); + valkeyCallback cb; struct dict *cbdict; dictIterator it; dictEntry *de; - redisCallback *existcb; + valkeyCallback *existcb; int pvariant, hasnext; const char *cstr, *astr; size_t clen, alen; @@ -846,7 +846,7 @@ static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void int ret; /* Don't accept new commands when the connection is about to be closed. */ - if (c->flags & (REDIS_DISCONNECTING | REDIS_FREEING)) return REDIS_ERR; + if (c->flags & (VALKEY_DISCONNECTING | VALKEY_FREEING)) return VALKEY_ERR; /* Setup callback */ cb.fn = fn; @@ -863,7 +863,7 @@ static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void clen -= pvariant; if (hasnext && strncasecmp(cstr,"subscribe\r\n",11) == 0) { - c->flags |= REDIS_SUBSCRIBED; + c->flags |= VALKEY_SUBSCRIBED; /* Add every channel/pattern to the list of subscription callbacks. */ while ((p = nextArgument(p,&astr,&alen)) != NULL) { @@ -890,7 +890,7 @@ static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void } else if (strncasecmp(cstr,"unsubscribe\r\n",13) == 0) { /* It is only useful to call (P)UNSUBSCRIBE when the context is * subscribed to one or more channels or patterns. */ - if (!(c->flags & REDIS_SUBSCRIBED)) return REDIS_ERR; + if (!(c->flags & VALKEY_SUBSCRIBED)) return VALKEY_ERR; if (pvariant) cbdict = ac->sub.patterns; @@ -942,85 +942,85 @@ static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void * should not append a callback function for this command. */ } else if (strncasecmp(cstr,"monitor\r\n",9) == 0) { /* Set monitor flag and push callback */ - c->flags |= REDIS_MONITORING; - if (__redisPushCallback(&ac->replies,&cb) != REDIS_OK) + c->flags |= VALKEY_MONITORING; + if (valkeyPushCallback(&ac->replies,&cb) != VALKEY_OK) goto oom; } else { - if (c->flags & REDIS_SUBSCRIBED) { - if (__redisPushCallback(&ac->sub.replies,&cb) != REDIS_OK) + if (c->flags & VALKEY_SUBSCRIBED) { + if (valkeyPushCallback(&ac->sub.replies,&cb) != VALKEY_OK) goto oom; } else { - if (__redisPushCallback(&ac->replies,&cb) != REDIS_OK) + if (valkeyPushCallback(&ac->replies,&cb) != VALKEY_OK) goto oom; } } - __redisAppendCommand(c,cmd,len); + valkeyAppendCmdLen(c,cmd,len); /* Always schedule a write when the write buffer is non-empty */ _EL_ADD_WRITE(ac); - return REDIS_OK; + return VALKEY_OK; oom: - __redisSetError(&(ac->c), REDIS_ERR_OOM, "Out of memory"); - __redisAsyncCopyError(ac); - return REDIS_ERR; + valkeySetError(&(ac->c), VALKEY_ERR_OOM, "Out of memory"); + valkeyAsyncCopyError(ac); + return VALKEY_ERR; } -int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap) { +int valkeyvAsyncCommand(valkeyAsyncContext *ac, valkeyCallbackFn *fn, void *privdata, const char *format, va_list ap) { char *cmd; int len; int status; - len = redisvFormatCommand(&cmd,format,ap); + len = valkeyvFormatCommand(&cmd,format,ap); /* We don't want to pass -1 or -2 to future functions as a length. */ if (len < 0) - return REDIS_ERR; + return VALKEY_ERR; - status = __redisAsyncCommand(ac,fn,privdata,cmd,len); - hi_free(cmd); + status = valkeyAsyncAppendCmdLen(ac,fn,privdata,cmd,len); + vk_free(cmd); return status; } -int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...) { +int valkeyAsyncCommand(valkeyAsyncContext *ac, valkeyCallbackFn *fn, void *privdata, const char *format, ...) { va_list ap; int status; va_start(ap,format); - status = redisvAsyncCommand(ac,fn,privdata,format,ap); + status = valkeyvAsyncCommand(ac,fn,privdata,format,ap); va_end(ap); return status; } -int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen) { +int valkeyAsyncCommandArgv(valkeyAsyncContext *ac, valkeyCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen) { sds cmd; long long len; int status; - len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen); + len = valkeyFormatSdsCommandArgv(&cmd,argc,argv,argvlen); if (len < 0) - return REDIS_ERR; - status = __redisAsyncCommand(ac,fn,privdata,cmd,len); + return VALKEY_ERR; + status = valkeyAsyncAppendCmdLen(ac,fn,privdata,cmd,len); sdsfree(cmd); return status; } -int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) { - int status = __redisAsyncCommand(ac,fn,privdata,cmd,len); +int valkeyAsyncFormattedCommand(valkeyAsyncContext *ac, valkeyCallbackFn *fn, void *privdata, const char *cmd, size_t len) { + int status = valkeyAsyncAppendCmdLen(ac,fn,privdata,cmd,len); return status; } -redisAsyncPushFn *redisAsyncSetPushCallback(redisAsyncContext *ac, redisAsyncPushFn *fn) { - redisAsyncPushFn *old = ac->push_cb; +valkeyAsyncPushFn *valkeyAsyncSetPushCallback(valkeyAsyncContext *ac, valkeyAsyncPushFn *fn) { + valkeyAsyncPushFn *old = ac->push_cb; ac->push_cb = fn; return old; } -int redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv) { +int valkeyAsyncSetTimeout(valkeyAsyncContext *ac, struct timeval tv) { if (!ac->c.command_timeout) { - ac->c.command_timeout = hi_calloc(1, sizeof(tv)); + ac->c.command_timeout = vk_calloc(1, sizeof(tv)); if (ac->c.command_timeout == NULL) { - __redisSetError(&ac->c, REDIS_ERR_OOM, "Out of memory"); - __redisAsyncCopyError(ac); - return REDIS_ERR; + valkeySetError(&ac->c, VALKEY_ERR_OOM, "Out of memory"); + valkeyAsyncCopyError(ac); + return VALKEY_ERR; } } @@ -1030,5 +1030,5 @@ int redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv) { *ac->c.command_timeout = tv; } - return REDIS_OK; + return VALKEY_OK; } diff --git a/libvalkey/async.h b/src/async.h similarity index 53% rename from libvalkey/async.h rename to src/async.h index 4f94660b..0b73758d 100644 --- a/libvalkey/async.h +++ b/src/async.h @@ -29,48 +29,48 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __HIREDIS_ASYNC_H -#define __HIREDIS_ASYNC_H -#include "hiredis.h" +#ifndef VALKEY_ASYNC_H +#define VALKEY_ASYNC_H +#include "valkey.h" #ifdef __cplusplus extern "C" { #endif -struct redisAsyncContext; /* need forward declaration of redisAsyncContext */ +struct valkeyAsyncContext; /* need forward declaration of valkeyAsyncContext */ struct dict; /* dictionary header is included in async.c */ /* Reply callback prototype and container */ -typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*); -typedef struct redisCallback { - struct redisCallback *next; /* simple singly linked list */ - redisCallbackFn *fn; +typedef void (valkeyCallbackFn)(struct valkeyAsyncContext*, void*, void*); +typedef struct valkeyCallback { + struct valkeyCallback *next; /* simple singly linked list */ + valkeyCallbackFn *fn; int pending_subs; int unsubscribe_sent; void *privdata; -} redisCallback; +} valkeyCallback; /* List of callbacks for either regular replies or pub/sub */ -typedef struct redisCallbackList { - redisCallback *head, *tail; -} redisCallbackList; +typedef struct valkeyCallbackList { + valkeyCallback *head, *tail; +} valkeyCallbackList; /* Connection callback prototypes */ -typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status); -typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status); -typedef void (redisConnectCallbackNC)(struct redisAsyncContext *, int status); -typedef void(redisTimerCallback)(void *timer, void *privdata); +typedef void (valkeyDisconnectCallback)(const struct valkeyAsyncContext*, int status); +typedef void (valkeyConnectCallback)(const struct valkeyAsyncContext*, int status); +typedef void (valkeyConnectCallbackNC)(struct valkeyAsyncContext *, int status); +typedef void(valkeyTimerCallback)(void *timer, void *privdata); -/* Context for an async connection to Redis */ -typedef struct redisAsyncContext { +/* Context for an async connection to Valkey */ +typedef struct valkeyAsyncContext { /* Hold the regular context, so it can be realloc'ed. */ - redisContext c; + valkeyContext c; /* Setup error flags so they can be used directly. */ int err; char *errstr; - /* Not used by hiredis */ + /* Not used by libvalkey */ void *data; void (*dataCleanup)(void *privdata); @@ -89,15 +89,15 @@ typedef struct redisAsyncContext { } ev; /* Called when either the connection is terminated due to an error or per - * user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */ - redisDisconnectCallback *onDisconnect; + * user request. The status is set accordingly (VALKEY_OK, VALKEY_ERR). */ + valkeyDisconnectCallback *onDisconnect; /* Called when the first write event was received. */ - redisConnectCallback *onConnect; - redisConnectCallbackNC *onConnectNC; + valkeyConnectCallback *onConnect; + valkeyConnectCallbackNC *onConnectNC; /* Regular command callbacks */ - redisCallbackList replies; + valkeyCallbackList replies; /* Address used for connect() */ struct sockaddr *saddr; @@ -105,45 +105,45 @@ typedef struct redisAsyncContext { /* Subscription callbacks */ struct { - redisCallbackList replies; + valkeyCallbackList replies; struct dict *channels; struct dict *patterns; int pending_unsubs; } sub; /* Any configured RESP3 PUSH handler */ - redisAsyncPushFn *push_cb; -} redisAsyncContext; - -/* Functions that proxy to hiredis */ -redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options); -redisAsyncContext *redisAsyncConnect(const char *ip, int port); -redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr); -redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, + valkeyAsyncPushFn *push_cb; +} valkeyAsyncContext; + +/* Functions that proxy to libvalkey */ +valkeyAsyncContext *valkeyAsyncConnectWithOptions(const valkeyOptions *options); +valkeyAsyncContext *valkeyAsyncConnect(const char *ip, int port); +valkeyAsyncContext *valkeyAsyncConnectBind(const char *ip, int port, const char *source_addr); +valkeyAsyncContext *valkeyAsyncConnectBindWithReuse(const char *ip, int port, const char *source_addr); -redisAsyncContext *redisAsyncConnectUnix(const char *path); -int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn); -int redisAsyncSetConnectCallbackNC(redisAsyncContext *ac, redisConnectCallbackNC *fn); -int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); +valkeyAsyncContext *valkeyAsyncConnectUnix(const char *path); +int valkeyAsyncSetConnectCallback(valkeyAsyncContext *ac, valkeyConnectCallback *fn); +int valkeyAsyncSetConnectCallbackNC(valkeyAsyncContext *ac, valkeyConnectCallbackNC *fn); +int valkeyAsyncSetDisconnectCallback(valkeyAsyncContext *ac, valkeyDisconnectCallback *fn); -redisAsyncPushFn *redisAsyncSetPushCallback(redisAsyncContext *ac, redisAsyncPushFn *fn); -int redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv); -void redisAsyncDisconnect(redisAsyncContext *ac); -void redisAsyncFree(redisAsyncContext *ac); +valkeyAsyncPushFn *valkeyAsyncSetPushCallback(valkeyAsyncContext *ac, valkeyAsyncPushFn *fn); +int valkeyAsyncSetTimeout(valkeyAsyncContext *ac, struct timeval tv); +void valkeyAsyncDisconnect(valkeyAsyncContext *ac); +void valkeyAsyncFree(valkeyAsyncContext *ac); /* Handle read/write events */ -void redisAsyncHandleRead(redisAsyncContext *ac); -void redisAsyncHandleWrite(redisAsyncContext *ac); -void redisAsyncHandleTimeout(redisAsyncContext *ac); -void redisAsyncRead(redisAsyncContext *ac); -void redisAsyncWrite(redisAsyncContext *ac); +void valkeyAsyncHandleRead(valkeyAsyncContext *ac); +void valkeyAsyncHandleWrite(valkeyAsyncContext *ac); +void valkeyAsyncHandleTimeout(valkeyAsyncContext *ac); +void valkeyAsyncRead(valkeyAsyncContext *ac); +void valkeyAsyncWrite(valkeyAsyncContext *ac); /* Command functions for an async context. Write the command to the * output buffer and register the provided callback. */ -int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap); -int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...); -int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen); -int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len); +int valkeyvAsyncCommand(valkeyAsyncContext *ac, valkeyCallbackFn *fn, void *privdata, const char *format, va_list ap); +int valkeyAsyncCommand(valkeyAsyncContext *ac, valkeyCallbackFn *fn, void *privdata, const char *format, ...); +int valkeyAsyncCommandArgv(valkeyAsyncContext *ac, valkeyCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen); +int valkeyAsyncFormattedCommand(valkeyAsyncContext *ac, valkeyCallbackFn *fn, void *privdata, const char *cmd, size_t len); #ifdef __cplusplus } diff --git a/libvalkey/async_private.h b/src/async_private.h similarity index 83% rename from libvalkey/async_private.h rename to src/async_private.h index ea0558d4..21b6de03 100644 --- a/libvalkey/async_private.h +++ b/src/async_private.h @@ -29,8 +29,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __HIREDIS_ASYNC_PRIVATE_H -#define __HIREDIS_ASYNC_PRIVATE_H +#ifndef VALKEY_ASYNC_PRIVATE_H +#define VALKEY_ASYNC_PRIVATE_H #define _EL_ADD_READ(ctx) \ do { \ @@ -53,23 +53,23 @@ ctx->ev.cleanup = NULL; \ } while(0) -static inline void refreshTimeout(redisAsyncContext *ctx) { - #define REDIS_TIMER_ISSET(tvp) \ +static inline void refreshTimeout(valkeyAsyncContext *ctx) { + #define VALKEY_TIMER_ISSET(tvp) \ (tvp && ((tvp)->tv_sec || (tvp)->tv_usec)) - #define REDIS_EL_TIMER(ac, tvp) \ - if ((ac)->ev.scheduleTimer && REDIS_TIMER_ISSET(tvp)) { \ + #define VALKEY_EL_TIMER(ac, tvp) \ + if ((ac)->ev.scheduleTimer && VALKEY_TIMER_ISSET(tvp)) { \ (ac)->ev.scheduleTimer((ac)->ev.data, *(tvp)); \ } - if (ctx->c.flags & REDIS_CONNECTED) { - REDIS_EL_TIMER(ctx, ctx->c.command_timeout); + if (ctx->c.flags & VALKEY_CONNECTED) { + VALKEY_EL_TIMER(ctx, ctx->c.command_timeout); } else { - REDIS_EL_TIMER(ctx, ctx->c.connect_timeout); + VALKEY_EL_TIMER(ctx, ctx->c.connect_timeout); } } -void __redisAsyncDisconnect(redisAsyncContext *ac); -void redisProcessCallbacks(redisAsyncContext *ac); +void valkeyAsyncDisconnectInternal(valkeyAsyncContext *ac); +void valkeyProcessCallbacks(valkeyAsyncContext *ac); -#endif /* __HIREDIS_ASYNC_PRIVATE_H */ +#endif /* VALKEY_ASYNC_PRIVATE_H */ diff --git a/src/dict.c b/src/dict.c index d793cd47..2ba4cf78 100644 --- a/src/dict.c +++ b/src/dict.c @@ -33,11 +33,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "fmacros.h" +#include "alloc.h" +#include #include #include -#include -#include - #include "dict.h" /* -------------------------- private prototypes ---------------------------- */ @@ -51,7 +51,7 @@ static int _dictInit(dict *ht, dictType *type, void *privDataPtr); /* Generic hash function (a popular one from Bernstein). * I tested a few and this was the best. */ -unsigned int dictGenHashFunction(const unsigned char *buf, int len) { +static unsigned int dictGenHashFunction(const unsigned char *buf, int len) { unsigned int hash = 5381; while (len--) @@ -71,12 +71,12 @@ static void _dictReset(dict *ht) { } /* Create a new hash table */ -dict *dictCreate(dictType *type, void *privDataPtr) { +static dict *dictCreate(dictType *type, void *privDataPtr) { dict *ht = vk_malloc(sizeof(*ht)); if (ht == NULL) return NULL; - _dictInit(ht, type, privDataPtr); + _dictInit(ht,type,privDataPtr); return ht; } @@ -89,7 +89,7 @@ static int _dictInit(dict *ht, dictType *type, void *privDataPtr) { } /* Expand or create the hashtable */ -int dictExpand(dict *ht, unsigned long size) { +static int dictExpand(dict *ht, unsigned long size) { dict n; /* the new hashtable */ unsigned long realsize = _dictNextPower(size), i; @@ -100,8 +100,8 @@ int dictExpand(dict *ht, unsigned long size) { _dictInit(&n, ht->type, ht->privdata); n.size = realsize; - n.sizemask = realsize - 1; - n.table = vk_calloc(realsize, sizeof(dictEntry *)); + n.sizemask = realsize-1; + n.table = vk_calloc(realsize,sizeof(dictEntry*)); if (n.table == NULL) return DICT_ERR; @@ -112,12 +112,11 @@ int dictExpand(dict *ht, unsigned long size) { for (i = 0; i < ht->size && ht->used > 0; i++) { dictEntry *he, *nextHe; - if (ht->table[i] == NULL) - continue; + if (ht->table[i] == NULL) continue; /* For each hash entry on this slot... */ he = ht->table[i]; - while (he) { + while(he) { unsigned int h; nextHe = he->next; @@ -139,7 +138,7 @@ int dictExpand(dict *ht, unsigned long size) { } /* Add an element to the target hash table */ -int dictAdd(dict *ht, void *key, void *val) { +static int dictAdd(dict *ht, void *key, void *val) { int index; dictEntry *entry; @@ -163,6 +162,65 @@ int dictAdd(dict *ht, void *key, void *val) { return DICT_OK; } +/* Add an element, discarding the old if the key already exists. + * Return 1 if the key was added from scratch, 0 if there was already an + * element with such key and dictReplace() just performed a value update + * operation. */ +static int dictReplace(dict *ht, void *key, void *val) { + dictEntry *entry, auxentry; + + /* Try to add the element. If the key + * does not exists dictAdd will succeed. */ + if (dictAdd(ht, key, val) == DICT_OK) + return 1; + /* It already exists, get the entry */ + entry = dictFind(ht, key); + if (entry == NULL) + return 0; + + /* Free the old value and set the new one */ + /* Set the new value and free the old one. Note that it is important + * to do that in this order, as the value may just be exactly the same + * as the previous one. In this context, think to reference counting, + * you want to increment (set), and then decrement (free), and not the + * reverse. */ + auxentry = *entry; + dictSetHashVal(ht, entry, val); + dictFreeEntryVal(ht, &auxentry); + return 0; +} + +/* Search and remove an element */ +static int dictDelete(dict *ht, const void *key) { + unsigned int h; + dictEntry *de, *prevde; + + if (ht->size == 0) + return DICT_ERR; + h = dictHashKey(ht, key) & ht->sizemask; + de = ht->table[h]; + + prevde = NULL; + while(de) { + if (dictCompareHashKeys(ht,key,de->key)) { + /* Unlink the element from the list */ + if (prevde) + prevde->next = de->next; + else + ht->table[h] = de->next; + + dictFreeEntryKey(ht,de); + dictFreeEntryVal(ht,de); + vk_free(de); + ht->used--; + return DICT_OK; + } + prevde = de; + de = de->next; + } + return DICT_ERR; /* not found */ +} + /* Destroy an entire hash table */ static int _dictClear(dict *ht) { unsigned long i; @@ -171,9 +229,8 @@ static int _dictClear(dict *ht) { for (i = 0; i < ht->size && ht->used > 0; i++) { dictEntry *he, *nextHe; - if ((he = ht->table[i]) == NULL) - continue; - while (he) { + if ((he = ht->table[i]) == NULL) continue; + while(he) { nextHe = he->next; dictFreeEntryKey(ht, he); dictFreeEntryVal(ht, he); @@ -190,20 +247,19 @@ static int _dictClear(dict *ht) { } /* Clear & Release the hash table */ -void dictRelease(dict *ht) { +static void dictRelease(dict *ht) { _dictClear(ht); vk_free(ht); } -dictEntry *dictFind(dict *ht, const void *key) { +static dictEntry *dictFind(dict *ht, const void *key) { dictEntry *he; unsigned int h; - if (ht->size == 0) - return NULL; + if (ht->size == 0) return NULL; h = dictHashKey(ht, key) & ht->sizemask; he = ht->table[h]; - while (he) { + while(he) { if (dictCompareHashKeys(ht, key, he->key)) return he; he = he->next; @@ -211,19 +267,19 @@ dictEntry *dictFind(dict *ht, const void *key) { return NULL; } -void dictInitIterator(dictIterator *iter, dict *ht) { +static void dictInitIterator(dictIterator *iter, dict *ht) { iter->ht = ht; iter->index = -1; iter->entry = NULL; iter->nextEntry = NULL; } -dictEntry *dictNext(dictIterator *iter) { +static dictEntry *dictNext(dictIterator *iter) { while (1) { if (iter->entry == NULL) { iter->index++; - if (iter->index >= (signed)iter->ht->size) - break; + if (iter->index >= + (signed)iter->ht->size) break; iter->entry = iter->ht->table[iter->index]; } else { iter->entry = iter->nextEntry; @@ -247,7 +303,7 @@ static int _dictExpandIfNeeded(dict *ht) { if (ht->size == 0) return dictExpand(ht, DICT_HT_INITIAL_SIZE); if (ht->used == ht->size) - return dictExpand(ht, ht->size * 2); + return dictExpand(ht, ht->size*2); return DICT_OK; } @@ -255,9 +311,8 @@ static int _dictExpandIfNeeded(dict *ht) { static unsigned long _dictNextPower(unsigned long size) { unsigned long i = DICT_HT_INITIAL_SIZE; - if (size >= LONG_MAX) - return LONG_MAX; - while (1) { + if (size >= LONG_MAX) return LONG_MAX; + while(1) { if (i >= size) return i; i *= 2; @@ -278,10 +333,11 @@ static int _dictKeyIndex(dict *ht, const void *key) { h = dictHashKey(ht, key) & ht->sizemask; /* Search if this slot does not already contain the given key */ he = ht->table[h]; - while (he) { + while(he) { if (dictCompareHashKeys(ht, key, he->key)) return -1; he = he->next; } return h; } + diff --git a/src/dict.h b/src/dict.h index 7e1d70d0..6ad0acd8 100644 --- a/src/dict.h +++ b/src/dict.h @@ -40,7 +40,7 @@ #define DICT_ERR 1 /* Unused arguments generate annoying warnings... */ -#define DICT_NOTUSED(V) ((void)V) +#define DICT_NOTUSED(V) ((void) V) typedef struct dictEntry { void *key; @@ -73,37 +73,35 @@ typedef struct dictIterator { } dictIterator; /* This is the initial size of every hash table */ -#define DICT_HT_INITIAL_SIZE 4 +#define DICT_HT_INITIAL_SIZE 4 /* ------------------------------- Macros ------------------------------------*/ -#define dictFreeEntryVal(ht, entry) \ - if ((ht)->type->valDestructor) \ - (ht)->type->valDestructor((ht)->privdata, (entry)->val) - -#define dictSetHashVal(ht, entry, _val_) \ - do { \ - if ((ht)->type->valDup) \ - entry->val = (ht)->type->valDup((ht)->privdata, _val_); \ - else \ - entry->val = (_val_); \ - } while (0) - -#define dictFreeEntryKey(ht, entry) \ - if ((ht)->type->keyDestructor) \ - (ht)->type->keyDestructor((ht)->privdata, (entry)->key) - -#define dictSetHashKey(ht, entry, _key_) \ - do { \ - if ((ht)->type->keyDup) \ - entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \ - else \ - entry->key = (_key_); \ - } while (0) - -#define dictCompareHashKeys(ht, key1, key2) \ - (((ht)->type->keyCompare) ? \ - (ht)->type->keyCompare((ht)->privdata, key1, key2) : \ - (key1) == (key2)) +#define dictFreeEntryVal(ht, entry) \ + if ((ht)->type->valDestructor) \ + (ht)->type->valDestructor((ht)->privdata, (entry)->val) + +#define dictSetHashVal(ht, entry, _val_) do { \ + if ((ht)->type->valDup) \ + entry->val = (ht)->type->valDup((ht)->privdata, _val_); \ + else \ + entry->val = (_val_); \ +} while(0) + +#define dictFreeEntryKey(ht, entry) \ + if ((ht)->type->keyDestructor) \ + (ht)->type->keyDestructor((ht)->privdata, (entry)->key) + +#define dictSetHashKey(ht, entry, _key_) do { \ + if ((ht)->type->keyDup) \ + entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \ + else \ + entry->key = (_key_); \ +} while(0) + +#define dictCompareHashKeys(ht, key1, key2) \ + (((ht)->type->keyCompare) ? \ + (ht)->type->keyCompare((ht)->privdata, key1, key2) : \ + (key1) == (key2)) #define dictHashKey(ht, key) (ht)->type->hashFunction(key) @@ -113,13 +111,15 @@ typedef struct dictIterator { #define dictSize(ht) ((ht)->used) /* API */ -unsigned int dictGenHashFunction(const unsigned char *buf, int len); -dict *dictCreate(dictType *type, void *privDataPtr); -int dictExpand(dict *ht, unsigned long size); -int dictAdd(dict *ht, void *key, void *val); -void dictRelease(dict *ht); -dictEntry *dictFind(dict *ht, const void *key); -void dictInitIterator(dictIterator *iter, dict *ht); -dictEntry *dictNext(dictIterator *iter); +static unsigned int dictGenHashFunction(const unsigned char *buf, int len); +static dict *dictCreate(dictType *type, void *privDataPtr); +static int dictExpand(dict *ht, unsigned long size); +static int dictAdd(dict *ht, void *key, void *val); +static int dictReplace(dict *ht, void *key, void *val); +static int dictDelete(dict *ht, const void *key); +static void dictRelease(dict *ht); +static dictEntry * dictFind(dict *ht, const void *key); +static void dictInitIterator(dictIterator *iter, dict *ht); +static dictEntry *dictNext(dictIterator *iter); #endif /* __DICT_H */ diff --git a/libvalkey/fmacros.h b/src/fmacros.h similarity index 77% rename from libvalkey/fmacros.h rename to src/fmacros.h index 754a53c2..b8e37d01 100644 --- a/libvalkey/fmacros.h +++ b/src/fmacros.h @@ -1,5 +1,5 @@ -#ifndef __HIREDIS_FMACRO_H -#define __HIREDIS_FMACRO_H +#ifndef VALKEY_FMACRO_H +#define VALKEY_FMACRO_H #ifndef _AIX #define _XOPEN_SOURCE 600 diff --git a/libvalkey/net.c b/src/net.c similarity index 61% rename from libvalkey/net.c rename to src/net.c index 8b7831e3..5d92156a 100644 --- a/libvalkey/net.c +++ b/src/net.c @@ -48,50 +48,50 @@ #include "sockcompat.h" #include "win32.h" -/* Defined in hiredis.c */ -void __redisSetError(redisContext *c, int type, const char *str); +/* Defined in valkey.c */ +void valkeySetError(valkeyContext *c, int type, const char *str); -int redisContextUpdateCommandTimeout(redisContext *c, const struct timeval *timeout); +int valkeyContextUpdateCommandTimeout(valkeyContext *c, const struct timeval *timeout); -void redisNetClose(redisContext *c) { - if (c && c->fd != REDIS_INVALID_FD) { +void valkeyNetClose(valkeyContext *c) { + if (c && c->fd != VALKEY_INVALID_FD) { close(c->fd); - c->fd = REDIS_INVALID_FD; + c->fd = VALKEY_INVALID_FD; } } -ssize_t redisNetRead(redisContext *c, char *buf, size_t bufcap) { +ssize_t valkeyNetRead(valkeyContext *c, char *buf, size_t bufcap) { ssize_t nread = recv(c->fd, buf, bufcap, 0); if (nread == -1) { - if ((errno == EWOULDBLOCK && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) { + if ((errno == EWOULDBLOCK && !(c->flags & VALKEY_BLOCK)) || (errno == EINTR)) { /* Try again later */ return 0; - } else if(errno == ETIMEDOUT && (c->flags & REDIS_BLOCK)) { + } else if(errno == ETIMEDOUT && (c->flags & VALKEY_BLOCK)) { /* especially in windows */ - __redisSetError(c, REDIS_ERR_TIMEOUT, "recv timeout"); + valkeySetError(c, VALKEY_ERR_TIMEOUT, "recv timeout"); return -1; } else { - __redisSetError(c, REDIS_ERR_IO, strerror(errno)); + valkeySetError(c, VALKEY_ERR_IO, strerror(errno)); return -1; } } else if (nread == 0) { - __redisSetError(c, REDIS_ERR_EOF, "Server closed the connection"); + valkeySetError(c, VALKEY_ERR_EOF, "Server closed the connection"); return -1; } else { return nread; } } -ssize_t redisNetWrite(redisContext *c) { +ssize_t valkeyNetWrite(valkeyContext *c) { ssize_t nwritten; nwritten = send(c->fd, c->obuf, sdslen(c->obuf), 0); if (nwritten < 0) { - if ((errno == EWOULDBLOCK && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) { + if ((errno == EWOULDBLOCK && !(c->flags & VALKEY_BLOCK)) || (errno == EINTR)) { /* Try again */ return 0; } else { - __redisSetError(c, REDIS_ERR_IO, strerror(errno)); + valkeySetError(c, VALKEY_ERR_IO, strerror(errno)); return -1; } } @@ -99,7 +99,7 @@ ssize_t redisNetWrite(redisContext *c) { return nwritten; } -static void __redisSetErrorFromErrno(redisContext *c, int type, const char *prefix) { +static void valkeySetErrorFromErrno(valkeyContext *c, int type, const char *prefix) { int errorno = errno; /* snprintf() may change errno */ char buf[128] = { 0 }; size_t len = 0; @@ -107,35 +107,35 @@ static void __redisSetErrorFromErrno(redisContext *c, int type, const char *pref if (prefix != NULL) len = snprintf(buf,sizeof(buf),"%s: ",prefix); strerror_r(errorno, (char *)(buf + len), sizeof(buf) - len); - __redisSetError(c,type,buf); + valkeySetError(c,type,buf); } -static int redisSetReuseAddr(redisContext *c) { +static int valkeySetReuseAddr(valkeyContext *c) { int on = 1; if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { - __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); - redisNetClose(c); - return REDIS_ERR; + valkeySetErrorFromErrno(c,VALKEY_ERR_IO,NULL); + valkeyNetClose(c); + return VALKEY_ERR; } - return REDIS_OK; + return VALKEY_OK; } -static int redisCreateSocket(redisContext *c, int type) { - redisFD s; - if ((s = socket(type, SOCK_STREAM, 0)) == REDIS_INVALID_FD) { - __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); - return REDIS_ERR; +static int valkeyCreateSocket(valkeyContext *c, int type) { + valkeyFD s; + if ((s = socket(type, SOCK_STREAM, 0)) == VALKEY_INVALID_FD) { + valkeySetErrorFromErrno(c,VALKEY_ERR_IO,NULL); + return VALKEY_ERR; } c->fd = s; if (type == AF_INET) { - if (redisSetReuseAddr(c) == REDIS_ERR) { - return REDIS_ERR; + if (valkeySetReuseAddr(c) == VALKEY_ERR) { + return VALKEY_ERR; } } - return REDIS_OK; + return VALKEY_OK; } -static int redisSetBlocking(redisContext *c, int blocking) { +static int valkeySetBlocking(valkeyContext *c, int blocking) { #ifndef _WIN32 int flags; @@ -143,9 +143,9 @@ static int redisSetBlocking(redisContext *c, int blocking) { * Note that fcntl(2) for F_GETFL and F_SETFL can't be * interrupted by a signal. */ if ((flags = fcntl(c->fd, F_GETFL)) == -1) { - __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)"); - redisNetClose(c); - return REDIS_ERR; + valkeySetErrorFromErrno(c,VALKEY_ERR_IO,"fcntl(F_GETFL)"); + valkeyNetClose(c); + return VALKEY_ERR; } if (blocking) @@ -154,86 +154,86 @@ static int redisSetBlocking(redisContext *c, int blocking) { flags |= O_NONBLOCK; if (fcntl(c->fd, F_SETFL, flags) == -1) { - __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)"); - redisNetClose(c); - return REDIS_ERR; + valkeySetErrorFromErrno(c,VALKEY_ERR_IO,"fcntl(F_SETFL)"); + valkeyNetClose(c); + return VALKEY_ERR; } #else u_long mode = blocking ? 0 : 1; if (ioctl(c->fd, FIONBIO, &mode) == -1) { - __redisSetErrorFromErrno(c, REDIS_ERR_IO, "ioctl(FIONBIO)"); - redisNetClose(c); - return REDIS_ERR; + valkeySetErrorFromErrno(c, VALKEY_ERR_IO, "ioctl(FIONBIO)"); + valkeyNetClose(c); + return VALKEY_ERR; } #endif /* _WIN32 */ - return REDIS_OK; + return VALKEY_OK; } -int redisKeepAlive(redisContext *c, int interval) { +int valkeyKeepAlive(valkeyContext *c, int interval) { int val = 1; - redisFD fd = c->fd; + valkeyFD fd = c->fd; /* TCP_KEEPALIVE makes no sense with AF_UNIX connections */ - if (c->connection_type == REDIS_CONN_UNIX) - return REDIS_ERR; + if (c->connection_type == VALKEY_CONN_UNIX) + return VALKEY_ERR; #ifndef _WIN32 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1){ - __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); - return REDIS_ERR; + valkeySetError(c,VALKEY_ERR_OTHER,strerror(errno)); + return VALKEY_ERR; } val = interval; #if defined(__APPLE__) && defined(__MACH__) if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &val, sizeof(val)) < 0) { - __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); - return REDIS_ERR; + valkeySetError(c,VALKEY_ERR_OTHER,strerror(errno)); + return VALKEY_ERR; } #else #if defined(__GLIBC__) && !defined(__FreeBSD_kernel__) if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) { - __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); - return REDIS_ERR; + valkeySetError(c,VALKEY_ERR_OTHER,strerror(errno)); + return VALKEY_ERR; } val = interval/3; if (val == 0) val = 1; if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) { - __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); - return REDIS_ERR; + valkeySetError(c,VALKEY_ERR_OTHER,strerror(errno)); + return VALKEY_ERR; } val = 3; if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) { - __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); - return REDIS_ERR; + valkeySetError(c,VALKEY_ERR_OTHER,strerror(errno)); + return VALKEY_ERR; } #endif #endif #else int res; - res = win32_redisKeepAlive(fd, interval * 1000); + res = win32_valkeyKeepAlive(fd, interval * 1000); if (res != 0) { - __redisSetError(c, REDIS_ERR_OTHER, strerror(res)); - return REDIS_ERR; + valkeySetError(c, VALKEY_ERR_OTHER, strerror(res)); + return VALKEY_ERR; } #endif - return REDIS_OK; + return VALKEY_OK; } -int redisSetTcpNoDelay(redisContext *c) { +int valkeySetTcpNoDelay(valkeyContext *c) { int yes = 1; if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) { - __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)"); - redisNetClose(c); - return REDIS_ERR; + valkeySetErrorFromErrno(c,VALKEY_ERR_IO,"setsockopt(TCP_NODELAY)"); + valkeyNetClose(c); + return VALKEY_ERR; } - return REDIS_OK; + return VALKEY_OK; } -int redisContextSetTcpUserTimeout(redisContext *c, unsigned int timeout) { +int valkeyContextSetTcpUserTimeout(valkeyContext *c, unsigned int timeout) { int res; #ifdef TCP_USER_TIMEOUT res = setsockopt(c->fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout, sizeof(timeout)); @@ -243,16 +243,16 @@ int redisContextSetTcpUserTimeout(redisContext *c, unsigned int timeout) { (void)timeout; #endif if (res == -1) { - __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_USER_TIMEOUT)"); - redisNetClose(c); - return REDIS_ERR; + valkeySetErrorFromErrno(c,VALKEY_ERR_IO,"setsockopt(TCP_USER_TIMEOUT)"); + valkeyNetClose(c); + return VALKEY_ERR; } - return REDIS_OK; + return VALKEY_OK; } #define __MAX_MSEC (((LONG_MAX) - 999) / 1000) -static int redisContextTimeoutMsec(redisContext *c, long *result) +static int valkeyContextTimeoutMsec(valkeyContext *c, long *result) { const struct timeval *timeout = c->connect_timeout; long msec = -1; @@ -260,9 +260,9 @@ static int redisContextTimeoutMsec(redisContext *c, long *result) /* Only use timeout when not NULL. */ if (timeout != NULL) { if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) { - __redisSetError(c, REDIS_ERR_IO, "Invalid timeout specified"); + valkeySetError(c, VALKEY_ERR_IO, "Invalid timeout specified"); *result = msec; - return REDIS_ERR; + return VALKEY_ERR; } msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000); @@ -273,10 +273,10 @@ static int redisContextTimeoutMsec(redisContext *c, long *result) } *result = msec; - return REDIS_OK; + return VALKEY_OK; } -static long redisPollMillis(void) { +static long valkeyPollMillis(void) { #ifndef _MSC_VER struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); @@ -288,49 +288,49 @@ static long redisPollMillis(void) { #endif } -static int redisContextWaitReady(redisContext *c, long msec) { +static int valkeyContextWaitReady(valkeyContext *c, long msec) { struct pollfd wfd; long end; int res; if (errno != EINPROGRESS) { - __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); - redisNetClose(c); - return REDIS_ERR; + valkeySetErrorFromErrno(c,VALKEY_ERR_IO,NULL); + valkeyNetClose(c); + return VALKEY_ERR; } wfd.fd = c->fd; wfd.events = POLLOUT; - end = msec >= 0 ? redisPollMillis() + msec : 0; + end = msec >= 0 ? valkeyPollMillis() + msec : 0; while ((res = poll(&wfd, 1, msec)) <= 0) { if (res < 0 && errno != EINTR) { - __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); - redisNetClose(c); - return REDIS_ERR; - } else if (res == 0 || (msec >= 0 && redisPollMillis() >= end)) { + valkeySetErrorFromErrno(c, VALKEY_ERR_IO, "poll(2)"); + valkeyNetClose(c); + return VALKEY_ERR; + } else if (res == 0 || (msec >= 0 && valkeyPollMillis() >= end)) { errno = ETIMEDOUT; - __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL); - redisNetClose(c); - return REDIS_ERR; + valkeySetErrorFromErrno(c, VALKEY_ERR_IO, NULL); + valkeyNetClose(c); + return VALKEY_ERR; } else { /* res < 0 && errno == EINTR, try again */ } } - if (redisCheckConnectDone(c, &res) != REDIS_OK || res == 0) { - redisCheckSocketError(c); - return REDIS_ERR; + if (valkeyCheckConnectDone(c, &res) != VALKEY_OK || res == 0) { + valkeyCheckSocketError(c); + return VALKEY_ERR; } - return REDIS_OK; + return VALKEY_OK; } -int redisCheckConnectDone(redisContext *c, int *completed) { +int valkeyCheckConnectDone(valkeyContext *c, int *completed) { int rc = connect(c->fd, (const struct sockaddr *)c->saddr, c->addrlen); if (rc == 0) { *completed = 1; - return REDIS_OK; + return VALKEY_OK; } int error = errno; if (error == EINPROGRESS) { @@ -342,7 +342,7 @@ int redisCheckConnectDone(redisContext *c, int *completed) { if (so_error == 0) { /* Socket is connected! */ *completed = 1; - return REDIS_OK; + return VALKEY_OK; } /* connection error; */ errno = so_error; @@ -352,23 +352,23 @@ int redisCheckConnectDone(redisContext *c, int *completed) { switch (error) { case EISCONN: *completed = 1; - return REDIS_OK; + return VALKEY_OK; case EALREADY: case EWOULDBLOCK: *completed = 0; - return REDIS_OK; + return VALKEY_OK; default: - return REDIS_ERR; + return VALKEY_ERR; } } -int redisCheckSocketError(redisContext *c) { +int valkeyCheckSocketError(valkeyContext *c) { int err = 0, errno_saved = errno; socklen_t errlen = sizeof(err); if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { - __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)"); - return REDIS_ERR; + valkeySetErrorFromErrno(c,VALKEY_ERR_IO,"getsockopt(SO_ERROR)"); + return VALKEY_ERR; } if (err == 0) { @@ -377,78 +377,78 @@ int redisCheckSocketError(redisContext *c) { if (err) { errno = err; - __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); - return REDIS_ERR; + valkeySetErrorFromErrno(c,VALKEY_ERR_IO,NULL); + return VALKEY_ERR; } - return REDIS_OK; + return VALKEY_OK; } -int redisContextSetTimeout(redisContext *c, const struct timeval tv) { +int valkeyContextSetTimeout(valkeyContext *c, const struct timeval tv) { const void *to_ptr = &tv; size_t to_sz = sizeof(tv); - if (redisContextUpdateCommandTimeout(c, &tv) != REDIS_OK) { - __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); - return REDIS_ERR; + if (valkeyContextUpdateCommandTimeout(c, &tv) != VALKEY_OK) { + valkeySetError(c, VALKEY_ERR_OOM, "Out of memory"); + return VALKEY_ERR; } if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,to_ptr,to_sz) == -1) { - __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_RCVTIMEO)"); - return REDIS_ERR; + valkeySetErrorFromErrno(c,VALKEY_ERR_IO,"setsockopt(SO_RCVTIMEO)"); + return VALKEY_ERR; } if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,to_ptr,to_sz) == -1) { - __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_SNDTIMEO)"); - return REDIS_ERR; + valkeySetErrorFromErrno(c,VALKEY_ERR_IO,"setsockopt(SO_SNDTIMEO)"); + return VALKEY_ERR; } - return REDIS_OK; + return VALKEY_OK; } -int redisContextUpdateConnectTimeout(redisContext *c, const struct timeval *timeout) { +int valkeyContextUpdateConnectTimeout(valkeyContext *c, const struct timeval *timeout) { /* Same timeval struct, short circuit */ if (c->connect_timeout == timeout) - return REDIS_OK; + return VALKEY_OK; /* Allocate context timeval if we need to */ if (c->connect_timeout == NULL) { - c->connect_timeout = hi_malloc(sizeof(*c->connect_timeout)); + c->connect_timeout = vk_malloc(sizeof(*c->connect_timeout)); if (c->connect_timeout == NULL) - return REDIS_ERR; + return VALKEY_ERR; } memcpy(c->connect_timeout, timeout, sizeof(*c->connect_timeout)); - return REDIS_OK; + return VALKEY_OK; } -int redisContextUpdateCommandTimeout(redisContext *c, const struct timeval *timeout) { +int valkeyContextUpdateCommandTimeout(valkeyContext *c, const struct timeval *timeout) { /* Same timeval struct, short circuit */ if (c->command_timeout == timeout) - return REDIS_OK; + return VALKEY_OK; /* Allocate context timeval if we need to */ if (c->command_timeout == NULL) { - c->command_timeout = hi_malloc(sizeof(*c->command_timeout)); + c->command_timeout = vk_malloc(sizeof(*c->command_timeout)); if (c->command_timeout == NULL) - return REDIS_ERR; + return VALKEY_ERR; } memcpy(c->command_timeout, timeout, sizeof(*c->command_timeout)); - return REDIS_OK; + return VALKEY_OK; } -static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, +static int _valkeyContextConnectTcp(valkeyContext *c, const char *addr, int port, const struct timeval *timeout, const char *source_addr) { - redisFD s; + valkeyFD s; int rv, n; char _port[6]; /* strlen("65535"); */ struct addrinfo hints, *servinfo, *bservinfo, *p, *b; - int blocking = (c->flags & REDIS_BLOCK); - int reuseaddr = (c->flags & REDIS_REUSEADDR); + int blocking = (c->flags & VALKEY_BLOCK); + int reuseaddr = (c->flags & VALKEY_REUSEADDR); int reuses = 0; long timeout_msec = -1; servinfo = NULL; - c->connection_type = REDIS_CONN_TCP; + c->connection_type = VALKEY_CONN_TCP; c->tcp.port = port; /* We need to take possession of the passed parameters @@ -459,31 +459,31 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, * This is a bit ugly, but atleast it works and doesn't leak memory. **/ if (c->tcp.host != addr) { - hi_free(c->tcp.host); + vk_free(c->tcp.host); - c->tcp.host = hi_strdup(addr); + c->tcp.host = vk_strdup(addr); if (c->tcp.host == NULL) goto oom; } if (timeout) { - if (redisContextUpdateConnectTimeout(c, timeout) == REDIS_ERR) + if (valkeyContextUpdateConnectTimeout(c, timeout) == VALKEY_ERR) goto oom; } else { - hi_free(c->connect_timeout); + vk_free(c->connect_timeout); c->connect_timeout = NULL; } - if (redisContextTimeoutMsec(c, &timeout_msec) != REDIS_OK) { + if (valkeyContextTimeoutMsec(c, &timeout_msec) != VALKEY_OK) { goto error; } if (source_addr == NULL) { - hi_free(c->tcp.source_addr); + vk_free(c->tcp.source_addr); c->tcp.source_addr = NULL; } else if (c->tcp.source_addr != source_addr) { - hi_free(c->tcp.source_addr); - c->tcp.source_addr = hi_strdup(source_addr); + vk_free(c->tcp.source_addr); + c->tcp.source_addr = vk_strdup(source_addr); } snprintf(_port, 6, "%d", port); @@ -494,9 +494,9 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, /* DNS lookup. To use dual stack, set both flags to prefer both IPv4 and * IPv6. By default, for historical reasons, we try IPv4 first and then we * try IPv6 only if no IPv4 address was found. */ - if (c->flags & REDIS_PREFER_IPV6 && c->flags & REDIS_PREFER_IPV4) + if (c->flags & VALKEY_PREFER_IPV6 && c->flags & VALKEY_PREFER_IPV4) hints.ai_family = AF_UNSPEC; - else if (c->flags & REDIS_PREFER_IPV6) + else if (c->flags & VALKEY_PREFER_IPV6) hints.ai_family = AF_INET6; else hints.ai_family = AF_INET; @@ -508,16 +508,16 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, rv = getaddrinfo(c->tcp.host, _port, &hints, &servinfo); } if (rv != 0) { - __redisSetError(c, REDIS_ERR_OTHER, gai_strerror(rv)); - return REDIS_ERR; + valkeySetError(c, VALKEY_ERR_OTHER, gai_strerror(rv)); + return VALKEY_ERR; } for (p = servinfo; p != NULL; p = p->ai_next) { addrretry: - if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == REDIS_INVALID_FD) + if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == VALKEY_INVALID_FD) continue; c->fd = s; - if (redisSetBlocking(c,0) != REDIS_OK) + if (valkeySetBlocking(c,0) != VALKEY_OK) goto error; if (c->tcp.source_addr) { int bound = 0; @@ -525,7 +525,7 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, if ((rv = getaddrinfo(c->tcp.source_addr, NULL, &hints, &bservinfo)) != 0) { char buf[128]; snprintf(buf,sizeof(buf),"Can't get addr: %s",gai_strerror(rv)); - __redisSetError(c,REDIS_ERR_OTHER,buf); + valkeySetError(c,VALKEY_ERR_OTHER,buf); goto error; } @@ -548,14 +548,14 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, if (!bound) { char buf[128]; snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno)); - __redisSetError(c,REDIS_ERR_OTHER,buf); + valkeySetError(c,VALKEY_ERR_OTHER,buf); goto error; } } /* For repeat connection */ - hi_free(c->saddr); - c->saddr = hi_malloc(p->ai_addrlen); + vk_free(c->saddr); + c->saddr = vk_malloc(p->ai_addrlen); if (c->saddr == NULL) goto oom; @@ -564,7 +564,7 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { if (errno == EHOSTUNREACH) { - redisNetClose(c); + valkeyNetClose(c); continue; } else if (errno == EINPROGRESS) { if (blocking) { @@ -575,92 +575,92 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, * for `connect()` */ } else if (errno == EADDRNOTAVAIL && reuseaddr) { - if (++reuses >= REDIS_CONNECT_RETRIES) { + if (++reuses >= VALKEY_CONNECT_RETRIES) { goto error; } else { - redisNetClose(c); + valkeyNetClose(c); goto addrretry; } } else { wait_for_ready: - if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) + if (valkeyContextWaitReady(c,timeout_msec) != VALKEY_OK) goto error; - if (redisSetTcpNoDelay(c) != REDIS_OK) + if (valkeySetTcpNoDelay(c) != VALKEY_OK) goto error; } } - if (blocking && redisSetBlocking(c,1) != REDIS_OK) + if (blocking && valkeySetBlocking(c,1) != VALKEY_OK) goto error; - c->flags |= REDIS_CONNECTED; - rv = REDIS_OK; + c->flags |= VALKEY_CONNECTED; + rv = VALKEY_OK; goto end; } if (p == NULL) { char buf[128]; snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno)); - __redisSetError(c,REDIS_ERR_OTHER,buf); + valkeySetError(c,VALKEY_ERR_OTHER,buf); goto error; } oom: - __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); + valkeySetError(c, VALKEY_ERR_OOM, "Out of memory"); error: - rv = REDIS_ERR; + rv = VALKEY_ERR; end: if(servinfo) { freeaddrinfo(servinfo); } - return rv; // Need to return REDIS_OK if alright + return rv; // Need to return VALKEY_OK if alright } -int redisContextConnectTcp(redisContext *c, const char *addr, int port, +int valkeyContextConnectTcp(valkeyContext *c, const char *addr, int port, const struct timeval *timeout) { - return _redisContextConnectTcp(c, addr, port, timeout, NULL); + return _valkeyContextConnectTcp(c, addr, port, timeout, NULL); } -int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, +int valkeyContextConnectBindTcp(valkeyContext *c, const char *addr, int port, const struct timeval *timeout, const char *source_addr) { - return _redisContextConnectTcp(c, addr, port, timeout, source_addr); + return _valkeyContextConnectTcp(c, addr, port, timeout, source_addr); } -int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) { +int valkeyContextConnectUnix(valkeyContext *c, const char *path, const struct timeval *timeout) { #ifndef _WIN32 - int blocking = (c->flags & REDIS_BLOCK); + int blocking = (c->flags & VALKEY_BLOCK); struct sockaddr_un *sa; long timeout_msec = -1; - if (redisCreateSocket(c,AF_UNIX) < 0) - return REDIS_ERR; - if (redisSetBlocking(c,0) != REDIS_OK) - return REDIS_ERR; + if (valkeyCreateSocket(c,AF_UNIX) < 0) + return VALKEY_ERR; + if (valkeySetBlocking(c,0) != VALKEY_OK) + return VALKEY_ERR; - c->connection_type = REDIS_CONN_UNIX; + c->connection_type = VALKEY_CONN_UNIX; if (c->unix_sock.path != path) { - hi_free(c->unix_sock.path); + vk_free(c->unix_sock.path); - c->unix_sock.path = hi_strdup(path); + c->unix_sock.path = vk_strdup(path); if (c->unix_sock.path == NULL) goto oom; } if (timeout) { - if (redisContextUpdateConnectTimeout(c, timeout) == REDIS_ERR) + if (valkeyContextUpdateConnectTimeout(c, timeout) == VALKEY_ERR) goto oom; } else { - hi_free(c->connect_timeout); + vk_free(c->connect_timeout); c->connect_timeout = NULL; } - if (redisContextTimeoutMsec(c,&timeout_msec) != REDIS_OK) - return REDIS_ERR; + if (valkeyContextTimeoutMsec(c,&timeout_msec) != VALKEY_OK) + return VALKEY_ERR; /* Don't leak sockaddr if we're reconnecting */ - if (c->saddr) hi_free(c->saddr); + if (c->saddr) vk_free(c->saddr); - sa = (struct sockaddr_un*)(c->saddr = hi_malloc(sizeof(struct sockaddr_un))); + sa = (struct sockaddr_un*)(c->saddr = vk_malloc(sizeof(struct sockaddr_un))); if (sa == NULL) goto oom; @@ -671,24 +671,24 @@ int redisContextConnectUnix(redisContext *c, const char *path, const struct time if (errno == EINPROGRESS && !blocking) { /* This is ok. */ } else { - if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) - return REDIS_ERR; + if (valkeyContextWaitReady(c,timeout_msec) != VALKEY_OK) + return VALKEY_ERR; } } /* Reset socket to be blocking after connect(2). */ - if (blocking && redisSetBlocking(c,1) != REDIS_OK) - return REDIS_ERR; + if (blocking && valkeySetBlocking(c,1) != VALKEY_OK) + return VALKEY_ERR; - c->flags |= REDIS_CONNECTED; - return REDIS_OK; + c->flags |= VALKEY_CONNECTED; + return VALKEY_OK; #else /* We currently do not support Unix sockets for Windows. */ /* TODO(m): https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ */ errno = EPROTONOSUPPORT; - return REDIS_ERR; + return VALKEY_ERR; #endif /* _WIN32 */ oom: - __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); - return REDIS_ERR; + valkeySetError(c, VALKEY_ERR_OOM, "Out of memory"); + return VALKEY_ERR; } diff --git a/libvalkey/net.h b/src/net.h similarity index 70% rename from libvalkey/net.h rename to src/net.h index e15d4626..2ca73725 100644 --- a/libvalkey/net.h +++ b/src/net.h @@ -32,26 +32,26 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __NET_H -#define __NET_H +#ifndef VALKEY_NET_H +#define VALKEY_NET_H -#include "hiredis.h" +#include "valkey.h" -void redisNetClose(redisContext *c); -ssize_t redisNetRead(redisContext *c, char *buf, size_t bufcap); -ssize_t redisNetWrite(redisContext *c); +void valkeyNetClose(valkeyContext *c); +ssize_t valkeyNetRead(valkeyContext *c, char *buf, size_t bufcap); +ssize_t valkeyNetWrite(valkeyContext *c); -int redisCheckSocketError(redisContext *c); -int redisContextSetTimeout(redisContext *c, const struct timeval tv); -int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout); -int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, +int valkeyCheckSocketError(valkeyContext *c); +int valkeyContextSetTimeout(valkeyContext *c, const struct timeval tv); +int valkeyContextConnectTcp(valkeyContext *c, const char *addr, int port, const struct timeval *timeout); +int valkeyContextConnectBindTcp(valkeyContext *c, const char *addr, int port, const struct timeval *timeout, const char *source_addr); -int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout); -int redisKeepAlive(redisContext *c, int interval); -int redisCheckConnectDone(redisContext *c, int *completed); +int valkeyContextConnectUnix(valkeyContext *c, const char *path, const struct timeval *timeout); +int valkeyKeepAlive(valkeyContext *c, int interval); +int valkeyCheckConnectDone(valkeyContext *c, int *completed); -int redisSetTcpNoDelay(redisContext *c); -int redisContextSetTcpUserTimeout(redisContext *c, unsigned int timeout); +int valkeySetTcpNoDelay(valkeyContext *c); +int valkeyContextSetTcpUserTimeout(valkeyContext *c, unsigned int timeout); #endif diff --git a/libvalkey/read.c b/src/read.c similarity index 71% rename from libvalkey/read.c rename to src/read.c index ebbe02c5..07f97ed1 100644 --- a/libvalkey/read.c +++ b/src/read.c @@ -48,9 +48,9 @@ #include "win32.h" /* Initial size of our nested reply stack and how much we grow it when needd */ -#define REDIS_READER_STACK_SIZE 9 +#define VALKEY_READER_STACK_SIZE 9 -static void __redisReaderSetError(redisReader *r, int type, const char *str) { +static void valkeyReaderSetError(valkeyReader *r, int type, const char *str) { size_t len; if (r->reply != NULL && r->fn && r->fn->freeObject) { @@ -98,20 +98,20 @@ static size_t chrtos(char *buf, size_t size, char byte) { return len; } -static void __redisReaderSetErrorProtocolByte(redisReader *r, char byte) { +static void valkeyReaderSetErrorProtocolByte(valkeyReader *r, char byte) { char cbuf[8], sbuf[128]; chrtos(cbuf,sizeof(cbuf),byte); snprintf(sbuf,sizeof(sbuf), "Protocol error, got %s as reply type byte", cbuf); - __redisReaderSetError(r,REDIS_ERR_PROTOCOL,sbuf); + valkeyReaderSetError(r,VALKEY_ERR_PROTOCOL,sbuf); } -static void __redisReaderSetErrorOOM(redisReader *r) { - __redisReaderSetError(r,REDIS_ERR_OOM,"Out of memory"); +static void valkeyReaderSetErrorOOM(valkeyReader *r) { + valkeyReaderSetError(r,VALKEY_ERR_OOM,"Out of memory"); } -static char *readBytes(redisReader *r, unsigned int bytes) { +static char *readBytes(valkeyReader *r, unsigned int bytes) { char *p; if (r->len-r->pos >= bytes) { p = r->buf+r->pos; @@ -147,8 +147,8 @@ static char *seekNewline(char *s, size_t len) { return ret; } -/* Convert a string into a long long. Returns REDIS_OK if the string could be - * parsed into a (non-overflowing) long long, REDIS_ERR otherwise. The value +/* Convert a string into a long long. Returns VALKEY_OK if the string could be + * parsed into a (non-overflowing) long long, VALKEY_ERR otherwise. The value * will be set to the parsed value when appropriate. * * Note that this function demands that the string strictly represents @@ -166,12 +166,12 @@ static int string2ll(const char *s, size_t slen, long long *value) { unsigned long long v; if (plen == slen) - return REDIS_ERR; + return VALKEY_ERR; /* Special case: first and only digit is 0. */ if (slen == 1 && p[0] == '0') { if (value != NULL) *value = 0; - return REDIS_OK; + return VALKEY_OK; } if (p[0] == '-') { @@ -180,7 +180,7 @@ static int string2ll(const char *s, size_t slen, long long *value) { /* Abort on only a negative sign. */ if (plen == slen) - return REDIS_ERR; + return VALKEY_ERR; } /* First digit should be 1-9, otherwise the string should just be 0. */ @@ -189,18 +189,18 @@ static int string2ll(const char *s, size_t slen, long long *value) { p++; plen++; } else if (p[0] == '0' && slen == 1) { *value = 0; - return REDIS_OK; + return VALKEY_OK; } else { - return REDIS_ERR; + return VALKEY_ERR; } while (plen < slen && p[0] >= '0' && p[0] <= '9') { if (v > (ULLONG_MAX / 10)) /* Overflow. */ - return REDIS_ERR; + return VALKEY_ERR; v *= 10; if (v > (ULLONG_MAX - (p[0]-'0'))) /* Overflow. */ - return REDIS_ERR; + return VALKEY_ERR; v += p[0]-'0'; p++; plen++; @@ -208,21 +208,21 @@ static int string2ll(const char *s, size_t slen, long long *value) { /* Return if not all bytes were used. */ if (plen < slen) - return REDIS_ERR; + return VALKEY_ERR; if (negative) { if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */ - return REDIS_ERR; + return VALKEY_ERR; if (value != NULL) *value = -v; } else { if (v > LLONG_MAX) /* Overflow. */ - return REDIS_ERR; + return VALKEY_ERR; if (value != NULL) *value = v; } - return REDIS_OK; + return VALKEY_OK; } -static char *readLine(redisReader *r, int *_len) { +static char *readLine(valkeyReader *r, int *_len) { char *p, *s; int len; @@ -237,8 +237,8 @@ static char *readLine(redisReader *r, int *_len) { return NULL; } -static void moveToNextTask(redisReader *r) { - redisReadTask *cur, *prv; +static void moveToNextTask(valkeyReader *r) { + valkeyReadTask *cur, *prv; while (r->ridx >= 0) { /* Return a.s.a.p. when the stack is now empty. */ if (r->ridx == 0) { @@ -248,11 +248,11 @@ static void moveToNextTask(redisReader *r) { cur = r->task[r->ridx]; prv = r->task[r->ridx-1]; - assert(prv->type == REDIS_REPLY_ARRAY || - prv->type == REDIS_REPLY_MAP || - prv->type == REDIS_REPLY_ATTR || - prv->type == REDIS_REPLY_SET || - prv->type == REDIS_REPLY_PUSH); + assert(prv->type == VALKEY_REPLY_ARRAY || + prv->type == VALKEY_REPLY_MAP || + prv->type == VALKEY_REPLY_ATTR || + prv->type == VALKEY_REPLY_SET || + prv->type == VALKEY_REPLY_PUSH); if (cur->idx == prv->elements-1) { r->ridx--; } else { @@ -266,35 +266,35 @@ static void moveToNextTask(redisReader *r) { } } -static int processLineItem(redisReader *r) { - redisReadTask *cur = r->task[r->ridx]; +static int processLineItem(valkeyReader *r) { + valkeyReadTask *cur = r->task[r->ridx]; void *obj; char *p; int len; if ((p = readLine(r,&len)) != NULL) { - if (cur->type == REDIS_REPLY_INTEGER) { + if (cur->type == VALKEY_REPLY_INTEGER) { long long v; - if (string2ll(p, len, &v) == REDIS_ERR) { - __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + if (string2ll(p, len, &v) == VALKEY_ERR) { + valkeyReaderSetError(r,VALKEY_ERR_PROTOCOL, "Bad integer value"); - return REDIS_ERR; + return VALKEY_ERR; } if (r->fn && r->fn->createInteger) { obj = r->fn->createInteger(cur,v); } else { - obj = (void*)REDIS_REPLY_INTEGER; + obj = (void*)VALKEY_REPLY_INTEGER; } - } else if (cur->type == REDIS_REPLY_DOUBLE) { + } else if (cur->type == VALKEY_REPLY_DOUBLE) { char buf[326], *eptr; double d; if ((size_t)len >= sizeof(buf)) { - __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + valkeyReaderSetError(r,VALKEY_ERR_PROTOCOL, "Double value is too large"); - return REDIS_ERR; + return VALKEY_ERR; } memcpy(buf,p,len); @@ -314,65 +314,65 @@ static int processLineItem(redisReader *r) { * etc. We explicity handle our two allowed infinite cases and NaN * above, so strtod() should only result in finite values. */ if (buf[0] == '\0' || eptr != &buf[len] || !isfinite(d)) { - __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + valkeyReaderSetError(r,VALKEY_ERR_PROTOCOL, "Bad double value"); - return REDIS_ERR; + return VALKEY_ERR; } } if (r->fn && r->fn->createDouble) { obj = r->fn->createDouble(cur,d,buf,len); } else { - obj = (void*)REDIS_REPLY_DOUBLE; + obj = (void*)VALKEY_REPLY_DOUBLE; } - } else if (cur->type == REDIS_REPLY_NIL) { + } else if (cur->type == VALKEY_REPLY_NIL) { if (len != 0) { - __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + valkeyReaderSetError(r,VALKEY_ERR_PROTOCOL, "Bad nil value"); - return REDIS_ERR; + return VALKEY_ERR; } if (r->fn && r->fn->createNil) obj = r->fn->createNil(cur); else - obj = (void*)REDIS_REPLY_NIL; - } else if (cur->type == REDIS_REPLY_BOOL) { + obj = (void*)VALKEY_REPLY_NIL; + } else if (cur->type == VALKEY_REPLY_BOOL) { int bval; if (len != 1 || !strchr("tTfF", p[0])) { - __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + valkeyReaderSetError(r,VALKEY_ERR_PROTOCOL, "Bad bool value"); - return REDIS_ERR; + return VALKEY_ERR; } bval = p[0] == 't' || p[0] == 'T'; if (r->fn && r->fn->createBool) obj = r->fn->createBool(cur,bval); else - obj = (void*)REDIS_REPLY_BOOL; - } else if (cur->type == REDIS_REPLY_BIGNUM) { + obj = (void*)VALKEY_REPLY_BOOL; + } else if (cur->type == VALKEY_REPLY_BIGNUM) { /* Ensure all characters are decimal digits (with possible leading * minus sign). */ for (int i = 0; i < len; i++) { /* XXX Consider: Allow leading '+'? Error on leading '0's? */ if (i == 0 && p[0] == '-') continue; if (p[i] < '0' || p[i] > '9') { - __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + valkeyReaderSetError(r,VALKEY_ERR_PROTOCOL, "Bad bignum value"); - return REDIS_ERR; + return VALKEY_ERR; } } if (r->fn && r->fn->createString) obj = r->fn->createString(cur,p,len); else - obj = (void*)REDIS_REPLY_BIGNUM; + obj = (void*)VALKEY_REPLY_BIGNUM; } else { /* Type will be error or status. */ for (int i = 0; i < len; i++) { if (p[i] == '\r' || p[i] == '\n') { - __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + valkeyReaderSetError(r,VALKEY_ERR_PROTOCOL, "Bad simple string value"); - return REDIS_ERR; + return VALKEY_ERR; } } if (r->fn && r->fn->createString) @@ -382,21 +382,21 @@ static int processLineItem(redisReader *r) { } if (obj == NULL) { - __redisReaderSetErrorOOM(r); - return REDIS_ERR; + valkeyReaderSetErrorOOM(r); + return VALKEY_ERR; } /* Set reply if this is the root object. */ if (r->ridx == 0) r->reply = obj; moveToNextTask(r); - return REDIS_OK; + return VALKEY_OK; } - return REDIS_ERR; + return VALKEY_ERR; } -static int processBulkItem(redisReader *r) { - redisReadTask *cur = r->task[r->ridx]; +static int processBulkItem(valkeyReader *r) { + valkeyReadTask *cur = r->task[r->ridx]; void *obj = NULL; char *p, *s; long long len; @@ -409,16 +409,16 @@ static int processBulkItem(redisReader *r) { p = r->buf+r->pos; bytelen = s-(r->buf+r->pos)+2; /* include \r\n */ - if (string2ll(p, bytelen - 2, &len) == REDIS_ERR) { - __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + if (string2ll(p, bytelen - 2, &len) == VALKEY_ERR) { + valkeyReaderSetError(r,VALKEY_ERR_PROTOCOL, "Bad bulk string length"); - return REDIS_ERR; + return VALKEY_ERR; } if (len < -1 || (LLONG_MAX > SIZE_MAX && len > (long long)SIZE_MAX)) { - __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + valkeyReaderSetError(r,VALKEY_ERR_PROTOCOL, "Bulk string length out of range"); - return REDIS_ERR; + return VALKEY_ERR; } if (len == -1) { @@ -426,19 +426,19 @@ static int processBulkItem(redisReader *r) { if (r->fn && r->fn->createNil) obj = r->fn->createNil(cur); else - obj = (void*)REDIS_REPLY_NIL; + obj = (void*)VALKEY_REPLY_NIL; success = 1; } else { /* Only continue when the buffer contains the entire bulk item. */ bytelen += len+2; /* include \r\n */ if (r->pos+bytelen <= r->len) { - if ((cur->type == REDIS_REPLY_VERB && len < 4) || - (cur->type == REDIS_REPLY_VERB && s[5] != ':')) + if ((cur->type == VALKEY_REPLY_VERB && len < 4) || + (cur->type == VALKEY_REPLY_VERB && s[5] != ':')) { - __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + valkeyReaderSetError(r,VALKEY_ERR_PROTOCOL, "Verbatim string 4 bytes of content type are " "missing or incorrectly encoded."); - return REDIS_ERR; + return VALKEY_ERR; } if (r->fn && r->fn->createString) obj = r->fn->createString(cur,s+2,len); @@ -451,8 +451,8 @@ static int processBulkItem(redisReader *r) { /* Proceed when obj was created. */ if (success) { if (obj == NULL) { - __redisReaderSetErrorOOM(r); - return REDIS_ERR; + valkeyReaderSetErrorOOM(r); + return VALKEY_ERR; } r->pos += bytelen; @@ -460,20 +460,20 @@ static int processBulkItem(redisReader *r) { /* Set reply if this is the root object. */ if (r->ridx == 0) r->reply = obj; moveToNextTask(r); - return REDIS_OK; + return VALKEY_OK; } } - return REDIS_ERR; + return VALKEY_ERR; } -static int redisReaderGrow(redisReader *r) { - redisReadTask **aux; +static int valkeyReaderGrow(valkeyReader *r) { + valkeyReadTask **aux; int newlen; /* Grow our stack size */ - newlen = r->tasks + REDIS_READER_STACK_SIZE; - aux = hi_realloc(r->task, sizeof(*r->task) * newlen); + newlen = r->tasks + VALKEY_READER_STACK_SIZE; + aux = vk_realloc(r->task, sizeof(*r->task) * newlen); if (aux == NULL) goto oom; @@ -481,35 +481,35 @@ static int redisReaderGrow(redisReader *r) { /* Allocate new tasks */ for (; r->tasks < newlen; r->tasks++) { - r->task[r->tasks] = hi_calloc(1, sizeof(**r->task)); + r->task[r->tasks] = vk_calloc(1, sizeof(**r->task)); if (r->task[r->tasks] == NULL) goto oom; } - return REDIS_OK; + return VALKEY_OK; oom: - __redisReaderSetErrorOOM(r); - return REDIS_ERR; + valkeyReaderSetErrorOOM(r); + return VALKEY_ERR; } /* Process the array, map and set types. */ -static int processAggregateItem(redisReader *r) { - redisReadTask *cur = r->task[r->ridx]; +static int processAggregateItem(valkeyReader *r) { + valkeyReadTask *cur = r->task[r->ridx]; void *obj; char *p; long long elements; int root = 0, len; if (r->ridx == r->tasks - 1) { - if (redisReaderGrow(r) == REDIS_ERR) - return REDIS_ERR; + if (valkeyReaderGrow(r) == VALKEY_ERR) + return VALKEY_ERR; } if ((p = readLine(r,&len)) != NULL) { - if (string2ll(p, len, &elements) == REDIS_ERR) { - __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + if (string2ll(p, len, &elements) == VALKEY_ERR) { + valkeyReaderSetError(r,VALKEY_ERR_PROTOCOL, "Bad multi-bulk length"); - return REDIS_ERR; + return VALKEY_ERR; } root = (r->ridx == 0); @@ -517,25 +517,25 @@ static int processAggregateItem(redisReader *r) { if (elements < -1 || (LLONG_MAX > SIZE_MAX && elements > SIZE_MAX) || (r->maxelements > 0 && elements > r->maxelements)) { - __redisReaderSetError(r,REDIS_ERR_PROTOCOL, + valkeyReaderSetError(r,VALKEY_ERR_PROTOCOL, "Multi-bulk length out of range"); - return REDIS_ERR; + return VALKEY_ERR; } if (elements == -1) { if (r->fn && r->fn->createNil) obj = r->fn->createNil(cur); else - obj = (void*)REDIS_REPLY_NIL; + obj = (void*)VALKEY_REPLY_NIL; if (obj == NULL) { - __redisReaderSetErrorOOM(r); - return REDIS_ERR; + valkeyReaderSetErrorOOM(r); + return VALKEY_ERR; } moveToNextTask(r); } else { - if (cur->type == REDIS_REPLY_MAP || cur->type == REDIS_REPLY_ATTR) elements *= 2; + if (cur->type == VALKEY_REPLY_MAP || cur->type == VALKEY_REPLY_ATTR) elements *= 2; if (r->fn && r->fn->createArray) obj = r->fn->createArray(cur,elements); @@ -543,8 +543,8 @@ static int processAggregateItem(redisReader *r) { obj = (void*)(uintptr_t)cur->type; if (obj == NULL) { - __redisReaderSetErrorOOM(r); - return REDIS_ERR; + valkeyReaderSetErrorOOM(r); + return VALKEY_ERR; } /* Modify task stack when there are more than 0 elements. */ @@ -565,14 +565,14 @@ static int processAggregateItem(redisReader *r) { /* Set reply if this is the root object. */ if (root) r->reply = obj; - return REDIS_OK; + return VALKEY_OK; } - return REDIS_ERR; + return VALKEY_ERR; } -static int processItem(redisReader *r) { - redisReadTask *cur = r->task[r->ridx]; +static int processItem(valkeyReader *r) { + valkeyReadTask *cur = r->task[r->ridx]; char *p; /* check if we need to read type */ @@ -580,86 +580,86 @@ static int processItem(redisReader *r) { if ((p = readBytes(r,1)) != NULL) { switch (p[0]) { case '-': - cur->type = REDIS_REPLY_ERROR; + cur->type = VALKEY_REPLY_ERROR; break; case '+': - cur->type = REDIS_REPLY_STATUS; + cur->type = VALKEY_REPLY_STATUS; break; case ':': - cur->type = REDIS_REPLY_INTEGER; + cur->type = VALKEY_REPLY_INTEGER; break; case ',': - cur->type = REDIS_REPLY_DOUBLE; + cur->type = VALKEY_REPLY_DOUBLE; break; case '_': - cur->type = REDIS_REPLY_NIL; + cur->type = VALKEY_REPLY_NIL; break; case '$': - cur->type = REDIS_REPLY_STRING; + cur->type = VALKEY_REPLY_STRING; break; case '*': - cur->type = REDIS_REPLY_ARRAY; + cur->type = VALKEY_REPLY_ARRAY; break; case '%': - cur->type = REDIS_REPLY_MAP; + cur->type = VALKEY_REPLY_MAP; break; case '|': - cur->type = REDIS_REPLY_ATTR; + cur->type = VALKEY_REPLY_ATTR; break; case '~': - cur->type = REDIS_REPLY_SET; + cur->type = VALKEY_REPLY_SET; break; case '#': - cur->type = REDIS_REPLY_BOOL; + cur->type = VALKEY_REPLY_BOOL; break; case '=': - cur->type = REDIS_REPLY_VERB; + cur->type = VALKEY_REPLY_VERB; break; case '>': - cur->type = REDIS_REPLY_PUSH; + cur->type = VALKEY_REPLY_PUSH; break; case '(': - cur->type = REDIS_REPLY_BIGNUM; + cur->type = VALKEY_REPLY_BIGNUM; break; default: - __redisReaderSetErrorProtocolByte(r,*p); - return REDIS_ERR; + valkeyReaderSetErrorProtocolByte(r,*p); + return VALKEY_ERR; } } else { /* could not consume 1 byte */ - return REDIS_ERR; + return VALKEY_ERR; } } /* process typed item */ switch(cur->type) { - case REDIS_REPLY_ERROR: - case REDIS_REPLY_STATUS: - case REDIS_REPLY_INTEGER: - case REDIS_REPLY_DOUBLE: - case REDIS_REPLY_NIL: - case REDIS_REPLY_BOOL: - case REDIS_REPLY_BIGNUM: + case VALKEY_REPLY_ERROR: + case VALKEY_REPLY_STATUS: + case VALKEY_REPLY_INTEGER: + case VALKEY_REPLY_DOUBLE: + case VALKEY_REPLY_NIL: + case VALKEY_REPLY_BOOL: + case VALKEY_REPLY_BIGNUM: return processLineItem(r); - case REDIS_REPLY_STRING: - case REDIS_REPLY_VERB: + case VALKEY_REPLY_STRING: + case VALKEY_REPLY_VERB: return processBulkItem(r); - case REDIS_REPLY_ARRAY: - case REDIS_REPLY_MAP: - case REDIS_REPLY_ATTR: - case REDIS_REPLY_SET: - case REDIS_REPLY_PUSH: + case VALKEY_REPLY_ARRAY: + case VALKEY_REPLY_MAP: + case VALKEY_REPLY_ATTR: + case VALKEY_REPLY_SET: + case VALKEY_REPLY_PUSH: return processAggregateItem(r); default: assert(NULL); - return REDIS_ERR; /* Avoid warning. */ + return VALKEY_ERR; /* Avoid warning. */ } } -redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn) { - redisReader *r; +valkeyReader *valkeyReaderCreateWithFunctions(valkeyReplyObjectFunctions *fn) { + valkeyReader *r; - r = hi_calloc(1,sizeof(redisReader)); + r = vk_calloc(1,sizeof(valkeyReader)); if (r == NULL) return NULL; @@ -667,28 +667,28 @@ redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn) { if (r->buf == NULL) goto oom; - r->task = hi_calloc(REDIS_READER_STACK_SIZE, sizeof(*r->task)); + r->task = vk_calloc(VALKEY_READER_STACK_SIZE, sizeof(*r->task)); if (r->task == NULL) goto oom; - for (; r->tasks < REDIS_READER_STACK_SIZE; r->tasks++) { - r->task[r->tasks] = hi_calloc(1, sizeof(**r->task)); + for (; r->tasks < VALKEY_READER_STACK_SIZE; r->tasks++) { + r->task[r->tasks] = vk_calloc(1, sizeof(**r->task)); if (r->task[r->tasks] == NULL) goto oom; } r->fn = fn; - r->maxbuf = REDIS_READER_MAX_BUF; - r->maxelements = REDIS_READER_MAX_ARRAY_ELEMENTS; + r->maxbuf = VALKEY_READER_MAX_BUF; + r->maxelements = VALKEY_READER_MAX_ARRAY_ELEMENTS; r->ridx = -1; return r; oom: - redisReaderFree(r); + valkeyReaderFree(r); return NULL; } -void redisReaderFree(redisReader *r) { +void valkeyReaderFree(valkeyReader *r) { if (r == NULL) return; @@ -698,22 +698,22 @@ void redisReaderFree(redisReader *r) { if (r->task) { /* We know r->task[i] is allocated if i < r->tasks */ for (int i = 0; i < r->tasks; i++) { - hi_free(r->task[i]); + vk_free(r->task[i]); } - hi_free(r->task); + vk_free(r->task); } sdsfree(r->buf); - hi_free(r); + vk_free(r); } -int redisReaderFeed(redisReader *r, const char *buf, size_t len) { +int valkeyReaderFeed(valkeyReader *r, const char *buf, size_t len) { sds newbuf; /* Return early when this reader is in an erroneous state. */ if (r->err) - return REDIS_ERR; + return VALKEY_ERR; /* Copy the provided buffer. */ if (buf != NULL && len >= 1) { @@ -733,24 +733,24 @@ int redisReaderFeed(redisReader *r, const char *buf, size_t len) { r->len = sdslen(r->buf); } - return REDIS_OK; + return VALKEY_OK; oom: - __redisReaderSetErrorOOM(r); - return REDIS_ERR; + valkeyReaderSetErrorOOM(r); + return VALKEY_ERR; } -int redisReaderGetReply(redisReader *r, void **reply) { +int valkeyReaderGetReply(valkeyReader *r, void **reply) { /* Default target pointer to NULL. */ if (reply != NULL) *reply = NULL; /* Return early when this reader is in an erroneous state. */ if (r->err) - return REDIS_ERR; + return VALKEY_ERR; /* When the buffer is empty, there will never be a reply. */ if (r->len == 0) - return REDIS_OK; + return VALKEY_OK; /* Set first item to process when the stack is empty. */ if (r->ridx == -1) { @@ -765,17 +765,17 @@ int redisReaderGetReply(redisReader *r, void **reply) { /* Process items in reply. */ while (r->ridx >= 0) - if (processItem(r) != REDIS_OK) + if (processItem(r) != VALKEY_OK) break; /* Return ASAP when an error occurred. */ if (r->err) - return REDIS_ERR; + return VALKEY_ERR; /* Discard part of the buffer when we've consumed at least 1k, to avoid * doing unnecessary calls to memmove() in sds.c. */ if (r->pos >= 1024) { - if (sdsrange(r->buf,r->pos,-1) < 0) return REDIS_ERR; + if (sdsrange(r->buf,r->pos,-1) < 0) return VALKEY_ERR; r->pos = 0; r->len = sdslen(r->buf); } @@ -789,5 +789,5 @@ int redisReaderGetReply(redisReader *r, void **reply) { } r->reply = NULL; } - return REDIS_OK; + return VALKEY_OK; } diff --git a/libvalkey/read.h b/src/read.h similarity index 58% rename from libvalkey/read.h rename to src/read.h index 2d74d77a..8fb22832 100644 --- a/libvalkey/read.h +++ b/src/read.h @@ -30,69 +30,69 @@ */ -#ifndef __HIREDIS_READ_H -#define __HIREDIS_READ_H +#ifndef VALKEY_READ_H +#define VALKEY_READ_H #include /* for size_t */ -#define REDIS_ERR -1 -#define REDIS_OK 0 +#define VALKEY_ERR -1 +#define VALKEY_OK 0 /* When an error occurs, the err flag in a context is set to hold the type of - * error that occurred. REDIS_ERR_IO means there was an I/O error and you + * error that occurred. VALKEY_ERR_IO means there was an I/O error and you * should use the "errno" variable to find out what is wrong. * For other values, the "errstr" field will hold a description. */ -#define REDIS_ERR_IO 1 /* Error in read or write */ -#define REDIS_ERR_EOF 3 /* End of file */ -#define REDIS_ERR_PROTOCOL 4 /* Protocol error */ -#define REDIS_ERR_OOM 5 /* Out of memory */ -#define REDIS_ERR_TIMEOUT 6 /* Timed out */ -#define REDIS_ERR_OTHER 2 /* Everything else... */ - -#define REDIS_REPLY_STRING 1 -#define REDIS_REPLY_ARRAY 2 -#define REDIS_REPLY_INTEGER 3 -#define REDIS_REPLY_NIL 4 -#define REDIS_REPLY_STATUS 5 -#define REDIS_REPLY_ERROR 6 -#define REDIS_REPLY_DOUBLE 7 -#define REDIS_REPLY_BOOL 8 -#define REDIS_REPLY_MAP 9 -#define REDIS_REPLY_SET 10 -#define REDIS_REPLY_ATTR 11 -#define REDIS_REPLY_PUSH 12 -#define REDIS_REPLY_BIGNUM 13 -#define REDIS_REPLY_VERB 14 +#define VALKEY_ERR_IO 1 /* Error in read or write */ +#define VALKEY_ERR_EOF 3 /* End of file */ +#define VALKEY_ERR_PROTOCOL 4 /* Protocol error */ +#define VALKEY_ERR_OOM 5 /* Out of memory */ +#define VALKEY_ERR_TIMEOUT 6 /* Timed out */ +#define VALKEY_ERR_OTHER 2 /* Everything else... */ + +#define VALKEY_REPLY_STRING 1 +#define VALKEY_REPLY_ARRAY 2 +#define VALKEY_REPLY_INTEGER 3 +#define VALKEY_REPLY_NIL 4 +#define VALKEY_REPLY_STATUS 5 +#define VALKEY_REPLY_ERROR 6 +#define VALKEY_REPLY_DOUBLE 7 +#define VALKEY_REPLY_BOOL 8 +#define VALKEY_REPLY_MAP 9 +#define VALKEY_REPLY_SET 10 +#define VALKEY_REPLY_ATTR 11 +#define VALKEY_REPLY_PUSH 12 +#define VALKEY_REPLY_BIGNUM 13 +#define VALKEY_REPLY_VERB 14 /* Default max unused reader buffer. */ -#define REDIS_READER_MAX_BUF (1024*16) +#define VALKEY_READER_MAX_BUF (1024*16) /* Default multi-bulk element limit */ -#define REDIS_READER_MAX_ARRAY_ELEMENTS ((1LL<<32) - 1) +#define VALKEY_READER_MAX_ARRAY_ELEMENTS ((1LL<<32) - 1) #ifdef __cplusplus extern "C" { #endif -typedef struct redisReadTask { +typedef struct valkeyReadTask { int type; long long elements; /* number of elements in multibulk container */ int idx; /* index in parent (array) object */ void *obj; /* holds user-generated value for a read task */ - struct redisReadTask *parent; /* parent task */ + struct valkeyReadTask *parent; /* parent task */ void *privdata; /* user-settable arbitrary field */ -} redisReadTask; - -typedef struct redisReplyObjectFunctions { - void *(*createString)(const redisReadTask*, char*, size_t); - void *(*createArray)(const redisReadTask*, size_t); - void *(*createInteger)(const redisReadTask*, long long); - void *(*createDouble)(const redisReadTask*, double, char*, size_t); - void *(*createNil)(const redisReadTask*); - void *(*createBool)(const redisReadTask*, int); +} valkeyReadTask; + +typedef struct valkeyReplyObjectFunctions { + void *(*createString)(const valkeyReadTask*, char*, size_t); + void *(*createArray)(const valkeyReadTask*, size_t); + void *(*createInteger)(const valkeyReadTask*, long long); + void *(*createDouble)(const valkeyReadTask*, double, char*, size_t); + void *(*createNil)(const valkeyReadTask*); + void *(*createBool)(const valkeyReadTask*, int); void (*freeObject)(void*); -} redisReplyObjectFunctions; +} valkeyReplyObjectFunctions; -typedef struct redisReader { +typedef struct valkeyReader { int err; /* Error flags, 0 when there is no error */ char errstr[128]; /* String representation of error when applicable */ @@ -102,25 +102,25 @@ typedef struct redisReader { size_t maxbuf; /* Max length of unused buffer */ long long maxelements; /* Max multi-bulk elements */ - redisReadTask **task; + valkeyReadTask **task; int tasks; int ridx; /* Index of current read task */ void *reply; /* Temporary reply pointer */ - redisReplyObjectFunctions *fn; + valkeyReplyObjectFunctions *fn; void *privdata; -} redisReader; +} valkeyReader; /* Public API for the protocol parser. */ -redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn); -void redisReaderFree(redisReader *r); -int redisReaderFeed(redisReader *r, const char *buf, size_t len); -int redisReaderGetReply(redisReader *r, void **reply); - -#define redisReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p)) -#define redisReaderGetObject(_r) (((redisReader*)(_r))->reply) -#define redisReaderGetError(_r) (((redisReader*)(_r))->errstr) +valkeyReader *valkeyReaderCreateWithFunctions(valkeyReplyObjectFunctions *fn); +void valkeyReaderFree(valkeyReader *r); +int valkeyReaderFeed(valkeyReader *r, const char *buf, size_t len); +int valkeyReaderGetReply(valkeyReader *r, void **reply); + +#define valkeyReaderSetPrivdata(_r, _p) (int)(((valkeyReader*)(_r))->privdata = (_p)) +#define valkeyReaderGetObject(_r) (((valkeyReader*)(_r))->reply) +#define valkeyReaderGetError(_r) (((valkeyReader*)(_r))->errstr) #ifdef __cplusplus } diff --git a/libvalkey/sds.c b/src/sds.c similarity index 100% rename from libvalkey/sds.c rename to src/sds.c diff --git a/libvalkey/sds.h b/src/sds.h similarity index 99% rename from libvalkey/sds.h rename to src/sds.h index d9b67610..5ba04f62 100644 --- a/libvalkey/sds.h +++ b/src/sds.h @@ -273,7 +273,7 @@ void *sds_malloc(size_t size); void *sds_realloc(void *ptr, size_t size); void sds_free(void *ptr); -#ifdef REDIS_TEST +#ifdef VALKEY_TEST int sdsTest(int argc, char *argv[]); #endif diff --git a/libvalkey/sdsalloc.h b/src/sdsalloc.h similarity index 96% rename from libvalkey/sdsalloc.h rename to src/sdsalloc.h index 5538dd94..8da162a3 100644 --- a/libvalkey/sdsalloc.h +++ b/src/sdsalloc.h @@ -39,6 +39,6 @@ #include "alloc.h" -#define s_malloc hi_malloc -#define s_realloc hi_realloc -#define s_free hi_free +#define s_malloc vk_malloc +#define s_realloc vk_realloc +#define s_free vk_free diff --git a/libvalkey/sockcompat.c b/src/sockcompat.c similarity index 98% rename from libvalkey/sockcompat.c rename to src/sockcompat.c index 378745f4..20ad8c60 100644 --- a/libvalkey/sockcompat.c +++ b/src/sockcompat.c @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define REDIS_SOCKCOMPAT_IMPLEMENTATION +#define VALKEY_SOCKCOMPAT_IMPLEMENTATION #include "sockcompat.h" #ifdef _WIN32 @@ -261,7 +261,7 @@ int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout) { return ret != SOCKET_ERROR ? ret : -1; } -int win32_redisKeepAlive(SOCKET sockfd, int interval_ms) { +int win32_valkeyKeepAlive(SOCKET sockfd, int interval_ms) { struct tcp_keepalive cfg; DWORD bytes_in; int res; diff --git a/libvalkey/sockcompat.h b/src/sockcompat.h similarity index 96% rename from libvalkey/sockcompat.h rename to src/sockcompat.h index 6ca5d9fc..5298f152 100644 --- a/libvalkey/sockcompat.h +++ b/src/sockcompat.h @@ -72,9 +72,9 @@ ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags); typedef ULONG nfds_t; int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout); -int win32_redisKeepAlive(SOCKET sockfd, int interval_ms); +int win32_valkeyKeepAlive(SOCKET sockfd, int interval_ms); -#ifndef REDIS_SOCKCOMPAT_IMPLEMENTATION +#ifndef VALKEY_SOCKCOMPAT_IMPLEMENTATION #define getaddrinfo(node, service, hints, res) win32_getaddrinfo(node, service, hints, res) #undef gai_strerror #define gai_strerror(errcode) win32_gai_strerror(errcode) @@ -89,7 +89,7 @@ int win32_redisKeepAlive(SOCKET sockfd, int interval_ms); #define recv(sockfd, buf, len, flags) win32_recv(sockfd, buf, len, flags) #define send(sockfd, buf, len, flags) win32_send(sockfd, buf, len, flags) #define poll(fds, nfds, timeout) win32_poll(fds, nfds, timeout) -#endif /* REDIS_SOCKCOMPAT_IMPLEMENTATION */ +#endif /* VALKEY_SOCKCOMPAT_IMPLEMENTATION */ #endif /* _WIN32 */ #endif /* __SOCKCOMPAT_H */ diff --git a/libvalkey/ssl.c b/src/ssl.c similarity index 69% rename from libvalkey/ssl.c rename to src/ssl.c index c2f6178a..89a441c9 100644 --- a/libvalkey/ssl.c +++ b/src/ssl.c @@ -30,7 +30,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "hiredis.h" +#include "valkey.h" #include "async.h" #include "net.h" @@ -57,14 +57,14 @@ #include "win32.h" #include "async_private.h" -#include "hiredis_ssl.h" +#include "valkey_ssl.h" #define OPENSSL_1_1_0 0x10100000L -void __redisSetError(redisContext *c, int type, const char *str); +void valkeySetError(valkeyContext *c, int type, const char *str); -struct redisSSLContext { - /* Associated OpenSSL SSL_CTX as created by redisCreateSSLContext() */ +struct valkeySSLContext { + /* Associated OpenSSL SSL_CTX as created by valkeyCreateSSLContext() */ SSL_CTX *ssl_ctx; /* Requested SNI, or NULL */ @@ -72,7 +72,7 @@ struct redisSSLContext { }; /* The SSL connection context is attached to SSL/TLS connections as a privdata. */ -typedef struct redisSSL { +typedef struct valkeySSL { /** * OpenSSL SSL object. */ @@ -92,10 +92,10 @@ typedef struct redisSSL { * should resume whenever a read takes place, if possible */ int pendingWrite; -} redisSSL; +} valkeySSL; /* Forward declaration */ -redisContextFuncs redisContextSSLFuncs; +valkeyContextFuncs valkeyContextSSLFuncs; /** * OpenSSL global initialization and locking handling callbacks. @@ -103,10 +103,10 @@ redisContextFuncs redisContextSSLFuncs; */ #if OPENSSL_VERSION_NUMBER < OPENSSL_1_1_0 -#define HIREDIS_USE_CRYPTO_LOCKS +#define VALKEY_USE_CRYPTO_LOCKS #endif -#ifdef HIREDIS_USE_CRYPTO_LOCKS +#ifdef VALKEY_USE_CRYPTO_LOCKS #ifdef _WIN32 typedef CRITICAL_SECTION sslLockType; static void sslLockInit(sslLockType* l) { @@ -150,66 +150,66 @@ static int initOpensslLocks(void) { unsigned ii, nlocks; if (CRYPTO_get_locking_callback() != NULL) { /* Someone already set the callback before us. Don't destroy it! */ - return REDIS_OK; + return VALKEY_OK; } nlocks = CRYPTO_num_locks(); - ossl_locks = hi_malloc(sizeof(*ossl_locks) * nlocks); + ossl_locks = vk_malloc(sizeof(*ossl_locks) * nlocks); if (ossl_locks == NULL) - return REDIS_ERR; + return VALKEY_ERR; for (ii = 0; ii < nlocks; ii++) { sslLockInit(ossl_locks + ii); } CRYPTO_set_locking_callback(opensslDoLock); - return REDIS_OK; + return VALKEY_OK; } -#endif /* HIREDIS_USE_CRYPTO_LOCKS */ +#endif /* VALKEY_USE_CRYPTO_LOCKS */ -int redisInitOpenSSL(void) +int valkeyInitOpenSSL(void) { SSL_library_init(); -#ifdef HIREDIS_USE_CRYPTO_LOCKS +#ifdef VALKEY_USE_CRYPTO_LOCKS initOpensslLocks(); #endif - return REDIS_OK; + return VALKEY_OK; } /** - * redisSSLContext helper context destruction. + * valkeySSLContext helper context destruction. */ -const char *redisSSLContextGetError(redisSSLContextError error) +const char *valkeySSLContextGetError(valkeySSLContextError error) { switch (error) { - case REDIS_SSL_CTX_NONE: + case VALKEY_SSL_CTX_NONE: return "No Error"; - case REDIS_SSL_CTX_CREATE_FAILED: + case VALKEY_SSL_CTX_CREATE_FAILED: return "Failed to create OpenSSL SSL_CTX"; - case REDIS_SSL_CTX_CERT_KEY_REQUIRED: + case VALKEY_SSL_CTX_CERT_KEY_REQUIRED: return "Client cert and key must both be specified or skipped"; - case REDIS_SSL_CTX_CA_CERT_LOAD_FAILED: + case VALKEY_SSL_CTX_CA_CERT_LOAD_FAILED: return "Failed to load CA Certificate or CA Path"; - case REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED: + case VALKEY_SSL_CTX_CLIENT_CERT_LOAD_FAILED: return "Failed to load client certificate"; - case REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED: + case VALKEY_SSL_CTX_PRIVATE_KEY_LOAD_FAILED: return "Failed to load private key"; - case REDIS_SSL_CTX_OS_CERTSTORE_OPEN_FAILED: + case VALKEY_SSL_CTX_OS_CERTSTORE_OPEN_FAILED: return "Failed to open system certificate store"; - case REDIS_SSL_CTX_OS_CERT_ADD_FAILED: + case VALKEY_SSL_CTX_OS_CERT_ADD_FAILED: return "Failed to add CA certificates obtained from system to the SSL context"; default: return "Unknown error code"; } } -void redisFreeSSLContext(redisSSLContext *ctx) +void valkeyFreeSSLContext(valkeySSLContext *ctx) { if (!ctx) return; if (ctx->server_name) { - hi_free(ctx->server_name); + vk_free(ctx->server_name); ctx->server_name = NULL; } @@ -218,31 +218,31 @@ void redisFreeSSLContext(redisSSLContext *ctx) ctx->ssl_ctx = NULL; } - hi_free(ctx); + vk_free(ctx); } /** - * redisSSLContext helper context initialization. + * valkeySSLContext helper context initialization. */ -redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *capath, +valkeySSLContext *valkeyCreateSSLContext(const char *cacert_filename, const char *capath, const char *cert_filename, const char *private_key_filename, - const char *server_name, redisSSLContextError *error) + const char *server_name, valkeySSLContextError *error) { - redisSSLOptions options = { + valkeySSLOptions options = { .cacert_filename = cacert_filename, .capath = capath, .cert_filename = cert_filename, .private_key_filename = private_key_filename, .server_name = server_name, - .verify_mode = REDIS_SSL_VERIFY_PEER, + .verify_mode = VALKEY_SSL_VERIFY_PEER, }; - return redisCreateSSLContextWithOptions(&options, error); + return valkeyCreateSSLContextWithOptions(&options, error); } -redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options, redisSSLContextError *error) { +valkeySSLContext *valkeyCreateSSLContextWithOptions(valkeySSLOptions *options, valkeySSLContextError *error) { const char *cacert_filename = options->cacert_filename; const char *capath = options->capath; const char *cert_filename = options->cert_filename; @@ -254,7 +254,7 @@ redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options, redi PCCERT_CONTEXT win_ctx = NULL; #endif - redisSSLContext *ctx = hi_calloc(1, sizeof(redisSSLContext)); + valkeySSLContext *ctx = vk_calloc(1, sizeof(valkeySSLContext)); if (ctx == NULL) goto error; @@ -267,7 +267,7 @@ redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options, redi ctx->ssl_ctx = SSL_CTX_new(ssl_method); if (!ctx->ssl_ctx) { - if (error) *error = REDIS_SSL_CTX_CREATE_FAILED; + if (error) *error = VALKEY_SSL_CTX_CREATE_FAILED; goto error; } @@ -281,7 +281,7 @@ redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options, redi if ((cert_filename != NULL && private_key_filename == NULL) || (private_key_filename != NULL && cert_filename == NULL)) { - if (error) *error = REDIS_SSL_CTX_CERT_KEY_REQUIRED; + if (error) *error = VALKEY_SSL_CTX_CERT_KEY_REQUIRED; goto error; } @@ -290,7 +290,7 @@ redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options, redi if (0 == strcmp(cacert_filename, "wincert")) { win_store = CertOpenSystemStore(NULL, "Root"); if (!win_store) { - if (error) *error = REDIS_SSL_CTX_OS_CERTSTORE_OPEN_FAILED; + if (error) *error = VALKEY_SSL_CTX_OS_CERTSTORE_OPEN_FAILED; goto error; } X509_STORE* store = SSL_CTX_get_cert_store(ctx->ssl_ctx); @@ -301,7 +301,7 @@ redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options, redi if ((1 != X509_STORE_add_cert(store, x509)) || (1 != SSL_CTX_add_client_CA(ctx->ssl_ctx, x509))) { - if (error) *error = REDIS_SSL_CTX_OS_CERT_ADD_FAILED; + if (error) *error = VALKEY_SSL_CTX_OS_CERT_ADD_FAILED; goto error; } X509_free(x509); @@ -312,29 +312,29 @@ redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options, redi } else #endif if (!SSL_CTX_load_verify_locations(ctx->ssl_ctx, cacert_filename, capath)) { - if (error) *error = REDIS_SSL_CTX_CA_CERT_LOAD_FAILED; + if (error) *error = VALKEY_SSL_CTX_CA_CERT_LOAD_FAILED; goto error; } } else { if (!SSL_CTX_set_default_verify_paths(ctx->ssl_ctx)) { - if (error) *error = REDIS_SSL_CTX_CLIENT_DEFAULT_CERT_FAILED; + if (error) *error = VALKEY_SSL_CTX_CLIENT_DEFAULT_CERT_FAILED; goto error; } } if (cert_filename) { if (!SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, cert_filename)) { - if (error) *error = REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED; + if (error) *error = VALKEY_SSL_CTX_CLIENT_CERT_LOAD_FAILED; goto error; } if (!SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, private_key_filename, SSL_FILETYPE_PEM)) { - if (error) *error = REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED; + if (error) *error = VALKEY_SSL_CTX_PRIVATE_KEY_LOAD_FAILED; goto error; } } if (server_name) - ctx->server_name = hi_strdup(server_name); + ctx->server_name = vk_strdup(server_name); return ctx; @@ -343,7 +343,7 @@ redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options, redi CertFreeCertificateContext(win_ctx); CertCloseStore(win_store, 0); #endif - redisFreeSSLContext(ctx); + valkeyFreeSSLContext(ctx); return NULL; } @@ -352,16 +352,16 @@ redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options, redi */ -static int redisSSLConnect(redisContext *c, SSL *ssl) { +static int valkeySSLConnect(valkeyContext *c, SSL *ssl) { if (c->privctx) { - __redisSetError(c, REDIS_ERR_OTHER, "redisContext was already associated"); - return REDIS_ERR; + valkeySetError(c, VALKEY_ERR_OTHER, "valkeyContext was already associated"); + return VALKEY_ERR; } - redisSSL *rssl = hi_calloc(1, sizeof(redisSSL)); + valkeySSL *rssl = vk_calloc(1, sizeof(valkeySSL)); if (rssl == NULL) { - __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); - return REDIS_ERR; + valkeySetError(c, VALKEY_ERR_OOM, "Out of memory"); + return VALKEY_ERR; } rssl->ssl = ssl; @@ -374,18 +374,18 @@ static int redisSSLConnect(redisContext *c, SSL *ssl) { int rv = SSL_connect(rssl->ssl); if (rv == 1) { - c->funcs = &redisContextSSLFuncs; + c->funcs = &valkeyContextSSLFuncs; c->privctx = rssl; - return REDIS_OK; + return VALKEY_OK; } rv = SSL_get_error(rssl->ssl, rv); - if (((c->flags & REDIS_BLOCK) == 0) && + if (((c->flags & VALKEY_BLOCK) == 0) && (rv == SSL_ERROR_WANT_READ || rv == SSL_ERROR_WANT_WRITE)) { - c->funcs = &redisContextSSLFuncs; + c->funcs = &valkeyContextSSLFuncs; c->privctx = rssl; - return REDIS_OK; + return VALKEY_OK; } if (c->err == 0) { @@ -397,64 +397,64 @@ static int redisSSLConnect(redisContext *c, SSL *ssl) { snprintf(err,sizeof(err)-1,"SSL_connect failed: %s", ERR_reason_error_string(e)); } - __redisSetError(c, REDIS_ERR_IO, err); + valkeySetError(c, VALKEY_ERR_IO, err); } - hi_free(rssl); - return REDIS_ERR; + vk_free(rssl); + return VALKEY_ERR; } /** - * A wrapper around redisSSLConnect() for users who manage their own context and + * A wrapper around valkeySSLConnect() for users who manage their own context and * create their own SSL object. */ -int redisInitiateSSL(redisContext *c, SSL *ssl) { - return redisSSLConnect(c, ssl); +int valkeyInitiateSSL(valkeyContext *c, SSL *ssl) { + return valkeySSLConnect(c, ssl); } /** - * A wrapper around redisSSLConnect() for users who use redisSSLContext and don't + * A wrapper around valkeySSLConnect() for users who use valkeySSLContext and don't * manage their own SSL objects. */ -int redisInitiateSSLWithContext(redisContext *c, redisSSLContext *redis_ssl_ctx) +int valkeyInitiateSSLWithContext(valkeyContext *c, valkeySSLContext *valkey_ssl_ctx) { - if (!c || !redis_ssl_ctx) - return REDIS_ERR; + if (!c || !valkey_ssl_ctx) + return VALKEY_ERR; - /* We want to verify that redisSSLConnect() won't fail on this, as it will + /* We want to verify that valkeySSLConnect() won't fail on this, as it will * not own the SSL object in that case and we'll end up leaking. */ if (c->privctx) - return REDIS_ERR; + return VALKEY_ERR; - SSL *ssl = SSL_new(redis_ssl_ctx->ssl_ctx); + SSL *ssl = SSL_new(valkey_ssl_ctx->ssl_ctx); if (!ssl) { - __redisSetError(c, REDIS_ERR_OTHER, "Couldn't create new SSL instance"); + valkeySetError(c, VALKEY_ERR_OTHER, "Couldn't create new SSL instance"); goto error; } - if (redis_ssl_ctx->server_name) { - if (!SSL_set_tlsext_host_name(ssl, redis_ssl_ctx->server_name)) { - __redisSetError(c, REDIS_ERR_OTHER, "Failed to set server_name/SNI"); + if (valkey_ssl_ctx->server_name) { + if (!SSL_set_tlsext_host_name(ssl, valkey_ssl_ctx->server_name)) { + valkeySetError(c, VALKEY_ERR_OTHER, "Failed to set server_name/SNI"); goto error; } } - if (redisSSLConnect(c, ssl) != REDIS_OK) { + if (valkeySSLConnect(c, ssl) != VALKEY_OK) { goto error; } - return REDIS_OK; + return VALKEY_OK; error: if (ssl) SSL_free(ssl); - return REDIS_ERR; + return VALKEY_ERR; } -static int maybeCheckWant(redisSSL *rssl, int rv) { +static int maybeCheckWant(valkeySSL *rssl, int rv) { /** * If the error is WANT_READ or WANT_WRITE, the appropriate flags are set * and true is returned. False is returned otherwise @@ -471,32 +471,32 @@ static int maybeCheckWant(redisSSL *rssl, int rv) { } /** - * Implementation of redisContextFuncs for SSL connections. + * Implementation of valkeyContextFuncs for SSL connections. */ -static void redisSSLFree(void *privctx){ - redisSSL *rsc = privctx; +static void valkeySSLFree(void *privctx){ + valkeySSL *rsc = privctx; if (!rsc) return; if (rsc->ssl) { SSL_free(rsc->ssl); rsc->ssl = NULL; } - hi_free(rsc); + vk_free(rsc); } -static ssize_t redisSSLRead(redisContext *c, char *buf, size_t bufcap) { - redisSSL *rssl = c->privctx; +static ssize_t valkeySSLRead(valkeyContext *c, char *buf, size_t bufcap) { + valkeySSL *rssl = c->privctx; int nread = SSL_read(rssl->ssl, buf, bufcap); if (nread > 0) { return nread; } else if (nread == 0) { - __redisSetError(c, REDIS_ERR_EOF, "Server closed the connection"); + valkeySetError(c, VALKEY_ERR_EOF, "Server closed the connection"); return -1; } else { int err = SSL_get_error(rssl->ssl, nread); - if (c->flags & REDIS_BLOCK) { + if (c->flags & VALKEY_BLOCK) { /** * In blocking mode, we should never end up in a situation where * we get an error without it being an actual error, except @@ -510,7 +510,7 @@ static ssize_t redisSSLRead(redisContext *c, char *buf, size_t bufcap) { if (errno == EAGAIN) { msg = "Resource temporarily unavailable"; } - __redisSetError(c, REDIS_ERR_IO, msg); + valkeySetError(c, VALKEY_ERR_IO, msg); return -1; } } @@ -521,14 +521,14 @@ static ssize_t redisSSLRead(redisContext *c, char *buf, size_t bufcap) { if (maybeCheckWant(rssl, err)) { return 0; } else { - __redisSetError(c, REDIS_ERR_IO, NULL); + valkeySetError(c, VALKEY_ERR_IO, NULL); return -1; } } } -static ssize_t redisSSLWrite(redisContext *c) { - redisSSL *rssl = c->privctx; +static ssize_t valkeySSLWrite(valkeyContext *c) { + valkeySSL *rssl = c->privctx; size_t len = rssl->lastLen ? rssl->lastLen : sdslen(c->obuf); int rv = SSL_write(rssl->ssl, c->obuf, len); @@ -539,20 +539,20 @@ static ssize_t redisSSLWrite(redisContext *c) { rssl->lastLen = len; int err = SSL_get_error(rssl->ssl, rv); - if ((c->flags & REDIS_BLOCK) == 0 && maybeCheckWant(rssl, err)) { + if ((c->flags & VALKEY_BLOCK) == 0 && maybeCheckWant(rssl, err)) { return 0; } else { - __redisSetError(c, REDIS_ERR_IO, NULL); + valkeySetError(c, VALKEY_ERR_IO, NULL); return -1; } } return rv; } -static void redisSSLAsyncRead(redisAsyncContext *ac) { +static void valkeySSLAsyncRead(valkeyAsyncContext *ac) { int rv; - redisSSL *rssl = ac->c.privctx; - redisContext *c = &ac->c; + valkeySSL *rssl = ac->c.privctx; + valkeyContext *c = &ac->c; rssl->wantRead = 0; @@ -561,33 +561,33 @@ static void redisSSLAsyncRead(redisAsyncContext *ac) { /* This is probably just a write event */ rssl->pendingWrite = 0; - rv = redisBufferWrite(c, &done); - if (rv == REDIS_ERR) { - __redisAsyncDisconnect(ac); + rv = valkeyBufferWrite(c, &done); + if (rv == VALKEY_ERR) { + valkeyAsyncDisconnectInternal(ac); return; } else if (!done) { _EL_ADD_WRITE(ac); } } - rv = redisBufferRead(c); - if (rv == REDIS_ERR) { - __redisAsyncDisconnect(ac); + rv = valkeyBufferRead(c); + if (rv == VALKEY_ERR) { + valkeyAsyncDisconnectInternal(ac); } else { _EL_ADD_READ(ac); - redisProcessCallbacks(ac); + valkeyProcessCallbacks(ac); } } -static void redisSSLAsyncWrite(redisAsyncContext *ac) { +static void valkeySSLAsyncWrite(valkeyAsyncContext *ac) { int rv, done = 0; - redisSSL *rssl = ac->c.privctx; - redisContext *c = &ac->c; + valkeySSL *rssl = ac->c.privctx; + valkeyContext *c = &ac->c; rssl->pendingWrite = 0; - rv = redisBufferWrite(c, &done); - if (rv == REDIS_ERR) { - __redisAsyncDisconnect(ac); + rv = valkeyBufferWrite(c, &done); + if (rv == VALKEY_ERR) { + valkeyAsyncDisconnectInternal(ac); return; } @@ -609,12 +609,12 @@ static void redisSSLAsyncWrite(redisAsyncContext *ac) { _EL_ADD_READ(ac); } -redisContextFuncs redisContextSSLFuncs = { - .close = redisNetClose, - .free_privctx = redisSSLFree, - .async_read = redisSSLAsyncRead, - .async_write = redisSSLAsyncWrite, - .read = redisSSLRead, - .write = redisSSLWrite +valkeyContextFuncs valkeyContextSSLFuncs = { + .close = valkeyNetClose, + .free_privctx = valkeySSLFree, + .async_read = valkeySSLAsyncRead, + .async_write = valkeySSLAsyncWrite, + .read = valkeySSLRead, + .write = valkeySSLWrite }; diff --git a/libvalkey/test.c b/src/test.c similarity index 56% rename from libvalkey/test.c rename to src/test.c index 8b8ea93a..2844f72a 100644 --- a/libvalkey/test.c +++ b/src/test.c @@ -13,13 +13,13 @@ #include #include -#include "hiredis.h" +#include "valkey.h" #include "async.h" #include "adapters/poll.h" -#ifdef HIREDIS_TEST_SSL -#include "hiredis_ssl.h" +#ifdef VALKEY_TEST_SSL +#include "valkey_ssl.h" #endif -#ifdef HIREDIS_TEST_ASYNC +#ifdef VALKEY_TEST_ASYNC #include "adapters/libevent.h" #include #endif @@ -66,8 +66,8 @@ struct pushCounters { static int insecure_calloc_calls; -#ifdef HIREDIS_TEST_SSL -redisSSLContext *_ssl_ctx = NULL; +#ifdef VALKEY_TEST_SSL +valkeySSLContext *_ssl_ctx = NULL; #endif /* The following lines make up our testing "framework" :) */ @@ -104,27 +104,27 @@ static long long usec(void) { #define assert(e) (void)(e) #endif -#define redisTestPanic(msg) \ +#define valkeyTestPanic(msg) \ do { \ fprintf(stderr, "PANIC: %s (In function \"%s\", file \"%s\", line %d)\n", \ msg, __func__, __FILE__, __LINE__); \ exit(1); \ } while (1) -/* Helper to extract Redis version information. Aborts on any failure. */ -#define REDIS_VERSION_FIELD "redis_version:" -void get_redis_version(redisContext *c, int *majorptr, int *minorptr) { - redisReply *reply; +/* Helper to extract server version information. Aborts on any failure. */ +#define SERVER_VERSION_FIELD "redis_version:" +void get_server_version(valkeyContext *c, int *majorptr, int *minorptr) { + valkeyReply *reply; char *eptr, *s, *e; int major, minor; - reply = redisCommand(c, "INFO"); - if (reply == NULL || c->err || reply->type != REDIS_REPLY_STRING) + reply = valkeyCommand(c, "INFO"); + if (reply == NULL || c->err || reply->type != VALKEY_REPLY_STRING) goto abort; - if ((s = strstr(reply->str, REDIS_VERSION_FIELD)) == NULL) + if ((s = strstr(reply->str, SERVER_VERSION_FIELD)) == NULL) goto abort; - s += strlen(REDIS_VERSION_FIELD); + s += strlen(SERVER_VERSION_FIELD); /* We need a field terminator and at least 'x.y.z' (5) bytes of data */ if ((e = strstr(s, "\r\n")) == NULL || (e - s) < 5) @@ -144,22 +144,22 @@ void get_redis_version(redisContext *c, int *majorptr, int *minorptr) { abort: freeReplyObject(reply); - fprintf(stderr, "Error: Cannot determine Redis version, aborting\n"); + fprintf(stderr, "Error: Cannot determine server version, aborting\n"); exit(1); } -static redisContext *select_database(redisContext *c) { - redisReply *reply; +static valkeyContext *select_database(valkeyContext *c) { + valkeyReply *reply; /* Switch to DB 9 for testing, now that we know we can chat. */ - reply = redisCommand(c,"SELECT 9"); + reply = valkeyCommand(c,"SELECT 9"); assert(reply != NULL); freeReplyObject(reply); /* Make sure the DB is empty */ - reply = redisCommand(c,"DBSIZE"); + reply = valkeyCommand(c,"DBSIZE"); assert(reply != NULL); - if (reply->type == REDIS_REPLY_INTEGER && reply->integer == 0) { + if (reply->type == VALKEY_REPLY_INTEGER && reply->integer == 0) { /* Awesome, DB 9 is empty and we can continue. */ freeReplyObject(reply); } else { @@ -171,49 +171,49 @@ static redisContext *select_database(redisContext *c) { } /* Switch protocol */ -static void send_hello(redisContext *c, int version) { - redisReply *reply; +static void send_hello(valkeyContext *c, int version) { + valkeyReply *reply; int expected; - reply = redisCommand(c, "HELLO %d", version); - expected = version == 3 ? REDIS_REPLY_MAP : REDIS_REPLY_ARRAY; + reply = valkeyCommand(c, "HELLO %d", version); + expected = version == 3 ? VALKEY_REPLY_MAP : VALKEY_REPLY_ARRAY; assert(reply != NULL && reply->type == expected); freeReplyObject(reply); } /* Togggle client tracking */ -static void send_client_tracking(redisContext *c, const char *str) { - redisReply *reply; +static void send_client_tracking(valkeyContext *c, const char *str) { + valkeyReply *reply; - reply = redisCommand(c, "CLIENT TRACKING %s", str); - assert(reply != NULL && reply->type == REDIS_REPLY_STATUS); + reply = valkeyCommand(c, "CLIENT TRACKING %s", str); + assert(reply != NULL && reply->type == VALKEY_REPLY_STATUS); freeReplyObject(reply); } -static int disconnect(redisContext *c, int keep_fd) { - redisReply *reply; +static int disconnect(valkeyContext *c, int keep_fd) { + valkeyReply *reply; /* Make sure we're on DB 9. */ - reply = redisCommand(c,"SELECT 9"); + reply = valkeyCommand(c,"SELECT 9"); assert(reply != NULL); freeReplyObject(reply); - reply = redisCommand(c,"FLUSHDB"); + reply = valkeyCommand(c,"FLUSHDB"); assert(reply != NULL); freeReplyObject(reply); /* Free the context as well, but keep the fd if requested. */ if (keep_fd) - return redisFreeKeepFd(c); - redisFree(c); + return valkeyFreeKeepFd(c); + valkeyFree(c); return -1; } -static void do_ssl_handshake(redisContext *c) { -#ifdef HIREDIS_TEST_SSL - redisInitiateSSLWithContext(c, _ssl_ctx); +static void do_ssl_handshake(valkeyContext *c) { +#ifdef VALKEY_TEST_SSL + valkeyInitiateSSLWithContext(c, _ssl_ctx); if (c->err) { printf("SSL error: %s\n", c->errstr); - redisFree(c); + valkeyFree(c); exit(1); } #else @@ -221,33 +221,33 @@ static void do_ssl_handshake(redisContext *c) { #endif } -static redisContext *do_connect(struct config config) { - redisContext *c = NULL; +static valkeyContext *do_connect(struct config config) { + valkeyContext *c = NULL; if (config.type == CONN_TCP) { - c = redisConnect(config.tcp.host, config.tcp.port); + c = valkeyConnect(config.tcp.host, config.tcp.port); } else if (config.type == CONN_SSL) { - c = redisConnect(config.ssl.host, config.ssl.port); + c = valkeyConnect(config.ssl.host, config.ssl.port); } else if (config.type == CONN_UNIX) { - c = redisConnectUnix(config.unix_sock.path); + c = valkeyConnectUnix(config.unix_sock.path); } else if (config.type == CONN_FD) { /* Create a dummy connection just to get an fd to inherit */ - redisContext *dummy_ctx = redisConnectUnix(config.unix_sock.path); + valkeyContext *dummy_ctx = valkeyConnectUnix(config.unix_sock.path); if (dummy_ctx) { int fd = disconnect(dummy_ctx, 1); printf("Connecting to inherited fd %d\n", fd); - c = redisConnectFd(fd); + c = valkeyConnectFd(fd); } } else { - redisTestPanic("Unknown connection type!"); + valkeyTestPanic("Unknown connection type!"); } if (c == NULL) { - printf("Connection error: can't allocate redis context\n"); + printf("Connection error: can't allocate valkey context\n"); exit(1); } else if (c->err) { printf("Connection error: %s\n", c->errstr); - redisFree(c); + valkeyFree(c); exit(1); } @@ -258,8 +258,8 @@ static redisContext *do_connect(struct config config) { return select_database(c); } -static void do_reconnect(redisContext *c, struct config config) { - redisReconnect(c); +static void do_reconnect(valkeyContext *c, struct config config) { + valkeyReconnect(c); if (config.type == CONN_SSL) { do_ssl_handshake(c); @@ -271,46 +271,46 @@ static void test_format_commands(void) { int len; test("Format command without interpolation: "); - len = redisFormatCommand(&cmd,"SET foo bar"); + len = valkeyFormatCommand(&cmd,"SET foo bar"); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); - hi_free(cmd); + vk_free(cmd); test("Format command with %%s string interpolation: "); - len = redisFormatCommand(&cmd,"SET %s %s","foo","bar"); + len = valkeyFormatCommand(&cmd,"SET %s %s","foo","bar"); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); - hi_free(cmd); + vk_free(cmd); test("Format command with %%s and an empty string: "); - len = redisFormatCommand(&cmd,"SET %s %s","foo",""); + len = valkeyFormatCommand(&cmd,"SET %s %s","foo",""); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(0+2)); - hi_free(cmd); + vk_free(cmd); test("Format command with an empty string in between proper interpolations: "); - len = redisFormatCommand(&cmd,"SET %s %s","","foo"); + len = valkeyFormatCommand(&cmd,"SET %s %s","","foo"); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$0\r\n\r\n$3\r\nfoo\r\n",len) == 0 && len == 4+4+(3+2)+4+(0+2)+4+(3+2)); - hi_free(cmd); + vk_free(cmd); test("Format command with %%b string interpolation: "); - len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"b\0r",(size_t)3); + len = valkeyFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"b\0r",(size_t)3); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); - hi_free(cmd); + vk_free(cmd); test("Format command with %%b and an empty string: "); - len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"",(size_t)0); + len = valkeyFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"",(size_t)0); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(0+2)); - hi_free(cmd); + vk_free(cmd); test("Format command with literal %%: "); - len = redisFormatCommand(&cmd,"SET %% %%"); + len = valkeyFormatCommand(&cmd,"SET %% %%"); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$1\r\n%\r\n$1\r\n%\r\n",len) == 0 && len == 4+4+(3+2)+4+(1+2)+4+(1+2)); - hi_free(cmd); + vk_free(cmd); /* Vararg width depends on the type. These tests make sure that the * width is correctly determined using the format and subsequent varargs @@ -318,19 +318,19 @@ static void test_format_commands(void) { #define INTEGER_WIDTH_TEST(fmt, type) do { \ type value = 123; \ test("Format command with printf-delegation (" #type "): "); \ - len = redisFormatCommand(&cmd,"key:%08" fmt " str:%s", value, "hello"); \ + len = valkeyFormatCommand(&cmd,"key:%08" fmt " str:%s", value, "hello"); \ test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:00000123\r\n$9\r\nstr:hello\r\n",len) == 0 && \ len == 4+5+(12+2)+4+(9+2)); \ - hi_free(cmd); \ + vk_free(cmd); \ } while(0) #define FLOAT_WIDTH_TEST(type) do { \ type value = 123.0; \ test("Format command with printf-delegation (" #type "): "); \ - len = redisFormatCommand(&cmd,"key:%08.3f str:%s", value, "hello"); \ + len = valkeyFormatCommand(&cmd,"key:%08.3f str:%s", value, "hello"); \ test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:0123.000\r\n$9\r\nstr:hello\r\n",len) == 0 && \ len == 4+5+(12+2)+4+(9+2)); \ - hi_free(cmd); \ + vk_free(cmd); \ } while(0) INTEGER_WIDTH_TEST("d", int); @@ -347,11 +347,11 @@ static void test_format_commands(void) { FLOAT_WIDTH_TEST(double); test("Format command with unhandled printf format (specifier 'p' not supported): "); - len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3); + len = valkeyFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3); test_cond(len == -1); test("Format command with invalid printf format (specifier missing): "); - len = redisFormatCommand(&cmd,"%-"); + len = valkeyFormatCommand(&cmd,"%-"); test_cond(len == -1); const char *argv[3]; @@ -362,37 +362,37 @@ static void test_format_commands(void) { int argc = 3; test("Format command by passing argc/argv without lengths: "); - len = redisFormatCommandArgv(&cmd,argc,argv,NULL); + len = valkeyFormatCommandArgv(&cmd,argc,argv,NULL); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); - hi_free(cmd); + vk_free(cmd); test("Format command by passing argc/argv with lengths: "); - len = redisFormatCommandArgv(&cmd,argc,argv,lens); + len = valkeyFormatCommandArgv(&cmd,argc,argv,lens); test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(7+2)+4+(3+2)); - hi_free(cmd); + vk_free(cmd); sds sds_cmd; sds_cmd = NULL; test("Format command into sds by passing argc/argv without lengths: "); - len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,NULL); + len = valkeyFormatSdsCommandArgv(&sds_cmd,argc,argv,NULL); test_cond(strncmp(sds_cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(3+2)+4+(3+2)); sdsfree(sds_cmd); sds_cmd = NULL; test("Format command into sds by passing argc/argv with lengths: "); - len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,lens); + len = valkeyFormatSdsCommandArgv(&sds_cmd,argc,argv,lens); test_cond(strncmp(sds_cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 && len == 4+4+(3+2)+4+(7+2)+4+(3+2)); sdsfree(sds_cmd); } static void test_append_formatted_commands(struct config config) { - redisContext *c; - redisReply *reply; + valkeyContext *c; + valkeyReply *reply; char *cmd; int len; @@ -400,168 +400,168 @@ static void test_append_formatted_commands(struct config config) { test("Append format command: "); - len = redisFormatCommand(&cmd, "SET foo bar"); + len = valkeyFormatCommand(&cmd, "SET foo bar"); - test_cond(redisAppendFormattedCommand(c, cmd, len) == REDIS_OK); + test_cond(valkeyAppendFormattedCommand(c, cmd, len) == VALKEY_OK); - assert(redisGetReply(c, (void*)&reply) == REDIS_OK); + assert(valkeyGetReply(c, (void*)&reply) == VALKEY_OK); - hi_free(cmd); + vk_free(cmd); freeReplyObject(reply); disconnect(c, 0); } static void test_tcp_options(struct config cfg) { - redisContext *c; + valkeyContext *c; c = do_connect(cfg); test("We can enable TCP_KEEPALIVE: "); - test_cond(redisEnableKeepAlive(c) == REDIS_OK); + test_cond(valkeyEnableKeepAlive(c) == VALKEY_OK); #ifdef TCP_USER_TIMEOUT test("We can set TCP_USER_TIMEOUT: "); - test_cond(redisSetTcpUserTimeout(c, 100) == REDIS_OK); + test_cond(valkeySetTcpUserTimeout(c, 100) == VALKEY_OK); #else test("Setting TCP_USER_TIMEOUT errors when unsupported: "); - test_cond(redisSetTcpUserTimeout(c, 100) == REDIS_ERR && c->err == REDIS_ERR_IO); + test_cond(valkeySetTcpUserTimeout(c, 100) == VALKEY_ERR && c->err == VALKEY_ERR_IO); #endif - redisFree(c); + valkeyFree(c); } static void test_unix_keepalive(struct config cfg) { - redisContext *c; - redisReply *r; + valkeyContext *c; + valkeyReply *r; c = do_connect(cfg); test("Setting TCP_KEEPALIVE on a unix socket returns an error: "); - test_cond(redisEnableKeepAlive(c) == REDIS_ERR && c->err == 0); + test_cond(valkeyEnableKeepAlive(c) == VALKEY_ERR && c->err == 0); test("Setting TCP_KEEPALIVE on a unix socket doesn't break the connection: "); - r = redisCommand(c, "PING"); - test_cond(r != NULL && r->type == REDIS_REPLY_STATUS && r->len == 4 && + r = valkeyCommand(c, "PING"); + test_cond(r != NULL && r->type == VALKEY_REPLY_STATUS && r->len == 4 && !memcmp(r->str, "PONG", 4)); freeReplyObject(r); - redisFree(c); + valkeyFree(c); } static void test_reply_reader(void) { - redisReader *reader; + valkeyReader *reader; void *reply, *root; int ret; int i; test("Error handling in reply parser: "); - reader = redisReaderCreate(); - redisReaderFeed(reader,(char*)"@foo\r\n",6); - ret = redisReaderGetReply(reader,NULL); - test_cond(ret == REDIS_ERR && + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader,(char*)"@foo\r\n",6); + ret = valkeyReaderGetReply(reader,NULL); + test_cond(ret == VALKEY_ERR && strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0); - redisReaderFree(reader); + valkeyReaderFree(reader); /* when the reply already contains multiple items, they must be free'd * on an error. valgrind will bark when this doesn't happen. */ test("Memory cleanup in reply parser: "); - reader = redisReaderCreate(); - redisReaderFeed(reader,(char*)"*2\r\n",4); - redisReaderFeed(reader,(char*)"$5\r\nhello\r\n",11); - redisReaderFeed(reader,(char*)"@foo\r\n",6); - ret = redisReaderGetReply(reader,NULL); - test_cond(ret == REDIS_ERR && + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader,(char*)"*2\r\n",4); + valkeyReaderFeed(reader,(char*)"$5\r\nhello\r\n",11); + valkeyReaderFeed(reader,(char*)"@foo\r\n",6); + ret = valkeyReaderGetReply(reader,NULL); + test_cond(ret == VALKEY_ERR && strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0); - redisReaderFree(reader); + valkeyReaderFree(reader); - reader = redisReaderCreate(); + reader = valkeyReaderCreate(); test("Can handle arbitrarily nested multi-bulks: "); for (i = 0; i < 128; i++) { - redisReaderFeed(reader,(char*)"*1\r\n", 4); + valkeyReaderFeed(reader,(char*)"*1\r\n", 4); } - redisReaderFeed(reader,(char*)"$6\r\nLOLWUT\r\n",12); - ret = redisReaderGetReply(reader,&reply); + valkeyReaderFeed(reader,(char*)"$6\r\nLOLWUT\r\n",12); + ret = valkeyReaderGetReply(reader,&reply); root = reply; /* Keep track of the root reply */ - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_ARRAY && - ((redisReply*)reply)->elements == 1); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_ARRAY && + ((valkeyReply*)reply)->elements == 1); test("Can parse arbitrarily nested multi-bulks correctly: "); while(i--) { - assert(reply != NULL && ((redisReply*)reply)->type == REDIS_REPLY_ARRAY); - reply = ((redisReply*)reply)->element[0]; + assert(reply != NULL && ((valkeyReply*)reply)->type == VALKEY_REPLY_ARRAY); + reply = ((valkeyReply*)reply)->element[0]; } - test_cond(((redisReply*)reply)->type == REDIS_REPLY_STRING && - !memcmp(((redisReply*)reply)->str, "LOLWUT", 6)); + test_cond(((valkeyReply*)reply)->type == VALKEY_REPLY_STRING && + !memcmp(((valkeyReply*)reply)->str, "LOLWUT", 6)); freeReplyObject(root); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Correctly parses LLONG_MAX: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, ":9223372036854775807\r\n",22); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_INTEGER && - ((redisReply*)reply)->integer == LLONG_MAX); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, ":9223372036854775807\r\n",22); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_INTEGER && + ((valkeyReply*)reply)->integer == LLONG_MAX); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Set error when > LLONG_MAX: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, ":9223372036854775808\r\n",22); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_ERR && + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, ":9223372036854775808\r\n",22); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_ERR && strcasecmp(reader->errstr,"Bad integer value") == 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Correctly parses LLONG_MIN: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, ":-9223372036854775808\r\n",23); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_INTEGER && - ((redisReply*)reply)->integer == LLONG_MIN); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, ":-9223372036854775808\r\n",23); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_INTEGER && + ((valkeyReply*)reply)->integer == LLONG_MIN); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Set error when < LLONG_MIN: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, ":-9223372036854775809\r\n",23); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_ERR && + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, ":-9223372036854775809\r\n",23); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_ERR && strcasecmp(reader->errstr,"Bad integer value") == 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Set error when array < -1: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, "*-2\r\n+asdf\r\n",12); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_ERR && + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, "*-2\r\n+asdf\r\n",12); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_ERR && strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Set error when bulk < -1: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, "$-2\r\nasdf\r\n",11); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_ERR && + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, "$-2\r\nasdf\r\n",11); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_ERR && strcasecmp(reader->errstr,"Bulk string length out of range") == 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Can configure maximum multi-bulk elements: "); - reader = redisReaderCreate(); + reader = valkeyReaderCreate(); reader->maxelements = 1024; - redisReaderFeed(reader, "*1025\r\n", 7); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_ERR && + valkeyReaderFeed(reader, "*1025\r\n", 7); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_ERR && strcasecmp(reader->errstr, "Multi-bulk length out of range") == 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Multi-bulk never overflows regardless of maxelements: "); size_t bad_mbulk_len = (SIZE_MAX / sizeof(void *)) + 3; @@ -569,332 +569,332 @@ static void test_reply_reader(void) { snprintf(bad_mbulk_reply, sizeof(bad_mbulk_reply), "*%llu\r\n+asdf\r\n", (unsigned long long) bad_mbulk_len); - reader = redisReaderCreate(); + reader = valkeyReaderCreate(); reader->maxelements = 0; /* Don't rely on default limit */ - redisReaderFeed(reader, bad_mbulk_reply, strlen(bad_mbulk_reply)); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_ERR && strcasecmp(reader->errstr, "Out of memory") == 0); + valkeyReaderFeed(reader, bad_mbulk_reply, strlen(bad_mbulk_reply)); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_ERR && strcasecmp(reader->errstr, "Out of memory") == 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); #if LLONG_MAX > SIZE_MAX test("Set error when array > SIZE_MAX: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, "*9223372036854775807\r\n+asdf\r\n",29); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_ERR && + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, "*9223372036854775807\r\n+asdf\r\n",29); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_ERR && strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Set error when bulk > SIZE_MAX: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, "$9223372036854775807\r\nasdf\r\n",28); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_ERR && + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, "$9223372036854775807\r\nasdf\r\n",28); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_ERR && strcasecmp(reader->errstr,"Bulk string length out of range") == 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); #endif test("Works with NULL functions for reply: "); - reader = redisReaderCreate(); + reader = valkeyReaderCreate(); reader->fn = NULL; - redisReaderFeed(reader,(char*)"+OK\r\n",5); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS); - redisReaderFree(reader); + valkeyReaderFeed(reader,(char*)"+OK\r\n",5); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && reply == (void*)VALKEY_REPLY_STATUS); + valkeyReaderFree(reader); test("Works when a single newline (\\r\\n) covers two calls to feed: "); - reader = redisReaderCreate(); + reader = valkeyReaderCreate(); reader->fn = NULL; - redisReaderFeed(reader,(char*)"+OK\r",4); - ret = redisReaderGetReply(reader,&reply); - assert(ret == REDIS_OK && reply == NULL); - redisReaderFeed(reader,(char*)"\n",1); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS); - redisReaderFree(reader); + valkeyReaderFeed(reader,(char*)"+OK\r",4); + ret = valkeyReaderGetReply(reader,&reply); + assert(ret == VALKEY_OK && reply == NULL); + valkeyReaderFeed(reader,(char*)"\n",1); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && reply == (void*)VALKEY_REPLY_STATUS); + valkeyReaderFree(reader); test("Don't reset state after protocol error: "); - reader = redisReaderCreate(); + reader = valkeyReaderCreate(); reader->fn = NULL; - redisReaderFeed(reader,(char*)"x",1); - ret = redisReaderGetReply(reader,&reply); - assert(ret == REDIS_ERR); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_ERR && reply == NULL); - redisReaderFree(reader); + valkeyReaderFeed(reader,(char*)"x",1); + ret = valkeyReaderGetReply(reader,&reply); + assert(ret == VALKEY_ERR); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_ERR && reply == NULL); + valkeyReaderFree(reader); test("Don't reset state after protocol error(not segfault): "); - reader = redisReaderCreate(); - redisReaderFeed(reader,(char*)"*3\r\n$3\r\nSET\r\n$5\r\nhello\r\n$", 25); - ret = redisReaderGetReply(reader,&reply); - assert(ret == REDIS_OK); - redisReaderFeed(reader,(char*)"3\r\nval\r\n", 8); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_ARRAY && - ((redisReply*)reply)->elements == 3); - freeReplyObject(reply); - redisReaderFree(reader); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader,(char*)"*3\r\n$3\r\nSET\r\n$5\r\nhello\r\n$", 25); + ret = valkeyReaderGetReply(reader,&reply); + assert(ret == VALKEY_OK); + valkeyReaderFeed(reader,(char*)"3\r\nval\r\n", 8); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_ARRAY && + ((valkeyReply*)reply)->elements == 3); + freeReplyObject(reply); + valkeyReaderFree(reader); /* Regression test for issue #45 on GitHub. */ test("Don't do empty allocation for empty multi bulk: "); - reader = redisReaderCreate(); - redisReaderFeed(reader,(char*)"*0\r\n",4); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_ARRAY && - ((redisReply*)reply)->elements == 0); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader,(char*)"*0\r\n",4); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_ARRAY && + ((valkeyReply*)reply)->elements == 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); /* RESP3 verbatim strings (GitHub issue #802) */ test("Can parse RESP3 verbatim strings: "); - reader = redisReaderCreate(); - redisReaderFeed(reader,(char*)"=10\r\ntxt:LOLWUT\r\n",17); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_VERB && - !memcmp(((redisReply*)reply)->str,"LOLWUT", 6)); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader,(char*)"=10\r\ntxt:LOLWUT\r\n",17); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_VERB && + !memcmp(((valkeyReply*)reply)->str,"LOLWUT", 6)); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); /* RESP3 push messages (Github issue #815) */ test("Can parse RESP3 push messages: "); - reader = redisReaderCreate(); - redisReaderFeed(reader,(char*)">2\r\n$6\r\nLOLWUT\r\n:42\r\n",21); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_PUSH && - ((redisReply*)reply)->elements == 2 && - ((redisReply*)reply)->element[0]->type == REDIS_REPLY_STRING && - !memcmp(((redisReply*)reply)->element[0]->str,"LOLWUT",6) && - ((redisReply*)reply)->element[1]->type == REDIS_REPLY_INTEGER && - ((redisReply*)reply)->element[1]->integer == 42); - freeReplyObject(reply); - redisReaderFree(reader); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader,(char*)">2\r\n$6\r\nLOLWUT\r\n:42\r\n",21); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_PUSH && + ((valkeyReply*)reply)->elements == 2 && + ((valkeyReply*)reply)->element[0]->type == VALKEY_REPLY_STRING && + !memcmp(((valkeyReply*)reply)->element[0]->str,"LOLWUT",6) && + ((valkeyReply*)reply)->element[1]->type == VALKEY_REPLY_INTEGER && + ((valkeyReply*)reply)->element[1]->integer == 42); + freeReplyObject(reply); + valkeyReaderFree(reader); test("Can parse RESP3 doubles: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, ",3.14159265358979323846\r\n",25); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_DOUBLE && - fabs(((redisReply*)reply)->dval - 3.14159265358979323846) < 0.00000001 && - ((redisReply*)reply)->len == 22 && - strcmp(((redisReply*)reply)->str, "3.14159265358979323846") == 0); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, ",3.14159265358979323846\r\n",25); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_DOUBLE && + fabs(((valkeyReply*)reply)->dval - 3.14159265358979323846) < 0.00000001 && + ((valkeyReply*)reply)->len == 22 && + strcmp(((valkeyReply*)reply)->str, "3.14159265358979323846") == 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Set error on invalid RESP3 double: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, ",3.14159\000265358979323846\r\n",26); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_ERR && + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, ",3.14159\000265358979323846\r\n",26); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_ERR && strcasecmp(reader->errstr,"Bad double value") == 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Correctly parses RESP3 double INFINITY: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, ",inf\r\n",6); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_DOUBLE && - isinf(((redisReply*)reply)->dval) && - ((redisReply*)reply)->dval > 0); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, ",inf\r\n",6); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_DOUBLE && + isinf(((valkeyReply*)reply)->dval) && + ((valkeyReply*)reply)->dval > 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Correctly parses RESP3 double NaN: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, ",nan\r\n",6); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_DOUBLE && - isnan(((redisReply*)reply)->dval)); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, ",nan\r\n",6); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_DOUBLE && + isnan(((valkeyReply*)reply)->dval)); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Correctly parses RESP3 double -Nan: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, ",-nan\r\n", 7); - ret = redisReaderGetReply(reader, &reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_DOUBLE && - isnan(((redisReply*)reply)->dval)); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, ",-nan\r\n", 7); + ret = valkeyReaderGetReply(reader, &reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_DOUBLE && + isnan(((valkeyReply*)reply)->dval)); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Can parse RESP3 nil: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, "_\r\n",3); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_NIL); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, "_\r\n",3); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_NIL); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Set error on invalid RESP3 nil: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, "_nil\r\n",6); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_ERR && + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, "_nil\r\n",6); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_ERR && strcasecmp(reader->errstr,"Bad nil value") == 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Can parse RESP3 bool (true): "); - reader = redisReaderCreate(); - redisReaderFeed(reader, "#t\r\n",4); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_BOOL && - ((redisReply*)reply)->integer); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, "#t\r\n",4); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_BOOL && + ((valkeyReply*)reply)->integer); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Can parse RESP3 bool (false): "); - reader = redisReaderCreate(); - redisReaderFeed(reader, "#f\r\n",4); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_BOOL && - !((redisReply*)reply)->integer); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, "#f\r\n",4); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_BOOL && + !((valkeyReply*)reply)->integer); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Set error on invalid RESP3 bool: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, "#foobar\r\n",9); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_ERR && + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, "#foobar\r\n",9); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_ERR && strcasecmp(reader->errstr,"Bad bool value") == 0); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Can parse RESP3 map: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, "%2\r\n+first\r\n:123\r\n$6\r\nsecond\r\n#t\r\n",34); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_MAP && - ((redisReply*)reply)->elements == 4 && - ((redisReply*)reply)->element[0]->type == REDIS_REPLY_STATUS && - ((redisReply*)reply)->element[0]->len == 5 && - !strcmp(((redisReply*)reply)->element[0]->str,"first") && - ((redisReply*)reply)->element[1]->type == REDIS_REPLY_INTEGER && - ((redisReply*)reply)->element[1]->integer == 123 && - ((redisReply*)reply)->element[2]->type == REDIS_REPLY_STRING && - ((redisReply*)reply)->element[2]->len == 6 && - !strcmp(((redisReply*)reply)->element[2]->str,"second") && - ((redisReply*)reply)->element[3]->type == REDIS_REPLY_BOOL && - ((redisReply*)reply)->element[3]->integer); - freeReplyObject(reply); - redisReaderFree(reader); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, "%2\r\n+first\r\n:123\r\n$6\r\nsecond\r\n#t\r\n",34); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_MAP && + ((valkeyReply*)reply)->elements == 4 && + ((valkeyReply*)reply)->element[0]->type == VALKEY_REPLY_STATUS && + ((valkeyReply*)reply)->element[0]->len == 5 && + !strcmp(((valkeyReply*)reply)->element[0]->str,"first") && + ((valkeyReply*)reply)->element[1]->type == VALKEY_REPLY_INTEGER && + ((valkeyReply*)reply)->element[1]->integer == 123 && + ((valkeyReply*)reply)->element[2]->type == VALKEY_REPLY_STRING && + ((valkeyReply*)reply)->element[2]->len == 6 && + !strcmp(((valkeyReply*)reply)->element[2]->str,"second") && + ((valkeyReply*)reply)->element[3]->type == VALKEY_REPLY_BOOL && + ((valkeyReply*)reply)->element[3]->integer); + freeReplyObject(reply); + valkeyReaderFree(reader); test("Can parse RESP3 attribute: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, "|2\r\n+foo\r\n:123\r\n+bar\r\n#t\r\n",26); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_ATTR && - ((redisReply*)reply)->elements == 4 && - ((redisReply*)reply)->element[0]->type == REDIS_REPLY_STATUS && - ((redisReply*)reply)->element[0]->len == 3 && - !strcmp(((redisReply*)reply)->element[0]->str,"foo") && - ((redisReply*)reply)->element[1]->type == REDIS_REPLY_INTEGER && - ((redisReply*)reply)->element[1]->integer == 123 && - ((redisReply*)reply)->element[2]->type == REDIS_REPLY_STATUS && - ((redisReply*)reply)->element[2]->len == 3 && - !strcmp(((redisReply*)reply)->element[2]->str,"bar") && - ((redisReply*)reply)->element[3]->type == REDIS_REPLY_BOOL && - ((redisReply*)reply)->element[3]->integer); - freeReplyObject(reply); - redisReaderFree(reader); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, "|2\r\n+foo\r\n:123\r\n+bar\r\n#t\r\n",26); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_ATTR && + ((valkeyReply*)reply)->elements == 4 && + ((valkeyReply*)reply)->element[0]->type == VALKEY_REPLY_STATUS && + ((valkeyReply*)reply)->element[0]->len == 3 && + !strcmp(((valkeyReply*)reply)->element[0]->str,"foo") && + ((valkeyReply*)reply)->element[1]->type == VALKEY_REPLY_INTEGER && + ((valkeyReply*)reply)->element[1]->integer == 123 && + ((valkeyReply*)reply)->element[2]->type == VALKEY_REPLY_STATUS && + ((valkeyReply*)reply)->element[2]->len == 3 && + !strcmp(((valkeyReply*)reply)->element[2]->str,"bar") && + ((valkeyReply*)reply)->element[3]->type == VALKEY_REPLY_BOOL && + ((valkeyReply*)reply)->element[3]->integer); + freeReplyObject(reply); + valkeyReaderFree(reader); test("Can parse RESP3 set: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, "~5\r\n+orange\r\n$5\r\napple\r\n#f\r\n:100\r\n:999\r\n",40); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_SET && - ((redisReply*)reply)->elements == 5 && - ((redisReply*)reply)->element[0]->type == REDIS_REPLY_STATUS && - ((redisReply*)reply)->element[0]->len == 6 && - !strcmp(((redisReply*)reply)->element[0]->str,"orange") && - ((redisReply*)reply)->element[1]->type == REDIS_REPLY_STRING && - ((redisReply*)reply)->element[1]->len == 5 && - !strcmp(((redisReply*)reply)->element[1]->str,"apple") && - ((redisReply*)reply)->element[2]->type == REDIS_REPLY_BOOL && - !((redisReply*)reply)->element[2]->integer && - ((redisReply*)reply)->element[3]->type == REDIS_REPLY_INTEGER && - ((redisReply*)reply)->element[3]->integer == 100 && - ((redisReply*)reply)->element[4]->type == REDIS_REPLY_INTEGER && - ((redisReply*)reply)->element[4]->integer == 999); - freeReplyObject(reply); - redisReaderFree(reader); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, "~5\r\n+orange\r\n$5\r\napple\r\n#f\r\n:100\r\n:999\r\n",40); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_SET && + ((valkeyReply*)reply)->elements == 5 && + ((valkeyReply*)reply)->element[0]->type == VALKEY_REPLY_STATUS && + ((valkeyReply*)reply)->element[0]->len == 6 && + !strcmp(((valkeyReply*)reply)->element[0]->str,"orange") && + ((valkeyReply*)reply)->element[1]->type == VALKEY_REPLY_STRING && + ((valkeyReply*)reply)->element[1]->len == 5 && + !strcmp(((valkeyReply*)reply)->element[1]->str,"apple") && + ((valkeyReply*)reply)->element[2]->type == VALKEY_REPLY_BOOL && + !((valkeyReply*)reply)->element[2]->integer && + ((valkeyReply*)reply)->element[3]->type == VALKEY_REPLY_INTEGER && + ((valkeyReply*)reply)->element[3]->integer == 100 && + ((valkeyReply*)reply)->element[4]->type == VALKEY_REPLY_INTEGER && + ((valkeyReply*)reply)->element[4]->integer == 999); + freeReplyObject(reply); + valkeyReaderFree(reader); test("Can parse RESP3 bignum: "); - reader = redisReaderCreate(); - redisReaderFeed(reader,"(3492890328409238509324850943850943825024385\r\n",46); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_BIGNUM && - ((redisReply*)reply)->len == 43 && - !strcmp(((redisReply*)reply)->str,"3492890328409238509324850943850943825024385")); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader,"(3492890328409238509324850943850943825024385\r\n",46); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_BIGNUM && + ((valkeyReply*)reply)->len == 43 && + !strcmp(((valkeyReply*)reply)->str,"3492890328409238509324850943850943825024385")); freeReplyObject(reply); - redisReaderFree(reader); + valkeyReaderFree(reader); test("Can parse RESP3 doubles in an array: "); - reader = redisReaderCreate(); - redisReaderFeed(reader, "*1\r\n,3.14159265358979323846\r\n",31); - ret = redisReaderGetReply(reader,&reply); - test_cond(ret == REDIS_OK && - ((redisReply*)reply)->type == REDIS_REPLY_ARRAY && - ((redisReply*)reply)->elements == 1 && - ((redisReply*)reply)->element[0]->type == REDIS_REPLY_DOUBLE && - fabs(((redisReply*)reply)->element[0]->dval - 3.14159265358979323846) < 0.00000001 && - ((redisReply*)reply)->element[0]->len == 22 && - strcmp(((redisReply*)reply)->element[0]->str, "3.14159265358979323846") == 0); - freeReplyObject(reply); - redisReaderFree(reader); + reader = valkeyReaderCreate(); + valkeyReaderFeed(reader, "*1\r\n,3.14159265358979323846\r\n",31); + ret = valkeyReaderGetReply(reader,&reply); + test_cond(ret == VALKEY_OK && + ((valkeyReply*)reply)->type == VALKEY_REPLY_ARRAY && + ((valkeyReply*)reply)->elements == 1 && + ((valkeyReply*)reply)->element[0]->type == VALKEY_REPLY_DOUBLE && + fabs(((valkeyReply*)reply)->element[0]->dval - 3.14159265358979323846) < 0.00000001 && + ((valkeyReply*)reply)->element[0]->len == 22 && + strcmp(((valkeyReply*)reply)->element[0]->str, "3.14159265358979323846") == 0); + freeReplyObject(reply); + valkeyReaderFree(reader); } static void test_free_null(void) { - void *redisCtx = NULL; + void *valkeyCtx = NULL; void *reply = NULL; - test("Don't fail when redisFree is passed a NULL value: "); - redisFree(redisCtx); - test_cond(redisCtx == NULL); + test("Don't fail when valkeyFree is passed a NULL value: "); + valkeyFree(valkeyCtx); + test_cond(valkeyCtx == NULL); test("Don't fail when freeReplyObject is passed a NULL value: "); freeReplyObject(reply); test_cond(reply == NULL); } -static void *hi_malloc_fail(size_t size) { +static void *vk_malloc_fail(size_t size) { (void)size; return NULL; } -static void *hi_calloc_fail(size_t nmemb, size_t size) { +static void *vk_calloc_fail(size_t nmemb, size_t size) { (void)nmemb; (void)size; return NULL; } -static void *hi_calloc_insecure(size_t nmemb, size_t size) { +static void *vk_calloc_insecure(size_t nmemb, size_t size) { (void)nmemb; (void)size; insecure_calloc_calls++; return (void*)0xdeadc0de; } -static void *hi_realloc_fail(void *ptr, size_t size) { +static void *vk_realloc_fail(void *ptr, size_t size) { (void)ptr; (void)size; return NULL; @@ -903,52 +903,52 @@ static void *hi_realloc_fail(void *ptr, size_t size) { static void test_allocator_injection(void) { void *ptr; - hiredisAllocFuncs ha = { - .mallocFn = hi_malloc_fail, - .callocFn = hi_calloc_fail, - .reallocFn = hi_realloc_fail, + valkeyAllocFuncs ha = { + .mallocFn = vk_malloc_fail, + .callocFn = vk_calloc_fail, + .reallocFn = vk_realloc_fail, .strdupFn = strdup, .freeFn = free, }; - // Override hiredis allocators - hiredisSetAllocators(&ha); + // Override valkey allocators + valkeySetAllocators(&ha); - test("redisContext uses injected allocators: "); - redisContext *c = redisConnect("localhost", 6379); + test("valkeyContext uses injected allocators: "); + valkeyContext *c = valkeyConnect("localhost", 6379); test_cond(c == NULL); - test("redisReader uses injected allocators: "); - redisReader *reader = redisReaderCreate(); + test("valkeyReader uses injected allocators: "); + valkeyReader *reader = valkeyReaderCreate(); test_cond(reader == NULL); - /* Make sure hiredis itself protects against a non-overflow checking calloc */ - test("hiredis calloc wrapper protects against overflow: "); - ha.callocFn = hi_calloc_insecure; - hiredisSetAllocators(&ha); - ptr = hi_calloc((SIZE_MAX / sizeof(void*)) + 3, sizeof(void*)); + /* Make sure libvalkey itself protects against a non-overflow checking calloc */ + test("libvalkey calloc wrapper protects against overflow: "); + ha.callocFn = vk_calloc_insecure; + valkeySetAllocators(&ha); + ptr = vk_calloc((SIZE_MAX / sizeof(void*)) + 3, sizeof(void*)); test_cond(ptr == NULL && insecure_calloc_calls == 0); // Return allocators to default - hiredisResetAllocators(); + valkeyResetAllocators(); } -#define HIREDIS_BAD_DOMAIN "idontexist-noreally.com" +#define VALKEY_BAD_DOMAIN "idontexist-noreally.com" static void test_blocking_connection_errors(void) { struct addrinfo hints = {.ai_family = AF_INET}; struct addrinfo *ai_tmp = NULL; - redisContext *c; + valkeyContext *c; - int rv = getaddrinfo(HIREDIS_BAD_DOMAIN, "6379", &hints, &ai_tmp); + int rv = getaddrinfo(VALKEY_BAD_DOMAIN, "6379", &hints, &ai_tmp); if (rv != 0) { // Address does *not* exist test("Returns error when host cannot be resolved: "); // First see if this domain name *actually* resolves to NXDOMAIN - c = redisConnect(HIREDIS_BAD_DOMAIN, 6379); + c = valkeyConnect(VALKEY_BAD_DOMAIN, 6379); test_cond( - c->err == REDIS_ERR_OTHER && + c->err == VALKEY_ERR_OTHER && (strcmp(c->errstr, "Name or service not known") == 0 || - strcmp(c->errstr, "Can't resolve: " HIREDIS_BAD_DOMAIN) == 0 || + strcmp(c->errstr, "Can't resolve: " VALKEY_BAD_DOMAIN) == 0 || strcmp(c->errstr, "Name does not resolve") == 0 || strcmp(c->errstr, "nodename nor servname provided, or not known") == 0 || strcmp(c->errstr, "node name or service name not known") == 0 || @@ -957,71 +957,71 @@ static void test_blocking_connection_errors(void) { strcmp(c->errstr, "hostname nor servname provided, or not known") == 0 || strcmp(c->errstr, "no address associated with name") == 0 || strcmp(c->errstr, "No such host is known. ") == 0)); - redisFree(c); + valkeyFree(c); } else { printf("Skipping NXDOMAIN test. Found evil ISP!\n"); freeaddrinfo(ai_tmp); } #ifndef _WIN32 - redisOptions opt = {0}; + valkeyOptions opt = {0}; struct timeval tv; test("Returns error when the port is not open: "); - c = redisConnect((char*)"localhost", 1); - test_cond(c->err == REDIS_ERR_IO && + c = valkeyConnect((char*)"localhost", 1); + test_cond(c->err == VALKEY_ERR_IO && strcmp(c->errstr,"Connection refused") == 0); - redisFree(c); + valkeyFree(c); /* Verify we don't regress from the fix in PR #1180 */ test("We don't clobber connection exception with setsockopt error: "); tv = (struct timeval){.tv_sec = 0, .tv_usec = 500000}; opt.command_timeout = opt.connect_timeout = &tv; - REDIS_OPTIONS_SET_TCP(&opt, "localhost", 10337); - c = redisConnectWithOptions(&opt); - test_cond(c->err == REDIS_ERR_IO && + VALKEY_OPTIONS_SET_TCP(&opt, "localhost", 10337); + c = valkeyConnectWithOptions(&opt); + test_cond(c->err == VALKEY_ERR_IO && strcmp(c->errstr, "Connection refused") == 0); - redisFree(c); + valkeyFree(c); test("Returns error when the unix_sock socket path doesn't accept connections: "); - c = redisConnectUnix((char*)"/tmp/idontexist.sock"); - test_cond(c->err == REDIS_ERR_IO); /* Don't care about the message... */ - redisFree(c); + c = valkeyConnectUnix((char*)"/tmp/idontexist.sock"); + test_cond(c->err == VALKEY_ERR_IO); /* Don't care about the message... */ + valkeyFree(c); #endif } /* Test push handler */ void push_handler(void *privdata, void *r) { struct pushCounters *pcounts = privdata; - redisReply *reply = r, *payload; + valkeyReply *reply = r, *payload; - assert(reply && reply->type == REDIS_REPLY_PUSH && reply->elements == 2); + assert(reply && reply->type == VALKEY_REPLY_PUSH && reply->elements == 2); payload = reply->element[1]; - if (payload->type == REDIS_REPLY_ARRAY) { + if (payload->type == VALKEY_REPLY_ARRAY) { payload = payload->element[0]; } - if (payload->type == REDIS_REPLY_STRING) { + if (payload->type == VALKEY_REPLY_STRING) { pcounts->str++; - } else if (payload->type == REDIS_REPLY_NIL) { + } else if (payload->type == VALKEY_REPLY_NIL) { pcounts->nil++; } freeReplyObject(reply); } -/* Dummy function just to test setting a callback with redisOptions */ -void push_handler_async(redisAsyncContext *ac, void *reply) { +/* Dummy function just to test setting a callback with valkeyOptions */ +void push_handler_async(valkeyAsyncContext *ac, void *reply) { (void)ac; (void)reply; } -static void test_resp3_push_handler(redisContext *c) { +static void test_resp3_push_handler(valkeyContext *c) { struct pushCounters pc = {0}; - redisPushFn *old = NULL; - redisReply *reply; + valkeyPushFn *old = NULL; + valkeyReply *reply; void *privdata; /* Switch to RESP3 and turn on client tracking */ @@ -1030,61 +1030,61 @@ static void test_resp3_push_handler(redisContext *c) { privdata = c->privdata; c->privdata = &pc; - reply = redisCommand(c, "GET key:0"); + reply = valkeyCommand(c, "GET key:0"); assert(reply != NULL); freeReplyObject(reply); test("RESP3 PUSH messages are handled out of band by default: "); - reply = redisCommand(c, "SET key:0 val:0"); - test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS); + reply = valkeyCommand(c, "SET key:0 val:0"); + test_cond(reply != NULL && reply->type == VALKEY_REPLY_STATUS); freeReplyObject(reply); - assert((reply = redisCommand(c, "GET key:0")) != NULL); + assert((reply = valkeyCommand(c, "GET key:0")) != NULL); freeReplyObject(reply); - old = redisSetPushCallback(c, push_handler); + old = valkeySetPushCallback(c, push_handler); test("We can set a custom RESP3 PUSH handler: "); - reply = redisCommand(c, "SET key:0 val:0"); - /* We need another command because depending on the version of Redis, the + reply = valkeyCommand(c, "SET key:0 val:0"); + /* We need another command because depending on the server version, the * notification may be delivered after the command's reply. */ assert(reply != NULL); freeReplyObject(reply); - reply = redisCommand(c, "PING"); - test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && pc.str == 1); + reply = valkeyCommand(c, "PING"); + test_cond(reply != NULL && reply->type == VALKEY_REPLY_STATUS && pc.str == 1); freeReplyObject(reply); test("We properly handle a NIL invalidation payload: "); - reply = redisCommand(c, "FLUSHDB"); + reply = valkeyCommand(c, "FLUSHDB"); assert(reply != NULL); freeReplyObject(reply); - reply = redisCommand(c, "PING"); - test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && pc.nil == 1); + reply = valkeyCommand(c, "PING"); + test_cond(reply != NULL && reply->type == VALKEY_REPLY_STATUS && pc.nil == 1); freeReplyObject(reply); /* Unset the push callback and generate an invalidate message making * sure it is not handled out of band. */ test("With no handler, PUSH replies come in-band: "); - redisSetPushCallback(c, NULL); - assert((reply = redisCommand(c, "GET key:0")) != NULL); + valkeySetPushCallback(c, NULL); + assert((reply = valkeyCommand(c, "GET key:0")) != NULL); freeReplyObject(reply); - assert((reply = redisCommand(c, "SET key:0 invalid")) != NULL); - /* Depending on Redis version, we may receive either push notification or + assert((reply = valkeyCommand(c, "SET key:0 invalid")) != NULL); + /* Depending on server version, we may receive either push notification or * status reply. Both cases are valid. */ - if (reply->type == REDIS_REPLY_STATUS) { + if (reply->type == VALKEY_REPLY_STATUS) { freeReplyObject(reply); - reply = redisCommand(c, "PING"); + reply = valkeyCommand(c, "PING"); } - test_cond(reply->type == REDIS_REPLY_PUSH); + test_cond(reply->type == VALKEY_REPLY_PUSH); freeReplyObject(reply); test("With no PUSH handler, no replies are lost: "); - assert(redisGetReply(c, (void**)&reply) == REDIS_OK); - test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS); + assert(valkeyGetReply(c, (void**)&reply) == VALKEY_OK); + test_cond(reply != NULL && reply->type == VALKEY_REPLY_STATUS); freeReplyObject(reply); /* Return to the originally set PUSH handler */ assert(old != NULL); - redisSetPushCallback(c, old); + valkeySetPushCallback(c, old); /* Switch back to RESP2 and disable tracking */ c->privdata = privdata; @@ -1092,49 +1092,49 @@ static void test_resp3_push_handler(redisContext *c) { send_hello(c, 2); } -redisOptions get_redis_tcp_options(struct config config) { - redisOptions options = {0}; - REDIS_OPTIONS_SET_TCP(&options, config.tcp.host, config.tcp.port); +valkeyOptions get_server_tcp_options(struct config config) { + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_TCP(&options, config.tcp.host, config.tcp.port); return options; } static void test_resp3_push_options(struct config config) { - redisAsyncContext *ac; - redisContext *c; - redisOptions options; + valkeyAsyncContext *ac; + valkeyContext *c; + valkeyOptions options; - test("We set a default RESP3 handler for redisContext: "); - options = get_redis_tcp_options(config); - assert((c = redisConnectWithOptions(&options)) != NULL); + test("We set a default RESP3 handler for valkeyContext: "); + options = get_server_tcp_options(config); + assert((c = valkeyConnectWithOptions(&options)) != NULL); test_cond(c->push_cb != NULL); - redisFree(c); + valkeyFree(c); - test("We don't set a default RESP3 push handler for redisAsyncContext: "); - options = get_redis_tcp_options(config); - assert((ac = redisAsyncConnectWithOptions(&options)) != NULL); + test("We don't set a default RESP3 push handler for valkeyAsyncContext: "); + options = get_server_tcp_options(config); + assert((ac = valkeyAsyncConnectWithOptions(&options)) != NULL); test_cond(ac->c.push_cb == NULL); - redisAsyncFree(ac); + valkeyAsyncFree(ac); - test("Our REDIS_OPT_NO_PUSH_AUTOFREE flag works: "); - options = get_redis_tcp_options(config); - options.options |= REDIS_OPT_NO_PUSH_AUTOFREE; - assert((c = redisConnectWithOptions(&options)) != NULL); + test("Our VALKEY_OPT_NO_PUSH_AUTOFREE flag works: "); + options = get_server_tcp_options(config); + options.options |= VALKEY_OPT_NO_PUSH_AUTOFREE; + assert((c = valkeyConnectWithOptions(&options)) != NULL); test_cond(c->push_cb == NULL); - redisFree(c); + valkeyFree(c); - test("We can use redisOptions to set a custom PUSH handler for redisContext: "); - options = get_redis_tcp_options(config); + test("We can use valkeyOptions to set a custom PUSH handler for valkeyContext: "); + options = get_server_tcp_options(config); options.push_cb = push_handler; - assert((c = redisConnectWithOptions(&options)) != NULL); + assert((c = valkeyConnectWithOptions(&options)) != NULL); test_cond(c->push_cb == push_handler); - redisFree(c); + valkeyFree(c); - test("We can use redisOptions to set a custom PUSH handler for redisAsyncContext: "); - options = get_redis_tcp_options(config); + test("We can use valkeyOptions to set a custom PUSH handler for valkeyAsyncContext: "); + options = get_server_tcp_options(config); options.async_push_cb = push_handler_async; - assert((ac = redisAsyncConnectWithOptions(&options)) != NULL); + assert((ac = valkeyAsyncConnectWithOptions(&options)) != NULL); test_cond(ac->push_cb == push_handler_async); - redisAsyncFree(ac); + valkeyAsyncFree(ac); } void free_privdata(void *privdata) { @@ -1144,52 +1144,52 @@ void free_privdata(void *privdata) { static void test_privdata_hooks(struct config config) { struct privdata data = {0}; - redisOptions options; - redisContext *c; + valkeyOptions options; + valkeyContext *c; - test("We can use redisOptions to set privdata: "); - options = get_redis_tcp_options(config); - REDIS_OPTIONS_SET_PRIVDATA(&options, &data, free_privdata); - assert((c = redisConnectWithOptions(&options)) != NULL); + test("We can use valkeyOptions to set privdata: "); + options = get_server_tcp_options(config); + VALKEY_OPTIONS_SET_PRIVDATA(&options, &data, free_privdata); + assert((c = valkeyConnectWithOptions(&options)) != NULL); test_cond(c->privdata == &data); test("Our privdata destructor fires when we free the context: "); - redisFree(c); + valkeyFree(c); test_cond(data.dtor_counter == 1); } static void test_blocking_connection(struct config config) { - redisContext *c; - redisReply *reply; + valkeyContext *c; + valkeyReply *reply; int major; c = do_connect(config); test("Is able to deliver commands: "); - reply = redisCommand(c,"PING"); - test_cond(reply->type == REDIS_REPLY_STATUS && + reply = valkeyCommand(c,"PING"); + test_cond(reply->type == VALKEY_REPLY_STATUS && strcasecmp(reply->str,"pong") == 0) freeReplyObject(reply); test("Is a able to send commands verbatim: "); - reply = redisCommand(c,"SET foo bar"); - test_cond (reply->type == REDIS_REPLY_STATUS && + reply = valkeyCommand(c,"SET foo bar"); + test_cond (reply->type == VALKEY_REPLY_STATUS && strcasecmp(reply->str,"ok") == 0) freeReplyObject(reply); test("%%s String interpolation works: "); - reply = redisCommand(c,"SET %s %s","foo","hello world"); + reply = valkeyCommand(c,"SET %s %s","foo","hello world"); freeReplyObject(reply); - reply = redisCommand(c,"GET foo"); - test_cond(reply->type == REDIS_REPLY_STRING && + reply = valkeyCommand(c,"GET foo"); + test_cond(reply->type == VALKEY_REPLY_STRING && strcmp(reply->str,"hello world") == 0); freeReplyObject(reply); test("%%b String interpolation works: "); - reply = redisCommand(c,"SET %b %b","foo",(size_t)3,"hello\x00world",(size_t)11); + reply = valkeyCommand(c,"SET %b %b","foo",(size_t)3,"hello\x00world",(size_t)11); freeReplyObject(reply); - reply = redisCommand(c,"GET foo"); - test_cond(reply->type == REDIS_REPLY_STRING && + reply = valkeyCommand(c,"GET foo"); + test_cond(reply->type == VALKEY_REPLY_STRING && memcmp(reply->str,"hello\x00world",11) == 0) test("Binary reply length is correct: "); @@ -1197,21 +1197,21 @@ static void test_blocking_connection(struct config config) { freeReplyObject(reply); test("Can parse nil replies: "); - reply = redisCommand(c,"GET nokey"); - test_cond(reply->type == REDIS_REPLY_NIL) + reply = valkeyCommand(c,"GET nokey"); + test_cond(reply->type == VALKEY_REPLY_NIL) freeReplyObject(reply); /* test 7 */ test("Can parse integer replies: "); - reply = redisCommand(c,"INCR mycounter"); - test_cond(reply->type == REDIS_REPLY_INTEGER && reply->integer == 1) + reply = valkeyCommand(c,"INCR mycounter"); + test_cond(reply->type == VALKEY_REPLY_INTEGER && reply->integer == 1) freeReplyObject(reply); test("Can parse multi bulk replies: "); - freeReplyObject(redisCommand(c,"LPUSH mylist foo")); - freeReplyObject(redisCommand(c,"LPUSH mylist bar")); - reply = redisCommand(c,"LRANGE mylist 0 -1"); - test_cond(reply->type == REDIS_REPLY_ARRAY && + freeReplyObject(valkeyCommand(c,"LPUSH mylist foo")); + freeReplyObject(valkeyCommand(c,"LPUSH mylist bar")); + reply = valkeyCommand(c,"LRANGE mylist 0 -1"); + test_cond(reply->type == VALKEY_REPLY_ARRAY && reply->elements == 2 && !memcmp(reply->element[0]->str,"bar",3) && !memcmp(reply->element[1]->str,"foo",3)) @@ -1220,33 +1220,33 @@ static void test_blocking_connection(struct config config) { /* m/e with multi bulk reply *before* other reply. * specifically test ordering of reply items to parse. */ test("Can handle nested multi bulk replies: "); - freeReplyObject(redisCommand(c,"MULTI")); - freeReplyObject(redisCommand(c,"LRANGE mylist 0 -1")); - freeReplyObject(redisCommand(c,"PING")); - reply = (redisCommand(c,"EXEC")); - test_cond(reply->type == REDIS_REPLY_ARRAY && + freeReplyObject(valkeyCommand(c,"MULTI")); + freeReplyObject(valkeyCommand(c,"LRANGE mylist 0 -1")); + freeReplyObject(valkeyCommand(c,"PING")); + reply = (valkeyCommand(c,"EXEC")); + test_cond(reply->type == VALKEY_REPLY_ARRAY && reply->elements == 2 && - reply->element[0]->type == REDIS_REPLY_ARRAY && + reply->element[0]->type == VALKEY_REPLY_ARRAY && reply->element[0]->elements == 2 && !memcmp(reply->element[0]->element[0]->str,"bar",3) && !memcmp(reply->element[0]->element[1]->str,"foo",3) && - reply->element[1]->type == REDIS_REPLY_STATUS && + reply->element[1]->type == VALKEY_REPLY_STATUS && strcasecmp(reply->element[1]->str,"pong") == 0); freeReplyObject(reply); test("Send command by passing argc/argv: "); const char *argv[3] = {"SET", "foo", "bar"}; size_t argvlen[3] = {3, 3, 3}; - reply = redisCommandArgv(c,3,argv,argvlen); - test_cond(reply->type == REDIS_REPLY_STATUS); + reply = valkeyCommandArgv(c,3,argv,argvlen); + test_cond(reply->type == VALKEY_REPLY_STATUS); freeReplyObject(reply); - /* Make sure passing NULL to redisGetReply is safe */ - test("Can pass NULL to redisGetReply: "); - assert(redisAppendCommand(c, "PING") == REDIS_OK); - test_cond(redisGetReply(c, NULL) == REDIS_OK); + /* Make sure passing NULL to valkeyGetReply is safe */ + test("Can pass NULL to valkeyGetReply: "); + assert(valkeyAppendCommand(c, "PING") == VALKEY_OK); + test_cond(valkeyGetReply(c, NULL) == VALKEY_OK); - get_redis_version(c, &major, NULL); + get_server_version(c, &major, NULL); if (major >= 6) test_resp3_push_handler(c); test_resp3_push_options(config); @@ -1256,45 +1256,45 @@ static void test_blocking_connection(struct config config) { } /* Send DEBUG SLEEP 0 to detect if we have this command */ -static int detect_debug_sleep(redisContext *c) { +static int detect_debug_sleep(valkeyContext *c) { int detected; - redisReply *reply = redisCommand(c, "DEBUG SLEEP 0\r\n"); + valkeyReply *reply = valkeyCommand(c, "DEBUG SLEEP 0\r\n"); if (reply == NULL || c->err) { const char *cause = c->err ? c->errstr : "(none)"; - fprintf(stderr, "Error testing for DEBUG SLEEP (Redis error: %s), exiting\n", cause); + fprintf(stderr, "Error testing for DEBUG SLEEP (server error: %s), exiting\n", cause); exit(-1); } - detected = reply->type == REDIS_REPLY_STATUS; + detected = reply->type == VALKEY_REPLY_STATUS; freeReplyObject(reply); return detected; } static void test_blocking_connection_timeouts(struct config config) { - redisContext *c; - redisReply *reply; + valkeyContext *c; + valkeyReply *reply; ssize_t s; const char *sleep_cmd = "DEBUG SLEEP 3\r\n"; struct timeval tv; c = do_connect(config); test("Successfully completes a command when the timeout is not exceeded: "); - reply = redisCommand(c,"SET foo fast"); + reply = valkeyCommand(c,"SET foo fast"); freeReplyObject(reply); tv.tv_sec = 0; tv.tv_usec = 10000; - redisSetTimeout(c, tv); - reply = redisCommand(c, "GET foo"); - test_cond(reply != NULL && reply->type == REDIS_REPLY_STRING && memcmp(reply->str, "fast", 4) == 0); + valkeySetTimeout(c, tv); + reply = valkeyCommand(c, "GET foo"); + test_cond(reply != NULL && reply->type == VALKEY_REPLY_STRING && memcmp(reply->str, "fast", 4) == 0); freeReplyObject(reply); disconnect(c, 0); c = do_connect(config); test("Does not return a reply when the command times out: "); if (detect_debug_sleep(c)) { - redisAppendFormattedCommand(c, sleep_cmd, strlen(sleep_cmd)); + valkeyAppendFormattedCommand(c, sleep_cmd, strlen(sleep_cmd)); // flush connection buffer without waiting for the reply s = c->funcs->write(c); @@ -1304,18 +1304,18 @@ static void test_blocking_connection_timeouts(struct config config) { tv.tv_sec = 0; tv.tv_usec = 10000; - redisSetTimeout(c, tv); - reply = redisCommand(c, "GET foo"); + valkeySetTimeout(c, tv); + reply = valkeyCommand(c, "GET foo"); #ifndef _WIN32 - test_cond(s > 0 && reply == NULL && c->err == REDIS_ERR_IO && + test_cond(s > 0 && reply == NULL && c->err == VALKEY_ERR_IO && strcmp(c->errstr, "Resource temporarily unavailable") == 0); #else - test_cond(s > 0 && reply == NULL && c->err == REDIS_ERR_TIMEOUT && + test_cond(s > 0 && reply == NULL && c->err == VALKEY_ERR_TIMEOUT && strcmp(c->errstr, "recv timeout") == 0); #endif freeReplyObject(reply); - // wait for the DEBUG SLEEP to complete so that Redis server is unblocked for the following tests + // wait for the DEBUG SLEEP to complete so that the server is unblocked for the following tests millisleep(3000); } else { test_skipped(); @@ -1323,38 +1323,38 @@ static void test_blocking_connection_timeouts(struct config config) { test("Reconnect properly reconnects after a timeout: "); do_reconnect(c, config); - reply = redisCommand(c, "PING"); - test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); + reply = valkeyCommand(c, "PING"); + test_cond(reply != NULL && reply->type == VALKEY_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); freeReplyObject(reply); test("Reconnect properly uses owned parameters: "); config.tcp.host = "foo"; config.unix_sock.path = "foo"; do_reconnect(c, config); - reply = redisCommand(c, "PING"); - test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); + reply = valkeyCommand(c, "PING"); + test_cond(reply != NULL && reply->type == VALKEY_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); freeReplyObject(reply); disconnect(c, 0); } static void test_blocking_io_errors(struct config config) { - redisContext *c; - redisReply *reply; + valkeyContext *c; + valkeyReply *reply; void *_reply; int major, minor; /* Connect to target given by config. */ c = do_connect(config); - get_redis_version(c, &major, &minor); + get_server_version(c, &major, &minor); test("Returns I/O error when the connection is lost: "); - reply = redisCommand(c,"QUIT"); + reply = valkeyCommand(c,"QUIT"); if (major > 2 || (major == 2 && minor > 0)) { /* > 2.0 returns OK on QUIT and read() should be issued once more * to know the descriptor is at EOF. */ test_cond(strcasecmp(reply->str,"OK") == 0 && - redisGetReply(c,&_reply) == REDIS_ERR); + valkeyGetReply(c,&_reply) == VALKEY_ERR); freeReplyObject(reply); } else { test_cond(reply == NULL); @@ -1366,26 +1366,26 @@ static void test_blocking_io_errors(struct config config) { * On >2.0, QUIT will return with OK and another read(2) needed to be * issued to find out the socket was closed by the server. In both * conditions, the error will be set to EOF. */ - assert(c->err == REDIS_ERR_EOF && + assert(c->err == VALKEY_ERR_EOF && strcmp(c->errstr,"Server closed the connection") == 0); #endif - redisFree(c); + valkeyFree(c); c = do_connect(config); test("Returns I/O error on socket timeout: "); struct timeval tv = { 0, 1000 }; - assert(redisSetTimeout(c,tv) == REDIS_OK); - int respcode = redisGetReply(c,&_reply); + assert(valkeySetTimeout(c,tv) == VALKEY_OK); + int respcode = valkeyGetReply(c,&_reply); #ifndef _WIN32 - test_cond(respcode == REDIS_ERR && c->err == REDIS_ERR_IO && errno == EAGAIN); + test_cond(respcode == VALKEY_ERR && c->err == VALKEY_ERR_IO && errno == EAGAIN); #else - test_cond(respcode == REDIS_ERR && c->err == REDIS_ERR_TIMEOUT); + test_cond(respcode == VALKEY_ERR && c->err == VALKEY_ERR_TIMEOUT); #endif - redisFree(c); + valkeyFree(c); } static void test_invalid_timeout_errors(struct config config) { - redisContext *c = NULL; + valkeyContext *c = NULL; test("Set error when an invalid timeout usec value is used during connect: "); @@ -1393,15 +1393,15 @@ static void test_invalid_timeout_errors(struct config config) { config.connect_timeout.tv_usec = 10000001; if (config.type == CONN_TCP || config.type == CONN_SSL) { - c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.connect_timeout); + c = valkeyConnectWithTimeout(config.tcp.host, config.tcp.port, config.connect_timeout); } else if(config.type == CONN_UNIX) { - c = redisConnectUnixWithTimeout(config.unix_sock.path, config.connect_timeout); + c = valkeyConnectUnixWithTimeout(config.unix_sock.path, config.connect_timeout); } else { - redisTestPanic("Unknown connection type!"); + valkeyTestPanic("Unknown connection type!"); } - test_cond(c != NULL && c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0); - redisFree(c); + test_cond(c != NULL && c->err == VALKEY_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0); + valkeyFree(c); test("Set error when an invalid timeout sec value is used during connect: "); @@ -1409,21 +1409,21 @@ static void test_invalid_timeout_errors(struct config config) { config.connect_timeout.tv_usec = 0; if (config.type == CONN_TCP || config.type == CONN_SSL) { - c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.connect_timeout); + c = valkeyConnectWithTimeout(config.tcp.host, config.tcp.port, config.connect_timeout); } else if(config.type == CONN_UNIX) { - c = redisConnectUnixWithTimeout(config.unix_sock.path, config.connect_timeout); + c = valkeyConnectUnixWithTimeout(config.unix_sock.path, config.connect_timeout); } else { - redisTestPanic("Unknown connection type!"); + valkeyTestPanic("Unknown connection type!"); } - test_cond(c != NULL && c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0); - redisFree(c); + test_cond(c != NULL && c->err == VALKEY_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0); + valkeyFree(c); } /* Wrap malloc to abort on failure so OOM checks don't make the test logic * harder to follow. */ -void *hi_malloc_safe(size_t size) { - void *ptr = hi_malloc(size); +void *vk_malloc_safe(size_t size) { + void *ptr = vk_malloc(size); if (ptr == NULL) { fprintf(stderr, "Error: Out of memory\n"); exit(-1); @@ -1433,103 +1433,103 @@ void *hi_malloc_safe(size_t size) { } static void test_throughput(struct config config) { - redisContext *c = do_connect(config); - redisReply **replies; + valkeyContext *c = do_connect(config); + valkeyReply **replies; int i, num; long long t1, t2; test("Throughput:\n"); for (i = 0; i < 500; i++) - freeReplyObject(redisCommand(c,"LPUSH mylist foo")); + freeReplyObject(valkeyCommand(c,"LPUSH mylist foo")); num = 1000; - replies = hi_malloc_safe(sizeof(redisReply*)*num); + replies = vk_malloc_safe(sizeof(valkeyReply*)*num); t1 = usec(); for (i = 0; i < num; i++) { - replies[i] = redisCommand(c,"PING"); - assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS); + replies[i] = valkeyCommand(c,"PING"); + assert(replies[i] != NULL && replies[i]->type == VALKEY_REPLY_STATUS); } t2 = usec(); for (i = 0; i < num; i++) freeReplyObject(replies[i]); - hi_free(replies); + vk_free(replies); printf("\t(%dx PING: %.3fs)\n", num, (t2-t1)/1000000.0); - replies = hi_malloc_safe(sizeof(redisReply*)*num); + replies = vk_malloc_safe(sizeof(valkeyReply*)*num); t1 = usec(); for (i = 0; i < num; i++) { - replies[i] = redisCommand(c,"LRANGE mylist 0 499"); - assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY); + replies[i] = valkeyCommand(c,"LRANGE mylist 0 499"); + assert(replies[i] != NULL && replies[i]->type == VALKEY_REPLY_ARRAY); assert(replies[i] != NULL && replies[i]->elements == 500); } t2 = usec(); for (i = 0; i < num; i++) freeReplyObject(replies[i]); - hi_free(replies); + vk_free(replies); printf("\t(%dx LRANGE with 500 elements: %.3fs)\n", num, (t2-t1)/1000000.0); - replies = hi_malloc_safe(sizeof(redisReply*)*num); + replies = vk_malloc_safe(sizeof(valkeyReply*)*num); t1 = usec(); for (i = 0; i < num; i++) { - replies[i] = redisCommand(c, "INCRBY incrkey %d", 1000000); - assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER); + replies[i] = valkeyCommand(c, "INCRBY incrkey %d", 1000000); + assert(replies[i] != NULL && replies[i]->type == VALKEY_REPLY_INTEGER); } t2 = usec(); for (i = 0; i < num; i++) freeReplyObject(replies[i]); - hi_free(replies); + vk_free(replies); printf("\t(%dx INCRBY: %.3fs)\n", num, (t2-t1)/1000000.0); num = 10000; - replies = hi_malloc_safe(sizeof(redisReply*)*num); + replies = vk_malloc_safe(sizeof(valkeyReply*)*num); for (i = 0; i < num; i++) - redisAppendCommand(c,"PING"); + valkeyAppendCommand(c,"PING"); t1 = usec(); for (i = 0; i < num; i++) { - assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); - assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS); + assert(valkeyGetReply(c, (void*)&replies[i]) == VALKEY_OK); + assert(replies[i] != NULL && replies[i]->type == VALKEY_REPLY_STATUS); } t2 = usec(); for (i = 0; i < num; i++) freeReplyObject(replies[i]); - hi_free(replies); + vk_free(replies); printf("\t(%dx PING (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); - replies = hi_malloc_safe(sizeof(redisReply*)*num); + replies = vk_malloc_safe(sizeof(valkeyReply*)*num); for (i = 0; i < num; i++) - redisAppendCommand(c,"LRANGE mylist 0 499"); + valkeyAppendCommand(c,"LRANGE mylist 0 499"); t1 = usec(); for (i = 0; i < num; i++) { - assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); - assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY); + assert(valkeyGetReply(c, (void*)&replies[i]) == VALKEY_OK); + assert(replies[i] != NULL && replies[i]->type == VALKEY_REPLY_ARRAY); assert(replies[i] != NULL && replies[i]->elements == 500); } t2 = usec(); for (i = 0; i < num; i++) freeReplyObject(replies[i]); - hi_free(replies); + vk_free(replies); printf("\t(%dx LRANGE with 500 elements (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); - replies = hi_malloc_safe(sizeof(redisReply*)*num); + replies = vk_malloc_safe(sizeof(valkeyReply*)*num); for (i = 0; i < num; i++) - redisAppendCommand(c,"INCRBY incrkey %d", 1000000); + valkeyAppendCommand(c,"INCRBY incrkey %d", 1000000); t1 = usec(); for (i = 0; i < num; i++) { - assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); - assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER); + assert(valkeyGetReply(c, (void*)&replies[i]) == VALKEY_OK); + assert(replies[i] != NULL && replies[i]->type == VALKEY_REPLY_INTEGER); } t2 = usec(); for (i = 0; i < num; i++) freeReplyObject(replies[i]); - hi_free(replies); + vk_free(replies); printf("\t(%dx INCRBY (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); disconnect(c, 0); } // static long __test_callback_flags = 0; -// static void __test_callback(redisContext *c, void *privdata) { +// static void __test_callback(valkeyContext *c, void *privdata) { // ((void)c); // /* Shift to detect execution order */ // __test_callback_flags <<= 8; // __test_callback_flags |= (long)privdata; // } // -// static void __test_reply_callback(redisContext *c, redisReply *reply, void *privdata) { +// static void __test_reply_callback(valkeyContext *c, valkeyReply *reply, void *privdata) { // ((void)c); // /* Shift to detect execution order */ // __test_callback_flags <<= 8; @@ -1537,105 +1537,105 @@ static void test_throughput(struct config config) { // if (reply) freeReplyObject(reply); // } // -// static redisContext *__connect_nonblock() { +// static valkeyContext *__connect_nonblock() { // /* Reset callback flags */ // __test_callback_flags = 0; -// return redisConnectNonBlock("127.0.0.1", port, NULL); +// return valkeyConnectNonBlock("127.0.0.1", port, NULL); // } // // static void test_nonblocking_connection() { -// redisContext *c; +// valkeyContext *c; // int wdone = 0; // // test("Calls command callback when command is issued: "); // c = __connect_nonblock(); -// redisSetCommandCallback(c,__test_callback,(void*)1); -// redisCommand(c,"PING"); +// valkeySetCommandCallback(c,__test_callback,(void*)1); +// valkeyCommand(c,"PING"); // test_cond(__test_callback_flags == 1); -// redisFree(c); +// valkeyFree(c); // -// test("Calls disconnect callback on redisDisconnect: "); +// test("Calls disconnect callback on valkeyDisconnect: "); // c = __connect_nonblock(); -// redisSetDisconnectCallback(c,__test_callback,(void*)2); -// redisDisconnect(c); +// valkeySetDisconnectCallback(c,__test_callback,(void*)2); +// valkeyDisconnect(c); // test_cond(__test_callback_flags == 2); -// redisFree(c); +// valkeyFree(c); // -// test("Calls disconnect callback and free callback on redisFree: "); +// test("Calls disconnect callback and free callback on valkeyFree: "); // c = __connect_nonblock(); -// redisSetDisconnectCallback(c,__test_callback,(void*)2); -// redisSetFreeCallback(c,__test_callback,(void*)4); -// redisFree(c); +// valkeySetDisconnectCallback(c,__test_callback,(void*)2); +// valkeySetFreeCallback(c,__test_callback,(void*)4); +// valkeyFree(c); // test_cond(__test_callback_flags == ((2 << 8) | 4)); // -// test("redisBufferWrite against empty write buffer: "); +// test("valkeyBufferWrite against empty write buffer: "); // c = __connect_nonblock(); -// test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1); -// redisFree(c); +// test_cond(valkeyBufferWrite(c,&wdone) == VALKEY_OK && wdone == 1); +// valkeyFree(c); // -// test("redisBufferWrite against not yet connected fd: "); +// test("valkeyBufferWrite against not yet connected fd: "); // c = __connect_nonblock(); -// redisCommand(c,"PING"); -// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR && +// valkeyCommand(c,"PING"); +// test_cond(valkeyBufferWrite(c,NULL) == VALKEY_ERR && // strncmp(c->error,"write:",6) == 0); -// redisFree(c); +// valkeyFree(c); // -// test("redisBufferWrite against closed fd: "); +// test("valkeyBufferWrite against closed fd: "); // c = __connect_nonblock(); -// redisCommand(c,"PING"); -// redisDisconnect(c); -// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR && +// valkeyCommand(c,"PING"); +// valkeyDisconnect(c); +// test_cond(valkeyBufferWrite(c,NULL) == VALKEY_ERR && // strncmp(c->error,"write:",6) == 0); -// redisFree(c); +// valkeyFree(c); // // test("Process callbacks in the right sequence: "); // c = __connect_nonblock(); -// redisCommandWithCallback(c,__test_reply_callback,(void*)1,"PING"); -// redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); -// redisCommandWithCallback(c,__test_reply_callback,(void*)3,"PING"); +// valkeyCommandWithCallback(c,__test_reply_callback,(void*)1,"PING"); +// valkeyCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); +// valkeyCommandWithCallback(c,__test_reply_callback,(void*)3,"PING"); // // /* Write output buffer */ // wdone = 0; // while(!wdone) { // usleep(500); -// redisBufferWrite(c,&wdone); +// valkeyBufferWrite(c,&wdone); // } // // /* Read until at least one callback is executed (the 3 replies will // * arrive in a single packet, causing all callbacks to be executed in // * a single pass). */ // while(__test_callback_flags == 0) { -// assert(redisBufferRead(c) == REDIS_OK); -// redisProcessCallbacks(c); +// assert(valkeyBufferRead(c) == VALKEY_OK); +// valkeyProcessCallbacks(c); // } // test_cond(__test_callback_flags == 0x010203); -// redisFree(c); +// valkeyFree(c); // -// test("redisDisconnect executes pending callbacks with NULL reply: "); +// test("valkeyDisconnect executes pending callbacks with NULL reply: "); // c = __connect_nonblock(); -// redisSetDisconnectCallback(c,__test_callback,(void*)1); -// redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); -// redisDisconnect(c); +// valkeySetDisconnectCallback(c,__test_callback,(void*)1); +// valkeyCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); +// valkeyDisconnect(c); // test_cond(__test_callback_flags == 0x0201); -// redisFree(c); +// valkeyFree(c); // } -#ifdef HIREDIS_TEST_ASYNC +#ifdef VALKEY_TEST_ASYNC #pragma GCC diagnostic ignored "-Woverlength-strings" /* required on gcc 4.8.x due to assert statements */ struct event_base *base; typedef struct TestState { - redisOptions *options; + valkeyOptions *options; int checkpoint; int resp3; int disconnect; } TestState; /* Helper to disconnect and stop event loop */ -void async_disconnect(redisAsyncContext *ac) { - redisAsyncDisconnect(ac); +void async_disconnect(valkeyAsyncContext *ac) { + valkeyAsyncDisconnect(ac); event_base_loopbreak(base); } @@ -1647,27 +1647,27 @@ void timeout_cb(int fd, short event, void *arg) { } /* Unexpected call, will trigger a failure */ -void unexpected_cb(redisAsyncContext *ac, void *r, void *privdata) { +void unexpected_cb(valkeyAsyncContext *ac, void *r, void *privdata) { (void) ac; (void) r; printf("Unexpected call: %s\n",(char*)privdata); exit(1); } /* Helper function to publish a message via own client. */ -void publish_msg(redisOptions *options, const char* channel, const char* msg) { - redisContext *c = redisConnectWithOptions(options); +void publish_msg(valkeyOptions *options, const char* channel, const char* msg) { + valkeyContext *c = valkeyConnectWithOptions(options); assert(c != NULL); - redisReply *reply = redisCommand(c,"PUBLISH %s %s",channel,msg); - assert(reply->type == REDIS_REPLY_INTEGER && reply->integer == 1); + valkeyReply *reply = valkeyCommand(c,"PUBLISH %s %s",channel,msg); + assert(reply->type == VALKEY_REPLY_INTEGER && reply->integer == 1); freeReplyObject(reply); disconnect(c, 0); } /* Expect a reply of type INTEGER */ -void integer_cb(redisAsyncContext *ac, void *r, void *privdata) { - redisReply *reply = r; +void integer_cb(valkeyAsyncContext *ac, void *r, void *privdata) { + valkeyReply *reply = r; TestState *state = privdata; - assert(reply != NULL && reply->type == REDIS_REPLY_INTEGER); + assert(reply != NULL && reply->type == VALKEY_REPLY_INTEGER); state->checkpoint++; if (state->disconnect) async_disconnect(ac); } @@ -1675,12 +1675,12 @@ void integer_cb(redisAsyncContext *ac, void *r, void *privdata) { /* Subscribe callback for test_pubsub_handling and test_pubsub_handling_resp3: * - a published message triggers an unsubscribe * - a command is sent before the unsubscribe response is received. */ -void subscribe_cb(redisAsyncContext *ac, void *r, void *privdata) { - redisReply *reply = r; +void subscribe_cb(valkeyAsyncContext *ac, void *r, void *privdata) { + valkeyReply *reply = r; TestState *state = privdata; assert(reply != NULL && - reply->type == (state->resp3 ? REDIS_REPLY_PUSH : REDIS_REPLY_ARRAY) && + reply->type == (state->resp3 ? VALKEY_REPLY_PUSH : VALKEY_REPLY_ARRAY) && reply->elements == 3); if (strcmp(reply->element[0]->str,"subscribe") == 0) { @@ -1694,12 +1694,12 @@ void subscribe_cb(redisAsyncContext *ac, void *r, void *privdata) { /* Unsubscribe after receiving the published message. Send unsubscribe * which should call the callback registered during subscribe */ - redisAsyncCommand(ac,unexpected_cb, + valkeyAsyncCommand(ac,unexpected_cb, (void*)"unsubscribe should call subscribe_cb()", "unsubscribe"); /* Send a regular command after unsubscribing, then disconnect */ state->disconnect = 1; - redisAsyncCommand(ac,integer_cb,state,"LPUSH mylist foo"); + valkeyAsyncCommand(ac,integer_cb,state,"LPUSH mylist foo"); } else if (strcmp(reply->element[0]->str,"unsubscribe") == 0) { assert(strcmp(reply->element[1]->str,"mychannel") == 0 && @@ -1711,16 +1711,16 @@ void subscribe_cb(redisAsyncContext *ac, void *r, void *privdata) { } /* Expect a reply of type ARRAY */ -void array_cb(redisAsyncContext *ac, void *r, void *privdata) { - redisReply *reply = r; +void array_cb(valkeyAsyncContext *ac, void *r, void *privdata) { + valkeyReply *reply = r; TestState *state = privdata; - assert(reply != NULL && reply->type == REDIS_REPLY_ARRAY); + assert(reply != NULL && reply->type == VALKEY_REPLY_ARRAY); state->checkpoint++; if (state->disconnect) async_disconnect(ac); } /* Expect a NULL reply */ -void null_cb(redisAsyncContext *ac, void *r, void *privdata) { +void null_cb(valkeyAsyncContext *ac, void *r, void *privdata) { (void) ac; assert(r == NULL); TestState *state = privdata; @@ -1739,17 +1739,17 @@ static void test_pubsub_handling(struct config config) { evtimer_add(timeout, &timeout_tv); /* Connect */ - redisOptions options = get_redis_tcp_options(config); - redisAsyncContext *ac = redisAsyncConnectWithOptions(&options); + valkeyOptions options = get_server_tcp_options(config); + valkeyAsyncContext *ac = valkeyAsyncConnectWithOptions(&options); assert(ac != NULL && ac->err == 0); - redisLibeventAttach(ac,base); + valkeyLibeventAttach(ac,base); /* Start subscribe */ TestState state = {.options = &options}; - redisAsyncCommand(ac,subscribe_cb,&state,"subscribe mychannel"); + valkeyAsyncCommand(ac,subscribe_cb,&state,"subscribe mychannel"); /* Make sure non-subscribe commands are handled */ - redisAsyncCommand(ac,array_cb,&state,"PING"); + valkeyAsyncCommand(ac,array_cb,&state,"PING"); /* Start event dispatching loop */ test_cond(event_base_dispatch(base) == 0); @@ -1761,7 +1761,7 @@ static void test_pubsub_handling(struct config config) { } /* Unexpected push message, will trigger a failure */ -void unexpected_push_cb(redisAsyncContext *ac, void *r) { +void unexpected_push_cb(valkeyAsyncContext *ac, void *r) { (void) ac; (void) r; printf("Unexpected call to the PUSH callback!\n"); exit(1); @@ -1779,27 +1779,27 @@ static void test_pubsub_handling_resp3(struct config config) { evtimer_add(timeout, &timeout_tv); /* Connect */ - redisOptions options = get_redis_tcp_options(config); - redisAsyncContext *ac = redisAsyncConnectWithOptions(&options); + valkeyOptions options = get_server_tcp_options(config); + valkeyAsyncContext *ac = valkeyAsyncConnectWithOptions(&options); assert(ac != NULL && ac->err == 0); - redisLibeventAttach(ac,base); + valkeyLibeventAttach(ac,base); /* Not expecting any push messages in this test */ - redisAsyncSetPushCallback(ac, unexpected_push_cb); + valkeyAsyncSetPushCallback(ac, unexpected_push_cb); /* Switch protocol */ - redisAsyncCommand(ac,NULL,NULL,"HELLO 3"); + valkeyAsyncCommand(ac,NULL,NULL,"HELLO 3"); /* Start subscribe */ TestState state = {.options = &options, .resp3 = 1}; - redisAsyncCommand(ac,subscribe_cb,&state,"subscribe mychannel"); + valkeyAsyncCommand(ac,subscribe_cb,&state,"subscribe mychannel"); /* Make sure non-subscribe commands are handled in RESP3 */ - redisAsyncCommand(ac,integer_cb,&state,"LPUSH mylist foo"); - redisAsyncCommand(ac,integer_cb,&state,"LPUSH mylist foo"); - redisAsyncCommand(ac,integer_cb,&state,"LPUSH mylist foo"); + valkeyAsyncCommand(ac,integer_cb,&state,"LPUSH mylist foo"); + valkeyAsyncCommand(ac,integer_cb,&state,"LPUSH mylist foo"); + valkeyAsyncCommand(ac,integer_cb,&state,"LPUSH mylist foo"); /* Handle an array with 3 elements as a non-subscribe command */ - redisAsyncCommand(ac,array_cb,&state,"LRANGE mylist 0 2"); + valkeyAsyncCommand(ac,array_cb,&state,"LRANGE mylist 0 2"); /* Start event dispatching loop */ test_cond(event_base_dispatch(base) == 0); @@ -1814,8 +1814,8 @@ static void test_pubsub_handling_resp3(struct config config) { * - a subscribe response triggers a published message * - the published message triggers a command that times out * - the command timeout triggers a disconnect */ -void subscribe_with_timeout_cb(redisAsyncContext *ac, void *r, void *privdata) { - redisReply *reply = r; +void subscribe_with_timeout_cb(valkeyAsyncContext *ac, void *r, void *privdata) { + valkeyReply *reply = r; TestState *state = privdata; /* The non-clean disconnect should trigger the @@ -1826,7 +1826,7 @@ void subscribe_with_timeout_cb(redisAsyncContext *ac, void *r, void *privdata) { return; } - assert(reply->type == (state->resp3 ? REDIS_REPLY_PUSH : REDIS_REPLY_ARRAY) && + assert(reply->type == (state->resp3 ? VALKEY_REPLY_PUSH : VALKEY_REPLY_ARRAY) && reply->elements == 3); if (strcmp(reply->element[0]->str,"subscribe") == 0) { @@ -1840,8 +1840,8 @@ void subscribe_with_timeout_cb(redisAsyncContext *ac, void *r, void *privdata) { state->checkpoint++; /* Send a command that will trigger a timeout */ - redisAsyncCommand(ac,null_cb,state,"DEBUG SLEEP 3"); - redisAsyncCommand(ac,null_cb,state,"LPUSH mylist foo"); + valkeyAsyncCommand(ac,null_cb,state,"DEBUG SLEEP 3"); + valkeyAsyncCommand(ac,null_cb,state,"LPUSH mylist foo"); } else { printf("Unexpected pubsub command: %s\n", reply->element[0]->str); exit(1); @@ -1860,24 +1860,24 @@ static void test_command_timeout_during_pubsub(struct config config) { evtimer_add(timeout,&timeout_tv); /* Connect */ - redisOptions options = get_redis_tcp_options(config); - redisAsyncContext *ac = redisAsyncConnectWithOptions(&options); + valkeyOptions options = get_server_tcp_options(config); + valkeyAsyncContext *ac = valkeyAsyncConnectWithOptions(&options); assert(ac != NULL && ac->err == 0); - redisLibeventAttach(ac,base); + valkeyLibeventAttach(ac,base); /* Configure a command timout */ struct timeval command_timeout = {.tv_sec = 2}; - redisAsyncSetTimeout(ac,command_timeout); + valkeyAsyncSetTimeout(ac,command_timeout); /* Not expecting any push messages in this test */ - redisAsyncSetPushCallback(ac,unexpected_push_cb); + valkeyAsyncSetPushCallback(ac,unexpected_push_cb); /* Switch protocol */ - redisAsyncCommand(ac,NULL,NULL,"HELLO 3"); + valkeyAsyncCommand(ac,NULL,NULL,"HELLO 3"); /* Start subscribe */ TestState state = {.options = &options, .resp3 = 1}; - redisAsyncCommand(ac,subscribe_with_timeout_cb,&state,"subscribe mychannel"); + valkeyAsyncCommand(ac,subscribe_with_timeout_cb,&state,"subscribe mychannel"); /* Start event dispatching loop */ assert(event_base_dispatch(base) == 0); @@ -1889,11 +1889,11 @@ static void test_command_timeout_during_pubsub(struct config config) { } /* Subscribe callback for test_pubsub_multiple_channels */ -void subscribe_channel_a_cb(redisAsyncContext *ac, void *r, void *privdata) { - redisReply *reply = r; +void subscribe_channel_a_cb(valkeyAsyncContext *ac, void *r, void *privdata) { + valkeyReply *reply = r; TestState *state = privdata; - assert(reply != NULL && reply->type == REDIS_REPLY_ARRAY && + assert(reply != NULL && reply->type == VALKEY_REPLY_ARRAY && reply->elements == 3); if (strcmp(reply->element[0]->str,"subscribe") == 0) { @@ -1906,16 +1906,16 @@ void subscribe_channel_a_cb(redisAsyncContext *ac, void *r, void *privdata) { state->checkpoint++; /* Unsubscribe to channels, including channel X & Z which we don't subscribe to */ - redisAsyncCommand(ac,unexpected_cb, + valkeyAsyncCommand(ac,unexpected_cb, (void*)"unsubscribe should not call unexpected_cb()", "unsubscribe B X A A Z"); /* Unsubscribe to patterns, none which we subscribe to */ - redisAsyncCommand(ac,unexpected_cb, + valkeyAsyncCommand(ac,unexpected_cb, (void*)"punsubscribe should not call unexpected_cb()", "punsubscribe"); /* Send a regular command after unsubscribing, then disconnect */ state->disconnect = 1; - redisAsyncCommand(ac,integer_cb,state,"LPUSH mylist foo"); + valkeyAsyncCommand(ac,integer_cb,state,"LPUSH mylist foo"); } else if (strcmp(reply->element[0]->str,"unsubscribe") == 0) { assert(strcmp(reply->element[1]->str,"A") == 0); state->checkpoint++; @@ -1926,12 +1926,12 @@ void subscribe_channel_a_cb(redisAsyncContext *ac, void *r, void *privdata) { } /* Subscribe callback for test_pubsub_multiple_channels */ -void subscribe_channel_b_cb(redisAsyncContext *ac, void *r, void *privdata) { - redisReply *reply = r; +void subscribe_channel_b_cb(valkeyAsyncContext *ac, void *r, void *privdata) { + valkeyReply *reply = r; TestState *state = privdata; (void)ac; - assert(reply != NULL && reply->type == REDIS_REPLY_ARRAY && + assert(reply != NULL && reply->type == VALKEY_REPLY_ARRAY && reply->elements == 3); if (strcmp(reply->element[0]->str,"subscribe") == 0) { @@ -1965,18 +1965,18 @@ static void test_pubsub_multiple_channels(struct config config) { evtimer_add(timeout,&timeout_tv); /* Connect */ - redisOptions options = get_redis_tcp_options(config); - redisAsyncContext *ac = redisAsyncConnectWithOptions(&options); + valkeyOptions options = get_server_tcp_options(config); + valkeyAsyncContext *ac = valkeyAsyncConnectWithOptions(&options); assert(ac != NULL && ac->err == 0); - redisLibeventAttach(ac,base); + valkeyLibeventAttach(ac,base); /* Not expecting any push messages in this test */ - redisAsyncSetPushCallback(ac,unexpected_push_cb); + valkeyAsyncSetPushCallback(ac,unexpected_push_cb); /* Start subscribing to two channels */ TestState state = {.options = &options}; - redisAsyncCommand(ac,subscribe_channel_a_cb,&state,"subscribe A"); - redisAsyncCommand(ac,subscribe_channel_b_cb,&state,"subscribe B"); + valkeyAsyncCommand(ac,subscribe_channel_a_cb,&state,"subscribe A"); + valkeyAsyncCommand(ac,subscribe_channel_b_cb,&state,"subscribe B"); /* Start event dispatching loop */ assert(event_base_dispatch(base) == 0); @@ -1988,8 +1988,8 @@ static void test_pubsub_multiple_channels(struct config config) { } /* Command callback for test_monitor() */ -void monitor_cb(redisAsyncContext *ac, void *r, void *privdata) { - redisReply *reply = r; +void monitor_cb(valkeyAsyncContext *ac, void *r, void *privdata) { + valkeyReply *reply = r; TestState *state = privdata; /* NULL reply is received when BYE triggers a disconnect. */ @@ -1998,31 +1998,31 @@ void monitor_cb(redisAsyncContext *ac, void *r, void *privdata) { return; } - assert(reply != NULL && reply->type == REDIS_REPLY_STATUS); + assert(reply != NULL && reply->type == VALKEY_REPLY_STATUS); state->checkpoint++; if (state->checkpoint == 1) { /* Response from MONITOR */ - redisContext *c = redisConnectWithOptions(state->options); + valkeyContext *c = valkeyConnectWithOptions(state->options); assert(c != NULL); - redisReply *reply = redisCommand(c,"SET first 1"); - assert(reply->type == REDIS_REPLY_STATUS); + valkeyReply *reply = valkeyCommand(c,"SET first 1"); + assert(reply->type == VALKEY_REPLY_STATUS); freeReplyObject(reply); - redisFree(c); + valkeyFree(c); } else if (state->checkpoint == 2) { /* Response for monitored command 'SET first 1' */ assert(strstr(reply->str,"first") != NULL); - redisContext *c = redisConnectWithOptions(state->options); + valkeyContext *c = valkeyConnectWithOptions(state->options); assert(c != NULL); - redisReply *reply = redisCommand(c,"SET second 2"); - assert(reply->type == REDIS_REPLY_STATUS); + valkeyReply *reply = valkeyCommand(c,"SET second 2"); + assert(reply->type == VALKEY_REPLY_STATUS); freeReplyObject(reply); - redisFree(c); + valkeyFree(c); } else if (state->checkpoint == 3) { /* Response for monitored command 'SET second 2' */ assert(strstr(reply->str,"second") != NULL); /* Send QUIT to disconnect */ - redisAsyncCommand(ac,NULL,NULL,"QUIT"); + valkeyAsyncCommand(ac,NULL,NULL,"QUIT"); } } @@ -2042,17 +2042,17 @@ static void test_monitor(struct config config) { evtimer_add(timeout, &timeout_tv); /* Connect */ - redisOptions options = get_redis_tcp_options(config); - redisAsyncContext *ac = redisAsyncConnectWithOptions(&options); + valkeyOptions options = get_server_tcp_options(config); + valkeyAsyncContext *ac = valkeyAsyncConnectWithOptions(&options); assert(ac != NULL && ac->err == 0); - redisLibeventAttach(ac,base); + valkeyLibeventAttach(ac,base); /* Not expecting any push messages in this test */ - redisAsyncSetPushCallback(ac,unexpected_push_cb); + valkeyAsyncSetPushCallback(ac,unexpected_push_cb); /* Start monitor */ TestState state = {.options = &options}; - redisAsyncCommand(ac,monitor_cb,&state,"monitor"); + valkeyAsyncCommand(ac,monitor_cb,&state,"monitor"); /* Start event dispatching loop */ test_cond(event_base_dispatch(base) == 0); @@ -2062,7 +2062,7 @@ static void test_monitor(struct config config) { /* Verify test checkpoints */ assert(state.checkpoint == 3); } -#endif /* HIREDIS_TEST_ASYNC */ +#endif /* VALKEY_TEST_ASYNC */ /* tests for async api using polling adapter, requires no extra libraries*/ @@ -2079,7 +2079,7 @@ typedef enum astest_no /* a static context for the async tests */ struct _astest { - redisAsyncContext *ac; + valkeyAsyncContext *ac; astest_no testno; int counter; int connects; @@ -2100,9 +2100,9 @@ static void asCleanup(void* data) t->ac = NULL; } -static void commandCallback(struct redisAsyncContext *ac, void* _reply, void* _privdata); +static void commandCallback(struct valkeyAsyncContext *ac, void* _reply, void* _privdata); -static void connectCallback(redisAsyncContext *c, int status) { +static void connectCallback(valkeyAsyncContext *c, int status) { struct _astest *t = (struct _astest *)c->data; assert(t == &astest); assert(t->connects == 0); @@ -2110,18 +2110,18 @@ static void connectCallback(redisAsyncContext *c, int status) { strcpy(t->errstr, c->errstr); t->connects++; t->connect_status = status; - t->connected = status == REDIS_OK ? 1 : -1; + t->connected = status == VALKEY_OK ? 1 : -1; if (t->testno == ASTEST_ISSUE_931) { /* disconnect again */ - redisAsyncDisconnect(c); + valkeyAsyncDisconnect(c); } else if (t->testno == ASTEST_ISSUE_931_PING) { - redisAsyncCommand(c, commandCallback, NULL, "PING"); + valkeyAsyncCommand(c, commandCallback, NULL, "PING"); } } -static void disconnectCallback(const redisAsyncContext *c, int status) { +static void disconnectCallback(const valkeyAsyncContext *c, int status) { assert(c->data == (void*)&astest); assert(astest.disconnects == 0); astest.err = c->err; @@ -2131,9 +2131,9 @@ static void disconnectCallback(const redisAsyncContext *c, int status) { astest.connected = 0; } -static void commandCallback(struct redisAsyncContext *ac, void* _reply, void* _privdata) +static void commandCallback(struct valkeyAsyncContext *ac, void* _reply, void* _privdata) { - redisReply *reply = (redisReply*)_reply; + valkeyReply *reply = (valkeyReply*)_reply; struct _astest *t = (struct _astest *)ac->data; assert(t == &astest); (void)_privdata; @@ -2142,61 +2142,61 @@ static void commandCallback(struct redisAsyncContext *ac, void* _reply, void* _p t->counter++; if (t->testno == ASTEST_PINGPONG ||t->testno == ASTEST_ISSUE_931_PING) { - assert(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); + assert(reply != NULL && reply->type == VALKEY_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); t->pongs++; - redisAsyncFree(ac); + valkeyAsyncFree(ac); } if (t->testno == ASTEST_PINGPONG_TIMEOUT) { /* two ping pongs */ - assert(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); + assert(reply != NULL && reply->type == VALKEY_REPLY_STATUS && strcmp(reply->str, "PONG") == 0); t->pongs++; if (t->counter == 1) { - int status = redisAsyncCommand(ac, commandCallback, NULL, "PING"); - assert(status == REDIS_OK); + int status = valkeyAsyncCommand(ac, commandCallback, NULL, "PING"); + assert(status == VALKEY_OK); } else { - redisAsyncFree(ac); + valkeyAsyncFree(ac); } } } -static redisAsyncContext *do_aconnect(struct config config, astest_no testno) +static valkeyAsyncContext *do_aconnect(struct config config, astest_no testno) { - redisOptions options = {0}; + valkeyOptions options = {0}; memset(&astest, 0, sizeof(astest)); astest.testno = testno; astest.connect_status = astest.disconnect_status = -2; if (config.type == CONN_TCP) { - options.type = REDIS_CONN_TCP; + options.type = VALKEY_CONN_TCP; options.connect_timeout = &config.connect_timeout; - REDIS_OPTIONS_SET_TCP(&options, config.tcp.host, config.tcp.port); + VALKEY_OPTIONS_SET_TCP(&options, config.tcp.host, config.tcp.port); } else if (config.type == CONN_SSL) { - options.type = REDIS_CONN_TCP; + options.type = VALKEY_CONN_TCP; options.connect_timeout = &config.connect_timeout; - REDIS_OPTIONS_SET_TCP(&options, config.ssl.host, config.ssl.port); + VALKEY_OPTIONS_SET_TCP(&options, config.ssl.host, config.ssl.port); } else if (config.type == CONN_UNIX) { - options.type = REDIS_CONN_UNIX; + options.type = VALKEY_CONN_UNIX; options.endpoint.unix_socket = config.unix_sock.path; } else if (config.type == CONN_FD) { - options.type = REDIS_CONN_USERFD; + options.type = VALKEY_CONN_USERFD; /* Create a dummy connection just to get an fd to inherit */ - redisContext *dummy_ctx = redisConnectUnix(config.unix_sock.path); + valkeyContext *dummy_ctx = valkeyConnectUnix(config.unix_sock.path); if (dummy_ctx) { - redisFD fd = disconnect(dummy_ctx, 1); + valkeyFD fd = disconnect(dummy_ctx, 1); printf("Connecting to inherited fd %d\n", (int)fd); options.endpoint.fd = fd; } } - redisAsyncContext *c = redisAsyncConnectWithOptions(&options); + valkeyAsyncContext *c = valkeyAsyncConnectWithOptions(&options); assert(c); astest.ac = c; c->data = &astest; c->dataCleanup = asCleanup; - redisPollAttach(c); - redisAsyncSetConnectCallbackNC(c, connectCallback); - redisAsyncSetDisconnectCallback(c, disconnectCallback); + valkeyPollAttach(c); + valkeyAsyncSetConnectCallbackNC(c, connectCallback); + valkeyAsyncSetDisconnectCallback(c, disconnectCallback); return c; } @@ -2212,25 +2212,25 @@ static void as_printerr(void) { static void test_async_polling(struct config config) { int status; - redisAsyncContext *c; + valkeyAsyncContext *c; struct config defaultconfig = config; test("Async connect: "); c = do_aconnect(config, ASTEST_CONNECT); assert(c); while(astest.connected == 0) - redisPollTick(c, 0.1); + valkeyPollTick(c, 0.1); assert(astest.connects == 1); - ASASSERT(astest.connect_status == REDIS_OK); + ASASSERT(astest.connect_status == VALKEY_OK); assert(astest.disconnects == 0); test_cond(astest.connected == 1); test("Async free after connect: "); assert(astest.ac != NULL); - redisAsyncFree(c); + valkeyAsyncFree(c); assert(astest.disconnects == 1); assert(astest.ac == NULL); - test_cond(astest.disconnect_status == REDIS_OK); + test_cond(astest.disconnect_status == VALKEY_OK); if (config.type == CONN_TCP || config.type == CONN_SSL) { /* timeout can only be simulated with network */ @@ -2241,14 +2241,14 @@ static void test_async_polling(struct config config) { assert(c); assert(c->err == 0); while(astest.connected == 0) - redisPollTick(c, 0.1); + valkeyPollTick(c, 0.1); assert(astest.connected == -1); /* * freeing should not be done, clearing should have happened. - *redisAsyncFree(c); + *valkeyAsyncFree(c); */ assert(astest.ac == NULL); - test_cond(astest.connect_status == REDIS_ERR); + test_cond(astest.connect_status == VALKEY_ERR); config = defaultconfig; } @@ -2256,51 +2256,45 @@ static void test_async_polling(struct config config) { test("Async PING/PONG: "); c = do_aconnect(config, ASTEST_PINGPONG); while(astest.connected == 0) - redisPollTick(c, 0.1); - status = redisAsyncCommand(c, commandCallback, NULL, "PING"); - assert(status == REDIS_OK); + valkeyPollTick(c, 0.1); + status = valkeyAsyncCommand(c, commandCallback, NULL, "PING"); + assert(status == VALKEY_OK); while(astest.ac) - redisPollTick(c, 0.1); + valkeyPollTick(c, 0.1); test_cond(astest.pongs == 1); - /* Test a ping/pong after connection that didn't time out. - * see https://github.com/redis/hiredis/issues/945 - */ + /* Test a ping/pong after connection that didn't time out. */ if (config.type == CONN_TCP || config.type == CONN_SSL) { test("Async PING/PONG after connect timeout: "); config.connect_timeout.tv_usec = 10000; /* 10ms */ c = do_aconnect(config, ASTEST_PINGPONG_TIMEOUT); while(astest.connected == 0) - redisPollTick(c, 0.1); + valkeyPollTick(c, 0.1); /* sleep 0.1 s, allowing old timeout to arrive */ millisleep(10); - status = redisAsyncCommand(c, commandCallback, NULL, "PING"); - assert(status == REDIS_OK); + status = valkeyAsyncCommand(c, commandCallback, NULL, "PING"); + assert(status == VALKEY_OK); while(astest.ac) - redisPollTick(c, 0.1); + valkeyPollTick(c, 0.1); test_cond(astest.pongs == 2); config = defaultconfig; } - /* Test disconnect from an on_connect callback - * see https://github.com/redis/hiredis/issues/931 - */ + /* Test disconnect from an on_connect callback */ test("Disconnect from onConnected callback (Issue #931): "); c = do_aconnect(config, ASTEST_ISSUE_931); while(astest.disconnects == 0) - redisPollTick(c, 0.1); + valkeyPollTick(c, 0.1); assert(astest.connected == 0); assert(astest.connects == 1); test_cond(astest.disconnects == 1); - /* Test ping/pong from an on_connect callback - * see https://github.com/redis/hiredis/issues/931 - */ + /* Test ping/pong from an on_connect callback */ test("Ping/Pong from onConnected callback (Issue #931): "); c = do_aconnect(config, ASTEST_ISSUE_931_PING); /* connect callback issues ping, response callback destroys context */ while(astest.ac) - redisPollTick(c, 0.1); + valkeyPollTick(c, 0.1); assert(astest.connected == 0); assert(astest.connects == 1); assert(astest.disconnects == 1); @@ -2315,7 +2309,7 @@ int main(int argc, char **argv) { .port = 6379 }, .unix_sock = { - .path = "/tmp/redis.sock" + .path = "/tmp/valkey.sock" } }; int throughput = 1; @@ -2341,7 +2335,7 @@ int main(int argc, char **argv) { test_inherit_fd = 0; } else if (argc >= 1 && !strcmp(argv[0],"--skips-as-fails")) { skips_as_fails = 1; -#ifdef HIREDIS_TEST_SSL +#ifdef VALKEY_TEST_SSL } else if (argc >= 2 && !strcmp(argv[0],"--ssl-port")) { argv++; argc--; cfg.ssl.port = atoi(argv[0]); @@ -2407,11 +2401,11 @@ int main(int argc, char **argv) { test_skipped(); } -#ifdef HIREDIS_TEST_SSL +#ifdef VALKEY_TEST_SSL if (cfg.ssl.port && cfg.ssl.host) { - redisInitOpenSSL(); - _ssl_ctx = redisCreateSSLContext(cfg.ssl.ca_cert, NULL, cfg.ssl.cert, cfg.ssl.key, NULL, NULL); + valkeyInitOpenSSL(); + _ssl_ctx = valkeyCreateSSLContext(cfg.ssl.ca_cert, NULL, cfg.ssl.cert, cfg.ssl.key, NULL, NULL); assert(_ssl_ctx != NULL); printf("\nTesting against SSL connection (%s:%d):\n", cfg.ssl.host, cfg.ssl.port); @@ -2424,19 +2418,19 @@ int main(int argc, char **argv) { test_append_formatted_commands(cfg); if (throughput) test_throughput(cfg); - redisFreeSSLContext(_ssl_ctx); + valkeyFreeSSLContext(_ssl_ctx); _ssl_ctx = NULL; } #endif -#ifdef HIREDIS_TEST_ASYNC +#ifdef VALKEY_TEST_ASYNC cfg.type = CONN_TCP; printf("\nTesting asynchronous API against TCP connection (%s:%d):\n", cfg.tcp.host, cfg.tcp.port); cfg.type = CONN_TCP; int major; - redisContext *c = do_connect(cfg); - get_redis_version(c, &major, NULL); + valkeyContext *c = do_connect(cfg); + get_server_version(c, &major, NULL); disconnect(c, 0); test_pubsub_handling(cfg); @@ -2446,7 +2440,7 @@ int main(int argc, char **argv) { test_pubsub_handling_resp3(cfg); test_command_timeout_during_pubsub(cfg); } -#endif /* HIREDIS_TEST_ASYNC */ +#endif /* VALKEY_TEST_ASYNC */ cfg.type = CONN_TCP; printf("\nTesting asynchronous API using polling_adapter TCP (%s:%d):\n", cfg.tcp.host, cfg.tcp.port); diff --git a/libvalkey/hiredis.c b/src/valkey.c similarity index 58% rename from libvalkey/hiredis.c rename to src/valkey.c index 739ce2a2..8e9fea43 100644 --- a/libvalkey/hiredis.c +++ b/src/valkey.c @@ -38,35 +38,35 @@ #include #include -#include "hiredis.h" +#include "valkey.h" #include "net.h" #include "sds.h" #include "async.h" #include "win32.h" -extern int redisContextUpdateConnectTimeout(redisContext *c, const struct timeval *timeout); -extern int redisContextUpdateCommandTimeout(redisContext *c, const struct timeval *timeout); +extern int valkeyContextUpdateConnectTimeout(valkeyContext *c, const struct timeval *timeout); +extern int valkeyContextUpdateCommandTimeout(valkeyContext *c, const struct timeval *timeout); -static redisContextFuncs redisContextDefaultFuncs = { - .close = redisNetClose, +static valkeyContextFuncs valkeyContextDefaultFuncs = { + .close = valkeyNetClose, .free_privctx = NULL, - .async_read = redisAsyncRead, - .async_write = redisAsyncWrite, - .read = redisNetRead, - .write = redisNetWrite + .async_read = valkeyAsyncRead, + .async_write = valkeyAsyncWrite, + .read = valkeyNetRead, + .write = valkeyNetWrite }; -static redisReply *createReplyObject(int type); -static void *createStringObject(const redisReadTask *task, char *str, size_t len); -static void *createArrayObject(const redisReadTask *task, size_t elements); -static void *createIntegerObject(const redisReadTask *task, long long value); -static void *createDoubleObject(const redisReadTask *task, double value, char *str, size_t len); -static void *createNilObject(const redisReadTask *task); -static void *createBoolObject(const redisReadTask *task, int bval); +static valkeyReply *createReplyObject(int type); +static void *createStringObject(const valkeyReadTask *task, char *str, size_t len); +static void *createArrayObject(const valkeyReadTask *task, size_t elements); +static void *createIntegerObject(const valkeyReadTask *task, long long value); +static void *createDoubleObject(const valkeyReadTask *task, double value, char *str, size_t len); +static void *createNilObject(const valkeyReadTask *task); +static void *createBoolObject(const valkeyReadTask *task, int bval); /* Default set of functions to build the reply. Keep in mind that such a * function returning NULL is interpreted as OOM. */ -static redisReplyObjectFunctions defaultFunctions = { +static valkeyReplyObjectFunctions defaultFunctions = { createStringObject, createArrayObject, createIntegerObject, @@ -77,8 +77,8 @@ static redisReplyObjectFunctions defaultFunctions = { }; /* Create a reply object */ -static redisReply *createReplyObject(int type) { - redisReply *r = hi_calloc(1,sizeof(*r)); +static valkeyReply *createReplyObject(int type) { + valkeyReply *r = vk_calloc(1,sizeof(*r)); if (r == NULL) return NULL; @@ -89,57 +89,57 @@ static redisReply *createReplyObject(int type) { /* Free a reply object */ void freeReplyObject(void *reply) { - redisReply *r = reply; + valkeyReply *r = reply; size_t j; if (r == NULL) return; switch(r->type) { - case REDIS_REPLY_INTEGER: - case REDIS_REPLY_NIL: - case REDIS_REPLY_BOOL: + case VALKEY_REPLY_INTEGER: + case VALKEY_REPLY_NIL: + case VALKEY_REPLY_BOOL: break; /* Nothing to free */ - case REDIS_REPLY_ARRAY: - case REDIS_REPLY_MAP: - case REDIS_REPLY_ATTR: - case REDIS_REPLY_SET: - case REDIS_REPLY_PUSH: + case VALKEY_REPLY_ARRAY: + case VALKEY_REPLY_MAP: + case VALKEY_REPLY_ATTR: + case VALKEY_REPLY_SET: + case VALKEY_REPLY_PUSH: if (r->element != NULL) { for (j = 0; j < r->elements; j++) freeReplyObject(r->element[j]); - hi_free(r->element); + vk_free(r->element); } break; - case REDIS_REPLY_ERROR: - case REDIS_REPLY_STATUS: - case REDIS_REPLY_STRING: - case REDIS_REPLY_DOUBLE: - case REDIS_REPLY_VERB: - case REDIS_REPLY_BIGNUM: - hi_free(r->str); + case VALKEY_REPLY_ERROR: + case VALKEY_REPLY_STATUS: + case VALKEY_REPLY_STRING: + case VALKEY_REPLY_DOUBLE: + case VALKEY_REPLY_VERB: + case VALKEY_REPLY_BIGNUM: + vk_free(r->str); break; } - hi_free(r); + vk_free(r); } -static void *createStringObject(const redisReadTask *task, char *str, size_t len) { - redisReply *r, *parent; +static void *createStringObject(const valkeyReadTask *task, char *str, size_t len) { + valkeyReply *r, *parent; char *buf; r = createReplyObject(task->type); if (r == NULL) return NULL; - assert(task->type == REDIS_REPLY_ERROR || - task->type == REDIS_REPLY_STATUS || - task->type == REDIS_REPLY_STRING || - task->type == REDIS_REPLY_VERB || - task->type == REDIS_REPLY_BIGNUM); + assert(task->type == VALKEY_REPLY_ERROR || + task->type == VALKEY_REPLY_STATUS || + task->type == VALKEY_REPLY_STRING || + task->type == VALKEY_REPLY_VERB || + task->type == VALKEY_REPLY_BIGNUM); /* Copy string value */ - if (task->type == REDIS_REPLY_VERB) { - buf = hi_malloc(len-4+1); /* Skip 4 bytes of verbatim type header. */ + if (task->type == VALKEY_REPLY_VERB) { + buf = vk_malloc(len-4+1); /* Skip 4 bytes of verbatim type header. */ if (buf == NULL) goto oom; memcpy(r->vtype,str,3); @@ -148,7 +148,7 @@ static void *createStringObject(const redisReadTask *task, char *str, size_t len buf[len-4] = '\0'; r->len = len - 4; } else { - buf = hi_malloc(len+1); + buf = vk_malloc(len+1); if (buf == NULL) goto oom; memcpy(buf,str,len); @@ -159,11 +159,11 @@ static void *createStringObject(const redisReadTask *task, char *str, size_t len if (task->parent) { parent = task->parent->obj; - assert(parent->type == REDIS_REPLY_ARRAY || - parent->type == REDIS_REPLY_MAP || - parent->type == REDIS_REPLY_ATTR || - parent->type == REDIS_REPLY_SET || - parent->type == REDIS_REPLY_PUSH); + assert(parent->type == VALKEY_REPLY_ARRAY || + parent->type == VALKEY_REPLY_MAP || + parent->type == VALKEY_REPLY_ATTR || + parent->type == VALKEY_REPLY_SET || + parent->type == VALKEY_REPLY_PUSH); parent->element[task->idx] = r; } return r; @@ -173,15 +173,15 @@ static void *createStringObject(const redisReadTask *task, char *str, size_t len return NULL; } -static void *createArrayObject(const redisReadTask *task, size_t elements) { - redisReply *r, *parent; +static void *createArrayObject(const valkeyReadTask *task, size_t elements) { + valkeyReply *r, *parent; r = createReplyObject(task->type); if (r == NULL) return NULL; if (elements > 0) { - r->element = hi_calloc(elements,sizeof(redisReply*)); + r->element = vk_calloc(elements,sizeof(valkeyReply*)); if (r->element == NULL) { freeReplyObject(r); return NULL; @@ -192,20 +192,20 @@ static void *createArrayObject(const redisReadTask *task, size_t elements) { if (task->parent) { parent = task->parent->obj; - assert(parent->type == REDIS_REPLY_ARRAY || - parent->type == REDIS_REPLY_MAP || - parent->type == REDIS_REPLY_ATTR || - parent->type == REDIS_REPLY_SET || - parent->type == REDIS_REPLY_PUSH); + assert(parent->type == VALKEY_REPLY_ARRAY || + parent->type == VALKEY_REPLY_MAP || + parent->type == VALKEY_REPLY_ATTR || + parent->type == VALKEY_REPLY_SET || + parent->type == VALKEY_REPLY_PUSH); parent->element[task->idx] = r; } return r; } -static void *createIntegerObject(const redisReadTask *task, long long value) { - redisReply *r, *parent; +static void *createIntegerObject(const valkeyReadTask *task, long long value) { + valkeyReply *r, *parent; - r = createReplyObject(REDIS_REPLY_INTEGER); + r = createReplyObject(VALKEY_REPLY_INTEGER); if (r == NULL) return NULL; @@ -213,28 +213,28 @@ static void *createIntegerObject(const redisReadTask *task, long long value) { if (task->parent) { parent = task->parent->obj; - assert(parent->type == REDIS_REPLY_ARRAY || - parent->type == REDIS_REPLY_MAP || - parent->type == REDIS_REPLY_ATTR || - parent->type == REDIS_REPLY_SET || - parent->type == REDIS_REPLY_PUSH); + assert(parent->type == VALKEY_REPLY_ARRAY || + parent->type == VALKEY_REPLY_MAP || + parent->type == VALKEY_REPLY_ATTR || + parent->type == VALKEY_REPLY_SET || + parent->type == VALKEY_REPLY_PUSH); parent->element[task->idx] = r; } return r; } -static void *createDoubleObject(const redisReadTask *task, double value, char *str, size_t len) { - redisReply *r, *parent; +static void *createDoubleObject(const valkeyReadTask *task, double value, char *str, size_t len) { + valkeyReply *r, *parent; - if (len == SIZE_MAX) // Prevents hi_malloc(0) if len equals to SIZE_MAX + if (len == SIZE_MAX) // Prevents vk_malloc(0) if len equals to SIZE_MAX return NULL; - r = createReplyObject(REDIS_REPLY_DOUBLE); + r = createReplyObject(VALKEY_REPLY_DOUBLE); if (r == NULL) return NULL; r->dval = value; - r->str = hi_malloc(len+1); + r->str = vk_malloc(len+1); if (r->str == NULL) { freeReplyObject(r); return NULL; @@ -242,7 +242,7 @@ static void *createDoubleObject(const redisReadTask *task, double value, char *s /* The double reply also has the original protocol string representing a * double as a null terminated string. This way the caller does not need - * to format back for string conversion, especially since Redis does efforts + * to format back for string conversion, especially since Valkey does efforts * to make the string more human readable avoiding the calssical double * decimal string conversion artifacts. */ memcpy(r->str, str, len); @@ -251,39 +251,39 @@ static void *createDoubleObject(const redisReadTask *task, double value, char *s if (task->parent) { parent = task->parent->obj; - assert(parent->type == REDIS_REPLY_ARRAY || - parent->type == REDIS_REPLY_MAP || - parent->type == REDIS_REPLY_ATTR || - parent->type == REDIS_REPLY_SET || - parent->type == REDIS_REPLY_PUSH); + assert(parent->type == VALKEY_REPLY_ARRAY || + parent->type == VALKEY_REPLY_MAP || + parent->type == VALKEY_REPLY_ATTR || + parent->type == VALKEY_REPLY_SET || + parent->type == VALKEY_REPLY_PUSH); parent->element[task->idx] = r; } return r; } -static void *createNilObject(const redisReadTask *task) { - redisReply *r, *parent; +static void *createNilObject(const valkeyReadTask *task) { + valkeyReply *r, *parent; - r = createReplyObject(REDIS_REPLY_NIL); + r = createReplyObject(VALKEY_REPLY_NIL); if (r == NULL) return NULL; if (task->parent) { parent = task->parent->obj; - assert(parent->type == REDIS_REPLY_ARRAY || - parent->type == REDIS_REPLY_MAP || - parent->type == REDIS_REPLY_ATTR || - parent->type == REDIS_REPLY_SET || - parent->type == REDIS_REPLY_PUSH); + assert(parent->type == VALKEY_REPLY_ARRAY || + parent->type == VALKEY_REPLY_MAP || + parent->type == VALKEY_REPLY_ATTR || + parent->type == VALKEY_REPLY_SET || + parent->type == VALKEY_REPLY_PUSH); parent->element[task->idx] = r; } return r; } -static void *createBoolObject(const redisReadTask *task, int bval) { - redisReply *r, *parent; +static void *createBoolObject(const valkeyReadTask *task, int bval) { + valkeyReply *r, *parent; - r = createReplyObject(REDIS_REPLY_BOOL); + r = createReplyObject(VALKEY_REPLY_BOOL); if (r == NULL) return NULL; @@ -291,18 +291,18 @@ static void *createBoolObject(const redisReadTask *task, int bval) { if (task->parent) { parent = task->parent->obj; - assert(parent->type == REDIS_REPLY_ARRAY || - parent->type == REDIS_REPLY_MAP || - parent->type == REDIS_REPLY_ATTR || - parent->type == REDIS_REPLY_SET || - parent->type == REDIS_REPLY_PUSH); + assert(parent->type == VALKEY_REPLY_ARRAY || + parent->type == VALKEY_REPLY_MAP || + parent->type == VALKEY_REPLY_ATTR || + parent->type == VALKEY_REPLY_SET || + parent->type == VALKEY_REPLY_PUSH); parent->element[task->idx] = r; } return r; } /* Return the number of digits of 'v' when converted to string in radix 10. - * Implementation borrowed from link in redis/src/util.c:string2ll(). */ + * Implementation borrowed from link in valkey/src/util.c:string2ll(). */ static uint32_t countDigits(uint64_t v) { uint32_t result = 1; for (;;) { @@ -320,7 +320,7 @@ static size_t bulklen(size_t len) { return 1+countDigits(len)+2+len+2; } -int redisvFormatCommand(char **target, const char *format, va_list ap) { +int valkeyvFormatCommand(char **target, const char *format, va_list ap) { const char *c = format; char *cmd = NULL; /* final command */ int pos; /* position in final command */ @@ -345,7 +345,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { if (*c != '%' || c[1] == '\0') { if (*c == ' ') { if (touched) { - newargv = hi_realloc(curargv,sizeof(char*)*(argc+1)); + newargv = vk_realloc(curargv,sizeof(char*)*(argc+1)); if (newargv == NULL) goto memory_err; curargv = newargv; curargv[argc++] = curarg; @@ -501,7 +501,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { /* Add the last argument if needed */ if (touched) { - newargv = hi_realloc(curargv,sizeof(char*)*(argc+1)); + newargv = vk_realloc(curargv,sizeof(char*)*(argc+1)); if (newargv == NULL) goto memory_err; curargv = newargv; curargv[argc++] = curarg; @@ -517,7 +517,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { totlen += 1+countDigits(argc)+2; /* Build the command at protocol level */ - cmd = hi_malloc(totlen+1); + cmd = vk_malloc(totlen+1); if (cmd == NULL) goto memory_err; pos = sprintf(cmd,"*%d\r\n",argc); @@ -532,7 +532,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { assert(pos == totlen); cmd[pos] = '\0'; - hi_free(curargv); + vk_free(curargv); *target = cmd; return totlen; @@ -548,16 +548,16 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { if (curargv) { while(argc--) sdsfree(curargv[argc]); - hi_free(curargv); + vk_free(curargv); } sdsfree(curarg); - hi_free(cmd); + vk_free(cmd); return error_type; } -/* Format a command according to the Redis protocol. This function +/* Format a command according to the RESP protocol. This function * takes a format similar to printf: * * %s represents a C null terminated string you want to interpolate @@ -566,14 +566,14 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { * When using %b you need to provide both the pointer to the string * and the length in bytes as a size_t. Examples: * - * len = redisFormatCommand(target, "GET %s", mykey); - * len = redisFormatCommand(target, "SET %s %b", mykey, myval, myvallen); + * len = valkeyFormatCommand(target, "GET %s", mykey); + * len = valkeyFormatCommand(target, "SET %s %b", mykey, myval, myvallen); */ -int redisFormatCommand(char **target, const char *format, ...) { +int valkeyFormatCommand(char **target, const char *format, ...) { va_list ap; int len; va_start(ap,format); - len = redisvFormatCommand(target,format,ap); + len = valkeyvFormatCommand(target,format,ap); va_end(ap); /* The API says "-1" means bad result, but we now also return "-2" in some @@ -584,13 +584,13 @@ int redisFormatCommand(char **target, const char *format, ...) { return len; } -/* Format a command according to the Redis protocol using an sds string and +/* Format a command according to the RESP protocol using an sds string and * sdscatfmt for the processing of arguments. This function takes the * number of arguments, an array with arguments and an array with their * lengths. If the latter is set to NULL, strlen will be used to compute the * argument lengths. */ -long long redisFormatSdsCommandArgv(sds *target, int argc, const char **argv, +long long valkeyFormatSdsCommandArgv(sds *target, int argc, const char **argv, const size_t *argvlen) { sds cmd, aux; @@ -637,16 +637,16 @@ long long redisFormatSdsCommandArgv(sds *target, int argc, const char **argv, return totlen; } -void redisFreeSdsCommand(sds cmd) { +void valkeyFreeSdsCommand(sds cmd) { sdsfree(cmd); } -/* Format a command according to the Redis protocol. This function takes the +/* Format a command according to the RESP protocol. This function takes the * number of arguments, an array with arguments and an array with their * lengths. If the latter is set to NULL, strlen will be used to compute the * argument lengths. */ -long long redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) { +long long valkeyFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) { char *cmd = NULL; /* final command */ size_t pos; /* position in final command */ size_t len, totlen; @@ -664,7 +664,7 @@ long long redisFormatCommandArgv(char **target, int argc, const char **argv, con } /* Build the command at protocol level */ - cmd = hi_malloc(totlen+1); + cmd = vk_malloc(totlen+1); if (cmd == NULL) return -1; @@ -684,11 +684,11 @@ long long redisFormatCommandArgv(char **target, int argc, const char **argv, con return totlen; } -void redisFreeCommand(char *cmd) { - hi_free(cmd); +void valkeyFreeCommand(char *cmd) { + vk_free(cmd); } -void __redisSetError(redisContext *c, int type, const char *str) { +void valkeySetError(valkeyContext *c, int type, const char *str) { size_t len; c->err = type; @@ -698,43 +698,43 @@ void __redisSetError(redisContext *c, int type, const char *str) { memcpy(c->errstr,str,len); c->errstr[len] = '\0'; } else { - /* Only REDIS_ERR_IO may lack a description! */ - assert(type == REDIS_ERR_IO); + /* Only VALKEY_ERR_IO may lack a description! */ + assert(type == VALKEY_ERR_IO); strerror_r(errno, c->errstr, sizeof(c->errstr)); } } -redisReader *redisReaderCreate(void) { - return redisReaderCreateWithFunctions(&defaultFunctions); +valkeyReader *valkeyReaderCreate(void) { + return valkeyReaderCreateWithFunctions(&defaultFunctions); } -static void redisPushAutoFree(void *privdata, void *reply) { +static void valkeyPushAutoFree(void *privdata, void *reply) { (void)privdata; freeReplyObject(reply); } -static redisContext *redisContextInit(void) { - redisContext *c; +static valkeyContext *valkeyContextInit(void) { + valkeyContext *c; - c = hi_calloc(1, sizeof(*c)); + c = vk_calloc(1, sizeof(*c)); if (c == NULL) return NULL; - c->funcs = &redisContextDefaultFuncs; + c->funcs = &valkeyContextDefaultFuncs; c->obuf = sdsempty(); - c->reader = redisReaderCreate(); - c->fd = REDIS_INVALID_FD; + c->reader = valkeyReaderCreate(); + c->fd = VALKEY_INVALID_FD; if (c->obuf == NULL || c->reader == NULL) { - redisFree(c); + valkeyFree(c); return NULL; } return c; } -void redisFree(redisContext *c) { +void valkeyFree(valkeyContext *c) { if (c == NULL) return; @@ -743,13 +743,13 @@ void redisFree(redisContext *c) { } sdsfree(c->obuf); - redisReaderFree(c->reader); - hi_free(c->tcp.host); - hi_free(c->tcp.source_addr); - hi_free(c->unix_sock.path); - hi_free(c->connect_timeout); - hi_free(c->command_timeout); - hi_free(c->saddr); + valkeyReaderFree(c->reader); + vk_free(c->tcp.host); + vk_free(c->tcp.source_addr); + vk_free(c->unix_sock.path); + vk_free(c->connect_timeout); + vk_free(c->command_timeout); + vk_free(c->saddr); if (c->privdata && c->free_privdata) c->free_privdata(c->privdata); @@ -758,17 +758,17 @@ void redisFree(redisContext *c) { c->funcs->free_privctx(c->privctx); memset(c, 0xff, sizeof(*c)); - hi_free(c); + vk_free(c); } -redisFD redisFreeKeepFd(redisContext *c) { - redisFD fd = c->fd; - c->fd = REDIS_INVALID_FD; - redisFree(c); +valkeyFD valkeyFreeKeepFd(valkeyContext *c) { + valkeyFD fd = c->fd; + c->fd = VALKEY_INVALID_FD; + valkeyFree(c); return fd; } -int redisReconnect(redisContext *c) { +int valkeyReconnect(valkeyContext *c) { c->err = 0; memset(c->errstr, '\0', strlen(c->errstr)); @@ -782,192 +782,192 @@ int redisReconnect(redisContext *c) { } sdsfree(c->obuf); - redisReaderFree(c->reader); + valkeyReaderFree(c->reader); c->obuf = sdsempty(); - c->reader = redisReaderCreate(); + c->reader = valkeyReaderCreate(); if (c->obuf == NULL || c->reader == NULL) { - __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); - return REDIS_ERR; + valkeySetError(c, VALKEY_ERR_OOM, "Out of memory"); + return VALKEY_ERR; } - int ret = REDIS_ERR; - if (c->connection_type == REDIS_CONN_TCP) { - ret = redisContextConnectBindTcp(c, c->tcp.host, c->tcp.port, + int ret = VALKEY_ERR; + if (c->connection_type == VALKEY_CONN_TCP) { + ret = valkeyContextConnectBindTcp(c, c->tcp.host, c->tcp.port, c->connect_timeout, c->tcp.source_addr); - } else if (c->connection_type == REDIS_CONN_UNIX) { - ret = redisContextConnectUnix(c, c->unix_sock.path, c->connect_timeout); + } else if (c->connection_type == VALKEY_CONN_UNIX) { + ret = valkeyContextConnectUnix(c, c->unix_sock.path, c->connect_timeout); } else { /* Something bad happened here and shouldn't have. There isn't enough information in the context to reconnect. */ - __redisSetError(c,REDIS_ERR_OTHER,"Not enough information to reconnect"); - ret = REDIS_ERR; + valkeySetError(c,VALKEY_ERR_OTHER,"Not enough information to reconnect"); + ret = VALKEY_ERR; } - if (c->command_timeout != NULL && (c->flags & REDIS_BLOCK) && c->fd != REDIS_INVALID_FD) { - redisContextSetTimeout(c, *c->command_timeout); + if (c->command_timeout != NULL && (c->flags & VALKEY_BLOCK) && c->fd != VALKEY_INVALID_FD) { + valkeyContextSetTimeout(c, *c->command_timeout); } return ret; } -redisContext *redisConnectWithOptions(const redisOptions *options) { - redisContext *c = redisContextInit(); +valkeyContext *valkeyConnectWithOptions(const valkeyOptions *options) { + valkeyContext *c = valkeyContextInit(); if (c == NULL) { return NULL; } - if (!(options->options & REDIS_OPT_NONBLOCK)) { - c->flags |= REDIS_BLOCK; + if (!(options->options & VALKEY_OPT_NONBLOCK)) { + c->flags |= VALKEY_BLOCK; } - if (options->options & REDIS_OPT_REUSEADDR) { - c->flags |= REDIS_REUSEADDR; + if (options->options & VALKEY_OPT_REUSEADDR) { + c->flags |= VALKEY_REUSEADDR; } - if (options->options & REDIS_OPT_NOAUTOFREE) { - c->flags |= REDIS_NO_AUTO_FREE; + if (options->options & VALKEY_OPT_NOAUTOFREE) { + c->flags |= VALKEY_NO_AUTO_FREE; } - if (options->options & REDIS_OPT_NOAUTOFREEREPLIES) { - c->flags |= REDIS_NO_AUTO_FREE_REPLIES; + if (options->options & VALKEY_OPT_NOAUTOFREEREPLIES) { + c->flags |= VALKEY_NO_AUTO_FREE_REPLIES; } - if (options->options & REDIS_OPT_PREFER_IPV4) { - c->flags |= REDIS_PREFER_IPV4; + if (options->options & VALKEY_OPT_PREFER_IPV4) { + c->flags |= VALKEY_PREFER_IPV4; } - if (options->options & REDIS_OPT_PREFER_IPV6) { - c->flags |= REDIS_PREFER_IPV6; + if (options->options & VALKEY_OPT_PREFER_IPV6) { + c->flags |= VALKEY_PREFER_IPV6; } /* Set any user supplied RESP3 PUSH handler or use freeReplyObject * as a default unless specifically flagged that we don't want one. */ if (options->push_cb != NULL) - redisSetPushCallback(c, options->push_cb); - else if (!(options->options & REDIS_OPT_NO_PUSH_AUTOFREE)) - redisSetPushCallback(c, redisPushAutoFree); + valkeySetPushCallback(c, options->push_cb); + else if (!(options->options & VALKEY_OPT_NO_PUSH_AUTOFREE)) + valkeySetPushCallback(c, valkeyPushAutoFree); c->privdata = options->privdata; c->free_privdata = options->free_privdata; - if (redisContextUpdateConnectTimeout(c, options->connect_timeout) != REDIS_OK || - redisContextUpdateCommandTimeout(c, options->command_timeout) != REDIS_OK) { - __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); + if (valkeyContextUpdateConnectTimeout(c, options->connect_timeout) != VALKEY_OK || + valkeyContextUpdateCommandTimeout(c, options->command_timeout) != VALKEY_OK) { + valkeySetError(c, VALKEY_ERR_OOM, "Out of memory"); return c; } - if (options->type == REDIS_CONN_TCP) { - redisContextConnectBindTcp(c, options->endpoint.tcp.ip, + if (options->type == VALKEY_CONN_TCP) { + valkeyContextConnectBindTcp(c, options->endpoint.tcp.ip, options->endpoint.tcp.port, options->connect_timeout, options->endpoint.tcp.source_addr); - } else if (options->type == REDIS_CONN_UNIX) { - redisContextConnectUnix(c, options->endpoint.unix_socket, + } else if (options->type == VALKEY_CONN_UNIX) { + valkeyContextConnectUnix(c, options->endpoint.unix_socket, options->connect_timeout); - } else if (options->type == REDIS_CONN_USERFD) { + } else if (options->type == VALKEY_CONN_USERFD) { c->fd = options->endpoint.fd; - c->flags |= REDIS_CONNECTED; + c->flags |= VALKEY_CONNECTED; } else { - redisFree(c); + valkeyFree(c); return NULL; } - if (c->err == 0 && c->fd != REDIS_INVALID_FD && - options->command_timeout != NULL && (c->flags & REDIS_BLOCK)) + if (c->err == 0 && c->fd != VALKEY_INVALID_FD && + options->command_timeout != NULL && (c->flags & VALKEY_BLOCK)) { - redisContextSetTimeout(c, *options->command_timeout); + valkeyContextSetTimeout(c, *options->command_timeout); } return c; } -/* Connect to a Redis instance. On error the field error in the returned +/* Connect to a server instance. On error the field error in the returned * context will be set to the return value of the error function. * When no set of reply functions is given, the default set will be used. */ -redisContext *redisConnect(const char *ip, int port) { - redisOptions options = {0}; - REDIS_OPTIONS_SET_TCP(&options, ip, port); - return redisConnectWithOptions(&options); +valkeyContext *valkeyConnect(const char *ip, int port) { + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_TCP(&options, ip, port); + return valkeyConnectWithOptions(&options); } -redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv) { - redisOptions options = {0}; - REDIS_OPTIONS_SET_TCP(&options, ip, port); +valkeyContext *valkeyConnectWithTimeout(const char *ip, int port, const struct timeval tv) { + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_TCP(&options, ip, port); options.connect_timeout = &tv; - return redisConnectWithOptions(&options); + return valkeyConnectWithOptions(&options); } -redisContext *redisConnectNonBlock(const char *ip, int port) { - redisOptions options = {0}; - REDIS_OPTIONS_SET_TCP(&options, ip, port); - options.options |= REDIS_OPT_NONBLOCK; - return redisConnectWithOptions(&options); +valkeyContext *valkeyConnectNonBlock(const char *ip, int port) { + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_TCP(&options, ip, port); + options.options |= VALKEY_OPT_NONBLOCK; + return valkeyConnectWithOptions(&options); } -redisContext *redisConnectBindNonBlock(const char *ip, int port, +valkeyContext *valkeyConnectBindNonBlock(const char *ip, int port, const char *source_addr) { - redisOptions options = {0}; - REDIS_OPTIONS_SET_TCP(&options, ip, port); + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_TCP(&options, ip, port); options.endpoint.tcp.source_addr = source_addr; - options.options |= REDIS_OPT_NONBLOCK; - return redisConnectWithOptions(&options); + options.options |= VALKEY_OPT_NONBLOCK; + return valkeyConnectWithOptions(&options); } -redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port, +valkeyContext *valkeyConnectBindNonBlockWithReuse(const char *ip, int port, const char *source_addr) { - redisOptions options = {0}; - REDIS_OPTIONS_SET_TCP(&options, ip, port); + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_TCP(&options, ip, port); options.endpoint.tcp.source_addr = source_addr; - options.options |= REDIS_OPT_NONBLOCK|REDIS_OPT_REUSEADDR; - return redisConnectWithOptions(&options); + options.options |= VALKEY_OPT_NONBLOCK|VALKEY_OPT_REUSEADDR; + return valkeyConnectWithOptions(&options); } -redisContext *redisConnectUnix(const char *path) { - redisOptions options = {0}; - REDIS_OPTIONS_SET_UNIX(&options, path); - return redisConnectWithOptions(&options); +valkeyContext *valkeyConnectUnix(const char *path) { + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_UNIX(&options, path); + return valkeyConnectWithOptions(&options); } -redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv) { - redisOptions options = {0}; - REDIS_OPTIONS_SET_UNIX(&options, path); +valkeyContext *valkeyConnectUnixWithTimeout(const char *path, const struct timeval tv) { + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_UNIX(&options, path); options.connect_timeout = &tv; - return redisConnectWithOptions(&options); + return valkeyConnectWithOptions(&options); } -redisContext *redisConnectUnixNonBlock(const char *path) { - redisOptions options = {0}; - REDIS_OPTIONS_SET_UNIX(&options, path); - options.options |= REDIS_OPT_NONBLOCK; - return redisConnectWithOptions(&options); +valkeyContext *valkeyConnectUnixNonBlock(const char *path) { + valkeyOptions options = {0}; + VALKEY_OPTIONS_SET_UNIX(&options, path); + options.options |= VALKEY_OPT_NONBLOCK; + return valkeyConnectWithOptions(&options); } -redisContext *redisConnectFd(redisFD fd) { - redisOptions options = {0}; - options.type = REDIS_CONN_USERFD; +valkeyContext *valkeyConnectFd(valkeyFD fd) { + valkeyOptions options = {0}; + options.type = VALKEY_CONN_USERFD; options.endpoint.fd = fd; - return redisConnectWithOptions(&options); + return valkeyConnectWithOptions(&options); } /* Set read/write timeout on a blocking socket. */ -int redisSetTimeout(redisContext *c, const struct timeval tv) { - if (c->flags & REDIS_BLOCK) - return redisContextSetTimeout(c,tv); - return REDIS_ERR; +int valkeySetTimeout(valkeyContext *c, const struct timeval tv) { + if (c->flags & VALKEY_BLOCK) + return valkeyContextSetTimeout(c,tv); + return VALKEY_ERR; } -int redisEnableKeepAliveWithInterval(redisContext *c, int interval) { - return redisKeepAlive(c, interval); +int valkeyEnableKeepAliveWithInterval(valkeyContext *c, int interval) { + return valkeyKeepAlive(c, interval); } /* Enable connection KeepAlive. */ -int redisEnableKeepAlive(redisContext *c) { - return redisKeepAlive(c, REDIS_KEEPALIVE_INTERVAL); +int valkeyEnableKeepAlive(valkeyContext *c) { + return valkeyKeepAlive(c, VALKEY_KEEPALIVE_INTERVAL); } /* Set the socket option TCP_USER_TIMEOUT. */ -int redisSetTcpUserTimeout(redisContext *c, unsigned int timeout) { - return redisContextSetTcpUserTimeout(c, timeout); +int valkeySetTcpUserTimeout(valkeyContext *c, unsigned int timeout) { + return valkeyContextSetTcpUserTimeout(c, timeout); } /* Set a user provided RESP3 PUSH handler and return any old one set. */ -redisPushFn *redisSetPushCallback(redisContext *c, redisPushFn *fn) { - redisPushFn *old = c->push_cb; +valkeyPushFn *valkeySetPushCallback(valkeyContext *c, valkeyPushFn *fn) { + valkeyPushFn *old = c->push_cb; c->push_cb = fn; return old; } @@ -975,46 +975,46 @@ redisPushFn *redisSetPushCallback(redisContext *c, redisPushFn *fn) { /* Use this function to handle a read event on the descriptor. It will try * and read some bytes from the socket and feed them to the reply parser. * - * After this function is called, you may use redisGetReplyFromReader to + * After this function is called, you may use valkeyGetReplyFromReader to * see if there is a reply available. */ -int redisBufferRead(redisContext *c) { +int valkeyBufferRead(valkeyContext *c) { char buf[1024*16]; int nread; /* Return early when the context has seen an error. */ if (c->err) - return REDIS_ERR; + return VALKEY_ERR; nread = c->funcs->read(c, buf, sizeof(buf)); if (nread < 0) { - return REDIS_ERR; + return VALKEY_ERR; } - if (nread > 0 && redisReaderFeed(c->reader, buf, nread) != REDIS_OK) { - __redisSetError(c, c->reader->err, c->reader->errstr); - return REDIS_ERR; + if (nread > 0 && valkeyReaderFeed(c->reader, buf, nread) != VALKEY_OK) { + valkeySetError(c, c->reader->err, c->reader->errstr); + return VALKEY_ERR; } - return REDIS_OK; + return VALKEY_OK; } /* Write the output buffer to the socket. * - * Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was + * Returns VALKEY_OK when the buffer is empty, or (a part of) the buffer was * successfully written to the socket. When the buffer is empty after the * write operation, "done" is set to 1 (if given). * - * Returns REDIS_ERR if an unrecoverable error occurred in the underlying + * Returns VALKEY_ERR if an unrecoverable error occurred in the underlying * c->funcs->write function. */ -int redisBufferWrite(redisContext *c, int *done) { +int valkeyBufferWrite(valkeyContext *c, int *done) { /* Return early when the context has seen an error. */ if (c->err) - return REDIS_ERR; + return VALKEY_ERR; if (sdslen(c->obuf) > 0) { ssize_t nwritten = c->funcs->write(c); if (nwritten < 0) { - return REDIS_ERR; + return VALKEY_ERR; } else if (nwritten > 0) { if (nwritten == (ssize_t)sdslen(c->obuf)) { sdsfree(c->obuf); @@ -1027,17 +1027,17 @@ int redisBufferWrite(redisContext *c, int *done) { } } if (done != NULL) *done = (sdslen(c->obuf) == 0); - return REDIS_OK; + return VALKEY_OK; oom: - __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); - return REDIS_ERR; + valkeySetError(c, VALKEY_ERR_OOM, "Out of memory"); + return VALKEY_ERR; } /* Internal helper that returns 1 if the reply was a RESP3 PUSH * message and we handled it with a user-provided callback. */ -static int redisHandledPushReply(redisContext *c, void *reply) { - if (reply && c->push_cb && redisIsPushReply(reply)) { +static int valkeyHandledPushReply(valkeyContext *c, void *reply) { + if (reply && c->push_cb && valkeyIsPushReply(reply)) { c->push_cb(c->privdata, reply); return 1; } @@ -1046,50 +1046,50 @@ static int redisHandledPushReply(redisContext *c, void *reply) { } /* Get a reply from our reader or set an error in the context. */ -int redisGetReplyFromReader(redisContext *c, void **reply) { - if (redisReaderGetReply(c->reader, reply) == REDIS_ERR) { - __redisSetError(c,c->reader->err,c->reader->errstr); - return REDIS_ERR; +int valkeyGetReplyFromReader(valkeyContext *c, void **reply) { + if (valkeyReaderGetReply(c->reader, reply) == VALKEY_ERR) { + valkeySetError(c,c->reader->err,c->reader->errstr); + return VALKEY_ERR; } - return REDIS_OK; + return VALKEY_OK; } /* Internal helper to get the next reply from our reader while handling * any PUSH messages we encounter along the way. This is separate from - * redisGetReplyFromReader so as to not change its behavior. */ -static int redisNextInBandReplyFromReader(redisContext *c, void **reply) { + * valkeyGetReplyFromReader so as to not change its behavior. */ +static int valkeyNextInBandReplyFromReader(valkeyContext *c, void **reply) { do { - if (redisGetReplyFromReader(c, reply) == REDIS_ERR) - return REDIS_ERR; - } while (redisHandledPushReply(c, *reply)); + if (valkeyGetReplyFromReader(c, reply) == VALKEY_ERR) + return VALKEY_ERR; + } while (valkeyHandledPushReply(c, *reply)); - return REDIS_OK; + return VALKEY_OK; } -int redisGetReply(redisContext *c, void **reply) { +int valkeyGetReply(valkeyContext *c, void **reply) { int wdone = 0; void *aux = NULL; /* Try to read pending replies */ - if (redisNextInBandReplyFromReader(c,&aux) == REDIS_ERR) - return REDIS_ERR; + if (valkeyNextInBandReplyFromReader(c,&aux) == VALKEY_ERR) + return VALKEY_ERR; /* For the blocking context, flush output buffer and read reply */ - if (aux == NULL && c->flags & REDIS_BLOCK) { + if (aux == NULL && c->flags & VALKEY_BLOCK) { /* Write until done */ do { - if (redisBufferWrite(c,&wdone) == REDIS_ERR) - return REDIS_ERR; + if (valkeyBufferWrite(c,&wdone) == VALKEY_ERR) + return VALKEY_ERR; } while (!wdone); /* Read until there is a reply */ do { - if (redisBufferRead(c) == REDIS_ERR) - return REDIS_ERR; + if (valkeyBufferRead(c) == VALKEY_ERR) + return VALKEY_ERR; - if (redisNextInBandReplyFromReader(c,&aux) == REDIS_ERR) - return REDIS_ERR; + if (valkeyNextInBandReplyFromReader(c,&aux) == VALKEY_ERR) + return VALKEY_ERR; } while (aux == NULL); } @@ -1100,90 +1100,90 @@ int redisGetReply(redisContext *c, void **reply) { freeReplyObject(aux); } - return REDIS_OK; + return VALKEY_OK; } -/* Helper function for the redisAppendCommand* family of functions. +/* Helper function for the valkeyAppendCommand* family of functions. * * Write a formatted command to the output buffer. When this family - * is used, you need to call redisGetReply yourself to retrieve + * is used, you need to call valkeyGetReply yourself to retrieve * the reply (or replies in pub/sub). */ -int __redisAppendCommand(redisContext *c, const char *cmd, size_t len) { +int valkeyAppendCmdLen(valkeyContext *c, const char *cmd, size_t len) { sds newbuf; newbuf = sdscatlen(c->obuf,cmd,len); if (newbuf == NULL) { - __redisSetError(c,REDIS_ERR_OOM,"Out of memory"); - return REDIS_ERR; + valkeySetError(c,VALKEY_ERR_OOM,"Out of memory"); + return VALKEY_ERR; } c->obuf = newbuf; - return REDIS_OK; + return VALKEY_OK; } -int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len) { +int valkeyAppendFormattedCommand(valkeyContext *c, const char *cmd, size_t len) { - if (__redisAppendCommand(c, cmd, len) != REDIS_OK) { - return REDIS_ERR; + if (valkeyAppendCmdLen(c, cmd, len) != VALKEY_OK) { + return VALKEY_ERR; } - return REDIS_OK; + return VALKEY_OK; } -int redisvAppendCommand(redisContext *c, const char *format, va_list ap) { +int valkeyvAppendCommand(valkeyContext *c, const char *format, va_list ap) { char *cmd; int len; - len = redisvFormatCommand(&cmd,format,ap); + len = valkeyvFormatCommand(&cmd,format,ap); if (len == -1) { - __redisSetError(c,REDIS_ERR_OOM,"Out of memory"); - return REDIS_ERR; + valkeySetError(c,VALKEY_ERR_OOM,"Out of memory"); + return VALKEY_ERR; } else if (len == -2) { - __redisSetError(c,REDIS_ERR_OTHER,"Invalid format string"); - return REDIS_ERR; + valkeySetError(c,VALKEY_ERR_OTHER,"Invalid format string"); + return VALKEY_ERR; } - if (__redisAppendCommand(c,cmd,len) != REDIS_OK) { - hi_free(cmd); - return REDIS_ERR; + if (valkeyAppendCmdLen(c,cmd,len) != VALKEY_OK) { + vk_free(cmd); + return VALKEY_ERR; } - hi_free(cmd); - return REDIS_OK; + vk_free(cmd); + return VALKEY_OK; } -int redisAppendCommand(redisContext *c, const char *format, ...) { +int valkeyAppendCommand(valkeyContext *c, const char *format, ...) { va_list ap; int ret; va_start(ap,format); - ret = redisvAppendCommand(c,format,ap); + ret = valkeyvAppendCommand(c,format,ap); va_end(ap); return ret; } -int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) { +int valkeyAppendCommandArgv(valkeyContext *c, int argc, const char **argv, const size_t *argvlen) { sds cmd; long long len; - len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen); + len = valkeyFormatSdsCommandArgv(&cmd,argc,argv,argvlen); if (len == -1) { - __redisSetError(c,REDIS_ERR_OOM,"Out of memory"); - return REDIS_ERR; + valkeySetError(c,VALKEY_ERR_OOM,"Out of memory"); + return VALKEY_ERR; } - if (__redisAppendCommand(c,cmd,len) != REDIS_OK) { + if (valkeyAppendCmdLen(c,cmd,len) != VALKEY_OK) { sdsfree(cmd); - return REDIS_ERR; + return VALKEY_ERR; } sdsfree(cmd); - return REDIS_OK; + return VALKEY_OK; } -/* Helper function for the redisCommand* family of functions. +/* Helper function for the valkeyCommand* family of functions. * * Write a formatted command to the output buffer. If the given context is * blocking, immediately read the reply into the "reply" pointer. When the @@ -1194,33 +1194,33 @@ int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const s * otherwise. When NULL is returned in a blocking context, the error field * in the context will be set. */ -static void *__redisBlockForReply(redisContext *c) { +static void *valkeyBlockForReply(valkeyContext *c) { void *reply; - if (c->flags & REDIS_BLOCK) { - if (redisGetReply(c,&reply) != REDIS_OK) + if (c->flags & VALKEY_BLOCK) { + if (valkeyGetReply(c,&reply) != VALKEY_OK) return NULL; return reply; } return NULL; } -void *redisvCommand(redisContext *c, const char *format, va_list ap) { - if (redisvAppendCommand(c,format,ap) != REDIS_OK) +void *valkeyvCommand(valkeyContext *c, const char *format, va_list ap) { + if (valkeyvAppendCommand(c,format,ap) != VALKEY_OK) return NULL; - return __redisBlockForReply(c); + return valkeyBlockForReply(c); } -void *redisCommand(redisContext *c, const char *format, ...) { +void *valkeyCommand(valkeyContext *c, const char *format, ...) { va_list ap; va_start(ap,format); - void *reply = redisvCommand(c,format,ap); + void *reply = valkeyvCommand(c,format,ap); va_end(ap); return reply; } -void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) { - if (redisAppendCommandArgv(c,argc,argv,argvlen) != REDIS_OK) +void *valkeyCommandArgv(valkeyContext *c, int argc, const char **argv, const size_t *argvlen) { + if (valkeyAppendCommandArgv(c,argc,argv,argvlen) != VALKEY_OK) return NULL; - return __redisBlockForReply(c); + return valkeyBlockForReply(c); } diff --git a/libvalkey/hiredis.h b/src/valkey.h similarity index 54% rename from libvalkey/hiredis.h rename to src/valkey.h index 3a5cd896..8d41bba5 100644 --- a/libvalkey/hiredis.h +++ b/src/valkey.h @@ -31,8 +31,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __HIREDIS_H -#define __HIREDIS_H +#ifndef VALKEY_H +#define VALKEY_H #include "read.h" #include /* for va_list */ #ifndef _MSC_VER @@ -45,141 +45,141 @@ typedef long long ssize_t; #include "sds.h" /* for sds */ #include "alloc.h" /* for allocation wrappers */ -#define HIREDIS_MAJOR 1 -#define HIREDIS_MINOR 2 -#define HIREDIS_PATCH 0 -#define HIREDIS_SONAME 1.2.1-dev +#define LIBVALKEY_MAJOR 1 +#define LIBVALKEY_MINOR 2 +#define LIBVALKEY_PATCH 0 +#define LIBVALKEY_SONAME 1.2.1-dev /* Connection type can be blocking or non-blocking and is set in the - * least significant bit of the flags field in redisContext. */ -#define REDIS_BLOCK 0x1 + * least significant bit of the flags field in valkeyContext. */ +#define VALKEY_BLOCK 0x1 /* Connection may be disconnected before being free'd. The second bit * in the flags field is set when the context is connected. */ -#define REDIS_CONNECTED 0x2 +#define VALKEY_CONNECTED 0x2 /* The async API might try to disconnect cleanly and flush the output * buffer and read all subsequent replies before disconnecting. * This flag means no new commands can come in and the connection * should be terminated once all replies have been read. */ -#define REDIS_DISCONNECTING 0x4 +#define VALKEY_DISCONNECTING 0x4 /* Flag specific to the async API which means that the context should be clean * up as soon as possible. */ -#define REDIS_FREEING 0x8 +#define VALKEY_FREEING 0x8 /* Flag that is set when an async callback is executed. */ -#define REDIS_IN_CALLBACK 0x10 +#define VALKEY_IN_CALLBACK 0x10 /* Flag that is set when the async context has one or more subscriptions. */ -#define REDIS_SUBSCRIBED 0x20 +#define VALKEY_SUBSCRIBED 0x20 /* Flag that is set when monitor mode is active */ -#define REDIS_MONITORING 0x40 +#define VALKEY_MONITORING 0x40 /* Flag that is set when we should set SO_REUSEADDR before calling bind() */ -#define REDIS_REUSEADDR 0x80 +#define VALKEY_REUSEADDR 0x80 /* Flag that is set when the async connection supports push replies. */ -#define REDIS_SUPPORTS_PUSH 0x100 +#define VALKEY_SUPPORTS_PUSH 0x100 /** * Flag that indicates the user does not want the context to * be automatically freed upon error */ -#define REDIS_NO_AUTO_FREE 0x200 +#define VALKEY_NO_AUTO_FREE 0x200 /* Flag that indicates the user does not want replies to be automatically freed */ -#define REDIS_NO_AUTO_FREE_REPLIES 0x400 +#define VALKEY_NO_AUTO_FREE_REPLIES 0x400 /* Flags to prefer IPv6 or IPv4 when doing DNS lookup. (If both are set, * AF_UNSPEC is used.) */ -#define REDIS_PREFER_IPV4 0x800 -#define REDIS_PREFER_IPV6 0x1000 +#define VALKEY_PREFER_IPV4 0x800 +#define VALKEY_PREFER_IPV6 0x1000 -#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */ +#define VALKEY_KEEPALIVE_INTERVAL 15 /* seconds */ /* number of times we retry to connect in the case of EADDRNOTAVAIL and * SO_REUSEADDR is being used. */ -#define REDIS_CONNECT_RETRIES 10 +#define VALKEY_CONNECT_RETRIES 10 /* Forward declarations for structs defined elsewhere */ -struct redisAsyncContext; -struct redisContext; +struct valkeyAsyncContext; +struct valkeyContext; /* RESP3 push helpers and callback prototypes */ -#define redisIsPushReply(r) (((redisReply*)(r))->type == REDIS_REPLY_PUSH) -typedef void (redisPushFn)(void *, void *); -typedef void (redisAsyncPushFn)(struct redisAsyncContext *, void *); +#define valkeyIsPushReply(r) (((valkeyReply*)(r))->type == VALKEY_REPLY_PUSH) +typedef void (valkeyPushFn)(void *, void *); +typedef void (valkeyAsyncPushFn)(struct valkeyAsyncContext *, void *); #ifdef __cplusplus extern "C" { #endif -/* This is the reply object returned by redisCommand() */ -typedef struct redisReply { - int type; /* REDIS_REPLY_* */ - long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ - double dval; /* The double when type is REDIS_REPLY_DOUBLE */ +/* This is the reply object returned by valkeyCommand() */ +typedef struct valkeyReply { + int type; /* VALKEY_REPLY_* */ + long long integer; /* The integer when type is VALKEY_REPLY_INTEGER */ + double dval; /* The double when type is VALKEY_REPLY_DOUBLE */ size_t len; /* Length of string */ - char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING - REDIS_REPLY_VERB, REDIS_REPLY_DOUBLE (in additional to dval), - and REDIS_REPLY_BIGNUM. */ - char vtype[4]; /* Used for REDIS_REPLY_VERB, contains the null + char *str; /* Used for VALKEY_REPLY_ERROR, VALKEY_REPLY_STRING + VALKEY_REPLY_VERB, VALKEY_REPLY_DOUBLE (in additional to dval), + and VALKEY_REPLY_BIGNUM. */ + char vtype[4]; /* Used for VALKEY_REPLY_VERB, contains the null terminated 3 character content type, such as "txt". */ - size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ - struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ -} redisReply; + size_t elements; /* number of elements, for VALKEY_REPLY_ARRAY */ + struct valkeyReply **element; /* elements vector for VALKEY_REPLY_ARRAY */ +} valkeyReply; -redisReader *redisReaderCreate(void); +valkeyReader *valkeyReaderCreate(void); -/* Function to free the reply objects hiredis returns by default. */ +/* Function to free the reply objects hivalkey returns by default. */ void freeReplyObject(void *reply); /* Functions to format a command according to the protocol. */ -int redisvFormatCommand(char **target, const char *format, va_list ap); -int redisFormatCommand(char **target, const char *format, ...); -long long redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen); -long long redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen); -void redisFreeCommand(char *cmd); -void redisFreeSdsCommand(sds cmd); - -enum redisConnectionType { - REDIS_CONN_TCP, - REDIS_CONN_UNIX, - REDIS_CONN_USERFD +int valkeyvFormatCommand(char **target, const char *format, va_list ap); +int valkeyFormatCommand(char **target, const char *format, ...); +long long valkeyFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen); +long long valkeyFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen); +void valkeyFreeCommand(char *cmd); +void valkeyFreeSdsCommand(sds cmd); + +enum valkeyConnectionType { + VALKEY_CONN_TCP, + VALKEY_CONN_UNIX, + VALKEY_CONN_USERFD }; -struct redisSsl; +struct valkeySsl; -#define REDIS_OPT_NONBLOCK 0x01 -#define REDIS_OPT_REUSEADDR 0x02 -#define REDIS_OPT_NOAUTOFREE 0x04 /* Don't automatically free the async +#define VALKEY_OPT_NONBLOCK 0x01 +#define VALKEY_OPT_REUSEADDR 0x02 +#define VALKEY_OPT_NOAUTOFREE 0x04 /* Don't automatically free the async * object on a connection failure, or * other implicit conditions. Only free * on an explicit call to disconnect() * or free() */ -#define REDIS_OPT_NO_PUSH_AUTOFREE 0x08 /* Don't automatically intercept and +#define VALKEY_OPT_NO_PUSH_AUTOFREE 0x08 /* Don't automatically intercept and * free RESP3 PUSH replies. */ -#define REDIS_OPT_NOAUTOFREEREPLIES 0x10 /* Don't automatically free replies. */ -#define REDIS_OPT_PREFER_IPV4 0x20 /* Prefer IPv4 in DNS lookups. */ -#define REDIS_OPT_PREFER_IPV6 0x40 /* Prefer IPv6 in DNS lookups. */ -#define REDIS_OPT_PREFER_IP_UNSPEC (REDIS_OPT_PREFER_IPV4 | REDIS_OPT_PREFER_IPV6) +#define VALKEY_OPT_NOAUTOFREEREPLIES 0x10 /* Don't automatically free replies. */ +#define VALKEY_OPT_PREFER_IPV4 0x20 /* Prefer IPv4 in DNS lookups. */ +#define VALKEY_OPT_PREFER_IPV6 0x40 /* Prefer IPv6 in DNS lookups. */ +#define VALKEY_OPT_PREFER_IP_UNSPEC (VALKEY_OPT_PREFER_IPV4 | VALKEY_OPT_PREFER_IPV6) /* In Unix systems a file descriptor is a regular signed int, with -1 * representing an invalid descriptor. In Windows it is a SOCKET * (32- or 64-bit unsigned integer depending on the architecture), where * all bits set (~0) is INVALID_SOCKET. */ #ifndef _WIN32 -typedef int redisFD; -#define REDIS_INVALID_FD -1 +typedef int valkeyFD; +#define VALKEY_INVALID_FD -1 #else #ifdef _WIN64 -typedef unsigned long long redisFD; /* SOCKET = 64-bit UINT_PTR */ +typedef unsigned long long valkeyFD; /* SOCKET = 64-bit UINT_PTR */ #else -typedef unsigned long redisFD; /* SOCKET = 32-bit UINT_PTR */ +typedef unsigned long valkeyFD; /* SOCKET = 32-bit UINT_PTR */ #endif -#define REDIS_INVALID_FD ((redisFD)(~0)) /* INVALID_SOCKET */ +#define VALKEY_INVALID_FD ((valkeyFD)(~0)) /* INVALID_SOCKET */ #endif typedef struct { @@ -188,12 +188,12 @@ typedef struct { * `endpoint` member field to use */ int type; - /* bit field of REDIS_OPT_xxx */ + /* bit field of VALKEY_OPT_xxx */ int options; /* timeout value for connect operation. If NULL, no timeout is used */ const struct timeval *connect_timeout; /* timeout value for commands. If NULL, no timeout is used. This can be - * updated at runtime with redisSetTimeout/redisAsyncSetTimeout. */ + * updated at runtime with valkeySetTimeout/valkeyAsyncSetTimeout. */ const struct timeval *command_timeout; union { /** use this field for tcp/ip connections */ @@ -205,9 +205,9 @@ typedef struct { /** use this field for unix domain sockets */ const char *unix_socket; /** - * use this field to have hiredis operate an already-open + * use this field to have libvalkey operate an already-open * file descriptor */ - redisFD fd; + valkeyFD fd; } endpoint; /* Optional user defined data/destructor */ @@ -215,56 +215,56 @@ typedef struct { void (*free_privdata)(void *); /* A user defined PUSH message callback */ - redisPushFn *push_cb; - redisAsyncPushFn *async_push_cb; -} redisOptions; + valkeyPushFn *push_cb; + valkeyAsyncPushFn *async_push_cb; +} valkeyOptions; /** * Helper macros to initialize options to their specified fields. */ -#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) do { \ - (opts)->type = REDIS_CONN_TCP; \ +#define VALKEY_OPTIONS_SET_TCP(opts, ip_, port_) do { \ + (opts)->type = VALKEY_CONN_TCP; \ (opts)->endpoint.tcp.ip = ip_; \ (opts)->endpoint.tcp.port = port_; \ } while(0) -#define REDIS_OPTIONS_SET_UNIX(opts, path) do { \ - (opts)->type = REDIS_CONN_UNIX; \ +#define VALKEY_OPTIONS_SET_UNIX(opts, path) do { \ + (opts)->type = VALKEY_CONN_UNIX; \ (opts)->endpoint.unix_socket = path; \ } while(0) -#define REDIS_OPTIONS_SET_PRIVDATA(opts, data, dtor) do { \ +#define VALKEY_OPTIONS_SET_PRIVDATA(opts, data, dtor) do { \ (opts)->privdata = data; \ (opts)->free_privdata = dtor; \ } while(0) -typedef struct redisContextFuncs { - void (*close)(struct redisContext *); +typedef struct valkeyContextFuncs { + void (*close)(struct valkeyContext *); void (*free_privctx)(void *); - void (*async_read)(struct redisAsyncContext *); - void (*async_write)(struct redisAsyncContext *); + void (*async_read)(struct valkeyAsyncContext *); + void (*async_write)(struct valkeyAsyncContext *); /* Read/Write data to the underlying communication stream, returning the * number of bytes read/written. In the event of an unrecoverable error * these functions shall return a value < 0. In the event of a * recoverable error, they should return 0. */ - ssize_t (*read)(struct redisContext *, char *, size_t); - ssize_t (*write)(struct redisContext *); -} redisContextFuncs; + ssize_t (*read)(struct valkeyContext *, char *, size_t); + ssize_t (*write)(struct valkeyContext *); +} valkeyContextFuncs; -/* Context for a connection to Redis */ -typedef struct redisContext { - const redisContextFuncs *funcs; /* Function table */ +/* Context for a connection to Valkey */ +typedef struct valkeyContext { + const valkeyContextFuncs *funcs; /* Function table */ int err; /* Error flags, 0 when there is no error */ char errstr[128]; /* String representation of error when applicable */ - redisFD fd; + valkeyFD fd; int flags; char *obuf; /* Write buffer */ - redisReader *reader; /* Protocol reader */ + valkeyReader *reader; /* Protocol reader */ - enum redisConnectionType connection_type; + enum valkeyConnectionType connection_type; struct timeval *connect_timeout; struct timeval *command_timeout; @@ -283,30 +283,30 @@ typedef struct redisContext { size_t addrlen; /* Optional data and corresponding destructor users can use to provide - * context to a given redisContext. Not used by hiredis. */ + * context to a given valkeyContext. Not used by libvalkey. */ void *privdata; void (*free_privdata)(void *); - /* Internal context pointer presently used by hiredis to manage + /* Internal context pointer presently used by libvalkey to manage * SSL connections. */ void *privctx; /* An optional RESP3 PUSH handler */ - redisPushFn *push_cb; -} redisContext; - -redisContext *redisConnectWithOptions(const redisOptions *options); -redisContext *redisConnect(const char *ip, int port); -redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv); -redisContext *redisConnectNonBlock(const char *ip, int port); -redisContext *redisConnectBindNonBlock(const char *ip, int port, + valkeyPushFn *push_cb; +} valkeyContext; + +valkeyContext *valkeyConnectWithOptions(const valkeyOptions *options); +valkeyContext *valkeyConnect(const char *ip, int port); +valkeyContext *valkeyConnectWithTimeout(const char *ip, int port, const struct timeval tv); +valkeyContext *valkeyConnectNonBlock(const char *ip, int port); +valkeyContext *valkeyConnectBindNonBlock(const char *ip, int port, const char *source_addr); -redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port, +valkeyContext *valkeyConnectBindNonBlockWithReuse(const char *ip, int port, const char *source_addr); -redisContext *redisConnectUnix(const char *path); -redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv); -redisContext *redisConnectUnixNonBlock(const char *path); -redisContext *redisConnectFd(redisFD fd); +valkeyContext *valkeyConnectUnix(const char *path); +valkeyContext *valkeyConnectUnixWithTimeout(const char *path, const struct timeval tv); +valkeyContext *valkeyConnectUnixNonBlock(const char *path); +valkeyContext *valkeyConnectFd(valkeyFD fd); /** * Reconnect the given context using the saved information. @@ -315,45 +315,45 @@ redisContext *redisConnectFd(redisFD fd); * host, ip (or path), timeout and bind address are reused, * flags are used unmodified from the existing context. * - * Returns REDIS_OK on successful connect or REDIS_ERR otherwise. + * Returns VALKEY_OK on successful connect or VALKEY_ERR otherwise. */ -int redisReconnect(redisContext *c); - -redisPushFn *redisSetPushCallback(redisContext *c, redisPushFn *fn); -int redisSetTimeout(redisContext *c, const struct timeval tv); -int redisEnableKeepAlive(redisContext *c); -int redisEnableKeepAliveWithInterval(redisContext *c, int interval); -int redisSetTcpUserTimeout(redisContext *c, unsigned int timeout); -void redisFree(redisContext *c); -redisFD redisFreeKeepFd(redisContext *c); -int redisBufferRead(redisContext *c); -int redisBufferWrite(redisContext *c, int *done); +int valkeyReconnect(valkeyContext *c); + +valkeyPushFn *valkeySetPushCallback(valkeyContext *c, valkeyPushFn *fn); +int valkeySetTimeout(valkeyContext *c, const struct timeval tv); +int valkeyEnableKeepAlive(valkeyContext *c); +int valkeyEnableKeepAliveWithInterval(valkeyContext *c, int interval); +int valkeySetTcpUserTimeout(valkeyContext *c, unsigned int timeout); +void valkeyFree(valkeyContext *c); +valkeyFD valkeyFreeKeepFd(valkeyContext *c); +int valkeyBufferRead(valkeyContext *c); +int valkeyBufferWrite(valkeyContext *c, int *done); /* In a blocking context, this function first checks if there are unconsumed * replies to return and returns one if so. Otherwise, it flushes the output * buffer to the socket and reads until it has a reply. In a non-blocking * context, it will return unconsumed replies until there are no more. */ -int redisGetReply(redisContext *c, void **reply); -int redisGetReplyFromReader(redisContext *c, void **reply); +int valkeyGetReply(valkeyContext *c, void **reply); +int valkeyGetReplyFromReader(valkeyContext *c, void **reply); /* Write a formatted command to the output buffer. Use these functions in blocking mode * to get a pipeline of commands. */ -int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len); +int valkeyAppendFormattedCommand(valkeyContext *c, const char *cmd, size_t len); /* Write a command to the output buffer. Use these functions in blocking mode * to get a pipeline of commands. */ -int redisvAppendCommand(redisContext *c, const char *format, va_list ap); -int redisAppendCommand(redisContext *c, const char *format, ...); -int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); +int valkeyvAppendCommand(valkeyContext *c, const char *format, va_list ap); +int valkeyAppendCommand(valkeyContext *c, const char *format, ...); +int valkeyAppendCommandArgv(valkeyContext *c, int argc, const char **argv, const size_t *argvlen); -/* Issue a command to Redis. In a blocking context, it is identical to calling - * redisAppendCommand, followed by redisGetReply. The function will return +/* Issue a command to Valkey. In a blocking context, it is identical to calling + * valkeyAppendCommand, followed by valkeyGetReply. The function will return * NULL if there was an error in performing the request, otherwise it will * return the reply. In a non-blocking context, it is identical to calling - * only redisAppendCommand and will always return NULL. */ -void *redisvCommand(redisContext *c, const char *format, va_list ap); -void *redisCommand(redisContext *c, const char *format, ...); -void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); + * only valkeyAppendCommand and will always return NULL. */ +void *valkeyvCommand(valkeyContext *c, const char *format, va_list ap); +void *valkeyCommand(valkeyContext *c, const char *format, ...); +void *valkeyCommandArgv(valkeyContext *c, int argc, const char **argv, const size_t *argvlen); #ifdef __cplusplus } diff --git a/libvalkey/hiredis_ssl.h b/src/valkey_ssl.h similarity index 62% rename from libvalkey/hiredis_ssl.h rename to src/valkey_ssl.h index 5f92cca9..50a951d0 100644 --- a/libvalkey/hiredis_ssl.h +++ b/src/valkey_ssl.h @@ -29,8 +29,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __HIREDIS_SSL_H -#define __HIREDIS_SSL_H +#ifndef VALKEY_SSL_H +#define VALKEY_SSL_H #ifdef __cplusplus extern "C" { @@ -44,34 +44,34 @@ struct ssl_st; /* A wrapper around OpenSSL SSL_CTX to allow easy SSL use without directly * calling OpenSSL. */ -typedef struct redisSSLContext redisSSLContext; +typedef struct valkeySSLContext valkeySSLContext; /** - * Initialization errors that redisCreateSSLContext() may return. + * Initialization errors that valkeyCreateSSLContext() may return. */ typedef enum { - REDIS_SSL_CTX_NONE = 0, /* No Error */ - REDIS_SSL_CTX_CREATE_FAILED, /* Failed to create OpenSSL SSL_CTX */ - REDIS_SSL_CTX_CERT_KEY_REQUIRED, /* Client cert and key must both be specified or skipped */ - REDIS_SSL_CTX_CA_CERT_LOAD_FAILED, /* Failed to load CA Certificate or CA Path */ - REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED, /* Failed to load client certificate */ - REDIS_SSL_CTX_CLIENT_DEFAULT_CERT_FAILED, /* Failed to set client default certificate directory */ - REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED, /* Failed to load private key */ - REDIS_SSL_CTX_OS_CERTSTORE_OPEN_FAILED, /* Failed to open system certificate store */ - REDIS_SSL_CTX_OS_CERT_ADD_FAILED /* Failed to add CA certificates obtained from system to the SSL context */ -} redisSSLContextError; + VALKEY_SSL_CTX_NONE = 0, /* No Error */ + VALKEY_SSL_CTX_CREATE_FAILED, /* Failed to create OpenSSL SSL_CTX */ + VALKEY_SSL_CTX_CERT_KEY_REQUIRED, /* Client cert and key must both be specified or skipped */ + VALKEY_SSL_CTX_CA_CERT_LOAD_FAILED, /* Failed to load CA Certificate or CA Path */ + VALKEY_SSL_CTX_CLIENT_CERT_LOAD_FAILED, /* Failed to load client certificate */ + VALKEY_SSL_CTX_CLIENT_DEFAULT_CERT_FAILED, /* Failed to set client default certificate directory */ + VALKEY_SSL_CTX_PRIVATE_KEY_LOAD_FAILED, /* Failed to load private key */ + VALKEY_SSL_CTX_OS_CERTSTORE_OPEN_FAILED, /* Failed to open system certificate store */ + VALKEY_SSL_CTX_OS_CERT_ADD_FAILED /* Failed to add CA certificates obtained from system to the SSL context */ +} valkeySSLContextError; /* Constants that mirror OpenSSL's verify modes. By default, - * REDIS_SSL_VERIFY_PEER is used with redisCreateSSLContext(). - * Some Redis clients disable peer verification if there are no + * VALKEY_SSL_VERIFY_PEER is used with valkeyCreateSSLContext(). + * Some clients disable peer verification if there are no * certificates specified. */ -#define REDIS_SSL_VERIFY_NONE 0x00 -#define REDIS_SSL_VERIFY_PEER 0x01 -#define REDIS_SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 -#define REDIS_SSL_VERIFY_CLIENT_ONCE 0x04 -#define REDIS_SSL_VERIFY_POST_HANDSHAKE 0x08 +#define VALKEY_SSL_VERIFY_NONE 0x00 +#define VALKEY_SSL_VERIFY_PEER 0x01 +#define VALKEY_SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +#define VALKEY_SSL_VERIFY_CLIENT_ONCE 0x04 +#define VALKEY_SSL_VERIFY_POST_HANDSHAKE 0x08 /* Options to create an OpenSSL context. */ typedef struct { @@ -81,13 +81,13 @@ typedef struct { const char *private_key_filename; const char *server_name; int verify_mode; -} redisSSLOptions; +} valkeySSLOptions; /** * Return the error message corresponding with the specified error code. */ -const char *redisSSLContextGetError(redisSSLContextError error); +const char *valkeySSLContextGetError(valkeySSLContextError error); /** * Helper function to initialize the OpenSSL library. @@ -96,7 +96,7 @@ const char *redisSSLContextGetError(redisSSLContextError error); * call this function only once, and only if OpenSSL is not directly initialized * elsewhere. */ -int redisInitOpenSSL(void); +int valkeyInitOpenSSL(void); /** * Helper function to initialize an OpenSSL context that can be used @@ -119,45 +119,45 @@ int redisInitOpenSSL(void); * (returning a NULL). */ -redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *capath, +valkeySSLContext *valkeyCreateSSLContext(const char *cacert_filename, const char *capath, const char *cert_filename, const char *private_key_filename, - const char *server_name, redisSSLContextError *error); + const char *server_name, valkeySSLContextError *error); /** * Helper function to initialize an OpenSSL context that can be used - * to initiate SSL connections. This is a more extensible version of redisCreateSSLContext(). + * to initiate SSL connections. This is a more extensible version of valkeyCreateSSLContext(). * * options contains a structure of SSL options to use. * * If error is non-null, it will be populated in case the context creation fails * (returning a NULL). */ -redisSSLContext *redisCreateSSLContextWithOptions(redisSSLOptions *options, - redisSSLContextError *error); +valkeySSLContext *valkeyCreateSSLContextWithOptions(valkeySSLOptions *options, + valkeySSLContextError *error); /** * Free a previously created OpenSSL context. */ -void redisFreeSSLContext(redisSSLContext *redis_ssl_ctx); +void valkeyFreeSSLContext(valkeySSLContext *valkey_ssl_ctx); /** - * Initiate SSL on an existing redisContext. + * Initiate SSL on an existing valkeyContext. * - * This is similar to redisInitiateSSL() but does not require the caller - * to directly interact with OpenSSL, and instead uses a redisSSLContext - * previously created using redisCreateSSLContext(). + * This is similar to valkeyInitiateSSL() but does not require the caller + * to directly interact with OpenSSL, and instead uses a valkeySSLContext + * previously created using valkeyCreateSSLContext(). */ -int redisInitiateSSLWithContext(redisContext *c, redisSSLContext *redis_ssl_ctx); +int valkeyInitiateSSLWithContext(valkeyContext *c, valkeySSLContext *valkey_ssl_ctx); /** * Initiate SSL/TLS negotiation on a provided OpenSSL SSL object. */ -int redisInitiateSSL(redisContext *c, struct ssl_st *ssl); +int valkeyInitiateSSL(valkeyContext *c, struct ssl_st *ssl); #ifdef __cplusplus } #endif -#endif /* __HIREDIS_SSL_H */ +#endif /* VALKEY_SSL_H */ diff --git a/src/win32.h b/src/win32.h index f1fa94cd..c9ddd1ff 100644 --- a/src/win32.h +++ b/src/win32.h @@ -38,6 +38,10 @@ #define inline __inline #endif +#ifndef strcasecmp +#define strcasecmp stricmp +#endif + #ifndef strncasecmp #define strncasecmp _strnicmp #endif @@ -46,6 +50,38 @@ #define alloca _alloca #endif +#ifndef va_copy +#define va_copy(d,s) ((d) = (s)) +#endif + +#ifndef snprintf +#define snprintf c99_snprintf + +__inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) +{ + int count = -1; + + if (size != 0) + count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + + return count; +} + +__inline int c99_snprintf(char* str, size_t size, const char* format, ...) +{ + int count; + va_list ap; + + va_start(ap, format); + count = c99_vsnprintf(str, size, format, ap); + va_end(ap); + + return count; +} +#endif + #endif /* _MSC_VER */ #ifdef _WIN32