summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlishu <[email protected]>2018-12-10 15:20:53 +0800
committerlishu <[email protected]>2018-12-10 15:20:53 +0800
commit53345b192a0631906d47b8283b3d3710591abfa4 (patch)
tree5a3ca2a8c00d79bb073bad8d0e4e969e37bfe84a /src
parent7ef7e02aba9ae50ee79cb3276c72ef7b13f89c5d (diff)
整理support
Diffstat (limited to 'src')
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/.gitignore7
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/.travis.yml16
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/CHANGELOG.md90
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/COPYING29
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/Makefile205
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/README.md281
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/ae.h154
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/glib.h153
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/libev.h147
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/libevent.h135
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/libuv.h122
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adlist.c341
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adlist.h93
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/async.c686
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/async.h129
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/command.c1700
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/command.h179
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/crc16.c87
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/dict.c338
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/dict.h126
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-ae.c62
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-glib.c73
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-libev.c52
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-libevent.c53
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-libuv.c53
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example.c78
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/fmacros.h23
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiarray.c188
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiarray.h56
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hircluster.c4820
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hircluster.h187
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis.c1021
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis.h221
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiutil.c554
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiutil.h265
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/net.c458
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/net.h53
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/nodes.conf7
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/read.c525
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/read.h129
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/redis.conf5
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/redis_comm.conf254
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/sds.c1095
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/sds.h105
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/test.c806
-rw-r--r--src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/win32.h42
46 files changed, 0 insertions, 16203 deletions
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/.gitignore b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/.gitignore
deleted file mode 100644
index c44b5c5..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-/hiredis-test
-/examples/hiredis-example*
-/*.o
-/*.so
-/*.dylib
-/*.a
-/*.pc
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/.travis.yml b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/.travis.yml
deleted file mode 100644
index 1df63b0..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/.travis.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-language: c
-compiler:
- - gcc
- - clang
-
-env:
- - CFLAGS="-Werror"
- - PRE="valgrind --track-origins=yes --leak-check=full"
- - TARGET="32bit" TARGET_VARS="32bit-vars" CFLAGS="-Werror"
- - TARGET="32bit" TARGET_VARS="32bit-vars" PRE="valgrind --track-origins=yes --leak-check=full"
-
-install:
- - sudo apt-get update -qq
- - sudo apt-get install libc6-dbg libc6-dev libc6-i686:i386 libc6-dev-i386 libc6-dbg:i386 valgrind -y
-
-script: make $TARGET CFLAGS="$CFLAGS" && make check PRE="$PRE" && make $TARGET_VARS hiredis-example
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/CHANGELOG.md b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/CHANGELOG.md
deleted file mode 100644
index 29d7cf3..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/CHANGELOG.md
+++ /dev/null
@@ -1,90 +0,0 @@
-### 0.13.1 - May 03, 2015
-
-This is a bug fix release.
-The new `reconnect` method introduced new struct members, which clashed with pre-defined names in pre-C99 code.
-Another commit forced C99 compilation just to make it work, but of course this is not desirable for outside projects.
-Other non-C99 code can now use hiredis as usual again.
-Sorry for the inconvenience.
-
-* Fix memory leak in async reply handling (Salvatore Sanfilippo)
-* Rename struct member to avoid name clash with pre-c99 code (Alex Balashov, ncopa)
-
-### 0.13.0 - April 16, 2015
-
-This release adds a minimal Windows compatibility layer.
-The parser, standalone since v0.12.0, can now be compiled on Windows
-(and thus used in other client libraries as well)
-
-* Windows compatibility layer for parser code (tzickel)
-* Properly escape data printed to PKGCONF file (Dan Skorupski)
-* Fix tests when assert() undefined (Keith Bennett, Matt Stancliff)
-* Implement a reconnect method for the client context, this changes the structure of `redisContext` (Aaron Bedra)
-
-### 0.12.1 - January 26, 2015
-
-* Fix `make install`: DESTDIR support, install all required files, install PKGCONF in proper location
-* Fix `make test` as 32 bit build on 64 bit platform
-
-### 0.12.0 - January 22, 2015
-
-* Add optional KeepAlive support
-
-* Try again on EINTR errors
-
-* Add libuv adapter
-
-* Add IPv6 support
-
-* Remove possiblity of multiple close on same fd
-
-* Add ability to bind source address on connect
-
-* Add redisConnectFd() and redisFreeKeepFd()
-
-* Fix getaddrinfo() memory leak
-
-* Free string if it is unused (fixes memory leak)
-
-* Improve redisAppendCommandArgv performance 2.5x
-
-* Add support for SO_REUSEADDR
-
-* Fix redisvFormatCommand format parsing
-
-* Add GLib 2.0 adapter
-
-* Refactor reading code into read.c
-
-* Fix errno error buffers to not clobber errors
-
-* Generate pkgconf during build
-
-* Silence _BSD_SOURCE warnings
-
-* Improve digit counting for multibulk creation
-
-
-### 0.11.0
-
-* Increase the maximum multi-bulk reply depth to 7.
-
-* Increase the read buffer size from 2k to 16k.
-
-* Use poll(2) instead of select(2) to support large fds (>= 1024).
-
-### 0.10.1
-
-* Makefile overhaul. Important to check out if you override one or more
- variables using environment variables or via arguments to the "make" tool.
-
-* Issue #45: Fix potential memory leak for a multi bulk reply with 0 elements
- being created by the default reply object functions.
-
-* Issue #43: Don't crash in an asynchronous context when Redis returns an error
- reply after the connection has been made (this happens when the maximum
- number of connections is reached).
-
-### 0.10.0
-
-* See commit log.
-
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/COPYING b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/COPYING
deleted file mode 100644
index a5fc973..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/COPYING
+++ /dev/null
@@ -1,29 +0,0 @@
-Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
-Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-* Neither the name of Redis nor the names of its contributors may be used
- to endorse or promote products derived from this software without specific
- prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/Makefile b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/Makefile
deleted file mode 100644
index 58494bf..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/Makefile
+++ /dev/null
@@ -1,205 +0,0 @@
-# Hiredis Makefile
-# Copyright (C) 2010-2011 Salvatore Sanfilippo <antirez at gmail dot com>
-# Copyright (C) 2010-2011 Pieter Noordhuis <pcnoordhuis at gmail dot com>
-# This file is released under the BSD license, see the COPYING file
-
-OBJ=net.o hiredis.o sds.o async.o read.o hiarray.o hiutil.o command.o crc16.o adlist.o hircluster.o
-EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib
-TESTS=hiredis-test
-LIBNAME=libhiredis_vip
-PKGCONFNAME=hiredis.pc
-
-HIREDIS_VIP_MAJOR=$(shell grep HIREDIS_VIP_MAJOR hircluster.h | awk '{print $$3}')
-HIREDIS_VIP_MINOR=$(shell grep HIREDIS_VIP_MINOR hircluster.h | awk '{print $$3}')
-HIREDIS_VIP_PATCH=$(shell grep HIREDIS_VIP_PATCH hircluster.h | awk '{print $$3}')
-
-# Installation related variables and target
-PREFIX?=/usr/local
-INCLUDE_PATH?=include/hiredis-vip
-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
- daemonize yes
- pidfile /tmp/hiredis-test-redis.pid
- port $(REDIS_PORT)
- bind 127.0.0.1
- unixsocket /tmp/hiredis-test-redis.sock
-endef
-export REDIS_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')
-OPTIMIZATION?=-O3
-WARNINGS=-Wall -W -Wstrict-prototypes -Wwrite-strings
-DEBUG?= -g -ggdb
-REAL_CFLAGS=$(OPTIMIZATION) -fPIC $(CFLAGS) $(WARNINGS) $(DEBUG) $(ARCH)
-REAL_LDFLAGS=$(LDFLAGS) $(ARCH)
-
-DYLIBSUFFIX=so
-STLIBSUFFIX=a
-DYLIB_MINOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_VIP_MAJOR).$(HIREDIS_VIP_MINOR)
-DYLIB_MAJOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_VIP_MAJOR)
-DYLIBNAME=$(LIBNAME).$(DYLIBSUFFIX)
-DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS)
-STLIBNAME=$(LIBNAME).$(STLIBSUFFIX)
-STLIB_MAKE_CMD=ar rcs $(STLIBNAME)
-
-# Platform-specific overrides
-uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
-ifeq ($(uname_S),SunOS)
- REAL_LDFLAGS+= -ldl -lnsl -lsocket
- DYLIB_MAKE_CMD=$(CC) -G -o $(DYLIBNAME) -h $(DYLIB_MINOR_NAME) $(LDFLAGS)
- INSTALL= cp -r
-endif
-ifeq ($(uname_S),Darwin)
- DYLIBSUFFIX=dylib
- DYLIB_MINOR_NAME=$(LIBNAME).$(HIREDIS_VIP_MAJOR).$(HIREDIS_VIP_MINOR).$(DYLIBSUFFIX)
- DYLIB_MAJOR_NAME=$(LIBNAME).$(HIREDIS_VIP_MAJOR).$(DYLIBSUFFIX)
- DYLIB_MAKE_CMD=$(CC) -shared -Wl,-install_name,$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS)
-endif
-
-all: $(DYLIBNAME) $(STLIBNAME) hiredis-test $(PKGCONFNAME)
-
-# Deps (use make dep to generate this)
-
-adlist.o: adlist.c adlist.h hiutil.h
-async.o: async.c fmacros.h async.h hiredis.h read.h sds.h net.h dict.c dict.h
-command.o: command.c command.h hiredis.h read.h sds.h adlist.h hiutil.h hiarray.h
-crc16.o: crc16.c hiutil.h
-dict.o: dict.c fmacros.h dict.h
-hiarray.o: hiarray.c hiarray.h hiutil.h
-hircluster.o: hircluster.c fmacros.h hircluster.h hiredis.h read.h sds.h adlist.h hiarray.h hiutil.h async.h command.h dict.c dict.h
-hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h net.h
-hiutil.o: hiutil.c hiutil.h
-net.o: net.c fmacros.h net.h hiredis.h read.h sds.h
-read.o: read.c fmacros.h read.h sds.h
-sds.o: sds.c sds.h
-test.o: test.c fmacros.h hiredis.h read.h sds.h net.h
-
-$(DYLIBNAME): $(OBJ)
- $(DYLIB_MAKE_CMD) $(OBJ)
-
-$(STLIBNAME): $(OBJ)
- $(STLIB_MAKE_CMD) $(OBJ)
-
-dynamic: $(DYLIBNAME)
-static: $(STLIBNAME)
-
-# Binaries:
-hiredis-example-libevent: examples/example-libevent.c adapters/libevent.h $(STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -levent $(STLIBNAME)
-
-hiredis-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -lev $(STLIBNAME)
-
-hiredis-example-glib: examples/example-glib.c adapters/glib.h $(STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) $(shell pkg-config --cflags --libs glib-2.0) -I. $< $(STLIBNAME)
-
-ifndef AE_DIR
-hiredis-example-ae:
- @echo "Please specify AE_DIR (e.g. <redis repository>/src)"
- @false
-else
-hiredis-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
-hiredis-example-libuv:
- @echo "Please specify LIBUV_DIR (e.g. ../libuv/)"
- @false
-else
-hiredis-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(LIBUV_DIR)/include $< $(LIBUV_DIR)/.libs/libuv.a -lpthread $(STLIBNAME)
-endif
-
-hiredis-example: examples/example.c $(STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< $(STLIBNAME)
-
-examples: $(EXAMPLES)
-
-hiredis-test: test.o $(STLIBNAME)
-
-hiredis-%: %.o $(STLIBNAME)
- $(CC) $(REAL_CFLAGS) -o $@ $(REAL_LDFLAGS) $< $(STLIBNAME)
-
-test: hiredis-test
- ./hiredis-test
-
-check: hiredis-test
- @echo "$$REDIS_TEST_CONFIG" | $(REDIS_SERVER) -
- $(PRE) ./hiredis-test -h 127.0.0.1 -p $(REDIS_PORT) -s /tmp/hiredis-test-redis.sock || \
- ( kill `cat /tmp/hiredis-test-redis.pid` && false )
- kill `cat /tmp/hiredis-test-redis.pid`
-
-.c.o:
- $(CC) -std=c99 -pedantic -c $(REAL_CFLAGS) $<
-
-clean:
- rm -rf $(DYLIBNAME) $(STLIBNAME) $(TESTS) $(PKGCONFNAME) examples/hiredis-example* *.o *.gcda *.gcno *.gcov
-
-dep:
- $(CC) -MM *.c
-
-ifeq ($(uname_S),SunOS)
- INSTALL?= cp -r
-endif
-
-INSTALL?= cp -a
-
-$(PKGCONFNAME): hiredis.h
- @echo "Generating $@ for pkgconfig..."
- @echo prefix=$(PREFIX) > $@
- @echo exec_prefix=\$${prefix} >> $@
- @echo libdir=$(PREFIX)/$(LIBRARY_PATH) >> $@
- @echo includedir=$(PREFIX)/$(INCLUDE_PATH) >> $@
- @echo >> $@
- @echo Name: hiredis >> $@
- @echo Description: Minimalistic C client library for Redis. >> $@
- @echo Version: $(HIREDIS_VIP_MAJOR).$(HIREDIS_VIP_MINOR).$(HIREDIS_VIP_PATCH) >> $@
- @echo Libs: -L\$${libdir} -lhiredis >> $@
- @echo Cflags: -I\$${includedir} -D_FILE_OFFSET_BITS=64 >> $@
-
-install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME)
- mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_LIBRARY_PATH)
- $(INSTALL) hiredis.h async.h read.h sds.h hiutil.h hiarray.h dict.h dict.c adlist.h fmacros.h hircluster.h adapters $(INSTALL_INCLUDE_PATH)
- $(INSTALL) $(DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(DYLIB_MINOR_NAME)
- cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIB_MAJOR_NAME)
- cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MAJOR_NAME) $(DYLIBNAME)
- $(INSTALL) $(STLIBNAME) $(INSTALL_LIBRARY_PATH)
- mkdir -p $(INSTALL_PKGCONF_PATH)
- $(INSTALL) $(PKGCONFNAME) $(INSTALL_PKGCONF_PATH)
-
-32bit:
- @echo ""
- @echo "WARNING: if this fails under Linux you probably need to install libc6-dev-i386"
- @echo ""
- $(MAKE) CFLAGS="-m32" LDFLAGS="-m32"
-
-32bit-vars:
- $(eval CFLAGS=-m32)
- $(eval LDFLAGS=-m32)
-
-gprof:
- $(MAKE) CFLAGS="-pg" LDFLAGS="-pg"
-
-gcov:
- $(MAKE) CFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs"
-
-coverage: gcov
- make check
- mkdir -p tmp/lcov
- lcov -d . -c -o tmp/lcov/hiredis.info
- genhtml --legend -o tmp/lcov/report tmp/lcov/hiredis.info
-
-noopt:
- $(MAKE) OPTIMIZATION=""
-
-.PHONY: all test check clean dep install 32bit gprof gcov noopt
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/README.md b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/README.md
deleted file mode 100644
index bc69f55..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/README.md
+++ /dev/null
@@ -1,281 +0,0 @@
-
-# HIREDIS-VIP
-
-Hiredis-vip is a C client library for the [Redis](http://redis.io/) database.
-
-Hiredis-vip supported redis cluster.
-
-Hiredis-vip fully contained and based on [Hiredis](https://github.com/redis/hiredis) .
-
-## CLUSTER SUPPORT
-
-### FEATURES:
-
-* **`SUPPORT REDIS CLUSTER`**:
- * Connect to redis cluster and run commands.
-
-* **`SUPPORT MULTI-KEY COMMAND`**:
- * Support `MSET`, `MGET` and `DEL`.
-
-* **`SUPPORT PIPELING`**:
- * Support redis pipeline and can contain multi-key command like above.
-
-* **`SUPPORT Asynchronous API`**:
- * User can run commands with asynchronous mode.
-
-### CLUSTER API:
-
-```c
-redisClusterContext *redisClusterConnect(const char *addrs, int flags);
-redisClusterContext *redisClusterConnectWithTimeout(const char *addrs, const struct timeval tv, int flags);
-redisClusterContext *redisClusterConnectNonBlock(const char *addrs, int flags);
-void redisClusterFree(redisClusterContext *cc);
-void redisClusterSetMaxRedirect(redisClusterContext *cc, int max_redirect_count);
-void *redisClusterFormattedCommand(redisClusterContext *cc, char *cmd, int len);
-void *redisClustervCommand(redisClusterContext *cc, const char *format, va_list ap);
-void *redisClusterCommand(redisClusterContext *cc, const char *format, ...);
-void *redisClusterCommandArgv(redisClusterContext *cc, int argc, const char **argv, const size_t *argvlen);
-redisContext *ctx_get_by_node(struct cluster_node *node, const struct timeval *timeout, int flags);
-int redisClusterAppendFormattedCommand(redisClusterContext *cc, char *cmd, int len);
-int redisClustervAppendCommand(redisClusterContext *cc, const char *format, va_list ap);
-int redisClusterAppendCommand(redisClusterContext *cc, const char *format, ...);
-int redisClusterAppendCommandArgv(redisClusterContext *cc, int argc, const char **argv, const size_t *argvlen);
-int redisClusterGetReply(redisClusterContext *cc, void **reply);
-void redisCLusterReset(redisClusterContext *cc);
-
-redisClusterAsyncContext *redisClusterAsyncConnect(const char *addrs, int flags);
-int redisClusterAsyncSetConnectCallback(redisClusterAsyncContext *acc, redisConnectCallback *fn);
-int redisClusterAsyncSetDisconnectCallback(redisClusterAsyncContext *acc, redisDisconnectCallback *fn);
-int redisClusterAsyncFormattedCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, char *cmd, int len);
-int redisClustervAsyncCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, const char *format, va_list ap);
-int redisClusterAsyncCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, const char *format, ...);
-int redisClusterAsyncCommandArgv(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen);
-
-void redisClusterAsyncDisconnect(redisClusterAsyncContext *acc);
-void redisClusterAsyncFree(redisClusterAsyncContext *acc);
-```
-
-## Quick usage
-
-If you want used but not read the follow, please reference the examples:
-https://github.com/vipshop/hiredis-vip/wiki
-
-## Cluster synchronous API
-
-To consume the synchronous API, there are only a few function calls that need to be introduced:
-
-```c
-redisClusterContext *redisClusterConnect(const char *addrs, int flags);
-void redisClusterSetMaxRedirect(redisClusterContext *cc, int max_redirect_count);
-void *redisClusterCommand(redisClusterContext *cc, const char *format, ...);
-void redisClusterFree(redisClusterContext *cc);
-```
-
-### Cluster connecting
-
-The function `redisClusterConnect` is used to create a so-called `redisClusterContext`. The
-context is where Hiredis-vip Cluster holds state for connections. The `redisClusterContext`
-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.
-After trying to connect to Redis using `redisClusterContext` you should
-check the `err` field to see if establishing the connection was successful:
-```c
-redisClusterContext *cc = redisClusterConnect("127.0.0.1:6379", HIRCLUSTER_FLAG_NULL);
-if (cc != NULL && cc->err) {
- printf("Error: %s\n", cc->errstr);
- // handle error
-}
-```
-
-### Cluster sending commands
-
-The next that will be introduced is `redisClusterCommand`.
-This function takes a format similar to printf. In the simplest form,
-it is used like this:
-```c
-reply = redisClusterCommand(clustercontext, "SET foo bar");
-```
-
-The specifier `%s` interpolates a string in the command, and uses `strlen` to
-determine the length of the string:
-```c
-reply = redisClusterCommand(clustercontext, "SET foo %s", value);
-```
-Internally, Hiredis-vip splits the command in different arguments and will
-convert it to the protocol used to communicate with Redis.
-One or more spaces separates arguments, so you can use the specifiers
-anywhere in an argument:
-```c
-reply = redisClusterCommand(clustercontext, "SET key:%s %s", myid, value);
-```
-
-### Cluster multi-key commands
-
-Hiredis-vip supports mget/mset/del multi-key commands.
-Those multi-key commands is highly effective.
-Millions of keys in one mget command just used several seconds.
-
-Example:
-```c
-reply = redisClusterCommand(clustercontext, "mget %s %s %s %s", key1, key2, key3, key4);
-```
-
-### Cluster cleaning up
-
-To disconnect and free the context the following function can be used:
-```c
-void redisClusterFree(redisClusterContext *cc);
-```
-This function immediately closes the socket and then frees the allocations done in
-creating the context.
-
-### Cluster pipelining
-
-The function `redisClusterGetReply` is exported as part of the Hiredis API and can be used
-when a reply is expected on the socket. To pipeline commands, the only things that needs
-to be done is filling up the output buffer. For this cause, two commands can be used that
-are identical to the `redisClusterCommand` family, apart from not returning a reply:
-```c
-int redisClusterAppendCommand(redisClusterContext *cc, const char *format, ...);
-int redisClusterAppendCommandArgv(redisClusterContext *cc, int argc, const char **argv);
-```
-After calling either function one or more times, `redisClusterGetReply` can be used to receive the
-subsequent replies. The return value for this function is either `REDIS_OK` or `REDIS_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.
-```c
-void redisCLusterReset(redisClusterContext *cc);
-```
-Warning: You must call `redisCLusterReset` function after one pipelining anyway.
-
-The following examples shows a simple cluster pipeline:
-```c
-redisReply *reply;
-redisClusterAppendCommand(clusterContext,"SET foo bar");
-redisClusterAppendCommand(clusterContext,"GET foo");
-redisClusterGetReply(clusterContext,&reply); // reply for SET
-freeReplyObject(reply);
-redisClusterGetReply(clusterContext,&reply); // reply for GET
-freeReplyObject(reply);
-redisCLusterReset(clusterContext);
-```
-This API can also be used to implement a blocking subscriber:
-```c
-reply = redisClusterCommand(clusterContext,"SUBSCRIBE foo");
-freeReplyObject(reply);
-while(redisClusterGetReply(clusterContext,&reply) == REDIS_OK) {
- // consume message
- freeReplyObject(reply);
-}
-redisCLusterReset(clusterContext);
-```
-
-## Cluster asynchronous API
-
-Hiredis-vip comes with an cluster asynchronous API that works easily with any event library.
-Now we just support and test for libevent and redis ae, if you need for other event libraries,
-please contact with us, and we will support it quickly.
-
-### 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
-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.
-```c
-redisClusterAsyncContext *acc = redisClusterAsyncConnect("127.0.0.1:6379", HIRCLUSTER_FLAG_NULL);
-if (acc->err) {
- printf("Error: %s\n", acc->errstr);
- // handle error
-}
-```
-
-The cluster asynchronous context can hold a disconnect callback function that is called when the
-connection is disconnected (either because of an error or per user request). This function should
-have the following prototype:
-```c
-void(const redisAsyncContext *c, int status);
-```
-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`
-field in the context can be accessed to find out the cause of the error.
-
-You not need to reconnect in the disconnect callback, hiredis-vip will reconnect this connection itself
-when commands come to this redis node.
-
-Setting the disconnect callback can only be done once per context. For subsequent calls it will
-return `REDIS_ERR`. The function to set the disconnect callback has the following prototype:
-```c
-int redisClusterAsyncSetDisconnectCallback(redisClusterAsyncContext *acc, redisDisconnectCallback *fn);
-```
-### Sending commands and their callbacks
-
-In an cluster asynchronous context, commands are automatically pipelined due to the nature of an event loop.
-Therefore, unlike the cluster synchronous API, there is only a single way to send commands.
-Because commands are sent to Redis cluster 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(redisClusterAsyncContext *acc, 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 redisClusterAsyncCommand(
- redisClusterAsyncContext *acc,
- redisClusterCallbackFn *fn,
- void *privdata, const char *format, ...);
-```
-This function 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 `redisClusterAsyncCommand` 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
-valid for the duration of the callback.
-
-All pending callbacks are called with a `NULL` reply when the context encountered an error.
-
-### Disconnecting
-
-An cluster asynchronous connection can be terminated using:
-```c
-void redisClusterAsyncDisconnect(redisClusterAsyncContext *acc);
-```
-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.
-
-### Hooking it up to event library *X*
-
-There are a few hooks that need to be set on the cluster context object after it is created.
-See the `adapters/` directory for bindings to *ae* and *libevent*.
-
-## Package
-
-If you only want get library, you can "yum install hiredis-vip" or "apt-get install hiredis-vip" instead of building from source code.
-
-If you used hiredis-vip in your project, you can install "hiredis-vip-devel" package for development.
-
-Before install the package, execute the follow command first:
-
-**deb package** : `curl -s https://packagecloud.io/install/repositories/deep/packages/script.deb.sh | sudo bash`
-
-**rpm package** : `curl -s https://packagecloud.io/install/repositories/deep/packages/script.rpm.sh | sudo bash`
-
-You can also download the packages from "https://packagecloud.io/deep/packages" and install by yourself.
-
-If you want to support other OS packages, please contact with me.
-
-## AUTHORS
-
-Hiredis-vip was maintained and used at vipshop(https://github.com/vipshop).
-The redis client library part in hiredis-vip is same as hiredis(https://github.com/redis/hiredis).
-The redis cluster client library part in hiredis-vip is written by deep(https://github.com/deep011).
-Hiredis-vip is released under the BSD license.
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/ae.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/ae.h
deleted file mode 100644
index f861cf2..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/ae.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * 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 <sys/types.h>
-#include <ae.h>
-#include "../hiredis.h"
-#include "../async.h"
-
-#if 1 //shenzheng 2015-11-5 redis cluster
-#include "../hircluster.h"
-#endif //shenzheng 2015-11-5 redis cluster
-
-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);
- 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*)malloc(sizeof(*e));
- 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;
-}
-
-#if 1 //shenzheng 2015-11-5 redis cluster
-
-static int redisAeAttach_link(redisAsyncContext *ac, void *base)
-{
- redisAeAttach((aeEventLoop *)base, ac);
-}
-
-static int redisClusterAeAttach(aeEventLoop *loop, redisClusterAsyncContext *acc) {
-
- if(acc == NULL || loop == NULL)
- {
- return REDIS_ERR;
- }
-
- acc->adapter = loop;
- acc->attach_fn = redisAeAttach_link;
-
- return REDIS_OK;
-}
-
-#endif //shenzheng 2015-11-5 redis cluster
-
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/glib.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/glib.h
deleted file mode 100644
index e13eee7..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/glib.h
+++ /dev/null
@@ -1,153 +0,0 @@
-#ifndef __HIREDIS_GLIB_H__
-#define __HIREDIS_GLIB_H__
-
-#include <glib.h>
-
-#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 = data;
- g_return_if_fail(source);
- source->poll_fd.events |= G_IO_IN;
- g_main_context_wakeup(g_source_get_context(data));
-}
-
-static void
-redis_source_del_read (gpointer data)
-{
- RedisSource *source = data;
- g_return_if_fail(source);
- source->poll_fd.events &= ~G_IO_IN;
- g_main_context_wakeup(g_source_get_context(data));
-}
-
-static void
-redis_source_add_write (gpointer data)
-{
- RedisSource *source = data;
- g_return_if_fail(source);
- source->poll_fd.events |= G_IO_OUT;
- g_main_context_wakeup(g_source_get_context(data));
-}
-
-static void
-redis_source_del_write (gpointer data)
-{
- RedisSource *source = data;
- g_return_if_fail(source);
- source->poll_fd.events &= ~G_IO_OUT;
- g_main_context_wakeup(g_source_get_context(data));
-}
-
-static void
-redis_source_cleanup (gpointer data)
-{
- RedisSource *source = 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(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);
- 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/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/libev.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/libev.h
deleted file mode 100644
index 2bf8d52..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/libev.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * 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 <stdlib.h>
-#include <sys/types.h>
-#include <ev.h>
-#include "../hiredis.h"
-#include "../async.h"
-
-typedef struct redisLibevEvents {
- redisAsyncContext *context;
- struct ev_loop *loop;
- int reading, writing;
- ev_io rev, wev;
-} redisLibevEvents;
-
-static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) {
-#if EV_MULTIPLICITY
- ((void)loop);
-#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)loop);
-#endif
- ((void)revents);
-
- redisLibevEvents *e = (redisLibevEvents*)watcher->data;
- redisAsyncHandleWrite(e->context);
-}
-
-static void redisLibevAddRead(void *privdata) {
- redisLibevEvents *e = (redisLibevEvents*)privdata;
- struct ev_loop *loop = e->loop;
- ((void)loop);
- if (!e->reading) {
- e->reading = 1;
- ev_io_start(EV_A_ &e->rev);
- }
-}
-
-static void redisLibevDelRead(void *privdata) {
- redisLibevEvents *e = (redisLibevEvents*)privdata;
- struct ev_loop *loop = e->loop;
- ((void)loop);
- if (e->reading) {
- e->reading = 0;
- ev_io_stop(EV_A_ &e->rev);
- }
-}
-
-static void redisLibevAddWrite(void *privdata) {
- redisLibevEvents *e = (redisLibevEvents*)privdata;
- struct ev_loop *loop = e->loop;
- ((void)loop);
- if (!e->writing) {
- e->writing = 1;
- ev_io_start(EV_A_ &e->wev);
- }
-}
-
-static void redisLibevDelWrite(void *privdata) {
- redisLibevEvents *e = (redisLibevEvents*)privdata;
- struct ev_loop *loop = e->loop;
- ((void)loop);
- if (e->writing) {
- e->writing = 0;
- ev_io_stop(EV_A_ &e->wev);
- }
-}
-
-static void redisLibevCleanup(void *privdata) {
- redisLibevEvents *e = (redisLibevEvents*)privdata;
- redisLibevDelRead(privdata);
- redisLibevDelWrite(privdata);
- free(e);
-}
-
-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*)malloc(sizeof(*e));
- e->context = ac;
-#if EV_MULTIPLICITY
- e->loop = loop;
-#else
- e->loop = NULL;
-#endif
- e->reading = e->writing = 0;
- 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.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/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/libevent.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/libevent.h
deleted file mode 100644
index 6bc911c..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/libevent.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * 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 <event.h>
-#include "../hiredis.h"
-#include "../async.h"
-
-#if 1 //shenzheng 2015-9-21 redis cluster
-#include "../hircluster.h"
-#endif //shenzheng 2015-9-21 redis cluster
-
-typedef struct redisLibeventEvents {
- redisAsyncContext *context;
- struct event rev, wev;
-} redisLibeventEvents;
-
-static void redisLibeventReadEvent(int fd, short event, void *arg) {
- ((void)fd); ((void)event);
- redisLibeventEvents *e = (redisLibeventEvents*)arg;
- redisAsyncHandleRead(e->context);
-}
-
-static void redisLibeventWriteEvent(int fd, short event, void *arg) {
- ((void)fd); ((void)event);
- redisLibeventEvents *e = (redisLibeventEvents*)arg;
- redisAsyncHandleWrite(e->context);
-}
-
-static void redisLibeventAddRead(void *privdata) {
- redisLibeventEvents *e = (redisLibeventEvents*)privdata;
- event_add(&e->rev,NULL);
-}
-
-static void redisLibeventDelRead(void *privdata) {
- redisLibeventEvents *e = (redisLibeventEvents*)privdata;
- event_del(&e->rev);
-}
-
-static void redisLibeventAddWrite(void *privdata) {
- redisLibeventEvents *e = (redisLibeventEvents*)privdata;
- event_add(&e->wev,NULL);
-}
-
-static void redisLibeventDelWrite(void *privdata) {
- redisLibeventEvents *e = (redisLibeventEvents*)privdata;
- event_del(&e->wev);
-}
-
-static void redisLibeventCleanup(void *privdata) {
- redisLibeventEvents *e = (redisLibeventEvents*)privdata;
- event_del(&e->rev);
- event_del(&e->wev);
- free(e);
-}
-
-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*)malloc(sizeof(*e));
- 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.data = e;
-
- /* Initialize and install read/write events */
- event_set(&e->rev,c->fd,EV_READ,redisLibeventReadEvent,e);
- event_set(&e->wev,c->fd,EV_WRITE,redisLibeventWriteEvent,e);
- event_base_set(base,&e->rev);
- event_base_set(base,&e->wev);
- return REDIS_OK;
-}
-
-#if 1 //shenzheng 2015-9-21 redis cluster
-
-static int redisLibeventAttach_link(redisAsyncContext *ac, void *base)
-{
- redisLibeventAttach(ac, (struct event_base *)base);
-}
-
-static int redisClusterLibeventAttach(redisClusterAsyncContext *acc, struct event_base *base) {
-
- if(acc == NULL || base == NULL)
- {
- return REDIS_ERR;
- }
-
- acc->adapter = base;
- acc->attach_fn = redisLibeventAttach_link;
-
- return REDIS_OK;
-}
-
-#endif //shenzheng 2015-9-21 redis cluster
-
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/libuv.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/libuv.h
deleted file mode 100644
index 3c9a49f..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adapters/libuv.h
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef __HIREDIS_LIBUV_H__
-#define __HIREDIS_LIBUV_H__
-#include <stdlib.h>
-#include <uv.h>
-#include "../hiredis.h"
-#include "../async.h"
-#include <string.h>
-
-typedef struct redisLibuvEvents {
- redisAsyncContext* context;
- uv_poll_t handle;
- int events;
-} redisLibuvEvents;
-
-
-static void redisLibuvPoll(uv_poll_t* handle, int status, int events) {
- redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
-
- if (status != 0) {
- return;
- }
-
- if (events & UV_READABLE) {
- redisAsyncHandleRead(p->context);
- }
- if (events & UV_WRITABLE) {
- redisAsyncHandleWrite(p->context);
- }
-}
-
-
-static void redisLibuvAddRead(void *privdata) {
- redisLibuvEvents* p = (redisLibuvEvents*)privdata;
-
- 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;
-
- 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_close(uv_handle_t* handle) {
- redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
-
- free(p);
-}
-
-
-static void redisLibuvCleanup(void *privdata) {
- redisLibuvEvents* p = (redisLibuvEvents*)privdata;
-
- uv_close((uv_handle_t*)&p->handle, on_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;
-
- redisLibuvEvents* p = (redisLibuvEvents*)malloc(sizeof(*p));
-
- if (!p) {
- return REDIS_ERR;
- }
-
- memset(p, 0, sizeof(*p));
-
- if (uv_poll_init(loop, &p->handle, c->fd) != 0) {
- return REDIS_ERR;
- }
-
- ac->ev.data = p;
- p->handle.data = p;
- p->context = ac;
-
- return REDIS_OK;
-}
-
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adlist.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adlist.c
deleted file mode 100644
index b490a6b..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adlist.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/* adlist.c - A generic doubly linked list implementation
- *
- * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
- * 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 <stdlib.h>
-#include "adlist.h"
-#include "hiutil.h"
-
-/* Create a new list. The created list can be freed with
- * AlFreeList(), but private value of every node need to be freed
- * by the user before to call AlFreeList().
- *
- * On error, NULL is returned. Otherwise the pointer to the new list. */
-hilist *listCreate(void)
-{
- struct hilist *list;
-
- if ((list = hi_alloc(sizeof(*list))) == NULL)
- return NULL;
- list->head = list->tail = NULL;
- list->len = 0;
- list->dup = NULL;
- list->free = NULL;
- list->match = NULL;
- return list;
-}
-
-/* Free the whole list.
- *
- * This function can't fail. */
-void listRelease(hilist *list)
-{
- unsigned long len;
- listNode *current, *next;
-
- current = list->head;
- len = list->len;
- while(len--) {
- next = current->next;
- if (list->free) list->free(current->value);
- hi_free(current);
- current = next;
- }
- hi_free(list);
-}
-
-/* Add a new node to the list, to head, containing the specified 'value'
- * pointer as value.
- *
- * On error, NULL is returned and no operation is performed (i.e. the
- * list remains unaltered).
- * On success the 'list' pointer you pass to the function is returned. */
-hilist *listAddNodeHead(hilist *list, void *value)
-{
- listNode *node;
-
- if ((node = hi_alloc(sizeof(*node))) == NULL)
- return NULL;
- node->value = value;
- if (list->len == 0) {
- list->head = list->tail = node;
- node->prev = node->next = NULL;
- } else {
- node->prev = NULL;
- node->next = list->head;
- list->head->prev = node;
- list->head = node;
- }
- list->len++;
- return list;
-}
-
-/* Add a new node to the list, to tail, containing the specified 'value'
- * pointer as value.
- *
- * On error, NULL is returned and no operation is performed (i.e. the
- * list remains unaltered).
- * On success the 'list' pointer you pass to the function is returned. */
-hilist *listAddNodeTail(hilist *list, void *value)
-{
- listNode *node;
-
- if ((node = hi_alloc(sizeof(*node))) == NULL)
- return NULL;
- node->value = value;
- if (list->len == 0) {
- list->head = list->tail = node;
- node->prev = node->next = NULL;
- } else {
- node->prev = list->tail;
- node->next = NULL;
- list->tail->next = node;
- list->tail = node;
- }
- list->len++;
- return list;
-}
-
-hilist *listInsertNode(hilist *list, listNode *old_node, void *value, int after) {
- listNode *node;
-
- if ((node = hi_alloc(sizeof(*node))) == NULL)
- return NULL;
- node->value = value;
- if (after) {
- node->prev = old_node;
- node->next = old_node->next;
- if (list->tail == old_node) {
- list->tail = node;
- }
- } else {
- node->next = old_node;
- node->prev = old_node->prev;
- if (list->head == old_node) {
- list->head = node;
- }
- }
- if (node->prev != NULL) {
- node->prev->next = node;
- }
- if (node->next != NULL) {
- node->next->prev = node;
- }
- list->len++;
- return list;
-}
-
-/* Remove the specified node from the specified list.
- * It's up to the caller to free the private value of the node.
- *
- * This function can't fail. */
-void listDelNode(hilist *list, listNode *node)
-{
- if (node->prev)
- node->prev->next = node->next;
- else
- list->head = node->next;
- if (node->next)
- node->next->prev = node->prev;
- else
- list->tail = node->prev;
- if (list->free) list->free(node->value);
- hi_free(node);
- list->len--;
-}
-
-/* Returns a list iterator 'iter'. After the initialization every
- * call to listNext() will return the next element of the list.
- *
- * This function can't fail. */
-listIter *listGetIterator(hilist *list, int direction)
-{
- listIter *iter;
-
- if ((iter = hi_alloc(sizeof(*iter))) == NULL) return NULL;
- if (direction == AL_START_HEAD)
- iter->next = list->head;
- else
- iter->next = list->tail;
- iter->direction = direction;
- return iter;
-}
-
-/* Release the iterator memory */
-void listReleaseIterator(listIter *iter) {
- hi_free(iter);
-}
-
-/* Create an iterator in the list private iterator structure */
-void listRewind(hilist *list, listIter *li) {
- li->next = list->head;
- li->direction = AL_START_HEAD;
-}
-
-void listRewindTail(hilist *list, listIter *li) {
- li->next = list->tail;
- li->direction = AL_START_TAIL;
-}
-
-/* Return the next element of an iterator.
- * It's valid to remove the currently returned element using
- * listDelNode(), but not to remove other elements.
- *
- * The function returns a pointer to the next element of the list,
- * or NULL if there are no more elements, so the classical usage patter
- * is:
- *
- * iter = listGetIterator(list,<direction>);
- * while ((node = listNext(iter)) != NULL) {
- * doSomethingWith(listNodeValue(node));
- * }
- *
- * */
-listNode *listNext(listIter *iter)
-{
- listNode *current = iter->next;
-
- if (current != NULL) {
- if (iter->direction == AL_START_HEAD)
- iter->next = current->next;
- else
- iter->next = current->prev;
- }
- return current;
-}
-
-/* Duplicate the whole list. On out of memory NULL is returned.
- * On success a copy of the original list is returned.
- *
- * The 'Dup' method set with listSetDupMethod() function is used
- * to copy the node value. Otherwise the same pointer value of
- * the original node is used as value of the copied node.
- *
- * The original list both on success or error is never modified. */
-hilist *listDup(hilist *orig)
-{
- hilist *copy;
- listIter *iter;
- listNode *node;
-
- if ((copy = listCreate()) == NULL)
- return NULL;
- copy->dup = orig->dup;
- copy->free = orig->free;
- copy->match = orig->match;
- iter = listGetIterator(orig, AL_START_HEAD);
- while((node = listNext(iter)) != NULL) {
- void *value;
-
- if (copy->dup) {
- value = copy->dup(node->value);
- if (value == NULL) {
- listRelease(copy);
- listReleaseIterator(iter);
- return NULL;
- }
- } else
- value = node->value;
- if (listAddNodeTail(copy, value) == NULL) {
- listRelease(copy);
- listReleaseIterator(iter);
- return NULL;
- }
- }
- listReleaseIterator(iter);
- return copy;
-}
-
-/* Search the list for a node matching a given key.
- * The match is performed using the 'match' method
- * set with listSetMatchMethod(). If no 'match' method
- * is set, the 'value' pointer of every node is directly
- * compared with the 'key' pointer.
- *
- * On success the first matching node pointer is returned
- * (search starts from head). If no matching node exists
- * NULL is returned. */
-listNode *listSearchKey(hilist *list, void *key)
-{
- listIter *iter;
- listNode *node;
-
- iter = listGetIterator(list, AL_START_HEAD);
- while((node = listNext(iter)) != NULL) {
- if (list->match) {
- if (list->match(node->value, key)) {
- listReleaseIterator(iter);
- return node;
- }
- } else {
- if (key == node->value) {
- listReleaseIterator(iter);
- return node;
- }
- }
- }
- listReleaseIterator(iter);
- return NULL;
-}
-
-/* Return the element at the specified zero-based index
- * where 0 is the head, 1 is the element next to head
- * and so on. Negative integers are used in order to count
- * from the tail, -1 is the last element, -2 the penultimate
- * and so on. If the index is out of range NULL is returned. */
-listNode *listIndex(hilist *list, long index) {
- listNode *n;
-
- if (index < 0) {
- index = (-index)-1;
- n = list->tail;
- while(index-- && n) n = n->prev;
- } else {
- n = list->head;
- while(index-- && n) n = n->next;
- }
- return n;
-}
-
-/* Rotate the list removing the tail node and inserting it to the head. */
-void listRotate(hilist *list) {
- listNode *tail = list->tail;
-
- if (listLength(list) <= 1) return;
-
- /* Detach current tail */
- list->tail = tail->prev;
- list->tail->next = NULL;
- /* Move it as head */
- list->head->prev = tail;
- tail->prev = NULL;
- tail->next = list->head;
- list->head = tail;
-}
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adlist.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adlist.h
deleted file mode 100644
index 5b9a53e..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/adlist.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* adlist.h - A generic doubly linked list implementation
- *
- * Copyright (c) 2006-2012, Salvatore Sanfilippo <antirez at gmail dot com>
- * 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 __ADLIST_H__
-#define __ADLIST_H__
-
-/* Node, List, and Iterator are the only data structures used currently. */
-
-typedef struct listNode {
- struct listNode *prev;
- struct listNode *next;
- void *value;
-} listNode;
-
-typedef struct listIter {
- listNode *next;
- int direction;
-} listIter;
-
-typedef struct hilist {
- listNode *head;
- listNode *tail;
- void *(*dup)(void *ptr);
- void (*free)(void *ptr);
- int (*match)(void *ptr, void *key);
- unsigned long len;
-} hilist;
-
-/* Functions implemented as macros */
-#define listLength(l) ((l)->len)
-#define listFirst(l) ((l)->head)
-#define listLast(l) ((l)->tail)
-#define listPrevNode(n) ((n)->prev)
-#define listNextNode(n) ((n)->next)
-#define listNodeValue(n) ((n)->value)
-
-#define listSetDupMethod(l,m) ((l)->dup = (m))
-#define listSetFreeMethod(l,m) ((l)->free = (m))
-#define listSetMatchMethod(l,m) ((l)->match = (m))
-
-#define listGetDupMethod(l) ((l)->dup)
-#define listGetFree(l) ((l)->free)
-#define listGetMatchMethod(l) ((l)->match)
-
-/* Prototypes */
-hilist *listCreate(void);
-void listRelease(hilist *list);
-hilist *listAddNodeHead(hilist *list, void *value);
-hilist *listAddNodeTail(hilist *list, void *value);
-hilist *listInsertNode(hilist *list, listNode *old_node, void *value, int after);
-void listDelNode(hilist *list, listNode *node);
-listIter *listGetIterator(hilist *list, int direction);
-listNode *listNext(listIter *iter);
-void listReleaseIterator(listIter *iter);
-hilist *listDup(hilist *orig);
-listNode *listSearchKey(hilist *list, void *key);
-listNode *listIndex(hilist *list, long index);
-void listRewind(hilist *list, listIter *li);
-void listRewindTail(hilist *list, listIter *li);
-void listRotate(hilist *list);
-
-/* Directions for iterators */
-#define AL_START_HEAD 0
-#define AL_START_TAIL 1
-
-#endif /* __ADLIST_H__ */
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/async.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/async.c
deleted file mode 100644
index 28aa76f..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/async.c
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * 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 <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include "async.h"
-#include "net.h"
-#include "dict.c"
-#include "sds.h"
-
-#define _EL_ADD_READ(ctx) do { \
- if ((ctx)->ev.addRead) (ctx)->ev.addRead((ctx)->ev.data); \
- } while(0)
-#define _EL_DEL_READ(ctx) do { \
- if ((ctx)->ev.delRead) (ctx)->ev.delRead((ctx)->ev.data); \
- } while(0)
-#define _EL_ADD_WRITE(ctx) do { \
- if ((ctx)->ev.addWrite) (ctx)->ev.addWrite((ctx)->ev.data); \
- } while(0)
-#define _EL_DEL_WRITE(ctx) do { \
- if ((ctx)->ev.delWrite) (ctx)->ev.delWrite((ctx)->ev.data); \
- } while(0)
-#define _EL_CLEANUP(ctx) do { \
- if ((ctx)->ev.cleanup) (ctx)->ev.cleanup((ctx)->ev.data); \
- } while(0);
-
-/* Forward declaration of function in hiredis.c */
-int __redisAppendCommand(redisContext *c, const char *cmd, size_t len);
-
-/* Functions managing dictionary of callbacks for pub/sub. */
-static unsigned int callbackHash(const void *key) {
- return dictGenHashFunction((const unsigned char *)key,
- sdslen((const sds)key));
-}
-
-static void *callbackValDup(void *privdata, const void *src) {
- ((void) privdata);
- redisCallback *dup = malloc(sizeof(*dup));
- memcpy(dup,src,sizeof(*dup));
- return dup;
-}
-
-static int callbackKeyCompare(void *privdata, const void *key1, const void *key2) {
- int l1, l2;
- ((void) privdata);
-
- l1 = sdslen((const sds)key1);
- l2 = sdslen((const sds)key2);
- if (l1 != l2) return 0;
- return memcmp(key1,key2,l1) == 0;
-}
-
-static void callbackKeyDestructor(void *privdata, void *key) {
- ((void) privdata);
- sdsfree((sds)key);
-}
-
-static void callbackValDestructor(void *privdata, void *val) {
- ((void) privdata);
- free(val);
-}
-
-static dictType callbackDict = {
- callbackHash,
- NULL,
- callbackValDup,
- callbackKeyCompare,
- callbackKeyDestructor,
- callbackValDestructor
-};
-
-static redisAsyncContext *redisAsyncInitialize(redisContext *c) {
- redisAsyncContext *ac;
-
- ac = realloc(c,sizeof(redisAsyncContext));
- if (ac == NULL)
- return NULL;
-
- c = &(ac->c);
-
- /* The regular connect functions will always set the flag REDIS_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;
-
- ac->err = 0;
- ac->errstr = NULL;
- ac->data = NULL;
-
- ac->ev.data = NULL;
- ac->ev.addRead = NULL;
- ac->ev.delRead = NULL;
- ac->ev.addWrite = NULL;
- ac->ev.delWrite = NULL;
- ac->ev.cleanup = NULL;
-
- ac->onConnect = NULL;
- ac->onDisconnect = NULL;
-
- ac->replies.head = NULL;
- ac->replies.tail = NULL;
- ac->sub.invalid.head = NULL;
- ac->sub.invalid.tail = NULL;
- ac->sub.channels = dictCreate(&callbackDict,NULL);
- ac->sub.patterns = dictCreate(&callbackDict,NULL);
- return ac;
-}
-
-/* We want the error field to be accessible directly instead of requiring
- * an indirection to the redisContext struct. */
-static void __redisAsyncCopyError(redisAsyncContext *ac) {
- if (!ac)
- return;
-
- redisContext *c = &(ac->c);
- ac->err = c->err;
- ac->errstr = c->errstr;
-}
-
-redisAsyncContext *redisAsyncConnect(const char *ip, int port) {
- redisContext *c;
- redisAsyncContext *ac;
-
- c = redisConnectNonBlock(ip,port);
- if (c == NULL)
- return NULL;
-
- ac = redisAsyncInitialize(c);
- if (ac == NULL) {
- redisFree(c);
- return NULL;
- }
-
- __redisAsyncCopyError(ac);
- return ac;
-}
-
-redisAsyncContext *redisAsyncConnectBind(const char *ip, int port,
- const char *source_addr) {
- redisContext *c = redisConnectBindNonBlock(ip,port,source_addr);
- redisAsyncContext *ac = redisAsyncInitialize(c);
- __redisAsyncCopyError(ac);
- return ac;
-}
-
-redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port,
- const char *source_addr) {
- redisContext *c = redisConnectBindNonBlockWithReuse(ip,port,source_addr);
- redisAsyncContext *ac = redisAsyncInitialize(c);
- __redisAsyncCopyError(ac);
- return ac;
-}
-
-redisAsyncContext *redisAsyncConnectUnix(const char *path) {
- redisContext *c;
- redisAsyncContext *ac;
-
- c = redisConnectUnixNonBlock(path);
- if (c == NULL)
- return NULL;
-
- ac = redisAsyncInitialize(c);
- if (ac == NULL) {
- redisFree(c);
- return NULL;
- }
-
- __redisAsyncCopyError(ac);
- return ac;
-}
-
-int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn) {
- if (ac->onConnect == NULL) {
- ac->onConnect = fn;
-
- /* The common way to detect an established connection is to wait for
- * the first write event to be fired. This assumes the related event
- * library functions are already set. */
- _EL_ADD_WRITE(ac);
- return REDIS_OK;
- }
- return REDIS_ERR;
-}
-
-int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn) {
- if (ac->onDisconnect == NULL) {
- ac->onDisconnect = fn;
- return REDIS_OK;
- }
- return REDIS_ERR;
-}
-
-/* Helper functions to push/shift callbacks */
-static int __redisPushCallback(redisCallbackList *list, redisCallback *source) {
- redisCallback *cb;
-
- /* Copy callback from stack to heap */
- cb = malloc(sizeof(*cb));
- if (cb == NULL)
- return REDIS_ERR_OOM;
-
- if (source != NULL) {
- memcpy(cb,source,sizeof(*cb));
- cb->next = NULL;
- }
-
- /* Store callback in list */
- if (list->head == NULL)
- list->head = cb;
- if (list->tail != NULL)
- list->tail->next = cb;
- list->tail = cb;
- return REDIS_OK;
-}
-
-static int __redisShiftCallback(redisCallbackList *list, redisCallback *target) {
- redisCallback *cb = list->head;
- if (cb != NULL) {
- list->head = cb->next;
- if (cb == list->tail)
- list->tail = NULL;
-
- /* Copy callback from heap to stack */
- if (target != NULL)
- memcpy(target,cb,sizeof(*cb));
- free(cb);
- return REDIS_OK;
- }
- return REDIS_ERR;
-}
-
-static void __redisRunCallback(redisAsyncContext *ac, redisCallback *cb, redisReply *reply) {
- redisContext *c = &(ac->c);
- if (cb->fn != NULL) {
- c->flags |= REDIS_IN_CALLBACK;
- cb->fn(ac,reply,cb->privdata);
- c->flags &= ~REDIS_IN_CALLBACK;
- }
-}
-
-/* Helper function to free the context. */
-static void __redisAsyncFree(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
- redisCallback cb;
- dictIterator *it;
- dictEntry *de;
-
- /* Execute pending callbacks with NULL reply. */
- while (__redisShiftCallback(&ac->replies,&cb) == REDIS_OK)
- __redisRunCallback(ac,&cb,NULL);
-
- /* Execute callbacks for invalid commands */
- while (__redisShiftCallback(&ac->sub.invalid,&cb) == REDIS_OK)
- __redisRunCallback(ac,&cb,NULL);
-
- /* Run subscription callbacks callbacks with NULL reply */
- it = dictGetIterator(ac->sub.channels);
- while ((de = dictNext(it)) != NULL)
- __redisRunCallback(ac,dictGetEntryVal(de),NULL);
- dictReleaseIterator(it);
- dictRelease(ac->sub.channels);
-
- it = dictGetIterator(ac->sub.patterns);
- while ((de = dictNext(it)) != NULL)
- __redisRunCallback(ac,dictGetEntryVal(de),NULL);
- dictReleaseIterator(it);
- dictRelease(ac->sub.patterns);
-
- /* 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 (ac->onDisconnect && (c->flags & REDIS_CONNECTED)) {
- if (c->flags & REDIS_FREEING) {
- ac->onDisconnect(ac,REDIS_OK);
- } else {
- ac->onDisconnect(ac,(ac->err == 0) ? REDIS_OK : REDIS_ERR);
- }
- }
-
- /* Cleanup self */
- redisFree(c);
-}
-
-/* Free the async context. When this function is called from a callback,
- * control needs to be returned to redisProcessCallbacks() 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) {
- redisContext *c = &(ac->c);
- c->flags |= REDIS_FREEING;
- if (!(c->flags & REDIS_IN_CALLBACK))
- __redisAsyncFree(ac);
-}
-
-/* Helper function to make the disconnect happen and clean up. */
-static void __redisAsyncDisconnect(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
-
- /* Make sure error is accessible if there is any */
- __redisAsyncCopyError(ac);
-
- if (ac->err == 0) {
- /* For clean disconnects, there should be no pending callbacks. */
- assert(__redisShiftCallback(&ac->replies,NULL) == REDIS_ERR);
- } else {
- /* Disconnection is caused by an error, make sure that pending
- * callbacks cannot call new commands. */
- c->flags |= REDIS_DISCONNECTING;
- }
-
- /* For non-clean disconnects, __redisAsyncFree() will execute pending
- * callbacks with a NULL-reply. */
- __redisAsyncFree(ac);
-}
-
-/* Tries to do a clean disconnect from Redis, 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
- * when there are no pending callbacks. */
-void redisAsyncDisconnect(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
- c->flags |= REDIS_DISCONNECTING;
- if (!(c->flags & REDIS_IN_CALLBACK) && ac->replies.head == NULL)
- __redisAsyncDisconnect(ac);
-}
-
-static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply, redisCallback *dstcb) {
- redisContext *c = &(ac->c);
- dict *callbacks;
- dictEntry *de;
- int pvariant;
- char *stype;
- sds sname;
-
- /* Custom reply functions are not supported for pub/sub. This will fail
- * very hard when they are used... */
- if (reply->type == REDIS_REPLY_ARRAY) {
- assert(reply->elements >= 2);
- assert(reply->element[0]->type == REDIS_REPLY_STRING);
- stype = reply->element[0]->str;
- pvariant = (tolower(stype[0]) == 'p') ? 1 : 0;
-
- if (pvariant)
- callbacks = ac->sub.patterns;
- else
- callbacks = ac->sub.channels;
-
- /* Locate the right callback */
- assert(reply->element[1]->type == REDIS_REPLY_STRING);
- sname = sdsnewlen(reply->element[1]->str,reply->element[1]->len);
- de = dictFind(callbacks,sname);
- if (de != NULL) {
- memcpy(dstcb,dictGetEntryVal(de),sizeof(*dstcb));
-
- /* If this is an unsubscribe message, remove it. */
- if (strcasecmp(stype+pvariant,"unsubscribe") == 0) {
- dictDelete(callbacks,sname);
-
- /* If this was the last unsubscribe message, revert to
- * non-subscribe mode. */
- assert(reply->element[2]->type == REDIS_REPLY_INTEGER);
- if (reply->element[2]->integer == 0)
- c->flags &= ~REDIS_SUBSCRIBED;
- }
- }
- sdsfree(sname);
- } else {
- /* Shift callback for invalid commands. */
- __redisShiftCallback(&ac->sub.invalid,dstcb);
- }
- return REDIS_OK;
-}
-
-void redisProcessCallbacks(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
- redisCallback cb = {NULL, NULL, NULL};
- void *reply = NULL;
- int status;
-
- while((status = redisGetReply(c,&reply)) == REDIS_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) {
- __redisAsyncDisconnect(ac);
- return;
- }
-
- /* If monitor mode, repush callback */
- if(c->flags & REDIS_MONITORING) {
- __redisPushCallback(&ac->replies,&cb);
- }
-
- /* When the connection is not being disconnected, simply stop
- * trying to get replies and wait for the next loop tick. */
- break;
- }
-
- /* Even if the context is subscribed, pending regular callbacks will
- * get a reply before pub/sub messages arrive. */
- if (__redisShiftCallback(&ac->replies,&cb) != REDIS_OK) {
- /*
- * A spontaneous reply in a not-subscribed context can be the error
- * reply that is sent when a new connection exceeds the maximum
- * number of allowed connections on the server side.
- *
- * This is seen as an error instead of a regular reply because the
- * server closes the connection after sending it.
- *
- * To prevent the error from being overwritten by an EOF error the
- * connection is closed here. See issue #43.
- *
- * Another possibility is that the server is loading its dataset.
- * 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);
- c->reader->fn->freeObject(reply);
- __redisAsyncDisconnect(ac);
- return;
- }
- /* No more regular callbacks and no errors, the context *must* be subscribed or monitoring. */
- assert((c->flags & REDIS_SUBSCRIBED || c->flags & REDIS_MONITORING));
- if(c->flags & REDIS_SUBSCRIBED)
- __redisGetSubscribeCallback(ac,reply,&cb);
- }
-
- if (cb.fn != NULL) {
- __redisRunCallback(ac,&cb,reply);
- c->reader->fn->freeObject(reply);
-
- /* Proceed with free'ing when redisAsyncFree() was called. */
- if (c->flags & REDIS_FREEING) {
- __redisAsyncFree(ac);
- return;
- }
- } else {
- /* No callback for this reply. This can either be a NULL callback,
- * or there were no callbacks to begin with. Either way, don't
- * abort with an error, but simply ignore it because the client
- * doesn't know what the server will spit out over the wire. */
- c->reader->fn->freeObject(reply);
- }
- }
-
- /* Disconnect when there was an error reading the reply */
- if (status != REDIS_OK)
- __redisAsyncDisconnect(ac);
-}
-
-/* Internal helper function to detect socket status the first time a read or
- * write event fires. When connecting was not succesful, the connect callback
- * is called with a REDIS_ERR status and the context is free'd. */
-static int __redisAsyncHandleConnect(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
-
- if (redisCheckSocketError(c) == REDIS_ERR) {
- /* Try again later when connect(2) is still in progress. */
- if (errno == EINPROGRESS)
- return REDIS_OK;
-
- if (ac->onConnect) ac->onConnect(ac,REDIS_ERR);
- __redisAsyncDisconnect(ac);
- return REDIS_ERR;
- }
-
- /* Mark context as connected. */
- c->flags |= REDIS_CONNECTED;
- if (ac->onConnect) ac->onConnect(ac,REDIS_OK);
- return REDIS_OK;
-}
-
-/* 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);
-
- if (!(c->flags & REDIS_CONNECTED)) {
- /* Abort connect was not successful. */
- if (__redisAsyncHandleConnect(ac) != REDIS_OK)
- return;
- /* Try again later when the context is still not connected. */
- if (!(c->flags & REDIS_CONNECTED))
- return;
- }
-
- if (redisBufferRead(c) == REDIS_ERR) {
- __redisAsyncDisconnect(ac);
- } else {
- /* Always re-schedule reads */
- _EL_ADD_READ(ac);
- redisProcessCallbacks(ac);
- }
-}
-
-void redisAsyncHandleWrite(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
- int done = 0;
-
- if (!(c->flags & REDIS_CONNECTED)) {
- /* Abort connect was not successful. */
- if (__redisAsyncHandleConnect(ac) != REDIS_OK)
- return;
- /* Try again later when the context is still not connected. */
- if (!(c->flags & REDIS_CONNECTED))
- return;
- }
-
- if (redisBufferWrite(c,&done) == REDIS_ERR) {
- __redisAsyncDisconnect(ac);
- } else {
- /* Continue writing when not done, stop writing otherwise */
- if (!done)
- _EL_ADD_WRITE(ac);
- else
- _EL_DEL_WRITE(ac);
-
- /* Always schedule reads after writes */
- _EL_ADD_READ(ac);
- }
-}
-
-/* Sets a pointer to the first argument and its length starting at p. Returns
- * the number of bytes to skip to get to the following argument. */
-static const char *nextArgument(const char *start, const char **str, size_t *len) {
- const char *p = start;
- if (p[0] != '$') {
- p = strchr(p,'$');
- if (p == NULL) return NULL;
- }
-
- *len = (int)strtol(p+1,NULL,10);
- p = strchr(p,'\r');
- assert(p);
- *str = p+2;
- return p+2+(*len)+2;
-}
-
-/* Helper function for the redisAsyncCommand* 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;
- int pvariant, hasnext;
- const char *cstr, *astr;
- size_t clen, alen;
- const char *p;
- sds sname;
- 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;
-
- /* Setup callback */
- cb.fn = fn;
- cb.privdata = privdata;
-
- /* Find out which command will be appended. */
- p = nextArgument(cmd,&cstr,&clen);
- assert(p != NULL);
- hasnext = (p[0] == '$');
- pvariant = (tolower(cstr[0]) == 'p') ? 1 : 0;
- cstr += pvariant;
- clen -= pvariant;
-
- if (hasnext && strncasecmp(cstr,"subscribe\r\n",11) == 0) {
- c->flags |= REDIS_SUBSCRIBED;
-
- /* Add every channel/pattern to the list of subscription callbacks. */
- while ((p = nextArgument(p,&astr,&alen)) != NULL) {
- sname = sdsnewlen(astr,alen);
- if (pvariant)
- ret = dictReplace(ac->sub.patterns,sname,&cb);
- else
- ret = dictReplace(ac->sub.channels,sname,&cb);
-
- if (ret == 0) sdsfree(sname);
- }
- } 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;
-
- /* (P)UNSUBSCRIBE does not have its own response: every channel or
- * pattern that is unsubscribed will receive a message. This means we
- * 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;
- __redisPushCallback(&ac->replies,&cb);
- } else {
- if (c->flags & REDIS_SUBSCRIBED)
- /* This will likely result in an error reply, but it needs to be
- * received and passed to the callback. */
- __redisPushCallback(&ac->sub.invalid,&cb);
- else
- __redisPushCallback(&ac->replies,&cb);
- }
-
- __redisAppendCommand(c,cmd,len);
-
- /* Always schedule a write when the write buffer is non-empty */
- _EL_ADD_WRITE(ac);
-
- return REDIS_OK;
-}
-
-int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap) {
- char *cmd;
- int len;
- int status;
- len = redisvFormatCommand(&cmd,format,ap);
-
- /* We don't want to pass -1 or -2 to future functions as a length. */
- if (len < 0)
- return REDIS_ERR;
-
- status = __redisAsyncCommand(ac,fn,privdata,cmd,len);
- free(cmd);
- return status;
-}
-
-int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...) {
- va_list ap;
- int status;
- va_start(ap,format);
- status = redisvAsyncCommand(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) {
- sds cmd;
- int len;
- int status;
- len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen);
- status = __redisAsyncCommand(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);
- return status;
-}
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/async.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/async.h
deleted file mode 100644
index 59cbf46..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/async.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * 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_ASYNC_H
-#define __HIREDIS_ASYNC_H
-#include "hiredis.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct redisAsyncContext; /* need forward declaration of redisAsyncContext */
-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;
- void *privdata;
-} redisCallback;
-
-/* List of callbacks for either regular replies or pub/sub */
-typedef struct redisCallbackList {
- redisCallback *head, *tail;
-} redisCallbackList;
-
-/* Connection callback prototypes */
-typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status);
-typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status);
-
-/* Context for an async connection to Redis */
-typedef struct redisAsyncContext {
- /* Hold the regular context, so it can be realloc'ed. */
- redisContext c;
-
- /* Setup error flags so they can be used directly. */
- int err;
- char *errstr;
-
- /* Not used by hiredis */
- void *data;
-
- /* Event library data and hooks */
- struct {
- void *data;
-
- /* Hooks that are called when the library expects to start
- * reading/writing. These functions should be idempotent. */
- void (*addRead)(void *privdata);
- void (*delRead)(void *privdata);
- void (*addWrite)(void *privdata);
- void (*delWrite)(void *privdata);
- void (*cleanup)(void *privdata);
- } 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;
-
- /* Called when the first write event was received. */
- redisConnectCallback *onConnect;
-
- /* Regular command callbacks */
- redisCallbackList replies;
-
- /* Subscription callbacks */
- struct {
- redisCallbackList invalid;
- struct dict *channels;
- struct dict *patterns;
- } sub;
-} redisAsyncContext;
-
-/* Functions that proxy to hiredis */
-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,
- const char *source_addr);
-redisAsyncContext *redisAsyncConnectUnix(const char *path);
-int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn);
-int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
-void redisAsyncDisconnect(redisAsyncContext *ac);
-void redisAsyncFree(redisAsyncContext *ac);
-
-/* Handle read/write events */
-void redisAsyncHandleRead(redisAsyncContext *ac);
-void redisAsyncHandleWrite(redisAsyncContext *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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/command.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/command.c
deleted file mode 100644
index e32091b..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/command.c
+++ /dev/null
@@ -1,1700 +0,0 @@
-#include <ctype.h>
-#include <errno.h>
-
-#include "command.h"
-#include "hiutil.h"
-#include "hiarray.h"
-
-
-static uint64_t cmd_id = 0; /* command id counter */
-
-
-/*
- * Return true, if the redis command take no key, otherwise
- * return false
- */
-static int
-redis_argz(struct cmd *r)
-{
- switch (r->type) {
- case CMD_REQ_REDIS_PING:
- case CMD_REQ_REDIS_QUIT:
- return 1;
-
- default:
- break;
- }
-
- return 0;
-}
-
-/*
- * Return true, if the redis command accepts no arguments, otherwise
- * return false
- */
-static int
-redis_arg0(struct cmd *r)
-{
- switch (r->type) {
- case CMD_REQ_REDIS_EXISTS:
- case CMD_REQ_REDIS_PERSIST:
- case CMD_REQ_REDIS_PTTL:
- case CMD_REQ_REDIS_SORT:
- case CMD_REQ_REDIS_TTL:
- case CMD_REQ_REDIS_TYPE:
- case CMD_REQ_REDIS_DUMP:
-
- case CMD_REQ_REDIS_DECR:
- case CMD_REQ_REDIS_GET:
- case CMD_REQ_REDIS_INCR:
- case CMD_REQ_REDIS_STRLEN:
-
- case CMD_REQ_REDIS_HGETALL:
- case CMD_REQ_REDIS_HKEYS:
- case CMD_REQ_REDIS_HLEN:
- case CMD_REQ_REDIS_HVALS:
-
- case CMD_REQ_REDIS_LLEN:
- case CMD_REQ_REDIS_LPOP:
- case CMD_REQ_REDIS_RPOP:
-
- case CMD_REQ_REDIS_SCARD:
- case CMD_REQ_REDIS_SMEMBERS:
- case CMD_REQ_REDIS_SPOP:
-
- case CMD_REQ_REDIS_ZCARD:
- case CMD_REQ_REDIS_PFCOUNT:
- case CMD_REQ_REDIS_AUTH:
- return 1;
-
- default:
- break;
- }
-
- return 0;
-}
-
-/*
- * Return true, if the redis command accepts exactly 1 argument, otherwise
- * return false
- */
-static int
-redis_arg1(struct cmd *r)
-{
- switch (r->type) {
- case CMD_REQ_REDIS_EXPIRE:
- case CMD_REQ_REDIS_EXPIREAT:
- case CMD_REQ_REDIS_PEXPIRE:
- case CMD_REQ_REDIS_PEXPIREAT:
-
- case CMD_REQ_REDIS_APPEND:
- case CMD_REQ_REDIS_DECRBY:
- case CMD_REQ_REDIS_GETBIT:
- case CMD_REQ_REDIS_GETSET:
- case CMD_REQ_REDIS_INCRBY:
- case CMD_REQ_REDIS_INCRBYFLOAT:
- case CMD_REQ_REDIS_SETNX:
-
- case CMD_REQ_REDIS_HEXISTS:
- case CMD_REQ_REDIS_HGET:
-
- case CMD_REQ_REDIS_LINDEX:
- case CMD_REQ_REDIS_LPUSHX:
- case CMD_REQ_REDIS_RPOPLPUSH:
- case CMD_REQ_REDIS_RPUSHX:
-
- case CMD_REQ_REDIS_SISMEMBER:
-
- case CMD_REQ_REDIS_ZRANK:
- case CMD_REQ_REDIS_ZREVRANK:
- case CMD_REQ_REDIS_ZSCORE:
- return 1;
-
- default:
- break;
- }
-
- return 0;
-}
-
-/*
- * Return true, if the redis command accepts exactly 2 arguments, otherwise
- * return false
- */
-static int
-redis_arg2(struct cmd *r)
-{
- switch (r->type) {
- case CMD_REQ_REDIS_GETRANGE:
- case CMD_REQ_REDIS_PSETEX:
- case CMD_REQ_REDIS_SETBIT:
- case CMD_REQ_REDIS_SETEX:
- case CMD_REQ_REDIS_SETRANGE:
-
- case CMD_REQ_REDIS_HINCRBY:
- case CMD_REQ_REDIS_HINCRBYFLOAT:
- case CMD_REQ_REDIS_HSET:
- case CMD_REQ_REDIS_HSETNX:
-
- case CMD_REQ_REDIS_LRANGE:
- case CMD_REQ_REDIS_LREM:
- case CMD_REQ_REDIS_LSET:
- case CMD_REQ_REDIS_LTRIM:
-
- case CMD_REQ_REDIS_SMOVE:
-
- case CMD_REQ_REDIS_ZCOUNT:
- case CMD_REQ_REDIS_ZLEXCOUNT:
- case CMD_REQ_REDIS_ZINCRBY:
- case CMD_REQ_REDIS_ZREMRANGEBYLEX:
- case CMD_REQ_REDIS_ZREMRANGEBYRANK:
- case CMD_REQ_REDIS_ZREMRANGEBYSCORE:
-
- case CMD_REQ_REDIS_RESTORE:
- return 1;
-
- default:
- break;
- }
-
- return 0;
-}
-
-/*
- * Return true, if the redis command accepts exactly 3 arguments, otherwise
- * return false
- */
-static int
-redis_arg3(struct cmd *r)
-{
- switch (r->type) {
- case CMD_REQ_REDIS_LINSERT:
- return 1;
-
- default:
- break;
- }
-
- return 0;
-}
-
-/*
- * Return true, if the redis command accepts 0 or more arguments, otherwise
- * return false
- */
-static int
-redis_argn(struct cmd *r)
-{
- switch (r->type) {
- case CMD_REQ_REDIS_BITCOUNT:
-
- case CMD_REQ_REDIS_SET:
- case CMD_REQ_REDIS_HDEL:
- case CMD_REQ_REDIS_HMGET:
- case CMD_REQ_REDIS_HMSET:
- case CMD_REQ_REDIS_HSCAN:
-
- case CMD_REQ_REDIS_LPUSH:
- case CMD_REQ_REDIS_RPUSH:
-
- case CMD_REQ_REDIS_SADD:
- case CMD_REQ_REDIS_SDIFF:
- case CMD_REQ_REDIS_SDIFFSTORE:
- case CMD_REQ_REDIS_SINTER:
- case CMD_REQ_REDIS_SINTERSTORE:
- case CMD_REQ_REDIS_SREM:
- case CMD_REQ_REDIS_SUNION:
- case CMD_REQ_REDIS_SUNIONSTORE:
- case CMD_REQ_REDIS_SRANDMEMBER:
- case CMD_REQ_REDIS_SSCAN:
-
- case CMD_REQ_REDIS_PFADD:
- case CMD_REQ_REDIS_PFMERGE:
-
- case CMD_REQ_REDIS_ZADD:
- case CMD_REQ_REDIS_ZINTERSTORE:
- case CMD_REQ_REDIS_ZRANGE:
- case CMD_REQ_REDIS_ZRANGEBYSCORE:
- case CMD_REQ_REDIS_ZREM:
- case CMD_REQ_REDIS_ZREVRANGE:
- case CMD_REQ_REDIS_ZRANGEBYLEX:
- case CMD_REQ_REDIS_ZREVRANGEBYSCORE:
- case CMD_REQ_REDIS_ZUNIONSTORE:
- case CMD_REQ_REDIS_ZSCAN:
- return 1;
-
- default:
- break;
- }
-
- return 0;
-}
-
-/*
- * Return true, if the redis command is a vector command accepting one or
- * more keys, otherwise return false
- */
-static int
-redis_argx(struct cmd *r)
-{
- switch (r->type) {
- case CMD_REQ_REDIS_MGET:
- case CMD_REQ_REDIS_DEL:
- return 1;
-
- default:
- break;
- }
-
- return 0;
-}
-
-/*
- * Return true, if the redis command is a vector command accepting one or
- * more key-value pairs, otherwise return false
- */
-static int
-redis_argkvx(struct cmd *r)
-{
- switch (r->type) {
- case CMD_REQ_REDIS_MSET:
- return 1;
-
- default:
- break;
- }
-
- return 0;
-}
-
-/*
- * Return true, if the redis command is either EVAL or EVALSHA. These commands
- * have a special format with exactly 2 arguments, followed by one or more keys,
- * followed by zero or more arguments (the documentation online seems to suggest
- * that at least one argument is required, but that shouldn't be the case).
- */
-static int
-redis_argeval(struct cmd *r)
-{
- switch (r->type) {
- case CMD_REQ_REDIS_EVAL:
- case CMD_REQ_REDIS_EVALSHA:
- return 1;
-
- default:
- break;
- }
-
- return 0;
-}
-
-/*
- * Reference: http://redis.io/topics/protocol
- *
- * Redis >= 1.2 uses the unified protocol to send requests to the Redis
- * server. In the unified protocol all the arguments sent to the server
- * are binary safe and every request has the following general form:
- *
- * *<number of arguments> CR LF
- * $<number of bytes of argument 1> CR LF
- * <argument data> CR LF
- * ...
- * $<number of bytes of argument N> CR LF
- * <argument data> CR LF
- *
- * Before the unified request protocol, redis protocol for requests supported
- * the following commands
- * 1). Inline commands: simple commands where arguments are just space
- * separated strings. No binary safeness is possible.
- * 2). Bulk commands: bulk commands are exactly like inline commands, but
- * the last argument is handled in a special way in order to allow for
- * a binary-safe last argument.
- *
- * only supports the Redis unified protocol for requests.
- */
-void
-redis_parse_cmd(struct cmd *r)
-{
- int len;
- char *p, *m, *token = NULL;
- char *cmd_end;
- char ch;
- uint32_t rlen = 0; /* running length in parsing fsa */
- uint32_t rnarg = 0; /* running # arg used by parsing fsa */
- enum {
- SW_START,
- SW_NARG,
- SW_NARG_LF,
- SW_REQ_TYPE_LEN,
- SW_REQ_TYPE_LEN_LF,
- SW_REQ_TYPE,
- SW_REQ_TYPE_LF,
- SW_KEY_LEN,
- SW_KEY_LEN_LF,
- SW_KEY,
- SW_KEY_LF,
- SW_ARG1_LEN,
- SW_ARG1_LEN_LF,
- SW_ARG1,
- SW_ARG1_LF,
- SW_ARG2_LEN,
- SW_ARG2_LEN_LF,
- SW_ARG2,
- SW_ARG2_LF,
- SW_ARG3_LEN,
- SW_ARG3_LEN_LF,
- SW_ARG3,
- SW_ARG3_LF,
- SW_ARGN_LEN,
- SW_ARGN_LEN_LF,
- SW_ARGN,
- SW_ARGN_LF,
- SW_SENTINEL
- } state;
-
- state = SW_START;
- cmd_end = r->cmd + r->clen;
-
- ASSERT(state >= SW_START && state < SW_SENTINEL);
- ASSERT(r->cmd != NULL && r->clen > 0);
-
- for (p = r->cmd; p < cmd_end; p++) {
- ch = *p;
-
- switch (state) {
-
- case SW_START:
- case SW_NARG:
- if (token == NULL) {
- if (ch != '*') {
- goto error;
- }
- token = p;
- /* req_start <- p */
- r->narg_start = p;
- rnarg = 0;
- state = SW_NARG;
- } else if (isdigit(ch)) {
- rnarg = rnarg * 10 + (uint32_t)(ch - '0');
- } else if (ch == CR) {
- if (rnarg == 0) {
- goto error;
- }
- r->narg = rnarg;
- r->narg_end = p;
- token = NULL;
- state = SW_NARG_LF;
- } else {
- goto error;
- }
-
- break;
-
- case SW_NARG_LF:
- switch (ch) {
- case LF:
- state = SW_REQ_TYPE_LEN;
- break;
-
- default:
- goto error;
- }
-
- break;
-
- case SW_REQ_TYPE_LEN:
- if (token == NULL) {
- if (ch != '$') {
- goto error;
- }
- token = p;
- rlen = 0;
- } else if (isdigit(ch)) {
- rlen = rlen * 10 + (uint32_t)(ch - '0');
- } else if (ch == CR) {
- if (rlen == 0 || rnarg == 0) {
- goto error;
- }
- rnarg--;
- token = NULL;
- state = SW_REQ_TYPE_LEN_LF;
- } else {
- goto error;
- }
-
- break;
-
- case SW_REQ_TYPE_LEN_LF:
- switch (ch) {
- case LF:
- state = SW_REQ_TYPE;
- break;
-
- default:
- goto error;
- }
-
- break;
-
- case SW_REQ_TYPE:
- if (token == NULL) {
- token = p;
- }
-
- m = token + rlen;
- if (m >= cmd_end) {
- //m = cmd_end - 1;
- //p = m;
- //break;
- goto error;
- }
-
- if (*m != CR) {
- goto error;
- }
-
- p = m; /* move forward by rlen bytes */
- rlen = 0;
- m = token;
- token = NULL;
- r->type = CMD_UNKNOWN;
-
- switch (p - m) {
-
- case 3:
- if (str3icmp(m, 'g', 'e', 't')) {
- r->type = CMD_REQ_REDIS_GET;
- break;
- }
-
- if (str3icmp(m, 's', 'e', 't')) {
- r->type = CMD_REQ_REDIS_SET;
- break;
- }
-
- if (str3icmp(m, 't', 't', 'l')) {
- r->type = CMD_REQ_REDIS_TTL;
- break;
- }
-
- if (str3icmp(m, 'd', 'e', 'l')) {
- r->type = CMD_REQ_REDIS_DEL;
- break;
- }
-
- break;
-
- case 4:
- if (str4icmp(m, 'p', 't', 't', 'l')) {
- r->type = CMD_REQ_REDIS_PTTL;
- break;
- }
-
- if (str4icmp(m, 'd', 'e', 'c', 'r')) {
- r->type = CMD_REQ_REDIS_DECR;
- break;
- }
-
- if (str4icmp(m, 'd', 'u', 'm', 'p')) {
- r->type = CMD_REQ_REDIS_DUMP;
- break;
- }
-
- if (str4icmp(m, 'h', 'd', 'e', 'l')) {
- r->type = CMD_REQ_REDIS_HDEL;
- break;
- }
-
- if (str4icmp(m, 'h', 'g', 'e', 't')) {
- r->type = CMD_REQ_REDIS_HGET;
- break;
- }
-
- if (str4icmp(m, 'h', 'l', 'e', 'n')) {
- r->type = CMD_REQ_REDIS_HLEN;
- break;
- }
-
- if (str4icmp(m, 'h', 's', 'e', 't')) {
- r->type = CMD_REQ_REDIS_HSET;
- break;
- }
-
- if (str4icmp(m, 'i', 'n', 'c', 'r')) {
- r->type = CMD_REQ_REDIS_INCR;
- break;
- }
-
- if (str4icmp(m, 'l', 'l', 'e', 'n')) {
- r->type = CMD_REQ_REDIS_LLEN;
- break;
- }
-
- if (str4icmp(m, 'l', 'p', 'o', 'p')) {
- r->type = CMD_REQ_REDIS_LPOP;
- break;
- }
-
- if (str4icmp(m, 'l', 'r', 'e', 'm')) {
- r->type = CMD_REQ_REDIS_LREM;
- break;
- }
-
- if (str4icmp(m, 'l', 's', 'e', 't')) {
- r->type = CMD_REQ_REDIS_LSET;
- break;
- }
-
- if (str4icmp(m, 'r', 'p', 'o', 'p')) {
- r->type = CMD_REQ_REDIS_RPOP;
- break;
- }
-
- if (str4icmp(m, 's', 'a', 'd', 'd')) {
- r->type = CMD_REQ_REDIS_SADD;
- break;
- }
-
- if (str4icmp(m, 's', 'p', 'o', 'p')) {
- r->type = CMD_REQ_REDIS_SPOP;
- break;
- }
-
- if (str4icmp(m, 's', 'r', 'e', 'm')) {
- r->type = CMD_REQ_REDIS_SREM;
- break;
- }
-
- if (str4icmp(m, 't', 'y', 'p', 'e')) {
- r->type = CMD_REQ_REDIS_TYPE;
- break;
- }
-
- if (str4icmp(m, 'm', 'g', 'e', 't')) {
- r->type = CMD_REQ_REDIS_MGET;
- break;
- }
- if (str4icmp(m, 'm', 's', 'e', 't')) {
- r->type = CMD_REQ_REDIS_MSET;
- break;
- }
-
- if (str4icmp(m, 'z', 'a', 'd', 'd')) {
- r->type = CMD_REQ_REDIS_ZADD;
- break;
- }
-
- if (str4icmp(m, 'z', 'r', 'e', 'm')) {
- r->type = CMD_REQ_REDIS_ZREM;
- break;
- }
-
- if (str4icmp(m, 'e', 'v', 'a', 'l')) {
- r->type = CMD_REQ_REDIS_EVAL;
- break;
- }
-
- if (str4icmp(m, 's', 'o', 'r', 't')) {
- r->type = CMD_REQ_REDIS_SORT;
- break;
- }
-
- if (str4icmp(m, 'p', 'i', 'n', 'g')) {
- r->type = CMD_REQ_REDIS_PING;
- r->noforward = 1;
- break;
- }
-
- if (str4icmp(m, 'q', 'u', 'i', 't')) {
- r->type = CMD_REQ_REDIS_QUIT;
- r->quit = 1;
- break;
- }
-
- if (str4icmp(m, 'a', 'u', 't', 'h')) {
- r->type = CMD_REQ_REDIS_AUTH;
- r->noforward = 1;
- break;
- }
-
- break;
-
- case 5:
- if (str5icmp(m, 'h', 'k', 'e', 'y', 's')) {
- r->type = CMD_REQ_REDIS_HKEYS;
- break;
- }
-
- if (str5icmp(m, 'h', 'm', 'g', 'e', 't')) {
- r->type = CMD_REQ_REDIS_HMGET;
- break;
- }
-
- if (str5icmp(m, 'h', 'm', 's', 'e', 't')) {
- r->type = CMD_REQ_REDIS_HMSET;
- break;
- }
-
- if (str5icmp(m, 'h', 'v', 'a', 'l', 's')) {
- r->type = CMD_REQ_REDIS_HVALS;
- break;
- }
-
- if (str5icmp(m, 'h', 's', 'c', 'a', 'n')) {
- r->type = CMD_REQ_REDIS_HSCAN;
- break;
- }
-
- if (str5icmp(m, 'l', 'p', 'u', 's', 'h')) {
- r->type = CMD_REQ_REDIS_LPUSH;
- break;
- }
-
- if (str5icmp(m, 'l', 't', 'r', 'i', 'm')) {
- r->type = CMD_REQ_REDIS_LTRIM;
- break;
- }
-
- if (str5icmp(m, 'r', 'p', 'u', 's', 'h')) {
- r->type = CMD_REQ_REDIS_RPUSH;
- break;
- }
-
- if (str5icmp(m, 's', 'c', 'a', 'r', 'd')) {
- r->type = CMD_REQ_REDIS_SCARD;
- break;
- }
-
- if (str5icmp(m, 's', 'd', 'i', 'f', 'f')) {
- r->type = CMD_REQ_REDIS_SDIFF;
- break;
- }
-
- if (str5icmp(m, 's', 'e', 't', 'e', 'x')) {
- r->type = CMD_REQ_REDIS_SETEX;
- break;
- }
-
- if (str5icmp(m, 's', 'e', 't', 'n', 'x')) {
- r->type = CMD_REQ_REDIS_SETNX;
- break;
- }
-
- if (str5icmp(m, 's', 'm', 'o', 'v', 'e')) {
- r->type = CMD_REQ_REDIS_SMOVE;
- break;
- }
-
- if (str5icmp(m, 's', 's', 'c', 'a', 'n')) {
- r->type = CMD_REQ_REDIS_SSCAN;
- break;
- }
-
- if (str5icmp(m, 'z', 'c', 'a', 'r', 'd')) {
- r->type = CMD_REQ_REDIS_ZCARD;
- break;
- }
-
- if (str5icmp(m, 'z', 'r', 'a', 'n', 'k')) {
- r->type = CMD_REQ_REDIS_ZRANK;
- break;
- }
-
- if (str5icmp(m, 'z', 's', 'c', 'a', 'n')) {
- r->type = CMD_REQ_REDIS_ZSCAN;
- break;
- }
-
- if (str5icmp(m, 'p', 'f', 'a', 'd', 'd')) {
- r->type = CMD_REQ_REDIS_PFADD;
- break;
- }
-
- break;
-
- case 6:
- if (str6icmp(m, 'a', 'p', 'p', 'e', 'n', 'd')) {
- r->type = CMD_REQ_REDIS_APPEND;
- break;
- }
-
- if (str6icmp(m, 'd', 'e', 'c', 'r', 'b', 'y')) {
- r->type = CMD_REQ_REDIS_DECRBY;
- break;
- }
-
- if (str6icmp(m, 'e', 'x', 'i', 's', 't', 's')) {
- r->type = CMD_REQ_REDIS_EXISTS;
- break;
- }
-
- if (str6icmp(m, 'e', 'x', 'p', 'i', 'r', 'e')) {
- r->type = CMD_REQ_REDIS_EXPIRE;
- break;
- }
-
- if (str6icmp(m, 'g', 'e', 't', 'b', 'i', 't')) {
- r->type = CMD_REQ_REDIS_GETBIT;
- break;
- }
-
- if (str6icmp(m, 'g', 'e', 't', 's', 'e', 't')) {
- r->type = CMD_REQ_REDIS_GETSET;
- break;
- }
-
- if (str6icmp(m, 'p', 's', 'e', 't', 'e', 'x')) {
- r->type = CMD_REQ_REDIS_PSETEX;
- break;
- }
-
- if (str6icmp(m, 'h', 's', 'e', 't', 'n', 'x')) {
- r->type = CMD_REQ_REDIS_HSETNX;
- break;
- }
-
- if (str6icmp(m, 'i', 'n', 'c', 'r', 'b', 'y')) {
- r->type = CMD_REQ_REDIS_INCRBY;
- break;
- }
-
- if (str6icmp(m, 'l', 'i', 'n', 'd', 'e', 'x')) {
- r->type = CMD_REQ_REDIS_LINDEX;
- break;
- }
-
- if (str6icmp(m, 'l', 'p', 'u', 's', 'h', 'x')) {
- r->type = CMD_REQ_REDIS_LPUSHX;
- break;
- }
-
- if (str6icmp(m, 'l', 'r', 'a', 'n', 'g', 'e')) {
- r->type = CMD_REQ_REDIS_LRANGE;
- break;
- }
-
- if (str6icmp(m, 'r', 'p', 'u', 's', 'h', 'x')) {
- r->type = CMD_REQ_REDIS_RPUSHX;
- break;
- }
-
- if (str6icmp(m, 's', 'e', 't', 'b', 'i', 't')) {
- r->type = CMD_REQ_REDIS_SETBIT;
- break;
- }
-
- if (str6icmp(m, 's', 'i', 'n', 't', 'e', 'r')) {
- r->type = CMD_REQ_REDIS_SINTER;
- break;
- }
-
- if (str6icmp(m, 's', 't', 'r', 'l', 'e', 'n')) {
- r->type = CMD_REQ_REDIS_STRLEN;
- break;
- }
-
- if (str6icmp(m, 's', 'u', 'n', 'i', 'o', 'n')) {
- r->type = CMD_REQ_REDIS_SUNION;
- break;
- }
-
- if (str6icmp(m, 'z', 'c', 'o', 'u', 'n', 't')) {
- r->type = CMD_REQ_REDIS_ZCOUNT;
- break;
- }
-
- if (str6icmp(m, 'z', 'r', 'a', 'n', 'g', 'e')) {
- r->type = CMD_REQ_REDIS_ZRANGE;
- break;
- }
-
- if (str6icmp(m, 'z', 's', 'c', 'o', 'r', 'e')) {
- r->type = CMD_REQ_REDIS_ZSCORE;
- break;
- }
-
- break;
-
- case 7:
- if (str7icmp(m, 'p', 'e', 'r', 's', 'i', 's', 't')) {
- r->type = CMD_REQ_REDIS_PERSIST;
- break;
- }
-
- if (str7icmp(m, 'p', 'e', 'x', 'p', 'i', 'r', 'e')) {
- r->type = CMD_REQ_REDIS_PEXPIRE;
- break;
- }
-
- if (str7icmp(m, 'h', 'e', 'x', 'i', 's', 't', 's')) {
- r->type = CMD_REQ_REDIS_HEXISTS;
- break;
- }
-
- if (str7icmp(m, 'h', 'g', 'e', 't', 'a', 'l', 'l')) {
- r->type = CMD_REQ_REDIS_HGETALL;
- break;
- }
-
- if (str7icmp(m, 'h', 'i', 'n', 'c', 'r', 'b', 'y')) {
- r->type = CMD_REQ_REDIS_HINCRBY;
- break;
- }
-
- if (str7icmp(m, 'l', 'i', 'n', 's', 'e', 'r', 't')) {
- r->type = CMD_REQ_REDIS_LINSERT;
- break;
- }
-
- if (str7icmp(m, 'z', 'i', 'n', 'c', 'r', 'b', 'y')) {
- r->type = CMD_REQ_REDIS_ZINCRBY;
- break;
- }
-
- if (str7icmp(m, 'e', 'v', 'a', 'l', 's', 'h', 'a')) {
- r->type = CMD_REQ_REDIS_EVALSHA;
- break;
- }
-
- if (str7icmp(m, 'r', 'e', 's', 't', 'o', 'r', 'e')) {
- r->type = CMD_REQ_REDIS_RESTORE;
- break;
- }
-
- if (str7icmp(m, 'p', 'f', 'c', 'o', 'u', 'n', 't')) {
- r->type = CMD_REQ_REDIS_PFCOUNT;
- break;
- }
-
- if (str7icmp(m, 'p', 'f', 'm', 'e', 'r', 'g', 'e')) {
- r->type = CMD_REQ_REDIS_PFMERGE;
- break;
- }
-
- break;
-
- case 8:
- if (str8icmp(m, 'e', 'x', 'p', 'i', 'r', 'e', 'a', 't')) {
- r->type = CMD_REQ_REDIS_EXPIREAT;
- break;
- }
-
- if (str8icmp(m, 'b', 'i', 't', 'c', 'o', 'u', 'n', 't')) {
- r->type = CMD_REQ_REDIS_BITCOUNT;
- break;
- }
-
- if (str8icmp(m, 'g', 'e', 't', 'r', 'a', 'n', 'g', 'e')) {
- r->type = CMD_REQ_REDIS_GETRANGE;
- break;
- }
-
- if (str8icmp(m, 's', 'e', 't', 'r', 'a', 'n', 'g', 'e')) {
- r->type = CMD_REQ_REDIS_SETRANGE;
- break;
- }
-
- if (str8icmp(m, 's', 'm', 'e', 'm', 'b', 'e', 'r', 's')) {
- r->type = CMD_REQ_REDIS_SMEMBERS;
- break;
- }
-
- if (str8icmp(m, 'z', 'r', 'e', 'v', 'r', 'a', 'n', 'k')) {
- r->type = CMD_REQ_REDIS_ZREVRANK;
- break;
- }
-
- break;
-
- case 9:
- if (str9icmp(m, 'p', 'e', 'x', 'p', 'i', 'r', 'e', 'a', 't')) {
- r->type = CMD_REQ_REDIS_PEXPIREAT;
- break;
- }
-
- if (str9icmp(m, 'r', 'p', 'o', 'p', 'l', 'p', 'u', 's', 'h')) {
- r->type = CMD_REQ_REDIS_RPOPLPUSH;
- break;
- }
-
- if (str9icmp(m, 's', 'i', 's', 'm', 'e', 'm', 'b', 'e', 'r')) {
- r->type = CMD_REQ_REDIS_SISMEMBER;
- break;
- }
-
- if (str9icmp(m, 'z', 'r', 'e', 'v', 'r', 'a', 'n', 'g', 'e')) {
- r->type = CMD_REQ_REDIS_ZREVRANGE;
- break;
- }
-
- if (str9icmp(m, 'z', 'l', 'e', 'x', 'c', 'o', 'u', 'n', 't')) {
- r->type = CMD_REQ_REDIS_ZLEXCOUNT;
- break;
- }
-
- break;
-
- case 10:
- if (str10icmp(m, 's', 'd', 'i', 'f', 'f', 's', 't', 'o', 'r', 'e')) {
- r->type = CMD_REQ_REDIS_SDIFFSTORE;
- break;
- }
-
- case 11:
- if (str11icmp(m, 'i', 'n', 'c', 'r', 'b', 'y', 'f', 'l', 'o', 'a', 't')) {
- r->type = CMD_REQ_REDIS_INCRBYFLOAT;
- break;
- }
-
- if (str11icmp(m, 's', 'i', 'n', 't', 'e', 'r', 's', 't', 'o', 'r', 'e')) {
- r->type = CMD_REQ_REDIS_SINTERSTORE;
- break;
- }
-
- if (str11icmp(m, 's', 'r', 'a', 'n', 'd', 'm', 'e', 'm', 'b', 'e', 'r')) {
- r->type = CMD_REQ_REDIS_SRANDMEMBER;
- break;
- }
-
- if (str11icmp(m, 's', 'u', 'n', 'i', 'o', 'n', 's', 't', 'o', 'r', 'e')) {
- r->type = CMD_REQ_REDIS_SUNIONSTORE;
- break;
- }
-
- if (str11icmp(m, 'z', 'i', 'n', 't', 'e', 'r', 's', 't', 'o', 'r', 'e')) {
- r->type = CMD_REQ_REDIS_ZINTERSTORE;
- break;
- }
-
- if (str11icmp(m, 'z', 'u', 'n', 'i', 'o', 'n', 's', 't', 'o', 'r', 'e')) {
- r->type = CMD_REQ_REDIS_ZUNIONSTORE;
- break;
- }
-
- if (str11icmp(m, 'z', 'r', 'a', 'n', 'g', 'e', 'b', 'y', 'l', 'e', 'x')) {
- r->type = CMD_REQ_REDIS_ZRANGEBYLEX;
- break;
- }
-
- break;
-
- case 12:
- if (str12icmp(m, 'h', 'i', 'n', 'c', 'r', 'b', 'y', 'f', 'l', 'o', 'a', 't')) {
- r->type = CMD_REQ_REDIS_HINCRBYFLOAT;
- break;
- }
-
-
- break;
-
- case 13:
- if (str13icmp(m, 'z', 'r', 'a', 'n', 'g', 'e', 'b', 'y', 's', 'c', 'o', 'r', 'e')) {
- r->type = CMD_REQ_REDIS_ZRANGEBYSCORE;
- break;
- }
-
- break;
-
- case 14:
- if (str14icmp(m, 'z', 'r', 'e', 'm', 'r', 'a', 'n', 'g', 'e', 'b', 'y', 'l', 'e', 'x')) {
- r->type = CMD_REQ_REDIS_ZREMRANGEBYLEX;
- break;
- }
-
- break;
-
- case 15:
- if (str15icmp(m, 'z', 'r', 'e', 'm', 'r', 'a', 'n', 'g', 'e', 'b', 'y', 'r', 'a', 'n', 'k')) {
- r->type = CMD_REQ_REDIS_ZREMRANGEBYRANK;
- break;
- }
-
- break;
-
- case 16:
- if (str16icmp(m, 'z', 'r', 'e', 'm', 'r', 'a', 'n', 'g', 'e', 'b', 'y', 's', 'c', 'o', 'r', 'e')) {
- r->type = CMD_REQ_REDIS_ZREMRANGEBYSCORE;
- break;
- }
-
- if (str16icmp(m, 'z', 'r', 'e', 'v', 'r', 'a', 'n', 'g', 'e', 'b', 'y', 's', 'c', 'o', 'r', 'e')) {
- r->type = CMD_REQ_REDIS_ZREVRANGEBYSCORE;
- break;
- }
-
- break;
-
- default:
- break;
- }
-
- if (r->type == CMD_UNKNOWN) {
- goto error;
- }
-
- state = SW_REQ_TYPE_LF;
- break;
-
- case SW_REQ_TYPE_LF:
- switch (ch) {
- case LF:
- if (redis_argz(r)) {
- goto done;
- } else if (redis_argeval(r)) {
- state = SW_ARG1_LEN;
- } else {
- state = SW_KEY_LEN;
- }
- break;
-
- default:
- goto error;
- }
-
- break;
-
- case SW_KEY_LEN:
- if (token == NULL) {
- if (ch != '$') {
- goto error;
- }
- token = p;
- rlen = 0;
- } else if (isdigit(ch)) {
- rlen = rlen * 10 + (uint32_t)(ch - '0');
- } else if (ch == CR) {
-
- if (rnarg == 0) {
- goto error;
- }
- rnarg--;
- token = NULL;
- state = SW_KEY_LEN_LF;
- } else {
- goto error;
- }
-
- break;
-
- case SW_KEY_LEN_LF:
- switch (ch) {
- case LF:
- state = SW_KEY;
- break;
-
- default:
- goto error;
- }
-
- break;
-
- case SW_KEY:
- if (token == NULL) {
- token = p;
- }
-
- m = token + rlen;
- if (m >= cmd_end) {
- //m = b->last - 1;
- //p = m;
- //break;
- goto error;
- }
-
- if (*m != CR) {
- goto error;
- } else { /* got a key */
- struct keypos *kpos;
-
- p = m; /* move forward by rlen bytes */
- rlen = 0;
- m = token;
- token = NULL;
-
- kpos = hiarray_push(r->keys);
- if (kpos == NULL) {
- goto enomem;
- }
- kpos->start = m;
- kpos->end = p;
- //kpos->v_len = 0;
-
- state = SW_KEY_LF;
- }
-
- break;
-
- case SW_KEY_LF:
- switch (ch) {
- case LF:
- if (redis_arg0(r)) {
- if (rnarg != 0) {
- goto error;
- }
- goto done;
- } else if (redis_arg1(r)) {
- if (rnarg != 1) {
- goto error;
- }
- state = SW_ARG1_LEN;
- } else if (redis_arg2(r)) {
- if (rnarg != 2) {
- goto error;
- }
- state = SW_ARG1_LEN;
- } else if (redis_arg3(r)) {
- if (rnarg != 3) {
- goto error;
- }
- state = SW_ARG1_LEN;
- } else if (redis_argn(r)) {
- if (rnarg == 0) {
- goto done;
- }
- state = SW_ARG1_LEN;
- } else if (redis_argx(r)) {
- if (rnarg == 0) {
- goto done;
- }
- state = SW_KEY_LEN;
- } else if (redis_argkvx(r)) {
- if (rnarg == 0) {
- goto done;
- }
- if (r->narg % 2 == 0) {
- goto error;
- }
- state = SW_ARG1_LEN;
- } else if (redis_argeval(r)) {
- if (rnarg == 0) {
- goto done;
- }
- state = SW_ARGN_LEN;
- } else {
- goto error;
- }
-
- break;
-
- default:
- goto error;
- }
-
- break;
-
- case SW_ARG1_LEN:
- if (token == NULL) {
- if (ch != '$') {
- goto error;
- }
- rlen = 0;
- token = p;
- } else if (isdigit(ch)) {
- rlen = rlen * 10 + (uint32_t)(ch - '0');
- } else if (ch == CR) {
- if ((p - token) <= 1 || rnarg == 0) {
- goto error;
- }
- rnarg--;
- token = NULL;
-
- /*
- //for mset value length
- if(redis_argkvx(r))
- {
- struct keypos *kpos;
- uint32_t array_len = array_n(r->keys);
- if(array_len == 0)
- {
- goto error;
- }
-
- kpos = array_n(r->keys, array_len-1);
- if (kpos == NULL || kpos->v_len != 0) {
- goto error;
- }
-
- kpos->v_len = rlen;
- }
- */
- state = SW_ARG1_LEN_LF;
- } else {
- goto error;
- }
-
- break;
-
- case SW_ARG1_LEN_LF:
- switch (ch) {
- case LF:
- state = SW_ARG1;
- break;
-
- default:
- goto error;
- }
-
- break;
-
- case SW_ARG1:
- m = p + rlen;
- if (m >= cmd_end) {
- //rlen -= (uint32_t)(b->last - p);
- //m = b->last - 1;
- //p = m;
- //break;
- goto error;
- }
-
- if (*m != CR) {
- goto error;
- }
-
- p = m; /* move forward by rlen bytes */
- rlen = 0;
-
- state = SW_ARG1_LF;
-
- break;
-
- case SW_ARG1_LF:
- switch (ch) {
- case LF:
- if (redis_arg1(r)) {
- if (rnarg != 0) {
- goto error;
- }
- goto done;
- } else if (redis_arg2(r)) {
- if (rnarg != 1) {
- goto error;
- }
- state = SW_ARG2_LEN;
- } else if (redis_arg3(r)) {
- if (rnarg != 2) {
- goto error;
- }
- state = SW_ARG2_LEN;
- } else if (redis_argn(r)) {
- if (rnarg == 0) {
- goto done;
- }
- state = SW_ARGN_LEN;
- } else if (redis_argeval(r)) {
- if (rnarg < 2) {
- goto error;
- }
- state = SW_ARG2_LEN;
- } else if (redis_argkvx(r)) {
- if (rnarg == 0) {
- goto done;
- }
- state = SW_KEY_LEN;
- } else {
- goto error;
- }
-
- break;
-
- default:
- goto error;
- }
-
- break;
-
- case SW_ARG2_LEN:
- if (token == NULL) {
- if (ch != '$') {
- goto error;
- }
- rlen = 0;
- token = p;
- } else if (isdigit(ch)) {
- rlen = rlen * 10 + (uint32_t)(ch - '0');
- } else if (ch == CR) {
- if ((p - token) <= 1 || rnarg == 0) {
- goto error;
- }
- rnarg--;
- token = NULL;
- state = SW_ARG2_LEN_LF;
- } else {
- goto error;
- }
-
- break;
-
- case SW_ARG2_LEN_LF:
- switch (ch) {
- case LF:
- state = SW_ARG2;
- break;
-
- default:
- goto error;
- }
-
- break;
-
- case SW_ARG2:
- if (token == NULL && redis_argeval(r)) {
- /*
- * For EVAL/EVALSHA, ARG2 represents the # key/arg pairs which must
- * be tokenized and stored in contiguous memory.
- */
- token = p;
- }
-
- m = p + rlen;
- if (m >= cmd_end) {
- //rlen -= (uint32_t)(b->last - p);
- //m = b->last - 1;
- //p = m;
- //break;
- goto error;
- }
-
- if (*m != CR) {
- goto error;
- }
-
- p = m; /* move forward by rlen bytes */
- rlen = 0;
-
- if (redis_argeval(r)) {
- uint32_t nkey;
- char *chp;
-
- /*
- * For EVAL/EVALSHA, we need to find the integer value of this
- * argument. It tells us the number of keys in the script, and
- * we need to error out if number of keys is 0. At this point,
- * both p and m point to the end of the argument and r->token
- * points to the start.
- */
- if (p - token < 1) {
- goto error;
- }
-
- for (nkey = 0, chp = token; chp < p; chp++) {
- if (isdigit(*chp)) {
- nkey = nkey * 10 + (uint32_t)(*chp - '0');
- } else {
- goto error;
- }
- }
- if (nkey == 0) {
- goto error;
- }
-
- token = NULL;
- }
-
- state = SW_ARG2_LF;
-
- break;
-
- case SW_ARG2_LF:
- switch (ch) {
- case LF:
- if (redis_arg2(r)) {
- if (rnarg != 0) {
- goto error;
- }
- goto done;
- } else if (redis_arg3(r)) {
- if (rnarg != 1) {
- goto error;
- }
- state = SW_ARG3_LEN;
- } else if (redis_argn(r)) {
- if (rnarg == 0) {
- goto done;
- }
- state = SW_ARGN_LEN;
- } else if (redis_argeval(r)) {
- if (rnarg < 1) {
- goto error;
- }
- state = SW_KEY_LEN;
- } else {
- goto error;
- }
-
- break;
-
- default:
- goto error;
- }
-
- break;
-
- case SW_ARG3_LEN:
- if (token == NULL) {
- if (ch != '$') {
- goto error;
- }
- rlen = 0;
- token = p;
- } else if (isdigit(ch)) {
- rlen = rlen * 10 + (uint32_t)(ch - '0');
- } else if (ch == CR) {
- if ((p - token) <= 1 || rnarg == 0) {
- goto error;
- }
- rnarg--;
- token = NULL;
- state = SW_ARG3_LEN_LF;
- } else {
- goto error;
- }
-
- break;
-
- case SW_ARG3_LEN_LF:
- switch (ch) {
- case LF:
- state = SW_ARG3;
- break;
-
- default:
- goto error;
- }
-
- break;
-
- case SW_ARG3:
- m = p + rlen;
- if (m >= cmd_end) {
- //rlen -= (uint32_t)(b->last - p);
- //m = b->last - 1;
- //p = m;
- //break;
- goto error;
- }
-
- if (*m != CR) {
- goto error;
- }
-
- p = m; /* move forward by rlen bytes */
- rlen = 0;
- state = SW_ARG3_LF;
-
- break;
-
- case SW_ARG3_LF:
- switch (ch) {
- case LF:
- if (redis_arg3(r)) {
- if (rnarg != 0) {
- goto error;
- }
- goto done;
- } else if (redis_argn(r)) {
- if (rnarg == 0) {
- goto done;
- }
- state = SW_ARGN_LEN;
- } else {
- goto error;
- }
-
- break;
-
- default:
- goto error;
- }
-
- break;
-
- case SW_ARGN_LEN:
- if (token == NULL) {
- if (ch != '$') {
- goto error;
- }
- rlen = 0;
- token = p;
- } else if (isdigit(ch)) {
- rlen = rlen * 10 + (uint32_t)(ch - '0');
- } else if (ch == CR) {
- if ((p - token) <= 1 || rnarg == 0) {
- goto error;
- }
- rnarg--;
- token = NULL;
- state = SW_ARGN_LEN_LF;
- } else {
- goto error;
- }
-
- break;
-
- case SW_ARGN_LEN_LF:
- switch (ch) {
- case LF:
- state = SW_ARGN;
- break;
-
- default:
- goto error;
- }
-
- break;
-
- case SW_ARGN:
- m = p + rlen;
- if (m >= cmd_end) {
- //rlen -= (uint32_t)(b->last - p);
- //m = b->last - 1;
- //p = m;
- //break;
- goto error;
- }
-
- if (*m != CR) {
- goto error;
- }
-
- p = m; /* move forward by rlen bytes */
- rlen = 0;
- state = SW_ARGN_LF;
-
- break;
-
- case SW_ARGN_LF:
- switch (ch) {
- case LF:
- if (redis_argn(r) || redis_argeval(r)) {
- if (rnarg == 0) {
- goto done;
- }
- state = SW_ARGN_LEN;
- } else {
- goto error;
- }
-
- break;
-
- default:
- goto error;
- }
-
- break;
-
- case SW_SENTINEL:
- default:
- NOT_REACHED();
- break;
- }
- }
-
- ASSERT(p == cmd_end);
-
- return;
-
-done:
-
- ASSERT(r->type > CMD_UNKNOWN && r->type < CMD_SENTINEL);
-
- r->result = CMD_PARSE_OK;
-
- return;
-
-enomem:
-
- r->result = CMD_PARSE_ENOMEM;
-
- return;
-
-error:
-
- r->result = CMD_PARSE_ERROR;
- errno = EINVAL;
- if(r->errstr == NULL){
- r->errstr = hi_alloc(100*sizeof(*r->errstr));
- }
-
- len = _scnprintf(r->errstr, 100, "Parse command error. Cmd type: %d, state: %d, break position: %d.",
- r->type, state, (int)(p - r->cmd));
- r->errstr[len] = '\0';
-}
-
-struct cmd *command_get()
-{
- struct cmd *command;
- command = hi_alloc(sizeof(struct cmd));
- if(command == NULL)
- {
- return NULL;
- }
-
- command->id = ++cmd_id;
- command->result = CMD_PARSE_OK;
- command->errstr = NULL;
- command->type = CMD_UNKNOWN;
- command->cmd = NULL;
- command->clen = 0;
- command->keys = NULL;
- command->narg_start = NULL;
- command->narg_end = NULL;
- command->narg = 0;
- command->quit = 0;
- command->noforward = 0;
- command->slot_num = -1;
- command->frag_seq = NULL;
- command->reply = NULL;
- command->sub_commands = NULL;
-
- command->keys = hiarray_create(1, sizeof(struct keypos));
- if (command->keys == NULL)
- {
- hi_free(command);
- return NULL;
- }
-
- return command;
-}
-
-void command_destroy(struct cmd *command)
-{
- if(command == NULL)
- {
- return;
- }
-
- if(command->cmd != NULL)
- {
- free(command->cmd);
- }
-
- if(command->errstr != NULL){
- hi_free(command->errstr);
- }
-
- if(command->keys != NULL)
- {
- command->keys->nelem = 0;
- hiarray_destroy(command->keys);
- }
-
- if(command->frag_seq != NULL)
- {
- hi_free(command->frag_seq);
- command->frag_seq = NULL;
- }
-
- if(command->reply != NULL)
- {
- freeReplyObject(command->reply);
- }
-
- if(command->sub_commands != NULL)
- {
- listRelease(command->sub_commands);
- }
-
- hi_free(command);
-}
-
-
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/command.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/command.h
deleted file mode 100644
index b7c388a..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/command.h
+++ /dev/null
@@ -1,179 +0,0 @@
-#ifndef __COMMAND_H_
-#define __COMMAND_H_
-
-#include <stdint.h>
-
-#include "hiredis.h"
-#include "adlist.h"
-
-typedef enum cmd_parse_result {
- CMD_PARSE_OK, /* parsing ok */
- CMD_PARSE_ENOMEM, /* out of memory */
- CMD_PARSE_ERROR, /* parsing error */
- CMD_PARSE_REPAIR, /* more to parse -> repair parsed & unparsed data */
- CMD_PARSE_AGAIN, /* incomplete -> parse again */
-} cmd_parse_result_t;
-
-#define CMD_TYPE_CODEC(ACTION) \
- ACTION( UNKNOWN ) \
- ACTION( REQ_REDIS_DEL ) /* redis commands - keys */ \
- ACTION( REQ_REDIS_EXISTS ) \
- ACTION( REQ_REDIS_EXPIRE ) \
- ACTION( REQ_REDIS_EXPIREAT ) \
- ACTION( REQ_REDIS_PEXPIRE ) \
- ACTION( REQ_REDIS_PEXPIREAT ) \
- ACTION( REQ_REDIS_PERSIST ) \
- ACTION( REQ_REDIS_PTTL ) \
- ACTION( REQ_REDIS_SORT ) \
- ACTION( REQ_REDIS_TTL ) \
- ACTION( REQ_REDIS_TYPE ) \
- ACTION( REQ_REDIS_APPEND ) /* redis requests - string */ \
- ACTION( REQ_REDIS_BITCOUNT ) \
- ACTION( REQ_REDIS_DECR ) \
- ACTION( REQ_REDIS_DECRBY ) \
- ACTION( REQ_REDIS_DUMP ) \
- ACTION( REQ_REDIS_GET ) \
- ACTION( REQ_REDIS_GETBIT ) \
- ACTION( REQ_REDIS_GETRANGE ) \
- ACTION( REQ_REDIS_GETSET ) \
- ACTION( REQ_REDIS_INCR ) \
- ACTION( REQ_REDIS_INCRBY ) \
- ACTION( REQ_REDIS_INCRBYFLOAT ) \
- ACTION( REQ_REDIS_MGET ) \
- ACTION( REQ_REDIS_MSET ) \
- ACTION( REQ_REDIS_PSETEX ) \
- ACTION( REQ_REDIS_RESTORE ) \
- ACTION( REQ_REDIS_SET ) \
- ACTION( REQ_REDIS_SETBIT ) \
- ACTION( REQ_REDIS_SETEX ) \
- ACTION( REQ_REDIS_SETNX ) \
- ACTION( REQ_REDIS_SETRANGE ) \
- ACTION( REQ_REDIS_STRLEN ) \
- ACTION( REQ_REDIS_HDEL ) /* redis requests - hashes */ \
- ACTION( REQ_REDIS_HEXISTS ) \
- ACTION( REQ_REDIS_HGET ) \
- ACTION( REQ_REDIS_HGETALL ) \
- ACTION( REQ_REDIS_HINCRBY ) \
- ACTION( REQ_REDIS_HINCRBYFLOAT ) \
- ACTION( REQ_REDIS_HKEYS ) \
- ACTION( REQ_REDIS_HLEN ) \
- ACTION( REQ_REDIS_HMGET ) \
- ACTION( REQ_REDIS_HMSET ) \
- ACTION( REQ_REDIS_HSET ) \
- ACTION( REQ_REDIS_HSETNX ) \
- ACTION( REQ_REDIS_HSCAN) \
- ACTION( REQ_REDIS_HVALS ) \
- ACTION( REQ_REDIS_LINDEX ) /* redis requests - lists */ \
- ACTION( REQ_REDIS_LINSERT ) \
- ACTION( REQ_REDIS_LLEN ) \
- ACTION( REQ_REDIS_LPOP ) \
- ACTION( REQ_REDIS_LPUSH ) \
- ACTION( REQ_REDIS_LPUSHX ) \
- ACTION( REQ_REDIS_LRANGE ) \
- ACTION( REQ_REDIS_LREM ) \
- ACTION( REQ_REDIS_LSET ) \
- ACTION( REQ_REDIS_LTRIM ) \
- ACTION( REQ_REDIS_PFADD ) /* redis requests - hyperloglog */ \
- ACTION( REQ_REDIS_PFCOUNT ) \
- ACTION( REQ_REDIS_PFMERGE ) \
- ACTION( REQ_REDIS_RPOP ) \
- ACTION( REQ_REDIS_RPOPLPUSH ) \
- ACTION( REQ_REDIS_RPUSH ) \
- ACTION( REQ_REDIS_RPUSHX ) \
- ACTION( REQ_REDIS_SADD ) /* redis requests - sets */ \
- ACTION( REQ_REDIS_SCARD ) \
- ACTION( REQ_REDIS_SDIFF ) \
- ACTION( REQ_REDIS_SDIFFSTORE ) \
- ACTION( REQ_REDIS_SINTER ) \
- ACTION( REQ_REDIS_SINTERSTORE ) \
- ACTION( REQ_REDIS_SISMEMBER ) \
- ACTION( REQ_REDIS_SMEMBERS ) \
- ACTION( REQ_REDIS_SMOVE ) \
- ACTION( REQ_REDIS_SPOP ) \
- ACTION( REQ_REDIS_SRANDMEMBER ) \
- ACTION( REQ_REDIS_SREM ) \
- ACTION( REQ_REDIS_SUNION ) \
- ACTION( REQ_REDIS_SUNIONSTORE ) \
- ACTION( REQ_REDIS_SSCAN) \
- ACTION( REQ_REDIS_ZADD ) /* redis requests - sorted sets */ \
- ACTION( REQ_REDIS_ZCARD ) \
- ACTION( REQ_REDIS_ZCOUNT ) \
- ACTION( REQ_REDIS_ZINCRBY ) \
- ACTION( REQ_REDIS_ZINTERSTORE ) \
- ACTION( REQ_REDIS_ZLEXCOUNT ) \
- ACTION( REQ_REDIS_ZRANGE ) \
- ACTION( REQ_REDIS_ZRANGEBYLEX ) \
- ACTION( REQ_REDIS_ZRANGEBYSCORE ) \
- ACTION( REQ_REDIS_ZRANK ) \
- ACTION( REQ_REDIS_ZREM ) \
- ACTION( REQ_REDIS_ZREMRANGEBYRANK ) \
- ACTION( REQ_REDIS_ZREMRANGEBYLEX ) \
- ACTION( REQ_REDIS_ZREMRANGEBYSCORE ) \
- ACTION( REQ_REDIS_ZREVRANGE ) \
- ACTION( REQ_REDIS_ZREVRANGEBYSCORE ) \
- ACTION( REQ_REDIS_ZREVRANK ) \
- ACTION( REQ_REDIS_ZSCORE ) \
- ACTION( REQ_REDIS_ZUNIONSTORE ) \
- ACTION( REQ_REDIS_ZSCAN) \
- ACTION( REQ_REDIS_EVAL ) /* redis requests - eval */ \
- ACTION( REQ_REDIS_EVALSHA ) \
- ACTION( REQ_REDIS_PING ) /* redis requests - ping/quit */ \
- ACTION( REQ_REDIS_QUIT) \
- ACTION( REQ_REDIS_AUTH) \
- ACTION( RSP_REDIS_STATUS ) /* redis response */ \
- ACTION( RSP_REDIS_ERROR ) \
- ACTION( RSP_REDIS_INTEGER ) \
- ACTION( RSP_REDIS_BULK ) \
- ACTION( RSP_REDIS_MULTIBULK ) \
- ACTION( SENTINEL ) \
-
-
-#define DEFINE_ACTION(_name) CMD_##_name,
-typedef enum cmd_type {
- CMD_TYPE_CODEC(DEFINE_ACTION)
-} cmd_type_t;
-#undef DEFINE_ACTION
-
-
-struct keypos {
- char *start; /* key start pos */
- char *end; /* key end pos */
- uint32_t remain_len; /* remain length after keypos->end for more key-value pairs in command, like mset */
-};
-
-struct cmd {
-
- uint64_t id; /* command id */
-
- cmd_parse_result_t result; /* command parsing result */
- char *errstr; /* error info when the command parse failed */
-
- cmd_type_t type; /* command type */
-
- char *cmd;
- uint32_t clen; /* command length */
-
- struct hiarray *keys; /* array of keypos, for req */
-
- char *narg_start; /* narg start (redis) */
- char *narg_end; /* narg end (redis) */
- uint32_t narg; /* # arguments (redis) */
-
- unsigned quit:1; /* quit request? */
- unsigned noforward:1; /* not need forward (example: ping) */
-
- int slot_num; /* this command should send to witch slot?
- * -1:the keys in this command cross different slots*/
- struct cmd **frag_seq; /* sequence of fragment command, map from keys to fragments*/
-
- redisReply *reply;
-
- hilist *sub_commands; /* just for pipeline and multi-key commands */
-};
-
-void redis_parse_cmd(struct cmd *r);
-
-struct cmd *command_get(void);
-void command_destroy(struct cmd *command);
-
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/crc16.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/crc16.c
deleted file mode 100644
index 0f304f6..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/crc16.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2001-2010 Georges Menie (www.menie.org)
- * Copyright 2010-2012 Salvatore Sanfilippo (adapted to Redis coding style)
- * 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 the University of California, Berkeley 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 REGENTS 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 REGENTS AND 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.
- */
-
-/* CRC16 implementation according to CCITT standards.
- *
- * Note by @antirez: this is actually the XMODEM CRC 16 algorithm, using the
- * following parameters:
- *
- * Name : "XMODEM", also known as "ZMODEM", "CRC-16/ACORN"
- * Width : 16 bit
- * Poly : 1021 (That is actually x^16 + x^12 + x^5 + 1)
- * Initialization : 0000
- * Reflect Input byte : False
- * Reflect Output CRC : False
- * Xor constant to output CRC : 0000
- * Output for "123456789" : 31C3
- */
-#include "hiutil.h"
-
-static const uint16_t crc16tab[256]= {
- 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
- 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
- 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
- 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
- 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
- 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
- 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
- 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
- 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
- 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
- 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
- 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
- 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
- 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
- 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
- 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
- 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
- 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
- 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
- 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
- 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
- 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
- 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
- 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
- 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
- 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
- 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
- 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
- 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
- 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
- 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
- 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
-};
-
-uint16_t crc16(const char *buf, int len) {
- int counter;
- uint16_t crc = 0;
- for (counter = 0; counter < len; counter++)
- crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *buf++)&0x00FF];
- return crc;
-}
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/dict.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/dict.c
deleted file mode 100644
index 79b1041..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/dict.c
+++ /dev/null
@@ -1,338 +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 <antirez at gmail dot com>
- * 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 <stdlib.h>
-#include <assert.h>
-#include <limits.h>
-#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 = malloc(sizeof(*ht));
- _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 = calloc(realsize,sizeof(dictEntry*));
-
- /* 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);
- 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 = malloc(sizeof(*entry));
- 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 suceed. */
- if (dictAdd(ht, key, val) == DICT_OK)
- return 1;
- /* It already exists, get the entry */
- entry = dictFind(ht, key);
- /* 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);
- 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);
- free(he);
- ht->used--;
- he = nextHe;
- }
- }
- /* Free the table and the allocated cache structure */
- 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);
- 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 dictIterator *dictGetIterator(dict *ht) {
- dictIterator *iter = malloc(sizeof(*iter));
-
- iter->ht = ht;
- iter->index = -1;
- iter->entry = NULL;
- iter->nextEntry = NULL;
- return iter;
-}
-
-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;
-}
-
-static void dictReleaseIterator(dictIterator *iter) {
- free(iter);
-}
-
-/* ------------------------- private functions ------------------------------ */
-
-/* Expand the hash table if needed */
-static int _dictExpandIfNeeded(dict *ht) {
- /* If the hash table is empty expand it to the intial size,
- * if the table is "full" dobule 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/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/dict.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/dict.h
deleted file mode 100644
index 95fcd28..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/dict.h
+++ /dev/null
@@ -1,126 +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 <antirez at gmail dot com>
- * 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 dictIterator *dictGetIterator(dict *ht);
-static dictEntry *dictNext(dictIterator *iter);
-static void dictReleaseIterator(dictIterator *iter);
-
-#endif /* __DICT_H */
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-ae.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-ae.c
deleted file mode 100644
index 8efa730..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-ae.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/ae.h>
-
-/* 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;
- if (reply == NULL) return;
- printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
- /* Disconnect after receiving the reply to GET */
- redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- aeStop(loop);
- return;
- }
-
- printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- aeStop(loop);
- return;
- }
-
- printf("Disconnected...\n");
- aeStop(loop);
-}
-
-int main (int argc, char **argv) {
- signal(SIGPIPE, SIG_IGN);
-
- redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
- if (c->err) {
- /* Let *c leak for now... */
- printf("Error: %s\n", c->errstr);
- return 1;
- }
-
- 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");
- aeMain(loop);
- return 0;
-}
-
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-glib.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-glib.c
deleted file mode 100644
index d6e10f8..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-glib.c
+++ /dev/null
@@ -1,73 +0,0 @@
-#include <stdlib.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/glib.h>
-
-static GMainLoop *mainloop;
-
-static void
-connect_cb (const redisAsyncContext *ac G_GNUC_UNUSED,
- int status)
-{
- if (status != REDIS_OK) {
- g_printerr("Failed to connect: %s\n", ac->errstr);
- g_main_loop_quit(mainloop);
- } else {
- g_printerr("Connected...\n");
- }
-}
-
-static void
-disconnect_cb (const redisAsyncContext *ac G_GNUC_UNUSED,
- int status)
-{
- if (status != REDIS_OK) {
- g_error("Failed to disconnect: %s", ac->errstr);
- } else {
- g_printerr("Disconnected...\n");
- g_main_loop_quit(mainloop);
- }
-}
-
-static void
-command_cb(redisAsyncContext *ac,
- gpointer r,
- gpointer user_data G_GNUC_UNUSED)
-{
- redisReply *reply = r;
-
- if (reply) {
- g_print("REPLY: %s\n", reply->str);
- }
-
- redisAsyncDisconnect(ac);
-}
-
-gint
-main (gint argc G_GNUC_UNUSED,
- gchar *argv[] G_GNUC_UNUSED)
-{
- redisAsyncContext *ac;
- GMainContext *context = NULL;
- GSource *source;
-
- ac = redisAsyncConnect("127.0.0.1", 6379);
- if (ac->err) {
- g_printerr("%s\n", ac->errstr);
- exit(EXIT_FAILURE);
- }
-
- source = redis_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");
-
- g_main_loop_run(mainloop);
-
- return EXIT_SUCCESS;
-}
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-libev.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-libev.c
deleted file mode 100644
index cc8b166..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-libev.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/libev.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
- redisReply *reply = r;
- if (reply == NULL) return;
- printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
- /* Disconnect after receiving the reply to GET */
- redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
- signal(SIGPIPE, SIG_IGN);
-
- redisAsyncContext *c = redisAsyncConnect("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");
- ev_loop(EV_DEFAULT_ 0);
- return 0;
-}
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-libevent.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-libevent.c
deleted file mode 100644
index d333c22..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-libevent.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/libevent.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
- redisReply *reply = r;
- if (reply == NULL) return;
- printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
- /* Disconnect after receiving the reply to GET */
- redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
- signal(SIGPIPE, SIG_IGN);
- struct event_base *base = event_base_new();
-
- redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
- 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");
- event_base_dispatch(base);
- return 0;
-}
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-libuv.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-libuv.c
deleted file mode 100644
index a5462d4..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example-libuv.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/libuv.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
- redisReply *reply = r;
- if (reply == NULL) return;
- printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
- /* Disconnect after receiving the reply to GET */
- redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
- signal(SIGPIPE, SIG_IGN);
- uv_loop_t* loop = uv_default_loop();
-
- redisAsyncContext *c = redisAsyncConnect("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);
- redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
- redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
- uv_run(loop, UV_RUN_DEFAULT);
- return 0;
-}
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example.c
deleted file mode 100644
index 25226a8..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/examples/example.c
+++ /dev/null
@@ -1,78 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <hiredis.h>
-
-int main(int argc, char **argv) {
- unsigned int j;
- redisContext *c;
- redisReply *reply;
- const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1";
- int port = (argc > 2) ? atoi(argv[2]) : 6379;
-
- struct timeval timeout = { 1, 500000 }; // 1.5 seconds
- c = redisConnectWithTimeout(hostname, port, timeout);
- if (c == NULL || c->err) {
- if (c) {
- printf("Connection error: %s\n", c->errstr);
- redisFree(c);
- } else {
- printf("Connection error: can't allocate redis context\n");
- }
- exit(1);
- }
-
- /* PING server */
- reply = redisCommand(c,"PING");
- printf("PING: %s\n", reply->str);
- freeReplyObject(reply);
-
- /* Set a key */
- reply = redisCommand(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);
- printf("SET (binary API): %s\n", reply->str);
- freeReplyObject(reply);
-
- /* Try a GET and two INCR */
- reply = redisCommand(c,"GET foo");
- printf("GET foo: %s\n", reply->str);
- freeReplyObject(reply);
-
- reply = redisCommand(c,"INCR counter");
- printf("INCR counter: %lld\n", reply->integer);
- freeReplyObject(reply);
- /* again ... */
- reply = redisCommand(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");
- freeReplyObject(reply);
- for (j = 0; j < 10; j++) {
- char buf[64];
-
- snprintf(buf,64,"%d",j);
- reply = redisCommand(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) {
- for (j = 0; j < reply->elements; j++) {
- printf("%u) %s\n", j, reply->element[j]->str);
- }
- }
- freeReplyObject(reply);
-
- /* Disconnects and frees the context */
- redisFree(c);
-
- return 0;
-}
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/fmacros.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/fmacros.h
deleted file mode 100644
index a3b1df0..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/fmacros.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __HIREDIS_FMACRO_H
-#define __HIREDIS_FMACRO_H
-
-#if defined(__linux__)
-#ifndef _BSD_SOURCE
-#define _BSD_SOURCE
-#endif
-#define _DEFAULT_SOURCE
-#endif
-
-#if defined(__sun__)
-#define _POSIX_C_SOURCE 200112L
-#elif defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__)
-#define _XOPEN_SOURCE 600
-#else
-#define _XOPEN_SOURCE
-#endif
-
-#if __APPLE__ && __MACH__
-#define _OSX
-#endif
-
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiarray.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiarray.c
deleted file mode 100644
index cf742ec..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiarray.c
+++ /dev/null
@@ -1,188 +0,0 @@
-#include <stdlib.h>
-
-#include "hiutil.h"
-#include "hiarray.h"
-
-struct hiarray *
-hiarray_create(uint32_t n, size_t size)
-{
- struct hiarray *a;
-
- ASSERT(n != 0 && size != 0);
-
- a = hi_alloc(sizeof(*a));
- if (a == NULL) {
- return NULL;
- }
-
- a->elem = hi_alloc(n * size);
- if (a->elem == NULL) {
- hi_free(a);
- return NULL;
- }
-
- a->nelem = 0;
- a->size = size;
- a->nalloc = n;
-
- return a;
-}
-
-void
-hiarray_destroy(struct hiarray *a)
-{
- hiarray_deinit(a);
- hi_free(a);
-}
-
-int
-hiarray_init(struct hiarray *a, uint32_t n, size_t size)
-{
- ASSERT(n != 0 && size != 0);
-
- a->elem = hi_alloc(n * size);
- if (a->elem == NULL) {
- return HI_ENOMEM;
- }
-
- a->nelem = 0;
- a->size = size;
- a->nalloc = n;
-
- return HI_OK;
-}
-
-void
-hiarray_deinit(struct hiarray *a)
-{
- ASSERT(a->nelem == 0);
-
- if (a->elem != NULL) {
- hi_free(a->elem);
- }
-}
-
-uint32_t
-hiarray_idx(struct hiarray *a, void *elem)
-{
- uint8_t *p, *q;
- uint32_t off, idx;
-
- ASSERT(elem >= a->elem);
-
- p = a->elem;
- q = elem;
- off = (uint32_t)(q - p);
-
- ASSERT(off % (uint32_t)a->size == 0);
-
- idx = off / (uint32_t)a->size;
-
- return idx;
-}
-
-void *
-hiarray_push(struct hiarray *a)
-{
- void *elem, *new;
- size_t size;
-
- if (a->nelem == a->nalloc) {
-
- /* the array is full; allocate new array */
- size = a->size * a->nalloc;
- new = hi_realloc(a->elem, 2 * size);
- if (new == NULL) {
- return NULL;
- }
-
- a->elem = new;
- a->nalloc *= 2;
- }
-
- elem = (uint8_t *)a->elem + a->size * a->nelem;
- a->nelem++;
-
- return elem;
-}
-
-void *
-hiarray_pop(struct hiarray *a)
-{
- void *elem;
-
- ASSERT(a->nelem != 0);
-
- a->nelem--;
- elem = (uint8_t *)a->elem + a->size * a->nelem;
-
- return elem;
-}
-
-void *
-hiarray_get(struct hiarray *a, uint32_t idx)
-{
- void *elem;
-
- ASSERT(a->nelem != 0);
- ASSERT(idx < a->nelem);
-
- elem = (uint8_t *)a->elem + (a->size * idx);
-
- return elem;
-}
-
-void *
-hiarray_top(struct hiarray *a)
-{
- ASSERT(a->nelem != 0);
-
- return hiarray_get(a, a->nelem - 1);
-}
-
-void
-hiarray_swap(struct hiarray *a, struct hiarray *b)
-{
- struct hiarray tmp;
-
- tmp = *a;
- *a = *b;
- *b = tmp;
-}
-
-/*
- * Sort nelem elements of the array in ascending order based on the
- * compare comparator.
- */
-void
-hiarray_sort(struct hiarray *a, hiarray_compare_t compare)
-{
- ASSERT(a->nelem != 0);
-
- qsort(a->elem, a->nelem, a->size, compare);
-}
-
-/*
- * Calls the func once for each element in the array as long as func returns
- * success. On failure short-circuits and returns the error status.
- */
-int
-hiarray_each(struct hiarray *a, hiarray_each_t func, void *data)
-{
- uint32_t i, nelem;
-
- ASSERT(array_n(a) != 0);
- ASSERT(func != NULL);
-
- for (i = 0, nelem = hiarray_n(a); i < nelem; i++) {
- void *elem = hiarray_get(a, i);
- rstatus_t status;
-
- status = func(elem, data);
- if (status != HI_OK) {
- return status;
- }
- }
-
- return HI_OK;
-}
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiarray.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiarray.h
deleted file mode 100644
index fda3a4b..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiarray.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __HIARRAY_H_
-#define __HIARRAY_H_
-
-#include <stdio.h>
-
-typedef int (*hiarray_compare_t)(const void *, const void *);
-typedef int (*hiarray_each_t)(void *, void *);
-
-struct hiarray {
- uint32_t nelem; /* # element */
- void *elem; /* element */
- size_t size; /* element size */
- uint32_t nalloc; /* # allocated element */
-};
-
-#define null_hiarray { 0, NULL, 0, 0 }
-
-static inline void
-hiarray_null(struct hiarray *a)
-{
- a->nelem = 0;
- a->elem = NULL;
- a->size = 0;
- a->nalloc = 0;
-}
-
-static inline void
-hiarray_set(struct hiarray *a, void *elem, size_t size, uint32_t nalloc)
-{
- a->nelem = 0;
- a->elem = elem;
- a->size = size;
- a->nalloc = nalloc;
-}
-
-static inline uint32_t
-hiarray_n(const struct hiarray *a)
-{
- return a->nelem;
-}
-
-struct hiarray *hiarray_create(uint32_t n, size_t size);
-void hiarray_destroy(struct hiarray *a);
-int hiarray_init(struct hiarray *a, uint32_t n, size_t size);
-void hiarray_deinit(struct hiarray *a);
-
-uint32_t hiarray_idx(struct hiarray *a, void *elem);
-void *hiarray_push(struct hiarray *a);
-void *hiarray_pop(struct hiarray *a);
-void *hiarray_get(struct hiarray *a, uint32_t idx);
-void *hiarray_top(struct hiarray *a);
-void hiarray_swap(struct hiarray *a, struct hiarray *b);
-void hiarray_sort(struct hiarray *a, hiarray_compare_t compare);
-int hiarray_each(struct hiarray *a, hiarray_each_t func, void *data);
-
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hircluster.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hircluster.c
deleted file mode 100644
index c570933..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hircluster.c
+++ /dev/null
@@ -1,4820 +0,0 @@
-
-#include "fmacros.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "hircluster.h"
-#include "hiutil.h"
-#include "adlist.h"
-#include "hiarray.h"
-#include "command.h"
-#include "dict.c"
-
-#define REDIS_COMMAND_CLUSTER_NODES "CLUSTER NODES"
-#define REDIS_COMMAND_CLUSTER_SLOTS "CLUSTER SLOTS"
-
-#define REDIS_COMMAND_ASKING "ASKING"
-#define REDIS_COMMAND_PING "PING"
-
-#define REDIS_PROTOCOL_ASKING "*1\r\n$6\r\nASKING\r\n"
-
-#define IP_PORT_SEPARATOR ":"
-
-#define CLUSTER_ADDRESS_SEPARATOR ","
-
-#define CLUSTER_DEFAULT_MAX_REDIRECT_COUNT 5
-
-typedef struct cluster_async_data
-{
- redisClusterAsyncContext *acc;
- struct cluster_node *node;
- struct cmd *command;
- redisClusterCallbackFn *callback;
- int retry_count;
- void *privdata;
-}cluster_async_data;
-
-typedef enum CLUSTER_ERR_TYPE{
- CLUSTER_NOT_ERR = 0,
- CLUSTER_ERR_MOVED,
- CLUSTER_ERR_ASK,
- CLUSTER_ERR_TRYAGAIN,
- CLUSTER_ERR_CROSSSLOT,
- CLUSTER_ERR_CLUSTERDOWN,
- CLUSTER_ERR_SENTINEL
-}CLUSTER_ERR_TYPE;
-
-static void cluster_node_deinit(cluster_node *node);
-static void cluster_slot_destroy(cluster_slot *slot);
-static void cluster_open_slot_destroy(copen_slot *oslot);
-
-void listClusterNodeDestructor(void *val)
-{
- cluster_node_deinit(val);
-
- hi_free(val);
-}
-
-void listClusterSlotDestructor(void *val)
-{
- cluster_slot_destroy(val);
-}
-
-unsigned int dictSdsHash(const void *key) {
- return dictGenHashFunction((unsigned char*)key, sdslen((char*)key));
-}
-
-int dictSdsKeyCompare(void *privdata, const void *key1,
- const void *key2)
-{
- int l1,l2;
- DICT_NOTUSED(privdata);
-
- l1 = sdslen((sds)key1);
- l2 = sdslen((sds)key2);
- if (l1 != l2) return 0;
- return memcmp(key1, key2, l1) == 0;
-}
-
-void dictSdsDestructor(void *privdata, void *val)
-{
- DICT_NOTUSED(privdata);
-
- sdsfree(val);
-}
-
-void dictClusterNodeDestructor(void *privdata, void *val)
-{
- DICT_NOTUSED(privdata);
-
- cluster_node_deinit(val);
-
- hi_free(val);
-}
-
-/* Cluster nodes hash table, mapping nodes
- * name(437c719f50dc9d0745032f3b280ce7ecc40792ac)
- * or addresses(1.2.3.4:6379) to clusterNode structures.
- * Those nodes need destroy.
- */
-dictType clusterNodesDictType = {
- dictSdsHash, /* hash function */
- NULL, /* key dup */
- NULL, /* val dup */
- dictSdsKeyCompare, /* key compare */
- dictSdsDestructor, /* key destructor */
- dictClusterNodeDestructor /* val destructor */
-};
-
-/* Cluster nodes hash table, mapping nodes
- * name(437c719f50dc9d0745032f3b280ce7ecc40792ac)
- * or addresses(1.2.3.4:6379) to clusterNode structures.
- * Those nodes do not need destroy.
- */
-dictType clusterNodesRefDictType = {
- dictSdsHash, /* hash function */
- NULL, /* key dup */
- NULL, /* val dup */
- dictSdsKeyCompare, /* key compare */
- dictSdsDestructor, /* key destructor */
- NULL /* val destructor */
-};
-
-
-void listCommandFree(void *command)
-{
- struct cmd *cmd = command;
- command_destroy(cmd);
-}
-
-/* Defined in hiredis.c */
-void __redisSetError(redisContext *c, int type, const char *str);
-
-/* Forward declaration of function in hiredis.c */
-int __redisAppendCommand(redisContext *c, const char *cmd, size_t len);
-
-/* Helper function for the redisClusterCommand* 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
- * context is non-blocking, the "reply" pointer will not be used and the
- * command is simply appended to the write buffer.
- *
- * Returns the reply when a reply was succesfully retrieved. Returns NULL
- * otherwise. When NULL is returned in a blocking context, the error field
- * in the context will be set.
- */
-static void *__redisBlockForReply(redisContext *c) {
- void *reply;
-
- if (c->flags & REDIS_BLOCK) {
- if (redisGetReply(c,&reply) != REDIS_OK)
- return NULL;
- return reply;
- }
- return NULL;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Key space handling
- * -------------------------------------------------------------------------- */
-
-/* We have 16384 hash slots. The hash slot of a given key is obtained
- * as the least significant 14 bits of the crc16 of the key.
- *
- * However if the key contains the {...} pattern, only the part between
- * { and } is hashed. This may be useful in the future to force certain
- * keys to be in the same node (assuming no resharding is in progress). */
-static unsigned int keyHashSlot(char *key, int keylen) {
- int s, e; /* start-end indexes of { and } */
-
- for (s = 0; s < keylen; s++)
- if (key[s] == '{') break;
-
- /* No '{' ? Hash the whole key. This is the base case. */
- if (s == keylen) return crc16(key,keylen) & 0x3FFF;
-
- /* '{' found? Check if we have the corresponding '}'. */
- for (e = s+1; e < keylen; e++)
- if (key[e] == '}') break;
-
- /* No '}' or nothing betweeen {} ? Hash the whole key. */
- if (e == keylen || e == s+1) return crc16(key,keylen) & 0x3FFF;
-
- /* If we are here there is both a { and a } on its right. Hash
- * what is in the middle between { and }. */
- return crc16(key+s+1,e-s-1) & 0x3FFF;
-}
-
-static void __redisClusterSetError(redisClusterContext *cc, int type, const char *str) {
- size_t len;
-
- if(cc == NULL){
- return;
- }
-
- cc->err = type;
- if (str != NULL) {
- len = strlen(str);
- len = len < (sizeof(cc->errstr)-1) ? len : (sizeof(cc->errstr)-1);
- memcpy(cc->errstr,str,len);
- cc->errstr[len] = '\0';
- } else {
- /* Only REDIS_ERR_IO may lack a description! */
- assert(type == REDIS_ERR_IO);
- __redis_strerror_r(errno, cc->errstr, sizeof(cc->errstr));
- }
-}
-
-static int cluster_reply_error_type(redisReply *reply)
-{
-
- if(reply == NULL)
- {
- return REDIS_ERR;
- }
-
- if(reply->type == REDIS_REPLY_ERROR)
- {
- if((int)strlen(REDIS_ERROR_MOVED) < reply->len &&
- strncmp(reply->str, REDIS_ERROR_MOVED, strlen(REDIS_ERROR_MOVED)) == 0)
- {
- return CLUSTER_ERR_MOVED;
- }
- else if((int)strlen(REDIS_ERROR_ASK) < reply->len &&
- strncmp(reply->str, REDIS_ERROR_ASK, strlen(REDIS_ERROR_ASK)) == 0)
- {
- return CLUSTER_ERR_ASK;
- }
- else if((int)strlen(REDIS_ERROR_TRYAGAIN) < reply->len &&
- strncmp(reply->str, REDIS_ERROR_TRYAGAIN, strlen(REDIS_ERROR_TRYAGAIN)) == 0)
- {
- return CLUSTER_ERR_TRYAGAIN;
- }
- else if((int)strlen(REDIS_ERROR_CROSSSLOT) < reply->len &&
- strncmp(reply->str, REDIS_ERROR_CROSSSLOT, strlen(REDIS_ERROR_CROSSSLOT)) == 0)
- {
- return CLUSTER_ERR_CROSSSLOT;
- }
- else if((int)strlen(REDIS_ERROR_CLUSTERDOWN) < reply->len &&
- strncmp(reply->str, REDIS_ERROR_CLUSTERDOWN, strlen(REDIS_ERROR_CLUSTERDOWN)) == 0)
- {
- return CLUSTER_ERR_CLUSTERDOWN;
- }
- else
- {
- return CLUSTER_ERR_SENTINEL;
- }
- }
-
- return CLUSTER_NOT_ERR;
-}
-
-static int cluster_node_init(cluster_node *node)
-{
- if(node == NULL){
- return REDIS_ERR;
- }
-
- node->name = NULL;
- node->addr = NULL;
- node->host = NULL;
- node->port = 0;
- node->role = REDIS_ROLE_NULL;
- node->myself = 0;
- node->slaves = NULL;
- node->con = NULL;
- node->acon = NULL;
- node->slots = NULL;
- node->failure_count = 0;
- node->data = NULL;
- node->migrating = NULL;
- node->importing = NULL;
-
- return REDIS_OK;
-}
-
-static void cluster_node_deinit(cluster_node *node)
-{
- copen_slot **oslot;
-
- if(node == NULL)
- {
- return;
- }
-
- sdsfree(node->name);
- sdsfree(node->addr);
- sdsfree(node->host);
- node->port = 0;
- node->role = REDIS_ROLE_NULL;
- node->myself = 0;
-
- if(node->con != NULL)
- {
- redisFree(node->con);
- }
-
- if(node->acon != NULL)
- {
- redisAsyncFree(node->acon);
- }
-
- if(node->slots != NULL)
- {
- listRelease(node->slots);
- }
-
- if(node->slaves != NULL)
- {
- listRelease(node->slaves);
- }
-
- if(node->migrating)
- {
- while(hiarray_n(node->migrating))
- {
- oslot = hiarray_pop(node->migrating);
- cluster_open_slot_destroy(*oslot);
- }
-
- hiarray_destroy(node->migrating);
- node->migrating = NULL;
- }
-
- if(node->importing)
- {
- while(hiarray_n(node->importing))
- {
- oslot = hiarray_pop(node->importing);
- cluster_open_slot_destroy(*oslot);
- }
-
- hiarray_destroy(node->importing);
- node->importing = NULL;
- }
-}
-
-static int cluster_slot_init(cluster_slot *slot, cluster_node *node)
-{
- slot->start = 0;
- slot->end = 0;
- slot->node = node;
-
- return REDIS_OK;
-}
-
-static cluster_slot *cluster_slot_create(cluster_node *node)
-{
- cluster_slot *slot;
-
- slot = hi_alloc(sizeof(*slot));
- if(slot == NULL){
- return NULL;
- }
-
- cluster_slot_init(slot, node);
-
- if(node != NULL){
- ASSERT(node->role == REDIS_ROLE_MASTER);
- if(node->slots == NULL){
- node->slots = listCreate();
- if(node->slots == NULL)
- {
- cluster_slot_destroy(slot);
- return NULL;
- }
-
- node->slots->free = listClusterSlotDestructor;
- }
-
- listAddNodeTail(node->slots, slot);
- }
-
- return slot;
-}
-
-static int cluster_slot_ref_node(cluster_slot * slot, cluster_node *node)
-{
- if(slot == NULL || node == NULL){
- return REDIS_ERR;
- }
-
-
- if(node->role != REDIS_ROLE_MASTER){
- return REDIS_ERR;
- }
-
- if(node->slots == NULL){
- node->slots = listCreate();
- if(node->slots == NULL)
- {
- return REDIS_ERR;
- }
-
- node->slots->free = listClusterSlotDestructor;
- }
-
- listAddNodeTail(node->slots, slot);
- slot->node = node;
-
- return REDIS_OK;
-}
-
-static void cluster_slot_destroy(cluster_slot *slot)
-{
- slot->start = 0;
- slot->end = 0;
- slot->node = NULL;
-
- hi_free(slot);
-}
-
-static copen_slot *cluster_open_slot_create(uint32_t slot_num, int migrate,
- sds remote_name, cluster_node *node)
-{
- copen_slot *oslot;
-
- oslot = hi_alloc(sizeof(*oslot));
- if(oslot == NULL){
- return NULL;
- }
-
- oslot->slot_num = 0;
- oslot->migrate = 0;
- oslot->node = NULL;
- oslot->remote_name = NULL;
-
- oslot->slot_num = slot_num;
- oslot->migrate = migrate;
- oslot->node = node;
- oslot->remote_name = sdsdup(remote_name);
-
- return oslot;
-}
-
-static void cluster_open_slot_destroy(copen_slot *oslot)
-{
- oslot->slot_num = 0;
- oslot->migrate = 0;
- oslot->node = NULL;
-
- if(oslot->remote_name != NULL){
- sdsfree(oslot->remote_name);
- oslot->remote_name = NULL;
- }
-
- hi_free(oslot);
-}
-
-/**
- * Return a new node with the "cluster slots" command reply.
- */
-static cluster_node *node_get_with_slots(
- redisClusterContext *cc, redisReply *host_elem,
- redisReply *port_elem, uint8_t role)
-{
- cluster_node *node = NULL;
-
- if(host_elem == NULL || port_elem == NULL){
- return NULL;
- }
-
- if(host_elem->type != REDIS_REPLY_STRING ||
- host_elem->len <= 0){
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "Command(cluster slots) reply error: "
- "node ip is not string.");
- goto error;
- }
-
- if(port_elem->type != REDIS_REPLY_INTEGER ||
- port_elem->integer <= 0){
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "Command(cluster slots) reply error: "
- "node port is not integer.");
- goto error;
- }
-
- if(!hi_valid_port((int)port_elem->integer)){
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "Command(cluster slots) reply error: "
- "node port is not valid.");
- goto error;
- }
-
- node = hi_alloc(sizeof(cluster_node));
- if(node == NULL){
- __redisClusterSetError(cc,
- REDIS_ERR_OOM,"Out of memory");
- goto error;
- }
-
- cluster_node_init(node);
-
- if(role == REDIS_ROLE_MASTER){
- node->slots = listCreate();
- if(node->slots == NULL){
- hi_free(node);
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "slots for node listCreate error");
- goto error;
- }
-
- node->slots->free = listClusterSlotDestructor;
- }
-
- node->name = NULL;
- node->addr = sdsnewlen(host_elem->str, host_elem->len);
- node->addr = sdscatfmt(node->addr, ":%i", port_elem->integer);
-
- node->host = sdsnewlen(host_elem->str, host_elem->len);
- node->port = (int)port_elem->integer;
- node->role = role;
-
- return node;
-
-error:
-
- if(node != NULL){
- hi_free(node);
- }
-
- return NULL;
-}
-
-/**
- * Return a new node with the "cluster nodes" command reply.
- */
-static cluster_node *node_get_with_nodes(
- redisClusterContext *cc,
- sds *node_infos, int info_count, uint8_t role)
-{
- sds *ip_port = NULL;
- int count_ip_port = 0;
- cluster_node *node;
-
- if(info_count < 8)
- {
- return NULL;
- }
-
- node = hi_alloc(sizeof(cluster_node));
- if(node == NULL)
- {
- __redisClusterSetError(cc,
- REDIS_ERR_OOM,"Out of memory");
- goto error;
- }
-
- cluster_node_init(node);
-
- if(role == REDIS_ROLE_MASTER)
- {
- node->slots = listCreate();
- if(node->slots == NULL)
- {
- hi_free(node);
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "slots for node listCreate error");
- goto error;
- }
-
- node->slots->free = listClusterSlotDestructor;
- }
-
- node->name = node_infos[0];
- node->addr = node_infos[1];
-
- ip_port = sdssplitlen(node_infos[1], sdslen(node_infos[1]),
- IP_PORT_SEPARATOR, strlen(IP_PORT_SEPARATOR), &count_ip_port);
- if(ip_port == NULL || count_ip_port != 2)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "split ip port error");
- goto error;
- }
- node->host = ip_port[0];
- node->port = hi_atoi(ip_port[1], sdslen(ip_port[1]));
- node->role = role;
-
- sdsfree(ip_port[1]);
- free(ip_port);
-
- node_infos[0] = NULL;
- node_infos[1] = NULL;
-
- return node;
-
-error:
- if(ip_port != NULL)
- {
- sdsfreesplitres(ip_port, count_ip_port);
- }
-
- if(node != NULL)
- {
- hi_free(node);
- }
-
- return NULL;
-}
-
-static void cluster_nodes_swap_ctx(dict *nodes_f, dict *nodes_t)
-{
- dictIterator *di;
- dictEntry *de_f, *de_t;
- cluster_node *node_f, *node_t;
- redisContext *c;
- redisAsyncContext *ac;
-
- if(nodes_f == NULL || nodes_t == NULL){
- return;
- }
-
- di = dictGetIterator(nodes_t);
- while((de_t = dictNext(di)) != NULL){
- node_t = dictGetEntryVal(de_t);
- if(node_t == NULL){
- continue;
- }
-
- de_f = dictFind(nodes_f, node_t->addr);
- if(de_f == NULL){
- continue;
- }
-
- node_f = dictGetEntryVal(de_f);
- if(node_f->con != NULL){
- c = node_f->con;
- node_f->con = node_t->con;
- node_t->con = c;
- }
-
- if(node_f->acon != NULL){
- ac = node_f->acon;
- node_f->acon = node_t->acon;
- node_t->acon = ac;
- }
- }
-
- dictReleaseIterator(di);
-
-}
-
-static int
-cluster_slot_start_cmp(const void *t1, const void *t2)
-{
- const cluster_slot **s1 = t1, **s2 = t2;
-
- return (*s1)->start > (*s2)->start?1:-1;
-}
-
-static int
-cluster_master_slave_mapping_with_name(redisClusterContext *cc,
- dict **nodes, cluster_node *node, sds master_name)
-{
- int ret;
- dictEntry *di;
- cluster_node *node_old;
- listNode *lnode;
-
- if(node == NULL || master_name == NULL)
- {
- return REDIS_ERR;
- }
-
- if(*nodes == NULL)
- {
- *nodes = dictCreate(
- &clusterNodesRefDictType, NULL);
- }
-
- di = dictFind(*nodes, master_name);
- if(di == NULL)
- {
- ret = dictAdd(*nodes,
- sdsnewlen(master_name, sdslen(master_name)), node);
- if(ret != DICT_OK)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "the address already exists in the nodes");
- return REDIS_ERR;
- }
-
- }
- else
- {
- node_old = dictGetEntryVal(di);
- if(node_old == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "dict get value null");
- return REDIS_ERR;
- }
-
- if(node->role == REDIS_ROLE_MASTER &&
- node_old->role == REDIS_ROLE_MASTER)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "two masters have the same name");
- return REDIS_ERR;
- }
- else if(node->role == REDIS_ROLE_MASTER
- && node_old->role == REDIS_ROLE_SLAVE)
- {
- if(node->slaves == NULL)
- {
- node->slaves = listCreate();
- if(node->slaves == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,
- "Out of memory");
- return REDIS_ERR;
- }
-
- node->slaves->free =
- listClusterNodeDestructor;
- }
-
- if(node_old->slaves != NULL)
- {
- node_old->slaves->free = NULL;
- while(listLength(node_old->slaves) > 0)
- {
- lnode = listFirst(node_old->slaves);
- listAddNodeHead(node->slaves, lnode->value);
- listDelNode(node_old->slaves, lnode);
- }
- listRelease(node_old->slaves);
- node_old->slaves = NULL;
- }
-
- listAddNodeHead(node->slaves, node_old);
-
- dictSetHashVal(*nodes, di, node);
- }
- else if(node->role == REDIS_ROLE_SLAVE)
- {
- if(node_old->slaves == NULL)
- {
- node_old->slaves = listCreate();
- if(node_old->slaves == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,
- "Out of memory");
- return REDIS_ERR;
- }
-
- node_old->slaves->free =
- listClusterNodeDestructor;
- }
-
- listAddNodeTail(node_old->slaves, node);
- }
- else
- {
- NOT_REACHED();
- }
- }
-
- return REDIS_OK;
-}
-
-/**
- * Parse the "cluster slots" command reply to nodes dict.
- */
-dict *
-parse_cluster_slots(redisClusterContext *cc,
- redisReply *reply, int flags)
-{
- int ret;
- cluster_slot *slot = NULL;
- dict *nodes = NULL;
- dictEntry *den;
- redisReply *elem_slots;
- redisReply *elem_slots_begin, *elem_slots_end;
- redisReply *elem_nodes;
- redisReply *elem_ip, *elem_port;
- cluster_node *master = NULL, *slave;
- sds address;
- uint32_t i, idx;
-
- if(reply == NULL){
- return NULL;
- }
-
- nodes = dictCreate(&clusterNodesDictType, NULL);
- if(nodes == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OOM,
- "out of memory");
- goto error;
- }
-
- if(reply->type != REDIS_REPLY_ARRAY || reply->elements <= 0){
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "Command(cluster slots) reply error: "
- "reply is not an array.");
- goto error;
- }
-
- for(i = 0; i < reply->elements; i ++){
- elem_slots = reply->element[i];
- if(elem_slots->type != REDIS_REPLY_ARRAY ||
- elem_slots->elements < 3){
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "Command(cluster slots) reply error: "
- "first sub_reply is not an array.");
- goto error;
- }
-
- slot = cluster_slot_create(NULL);
- if(slot == NULL){
- __redisClusterSetError(cc, REDIS_ERR_OOM,
- "Slot create failed: out of memory.");
- goto error;
- }
-
- //one slots region
- for(idx = 0; idx < elem_slots->elements; idx ++){
- if(idx == 0){
- elem_slots_begin = elem_slots->element[idx];
- if(elem_slots_begin->type != REDIS_REPLY_INTEGER){
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "Command(cluster slots) reply error: "
- "slot begin is not an integer.");
- goto error;
- }
- slot->start = (int)(elem_slots_begin->integer);
- }else if(idx == 1){
- elem_slots_end = elem_slots->element[idx];
- if(elem_slots_end->type != REDIS_REPLY_INTEGER){
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "Command(cluster slots) reply error: "
- "slot end is not an integer.");
- goto error;
- }
-
- slot->end = (int)(elem_slots_end->integer);
-
- if(slot->start > slot->end){
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "Command(cluster slots) reply error: "
- "slot begin is bigger than slot end.");
- goto error;
- }
- }else{
- elem_nodes = elem_slots->element[idx];
- if(elem_nodes->type != REDIS_REPLY_ARRAY ||
- elem_nodes->elements != 2){
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "Command(cluster slots) reply error: "
- "nodes sub_reply is not an correct array.");
- goto error;
- }
-
- elem_ip = elem_nodes->element[0];
- elem_port = elem_nodes->element[1];
-
- if(elem_ip == NULL || elem_port == NULL ||
- elem_ip->type != REDIS_REPLY_STRING ||
- elem_port->type != REDIS_REPLY_INTEGER){
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "Command(cluster slots) reply error: "
- "master ip or port is not correct.");
- goto error;
- }
-
- //this is master.
- if(idx == 2){
- address = sdsnewlen(elem_ip->str, elem_ip->len);
- address = sdscatfmt(address, ":%i", elem_port->integer);
-
- den = dictFind(nodes, address);
- //master already exits, break to the next slots region.
- if(den != NULL){
- sdsfree(address);
-
- master = dictGetEntryVal(den);
- ret = cluster_slot_ref_node(slot, master);
- if(ret != REDIS_OK){
- __redisClusterSetError(cc, REDIS_ERR_OOM,
- "Slot ref node failed: out of memory.");
- goto error;
- }
-
- slot = NULL;
- break;
- }
-
- sdsfree(address);
- master = node_get_with_slots(cc, elem_ip,
- elem_port, REDIS_ROLE_MASTER);
- if(master == NULL){
- goto error;
- }
-
- ret = dictAdd(nodes,
- sdsnewlen(master->addr, sdslen(master->addr)), master);
- if(ret != DICT_OK){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "The address already exists in the nodes");
- cluster_node_deinit(master);
- hi_free(master);
- goto error;
- }
-
- ret = cluster_slot_ref_node(slot, master);
- if(ret != REDIS_OK){
- __redisClusterSetError(cc, REDIS_ERR_OOM,
- "Slot ref node failed: out of memory.");
- goto error;
- }
-
- slot = NULL;
- }else if(flags & HIRCLUSTER_FLAG_ADD_SLAVE){
- slave = node_get_with_slots(cc, elem_ip,
- elem_port, REDIS_ROLE_SLAVE);
- if(slave == NULL){
- goto error;
- }
-
- if(master->slaves == NULL){
- master->slaves = listCreate();
- if(master->slaves == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OOM,
- "Out of memory");
- cluster_node_deinit(slave);
- goto error;
- }
-
- master->slaves->free =
- listClusterNodeDestructor;
- }
-
- listAddNodeTail(master->slaves, slave);
- }
- }
- }
- }
-
- return nodes;
-
-error:
-
- if(nodes != NULL){
- dictRelease(nodes);
- }
-
- if(slot != NULL){
- cluster_slot_destroy(slot);
- }
-
- return NULL;
-}
-
-/**
- * Parse the "cluster nodes" command reply to nodes dict.
- */
-dict *
-parse_cluster_nodes(redisClusterContext *cc,
- char *str, int str_len, int flags)
-{
- int ret;
- dict *nodes = NULL;
- dict *nodes_name = NULL;
- cluster_node *master, *slave;
- cluster_slot *slot;
- char *pos, *start, *end, *line_start, *line_end;
- char *role;
- int role_len;
- uint8_t myself = 0;
- int slot_start, slot_end;
- sds *part = NULL, *slot_start_end = NULL;
- int count_part = 0, count_slot_start_end = 0;
- int k;
- int len;
-
- nodes = dictCreate(&clusterNodesDictType, NULL);
- if(nodes == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OOM,
- "out of memory");
- goto error;
- }
-
- start = str;
- end = start + str_len;
-
- line_start = start;
-
- for(pos = start; pos < end; pos ++){
- if(*pos == '\n'){
- line_end = pos - 1;
- len = line_end - line_start;
-
- part = sdssplitlen(line_start, len + 1, " ", 1, &count_part);
-
- if(part == NULL || count_part < 8){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "split cluster nodes error");
- goto error;
- }
-
- //the address string is ":0", skip this node.
- if(sdslen(part[1]) == 2 && strcmp(part[1], ":0") == 0){
- sdsfreesplitres(part, count_part);
- count_part = 0;
- part = NULL;
-
- start = pos + 1;
- line_start = start;
- pos = start;
-
- continue;
- }
-
- if(sdslen(part[2]) >= 7 && memcmp(part[2], "myself,", 7) == 0){
- role_len = sdslen(part[2]) - 7;
- role = part[2] + 7;
- myself = 1;
- }else{
- role_len = sdslen(part[2]);
- role = part[2];
- }
-
- //add master node
- if(role_len >= 6 && memcmp(role, "master", 6) == 0){
- if(count_part < 8){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "Master node parts number error: less than 8.");
- goto error;
- }
-
- master = node_get_with_nodes(cc,
- part, count_part, REDIS_ROLE_MASTER);
- if(master == NULL){
- goto error;
- }
-
- ret = dictAdd(nodes,
- sdsnewlen(master->addr, sdslen(master->addr)), master);
- if(ret != DICT_OK){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "The address already exists in the nodes");
- cluster_node_deinit(master);
- hi_free(master);
- goto error;
- }
-
- if(flags & HIRCLUSTER_FLAG_ADD_SLAVE){
- ret = cluster_master_slave_mapping_with_name(cc,
- &nodes_name, master, master->name);
- if(ret != REDIS_OK){
- cluster_node_deinit(master);
- hi_free(master);
- goto error;
- }
- }
-
- if(myself) master->myself = 1;
-
- for(k = 8; k < count_part; k ++){
- slot_start_end = sdssplitlen(part[k],
- sdslen(part[k]), "-", 1, &count_slot_start_end);
-
- if(slot_start_end == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "split slot start end error(NULL)");
- goto error;
- }else if(count_slot_start_end == 1){
- slot_start =
- hi_atoi(slot_start_end[0], sdslen(slot_start_end[0]));
- slot_end = slot_start;
- }else if(count_slot_start_end == 2){
- slot_start =
- hi_atoi(slot_start_end[0], sdslen(slot_start_end[0]));;
- slot_end =
- hi_atoi(slot_start_end[1], sdslen(slot_start_end[1]));;
- }else{
- //add open slot for master
- if(flags & HIRCLUSTER_FLAG_ADD_OPENSLOT &&
- count_slot_start_end == 3 &&
- sdslen(slot_start_end[0]) > 1 &&
- sdslen(slot_start_end[1]) == 1 &&
- sdslen(slot_start_end[2]) > 1 &&
- slot_start_end[0][0] == '[' &&
- slot_start_end[2][sdslen(slot_start_end[2])-1] == ']'){
-
- copen_slot *oslot, **oslot_elem;
-
- sdsrange(slot_start_end[0], 1, -1);
- sdsrange(slot_start_end[2], 0, -2);
-
- if(slot_start_end[1][0] == '>'){
- oslot = cluster_open_slot_create(
- hi_atoi(slot_start_end[0],
- sdslen(slot_start_end[0])),
- 1, slot_start_end[2], master);
- if(oslot == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "create open slot error");
- goto error;
- }
-
- if(master->migrating == NULL){
- master->migrating = hiarray_create(1, sizeof(oslot));
- if(master->migrating == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "create migrating array error");
- cluster_open_slot_destroy(oslot);
- goto error;
- }
- }
-
- oslot_elem = hiarray_push(master->migrating);
- if(oslot_elem == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "Push migrating array error: out of memory");
- cluster_open_slot_destroy(oslot);
- goto error;
- }
-
- *oslot_elem = oslot;
- }else if(slot_start_end[1][0] == '<'){
- oslot = cluster_open_slot_create(hi_atoi(slot_start_end[0],
- sdslen(slot_start_end[0])), 0, slot_start_end[2],
- master);
- if(oslot == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "create open slot error");
- goto error;
- }
-
- if(master->importing == NULL){
- master->importing = hiarray_create(1, sizeof(oslot));
- if(master->importing == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "create migrating array error");
- cluster_open_slot_destroy(oslot);
- goto error;
- }
- }
-
- oslot_elem = hiarray_push(master->importing);
- if(oslot_elem == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "push migrating array error: out of memory");
- cluster_open_slot_destroy(oslot);
- goto error;
- }
-
- *oslot_elem = oslot;
- }
- }
-
- slot_start = -1;
- slot_end = -1;
- }
-
- sdsfreesplitres(slot_start_end, count_slot_start_end);
- count_slot_start_end = 0;
- slot_start_end = NULL;
-
- if(slot_start < 0 || slot_end < 0 ||
- slot_start > slot_end || slot_end >= REDIS_CLUSTER_SLOTS){
- continue;
- }
-
- slot = cluster_slot_create(master);
- if(slot == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OOM,
- "Out of memory");
- goto error;
- }
-
- slot->start = (uint32_t)slot_start;
- slot->end = (uint32_t)slot_end;
- }
-
- }
- //add slave node
- else if((flags & HIRCLUSTER_FLAG_ADD_SLAVE) &&
- (role_len >= 5 && memcmp(role, "slave", 5) == 0)){
- slave = node_get_with_nodes(cc, part,
- count_part, REDIS_ROLE_SLAVE);
- if(slave == NULL){
- goto error;
- }
-
- ret = cluster_master_slave_mapping_with_name(cc,
- &nodes_name, slave, part[3]);
- if(ret != REDIS_OK){
- cluster_node_deinit(slave);
- hi_free(slave);
- goto error;
- }
-
- if(myself) slave->myself = 1;
- }
-
- if(myself == 1){
- myself = 0;
- }
-
- sdsfreesplitres(part, count_part);
- count_part = 0;
- part = NULL;
-
- start = pos + 1;
- line_start = start;
- pos = start;
- }
- }
-
- if(nodes_name != NULL){
- dictRelease(nodes_name);
- }
-
- return nodes;
-
-error:
-
- if(part != NULL){
- sdsfreesplitres(part, count_part);
- count_part = 0;
- part = NULL;
- }
-
- if(slot_start_end != NULL){
- sdsfreesplitres(slot_start_end, count_slot_start_end);
- count_slot_start_end = 0;
- slot_start_end = NULL;
- }
-
- if(nodes != NULL){
- dictRelease(nodes);
- }
-
- if(nodes_name != NULL){
- dictRelease(nodes_name);
- }
-
- return NULL;
-}
-
-/**
- * Update route with the "cluster nodes" or "cluster slots" command reply.
- */
-static int
-cluster_update_route_by_addr(redisClusterContext *cc,
- const char *ip, int port)
-{
- redisContext *c = NULL;
- redisReply *reply = NULL;
- dict *nodes = NULL;
- struct hiarray *slots = NULL;
- cluster_node *master;
- cluster_slot *slot, **slot_elem;
- dictIterator *dit = NULL;
- dictEntry *den;
- listIter *lit = NULL;
- listNode *lnode;
- cluster_node *table[REDIS_CLUSTER_SLOTS];
- uint32_t j, k;
-
- if(cc == NULL){
- return REDIS_ERR;
- }
-
- if(ip == NULL || port <= 0){
- __redisClusterSetError(cc,
- REDIS_ERR_OTHER,"Ip or port error!");
- goto error;
- }
-
- if(cc->timeout){
- c = redisConnectWithTimeout(ip, port, *cc->timeout);
- }else{
- c = redisConnect(ip, port);
- }
-
- if (c == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "Init redis context error(return NULL)");
- goto error;
- }else if(c->err){
- __redisClusterSetError(cc,c->err,c->errstr);
- goto error;
- }
-
- if(cc->flags & HIRCLUSTER_FLAG_ROUTE_USE_SLOTS){
- reply = redisCommand(c, REDIS_COMMAND_CLUSTER_SLOTS);
- if(reply == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "Command(cluster slots) reply error(NULL).");
- goto error;
- }else if(reply->type != REDIS_REPLY_ARRAY){
- if(reply->type == REDIS_REPLY_ERROR){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- reply->str);
- }else{
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "Command(cluster slots) reply error: type is not array.");
- }
-
- goto error;
- }
-
- nodes = parse_cluster_slots(cc, reply, cc->flags);
- }else{
- reply = redisCommand(c, REDIS_COMMAND_CLUSTER_NODES);
- if(reply == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "Command(cluster nodes) reply error(NULL).");
- goto error;
- }else if(reply->type != REDIS_REPLY_STRING){
- if(reply->type == REDIS_REPLY_ERROR){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- reply->str);
- }else{
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "Command(cluster nodes) reply error: type is not string.");
- }
-
- goto error;
- }
-
- nodes = parse_cluster_nodes(cc, reply->str, reply->len, cc->flags);
- }
-
- if(nodes == NULL){
- goto error;
- }
-
- memset(table, 0, REDIS_CLUSTER_SLOTS*sizeof(cluster_node *));
-
- slots = hiarray_create(dictSize(nodes), sizeof(cluster_slot*));
- if(slots == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "Slots array create failed: out of memory");
- goto error;
- }
-
- dit = dictGetIterator(nodes);
- if(dit == NULL){
- __redisClusterSetError(cc,REDIS_ERR_OOM,
- "Dict get iterator failed: out of memory");
- goto error;
- }
-
- while((den = dictNext(dit))){
- master = dictGetEntryVal(den);
- if(master->role != REDIS_ROLE_MASTER){
- __redisClusterSetError(cc,REDIS_ERR_OOM,
- "Node role must be master");
- goto error;
- }
-
- if(master->slots == NULL){
- continue;
- }
-
- lit = listGetIterator(master->slots, AL_START_HEAD);
- if(lit == NULL){
- __redisClusterSetError(cc, REDIS_ERR_OOM,
- "List get iterator failed: out of memory");
- goto error;
- }
-
- while((lnode = listNext(lit))){
- slot = listNodeValue(lnode);
- if(slot->start > slot->end ||
- slot->end >= REDIS_CLUSTER_SLOTS){
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "Slot region for node is error");
- goto error;
- }
-
- slot_elem = hiarray_push(slots);
- *slot_elem = slot;
- }
-
- listReleaseIterator(lit);
- }
-
- dictReleaseIterator(dit);
-
- hiarray_sort(slots, cluster_slot_start_cmp);
- for(j = 0; j < hiarray_n(slots); j ++){
- slot_elem = hiarray_get(slots, j);
-
- for(k = (*slot_elem)->start; k <= (*slot_elem)->end; k ++){
- if(table[k] != NULL){
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "Diffent node hold a same slot");
- goto error;
- }
-
- table[k] = (*slot_elem)->node;
- }
- }
-
- cluster_nodes_swap_ctx(cc->nodes, nodes);
- if(cc->nodes != NULL){
- dictRelease(cc->nodes);
- cc->nodes = NULL;
- }
- cc->nodes = nodes;
-
- if(cc->slots != NULL)
- {
- cc->slots->nelem = 0;
- hiarray_destroy(cc->slots);
- cc->slots = NULL;
- }
- cc->slots = slots;
-
- memcpy(cc->table, table, REDIS_CLUSTER_SLOTS*sizeof(cluster_node *));
- cc->route_version ++;
-
- freeReplyObject(reply);
-
- if(c != NULL){
- redisFree(c);
- }
-
- return REDIS_OK;
-
-error:
-
- if(dit != NULL){
- dictReleaseIterator(dit);
- }
-
- if(lit != NULL){
- listReleaseIterator(lit);
- }
-
- if(slots != NULL)
- {
- if(slots == cc->slots)
- {
- cc->slots = NULL;
- }
-
- slots->nelem = 0;
- hiarray_destroy(slots);
- }
-
- if(nodes != NULL){
- if(nodes == cc->nodes){
- cc->nodes = NULL;
- }
-
- dictRelease(nodes);
- }
-
- if(reply != NULL){
- freeReplyObject(reply);
- reply = NULL;
- }
-
- if(c != NULL){
- redisFree(c);
- }
-
- return REDIS_ERR;
-}
-
-
-/**
- * Update route with the "cluster nodes" command reply.
- */
-static int
-cluster_update_route_with_nodes_old(redisClusterContext *cc,
- const char *ip, int port)
-{
- int ret;
- redisContext *c = NULL;
- redisReply *reply = NULL;
- struct hiarray *slots = NULL;
- dict *nodes = NULL;
- dict *nodes_name = NULL;
- cluster_node *master, *slave;
- cluster_slot **slot;
- char *pos, *start, *end, *line_start, *line_end;
- char *role;
- int role_len;
- uint8_t myself = 0;
- int slot_start, slot_end;
- sds *part = NULL, *slot_start_end = NULL;
- int count_part = 0, count_slot_start_end = 0;
- int j, k;
- int len;
- cluster_node *table[REDIS_CLUSTER_SLOTS] = {NULL};
-
- if(cc == NULL)
- {
- return REDIS_ERR;
- }
-
- if(ip == NULL || port <= 0)
- {
- __redisClusterSetError(cc,
- REDIS_ERR_OTHER,"ip or port error!");
- goto error;
- }
-
- if(cc->timeout)
- {
- c = redisConnectWithTimeout(ip, port, *cc->timeout);
- }
- else
- {
- c = redisConnect(ip, port);
- }
-
- if (c == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "init redis context error(return NULL)");
- goto error;
- }
- else if(c->err)
- {
- __redisClusterSetError(cc,c->err,c->errstr);
- goto error;
- }
-
- reply = redisCommand(c, REDIS_COMMAND_CLUSTER_NODES);
-
- if(reply == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "command(cluster nodes) reply error(NULL)");
- goto error;
- }
- else if(reply->type != REDIS_REPLY_STRING)
- {
- if(reply->type == REDIS_REPLY_ERROR)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- reply->str);
- }
- else
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "command(cluster nodes) reply error(type is not string)");
- }
-
- goto error;
- }
-
- nodes = dictCreate(&clusterNodesDictType, NULL);
-
- slots = hiarray_create(10, sizeof(cluster_slot*));
- if(slots == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "array create error");
- goto error;
- }
-
- start = reply->str;
- end = start + reply->len;
-
- line_start = start;
-
- for(pos = start; pos < end; pos ++)
- {
- if(*pos == '\n')
- {
- line_end = pos - 1;
- len = line_end - line_start;
-
- part = sdssplitlen(line_start, len + 1, " ", 1, &count_part);
-
- if(part == NULL || count_part < 8)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "split cluster nodes error");
- goto error;
- }
-
- //the address string is ":0", skip this node.
- if(sdslen(part[1]) == 2 && strcmp(part[1], ":0") == 0)
- {
- sdsfreesplitres(part, count_part);
- count_part = 0;
- part = NULL;
-
- start = pos + 1;
- line_start = start;
- pos = start;
-
- continue;
- }
-
- if(sdslen(part[2]) >= 7 && memcmp(part[2], "myself,", 7) == 0)
- {
- role_len = sdslen(part[2]) - 7;
- role = part[2] + 7;
- myself = 1;
- }
- else
- {
- role_len = sdslen(part[2]);
- role = part[2];
- }
-
- //add master node
- if(role_len >= 6 && memcmp(role, "master", 6) == 0)
- {
- if(count_part < 8)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "master node part number error");
- goto error;
- }
-
- master = node_get_with_nodes(cc,
- part, count_part, REDIS_ROLE_MASTER);
- if(master == NULL)
- {
- goto error;
- }
-
- ret = dictAdd(nodes,
- sdsnewlen(master->addr, sdslen(master->addr)), master);
- if(ret != DICT_OK)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "the address already exists in the nodes");
- cluster_node_deinit(master);
- hi_free(master);
- goto error;
- }
-
- if(cc->flags & HIRCLUSTER_FLAG_ADD_SLAVE)
- {
- ret = cluster_master_slave_mapping_with_name(cc,
- &nodes_name, master, master->name);
- if(ret != REDIS_OK)
- {
- cluster_node_deinit(master);
- hi_free(master);
- goto error;
- }
- }
-
- if(myself == 1)
- {
- master->con = c;
- c = NULL;
- }
-
- for(k = 8; k < count_part; k ++)
- {
- slot_start_end = sdssplitlen(part[k],
- sdslen(part[k]), "-", 1, &count_slot_start_end);
-
- if(slot_start_end == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "split slot start end error(NULL)");
- goto error;
- }
- else if(count_slot_start_end == 1)
- {
- slot_start =
- hi_atoi(slot_start_end[0], sdslen(slot_start_end[0]));
- slot_end = slot_start;
- }
- else if(count_slot_start_end == 2)
- {
- slot_start =
- hi_atoi(slot_start_end[0], sdslen(slot_start_end[0]));;
- slot_end =
- hi_atoi(slot_start_end[1], sdslen(slot_start_end[1]));;
- }
- else
- {
- slot_start = -1;
- slot_end = -1;
- }
-
- sdsfreesplitres(slot_start_end, count_slot_start_end);
- count_slot_start_end = 0;
- slot_start_end = NULL;
-
- if(slot_start < 0 || slot_end < 0 ||
- slot_start > slot_end || slot_end >= REDIS_CLUSTER_SLOTS)
- {
- continue;
- }
-
- for(j = slot_start; j <= slot_end; j ++)
- {
- if(table[j] != NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "diffent node hold a same slot");
- goto error;
- }
- table[j] = master;
- }
-
- slot = hiarray_push(slots);
- if(slot == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "slot push in array error");
- goto error;
- }
-
- *slot = cluster_slot_create(master);
- if(*slot == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,
- "Out of memory");
- goto error;
- }
-
- (*slot)->start = (uint32_t)slot_start;
- (*slot)->end = (uint32_t)slot_end;
- }
-
- }
- //add slave node
- else if((cc->flags & HIRCLUSTER_FLAG_ADD_SLAVE) &&
- (role_len >= 5 && memcmp(role, "slave", 5) == 0))
- {
- slave = node_get_with_nodes(cc, part,
- count_part, REDIS_ROLE_SLAVE);
- if(slave == NULL)
- {
- goto error;
- }
-
- ret = cluster_master_slave_mapping_with_name(cc,
- &nodes_name, slave, part[3]);
- if(ret != REDIS_OK)
- {
- cluster_node_deinit(slave);
- hi_free(slave);
- goto error;
- }
-
- if(myself == 1)
- {
- slave->con = c;
- c = NULL;
- }
- }
-
- if(myself == 1)
- {
- myself = 0;
- }
-
- sdsfreesplitres(part, count_part);
- count_part = 0;
- part = NULL;
-
- start = pos + 1;
- line_start = start;
- pos = start;
- }
- }
-
- if(cc->slots != NULL)
- {
- cc->slots->nelem = 0;
- hiarray_destroy(cc->slots);
- cc->slots = NULL;
- }
- cc->slots = slots;
-
- cluster_nodes_swap_ctx(cc->nodes, nodes);
-
- if(cc->nodes != NULL)
- {
- dictRelease(cc->nodes);
- cc->nodes = NULL;
- }
- cc->nodes = nodes;
-
- hiarray_sort(cc->slots, cluster_slot_start_cmp);
-
- memcpy(cc->table, table, REDIS_CLUSTER_SLOTS*sizeof(cluster_node *));
- cc->route_version ++;
-
- freeReplyObject(reply);
-
- if(c != NULL)
- {
- redisFree(c);
- }
-
- if(nodes_name != NULL)
- {
- dictRelease(nodes_name);
- }
-
- return REDIS_OK;
-
-error:
-
- if(part != NULL)
- {
- sdsfreesplitres(part, count_part);
- count_part = 0;
- part = NULL;
- }
-
- if(slot_start_end != NULL)
- {
- sdsfreesplitres(slot_start_end, count_slot_start_end);
- count_slot_start_end = 0;
- slot_start_end = NULL;
- }
-
- if(slots != NULL)
- {
- if(slots == cc->slots)
- {
- cc->slots = NULL;
- }
-
- slots->nelem = 0;
- hiarray_destroy(slots);
- }
-
- if(nodes != NULL)
- {
- if(nodes == cc->nodes)
- {
- cc->nodes = NULL;
- }
-
- dictRelease(nodes);
- }
-
- if(nodes_name != NULL)
- {
- dictRelease(nodes_name);
- }
-
- if(reply != NULL)
- {
- freeReplyObject(reply);
- reply = NULL;
- }
-
- if(c != NULL)
- {
- redisFree(c);
- }
-
- return REDIS_ERR;
-}
-
-int
-cluster_update_route(redisClusterContext *cc)
-{
- int ret;
- int flag_err_not_set = 1;
- cluster_node *node;
- dictIterator *it;
- dictEntry *de;
-
- if(cc == NULL)
- {
- return REDIS_ERR;
- }
-
- if(cc->ip != NULL && cc->port > 0)
- {
- ret = cluster_update_route_by_addr(cc, cc->ip, cc->port);
- if(ret == REDIS_OK)
- {
- return REDIS_OK;
- }
-
- flag_err_not_set = 0;
- }
-
- if(cc->nodes == NULL)
- {
- if(flag_err_not_set)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER, "no server address");
- }
-
- return REDIS_ERR;
- }
-
- it = dictGetIterator(cc->nodes);
- while ((de = dictNext(it)) != NULL)
- {
- node = dictGetEntryVal(de);
- if(node == NULL || node->host == NULL || node->port < 0)
- {
- continue;
- }
-
- ret = cluster_update_route_by_addr(cc, node->host, node->port);
- if(ret == REDIS_OK)
- {
- if(cc->err)
- {
- cc->err = 0;
- memset(cc->errstr, '\0', strlen(cc->errstr));
- }
-
- dictReleaseIterator(it);
- return REDIS_OK;
- }
-
- flag_err_not_set = 0;
- }
-
- dictReleaseIterator(it);
-
- if(flag_err_not_set)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER, "no valid server address");
- }
-
- return REDIS_ERR;
-}
-
-static void print_cluster_node_list(redisClusterContext *cc)
-{
- dictIterator *di = NULL;
- dictEntry *de;
- listIter *it;
- listNode *ln;
- cluster_node *master, *slave;
- hilist *slaves;
-
- if(cc == NULL)
- {
- return;
- }
-
- di = dictGetIterator(cc->nodes);
-
- printf("name\taddress\trole\tslaves\n");
-
- while((de = dictNext(di)) != NULL) {
- master = dictGetEntryVal(de);
-
- printf("%s\t%s\t%d\t%s\n",master->name, master->addr,
- master->role, master->slaves?"hava":"null");
-
- slaves = master->slaves;
- if(slaves == NULL)
- {
- continue;
- }
-
- it = listGetIterator(slaves, AL_START_HEAD);
- while((ln = listNext(it)) != NULL)
- {
- slave = listNodeValue(ln);
- printf("%s\t%s\t%d\t%s\n",slave->name, slave->addr,
- slave->role, slave->slaves?"hava":"null");
- }
-
- listReleaseIterator(it);
-
- printf("\n");
- }
-}
-
-
-int test_cluster_update_route(redisClusterContext *cc)
-{
- int ret;
-
- ret = cluster_update_route(cc);
-
- //print_cluster_node_list(cc);
-
- return ret;
-}
-
-static redisClusterContext *redisClusterContextInit(void) {
- redisClusterContext *cc;
-
- cc = calloc(1,sizeof(redisClusterContext));
- if (cc == NULL)
- return NULL;
-
- cc->uni_ipfrag = NULL;
- cc->ipfrag_count = 0;
- cc->err = 0;
- cc->errstr[0] = '\0';
- cc->ip = NULL;
- cc->port = 0;
- cc->flags = 0;
- cc->timeout = NULL;
- cc->nodes = NULL;
- cc->slots = NULL;
- cc->max_redirect_count = CLUSTER_DEFAULT_MAX_REDIRECT_COUNT;
- cc->retry_count = 0;
- cc->requests = NULL;
- cc->need_update_route = 0;
- cc->update_route_time = 0LL;
-
- cc->route_version = 0LL;
-
- memset(cc->table, 0, REDIS_CLUSTER_SLOTS*sizeof(cluster_node *));
-
- return cc;
-}
-
-void redisClusterFree(redisClusterContext *cc) {
-
- if (cc == NULL)
- return;
-
- if(cc->uni_ipfrag)
- {
- sdsfreesplitres(cc->uni_ipfrag, cc->ipfrag_count);
- }
- if(cc->ip)
- {
- sdsfree(cc->ip);
- cc->ip = NULL;
- }
-
- if (cc->timeout)
- {
- free(cc->timeout);
- }
-
- memset(cc->table, 0, REDIS_CLUSTER_SLOTS*sizeof(cluster_node *));
-
- if(cc->slots != NULL)
- {
- cc->slots->nelem = 0;
- hiarray_destroy(cc->slots);
- cc->slots = NULL;
- }
-
- if(cc->nodes != NULL)
- {
- dictRelease(cc->nodes);
- }
-
- if(cc->requests != NULL)
- {
- listRelease(cc->requests);
- }
-
- free(cc);
-}
-
-static int redisClusterAddNode(redisClusterContext *cc, const char *addr)
-{
- dictEntry *node_entry;
- cluster_node *node;
- sds *ip_port = NULL;
- int ip_port_count = 0;
- sds ip;
- int port;
-
- if(cc == NULL)
- {
- return REDIS_ERR;
- }
-
- if(cc->nodes == NULL)
- {
- cc->nodes = dictCreate(&clusterNodesDictType, NULL);
- if(cc->nodes == NULL)
- {
- return REDIS_ERR;
- }
- }
-
- node_entry = dictFind(cc->nodes, addr);
- if(node_entry == NULL)
- {
- ip_port = sdssplitlen(addr, strlen(addr),
- IP_PORT_SEPARATOR, strlen(IP_PORT_SEPARATOR), &ip_port_count);
- if(ip_port == NULL || ip_port_count != 2 ||
- sdslen(ip_port[0]) <= 0 || sdslen(ip_port[1]) <= 0)
- {
- if(ip_port != NULL)
- {
- sdsfreesplitres(ip_port, ip_port_count);
- }
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"server address is error(correct is like: 127.0.0.1:1234)");
- return REDIS_ERR;
- }
-
- ip = ip_port[0];
- port = hi_atoi(ip_port[1], sdslen(ip_port[1]));
-
- if(port <= 0)
- {
- sdsfreesplitres(ip_port, ip_port_count);
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"server port is error");
- return REDIS_ERR;
- }
-
- sdsfree(ip_port[1]);
- free(ip_port);
- ip_port = NULL;
-
- node = hi_alloc(sizeof(cluster_node));
- if(node == NULL)
- {
- sdsfree(ip);
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"alloc cluster node error");
- return REDIS_ERR;
- }
-
- cluster_node_init(node);
-
- node->addr = sdsnew(addr);
- if(node->addr == NULL)
- {
- sdsfree(ip);
- hi_free(node);
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"new node address error");
- return REDIS_ERR;
- }
-
- node->host = ip;
- node->port = port;
-
- dictAdd(cc->nodes, sdsnewlen(node->addr, sdslen(node->addr)), node);
- }
-
- return REDIS_OK;
-}
-
-
-/* Connect to a Redis cluster. 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. */
-static redisClusterContext *_redisClusterConnect(redisClusterContext *cc, const char *addrs) {
-
- int ret;
- sds *address = NULL;
- int address_count = 0;
- int i;
-
- if(cc == NULL)
- {
- return NULL;
- }
-
-
- address = sdssplitlen(addrs, strlen(addrs), CLUSTER_ADDRESS_SEPARATOR,
- strlen(CLUSTER_ADDRESS_SEPARATOR), &address_count);
- if(address == NULL || address_count <= 0)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"servers address is error(correct is like: 127.0.0.1:1234,127.0.0.2:5678)");
- return cc;
- }
-
- for(i = 0; i < address_count; i ++)
- {
- ret = redisClusterAddNode(cc, address[i]);
- if(ret != REDIS_OK)
- {
- sdsfreesplitres(address, address_count);
- return cc;
- }
- }
-
- sdsfreesplitres(address, address_count);
-
- cluster_update_route(cc);
-
- return cc;
-}
-
-redisClusterContext *redisClusterConnect(const char *addrs, int flags)
-{
- redisClusterContext *cc;
-
- cc = redisClusterContextInit();
-
- if(cc == NULL)
- {
- return NULL;
- }
-
- cc->flags |= REDIS_BLOCK;
- if(flags)
- {
- cc->flags |= flags;
- }
-
- return _redisClusterConnect(cc, addrs);
-}
-
-redisClusterContext *redisClusterConnectWithTimeout(
- const char *addrs, const struct timeval tv, int flags)
-{
- redisClusterContext *cc;
-
- cc = redisClusterContextInit();
-
- if(cc == NULL)
- {
- return NULL;
- }
-
- cc->flags |= REDIS_BLOCK;
- if(flags)
- {
- cc->flags |= flags;
- }
-
- if (cc->timeout == NULL)
- {
- cc->timeout = malloc(sizeof(struct timeval));
- }
-
- memcpy(cc->timeout, &tv, sizeof(struct timeval));
-
- return _redisClusterConnect(cc, addrs);
-}
-
-redisClusterContext *redisClusterConnectNonBlock(const char *addrs, int flags) {
-
- redisClusterContext *cc;
-
- cc = redisClusterContextInit();
-
- if(cc == NULL)
- {
- return NULL;
- }
-
- cc->flags &= ~REDIS_BLOCK;
- if(flags)
- {
- cc->flags |= flags;
- }
-
- return _redisClusterConnect(cc, addrs);
-}
-
-redisContext *ctx_get_by_node(redisClusterContext *cc, cluster_node *m_node,
- const struct timeval *timeout, int flags)
-{
- cluster_node *slave;
- int fragNum;
- sds *ipFrag;
- char *uniqIP;
- listNode *list_node;
- cluster_node *node = m_node;
- redisContext *c = NULL;
-
- if(node == NULL)
- {
- return NULL;
- }
-
- if(flags & HIRCLUSTER_FLAG_ADD_SLAVE && node->slaves != NULL)
- {
- listIter *iter = listGetIterator(node->slaves, AL_START_HEAD);
- int i;
- while((list_node = listNext(iter)) != NULL)
- {
- slave = (cluster_node *)list_node->value;
- ipFrag = sdssplitlen(slave->host, sdslen(slave->host), ".", 1, &fragNum);
- if(cc->flags & HIRCLUSTER_FLAG_UNIQIP_FRAG_ONE)
- uniqIP = ipFrag[0];
- else if(cc->flags & HIRCLUSTER_FLAG_UNIQIP_FRAG_TWO)
- uniqIP = ipFrag[1];
- else if(cc->flags & HIRCLUSTER_FLAG_UNIQIP_FRAG_THREE)
- uniqIP = ipFrag[2];
- else
- uniqIP = ipFrag[3];
-
- for(i = 0; i < cc->ipfrag_count; i++)
- {
- if(strcmp(uniqIP, cc->uni_ipfrag[i]) == 0)
- {
- node = slave;
- if(node->con == NULL || node->con->err)
- node = m_node;
- sdsfreesplitres(ipFrag, fragNum);
- goto Done;
- }
- }
- sdsfreesplitres(ipFrag, fragNum);
- }
-Done:
- listReleaseIterator(iter);
- }
-
- c = node->con;
- if(c != NULL)
- {
- if(c->err)
- {
- redisReconnect(c);
- }
-
- return c;
- }
-
- if(node->host == NULL || node->port <= 0)
- {
- return NULL;
- }
-
- if(flags & REDIS_BLOCK)
- {
- if(timeout)
- {
- c = redisConnectWithTimeout(node->host, node->port, *timeout);
- }
- else
- {
- c = redisConnect(node->host, node->port);
- }
- }
- else
- {
- c = redisConnectNonBlock(node->host, node->port);
- }
-
- node->con = c;
-
- return c;
-}
-
-static cluster_node *node_get_by_slot(redisClusterContext *cc, uint32_t slot_num)
-{
- struct hiarray *slots;
- uint32_t slot_count;
- cluster_slot **slot;
- uint32_t middle, start, end;
- uint8_t stop = 0;
-
- if(cc == NULL)
- {
- return NULL;
- }
-
- if(slot_num >= REDIS_CLUSTER_SLOTS)
- {
- return NULL;
- }
-
- slots = cc->slots;
- if(slots == NULL)
- {
- return NULL;
- }
- slot_count = hiarray_n(slots);
-
- start = 0;
- end = slot_count - 1;
- middle = 0;
-
- do{
- if(start >= end)
- {
- stop = 1;
- middle = end;
- }
- else
- {
- middle = start + (end - start)/2;
- }
-
- ASSERT(middle >= 0 && middle < slot_count);
-
- slot = hiarray_get(slots, middle);
- if((*slot)->start > slot_num)
- {
- end = middle - 1;
- }
- else if((*slot)->end < slot_num)
- {
- start = middle + 1;
- }
- else
- {
- return (*slot)->node;
- }
-
-
- }while(!stop);
-
- printf("slot_num : %d\n", slot_num);
- printf("slot_count : %d\n", slot_count);
- printf("start : %d\n", start);
- printf("end : %d\n", end);
- printf("middle : %d\n", middle);
-
- return NULL;
-}
-
-
-static cluster_node *node_get_by_table(redisClusterContext *cc, uint32_t slot_num)
-{
- if(cc == NULL)
- {
- return NULL;
- }
-
- if(slot_num >= REDIS_CLUSTER_SLOTS)
- {
- return NULL;
- }
-
- return cc->table[slot_num];
-
-}
-
-static cluster_node *node_get_witch_connected(redisClusterContext *cc)
-{
- dictIterator *di;
- dictEntry *de;
- struct cluster_node *node;
- redisContext *c = NULL;
- redisReply *reply = NULL;
-
- if(cc == NULL || cc->nodes == NULL)
- {
- return NULL;
- }
-
- di = dictGetIterator(cc->nodes);
- while((de = dictNext(di)) != NULL)
- {
- node = dictGetEntryVal(de);
- if(node == NULL)
- {
- continue;
- }
-
- c = ctx_get_by_node(cc, node, cc->timeout, REDIS_BLOCK);
- if(c == NULL || c->err)
- {
- continue;
- }
-
- reply = redisCommand(c, REDIS_COMMAND_PING);
- if(reply != NULL && reply->type == REDIS_REPLY_STATUS &&
- reply->str != NULL && strcmp(reply->str, "PONG") == 0)
- {
- freeReplyObject(reply);
- reply = NULL;
-
- dictReleaseIterator(di);
-
- return node;
- }
- else if(reply != NULL)
- {
- freeReplyObject(reply);
- reply = NULL;
- }
- }
-
- dictReleaseIterator(di);
-
- return NULL;
-}
-
-static int slot_get_by_command(redisClusterContext *cc, char *cmd, int len)
-{
- struct cmd *command = NULL;
- struct keypos *kp;
- int key_count;
- uint32_t i;
- int slot_num = -1;
-
- if(cc == NULL || cmd == NULL || len <= 0)
- {
- goto done;
- }
-
- command = command_get();
- if(command == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- goto done;
- }
-
- command->cmd = cmd;
- command->clen = len;
- redis_parse_cmd(command);
- if(command->result != CMD_PARSE_OK)
- {
- __redisClusterSetError(cc, REDIS_ERR_PROTOCOL, "parse command error");
- goto done;
- }
-
- key_count = hiarray_n(command->keys);
-
- if(key_count <= 0)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER, "no keys in command(must have keys for redis cluster mode)");
- goto done;
- }
- else if(key_count == 1)
- {
- kp = hiarray_get(command->keys, 0);
- slot_num = keyHashSlot(kp->start, kp->end - kp->start);
-
- goto done;
- }
-
- for(i = 0; i < hiarray_n(command->keys); i ++)
- {
- kp = hiarray_get(command->keys, i);
-
- slot_num = keyHashSlot(kp->start, kp->end - kp->start);
- }
-
-done:
-
- if(command != NULL)
- {
- command->cmd = NULL;
- command_destroy(command);
- }
-
- return slot_num;
-}
-
-/* Get the cluster config from one node.
- * Return value: config_value string must free by usr.
- */
-static char * cluster_config_get(redisClusterContext *cc,
- const char *config_name, int *config_value_len)
-{
- redisContext *c;
- cluster_node *node;
- redisReply *reply = NULL, *sub_reply;
- char *config_value = NULL;
-
- if(cc == NULL || config_name == NULL
- || config_value_len == NULL)
- {
- return NULL;
- }
-
- node = node_get_witch_connected(cc);
- if(node == NULL)
- {
- __redisClusterSetError(cc,
- REDIS_ERR_OTHER, "no reachable node in cluster");
- goto error;
- }
-
- c = ctx_get_by_node(cc, node, cc->timeout, cc->flags);
-
- reply = redisCommand(c, "config get %s", config_name);
- if(reply == NULL)
- {
- __redisClusterSetError(cc,
- REDIS_ERR_OTHER, "reply for config get is null");
- goto error;
- }
-
- if(reply->type != REDIS_REPLY_ARRAY)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "reply for config get type is not array");
- goto error;
- }
-
- if(reply->elements != 2)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "reply for config get elements number is not 2");
- goto error;
- }
-
- sub_reply = reply->element[0];
- if(sub_reply == NULL || sub_reply->type != REDIS_REPLY_STRING)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "reply for config get config name is not string");
- goto error;
- }
-
- if(strcmp(sub_reply->str, config_name))
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "reply for config get config name is not we want");
- goto error;
- }
-
- sub_reply = reply->element[1];
- if(sub_reply == NULL || sub_reply->type != REDIS_REPLY_STRING)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "reply for config get config value type is not string");
- goto error;
- }
-
- config_value = sub_reply->str;
- *config_value_len = sub_reply->len;
- sub_reply->str= NULL;
-
- if(reply != NULL)
- {
- freeReplyObject(reply);
- }
-
- return config_value;
-
-error:
-
- if(reply != NULL)
- {
- freeReplyObject(reply);
- }
-
- return NULL;
-}
-
-/* Helper function for the redisClusterAppendCommand* family of functions.
- *
- * Write a formatted command to the output buffer. When this family
- * is used, you need to call redisGetReply yourself to retrieve
- * the reply (or replies in pub/sub).
- */
-static int __redisClusterAppendCommand(redisClusterContext *cc,
- struct cmd *command) {
-
- cluster_node *node;
- redisContext *c = NULL;
-
- if(cc == NULL || command == NULL)
- {
- return REDIS_ERR;
- }
-
- node = node_get_by_table(cc, (uint32_t)command->slot_num);
- if(node == NULL)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER, "node get by slot error");
- return REDIS_ERR;
- }
-
- c = ctx_get_by_node(cc, node,cc->timeout, cc->flags);
- if(c == NULL)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER, "ctx get by node is null");
- return REDIS_ERR;
- }
- else if(c->err)
- {
- __redisClusterSetError(cc, c->err, c->errstr);
- return REDIS_ERR;
- }
-
- if (__redisAppendCommand(c, command->cmd, command->clen) != REDIS_OK)
- {
- __redisClusterSetError(cc, c->err, c->errstr);
- return REDIS_ERR;
- }
-
- return REDIS_OK;
-}
-
-/* Helper function for the redisClusterGetReply* family of functions.
- */
-int __redisClusterGetReply(redisClusterContext *cc, int slot_num, void **reply)
-{
- cluster_node *node;
- redisContext *c;
-
- if(cc == NULL || slot_num < 0 || reply == NULL)
- {
- return REDIS_ERR;
- }
-
- node = node_get_by_table(cc, (uint32_t)slot_num);
- if(node == NULL)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER, "node get by table is null");
- return REDIS_ERR;
- }
-
- c = ctx_get_by_node(cc, node, cc->timeout, cc->flags);
- if(c == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- return REDIS_ERR;
- }
- else if(c->err)
- {
- if(cc->need_update_route == 0)
- {
- cc->retry_count ++;
- if(cc->retry_count > cc->max_redirect_count)
- {
- cc->need_update_route = 1;
- cc->retry_count = 0;
- }
- }
- __redisClusterSetError(cc, c->err, c->errstr);
- return REDIS_ERR;
- }
-
- if(redisGetReply(c, reply) != REDIS_OK)
- {
- __redisClusterSetError(cc, c->err, c->errstr);
- return REDIS_ERR;
- }
-
- if(cluster_reply_error_type(*reply) == CLUSTER_ERR_MOVED)
- {
- cc->need_update_route = 1;
- }
-
- return REDIS_OK;
-}
-
-static cluster_node *node_get_by_ask_error_reply(
- redisClusterContext *cc, redisReply *reply)
-{
- sds *part = NULL, *ip_port = NULL;
- int part_len = 0, ip_port_len;
- dictEntry *de;
- cluster_node *node = NULL;
-
- if(cc == NULL || reply == NULL)
- {
- return NULL;
- }
-
- if(cluster_reply_error_type(reply) != CLUSTER_ERR_ASK)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "reply is not ask error!");
- return NULL;
- }
-
- part = sdssplitlen(reply->str, reply->len, " ", 1, &part_len);
-
- if(part != NULL && part_len == 3)
- {
- ip_port = sdssplitlen(part[2], sdslen(part[2]),
- ":", 1, &ip_port_len);
-
- if(ip_port != NULL && ip_port_len == 2)
- {
- de = dictFind(cc->nodes, part[2]);
- if(de == NULL)
- {
- node = hi_alloc(sizeof(cluster_node));
- if(node == NULL)
- {
- __redisClusterSetError(cc,
- REDIS_ERR_OOM, "Out of memory");
-
- goto done;
- }
-
- cluster_node_init(node);
- node->addr = part[1];
- node->host = ip_port[0];
- node->port = hi_atoi(ip_port[1], sdslen(ip_port[1]));
- node->role = REDIS_ROLE_MASTER;
-
- dictAdd(cc->nodes, sdsnewlen(node->addr, sdslen(node->addr)), node);
-
- part = NULL;
- ip_port = NULL;
- }
- else
- {
- node = de->val;
-
- goto done;
- }
- }
- else
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "ask error reply address part parse error!");
-
- goto done;
- }
-
- }
- else
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "ask error reply parse error!");
-
- goto done;
- }
-
-done:
-
- if(part != NULL)
- {
- sdsfreesplitres(part, part_len);
- part = NULL;
- }
-
- if(ip_port != NULL)
- {
- sdsfreesplitres(ip_port, ip_port_len);
- ip_port = NULL;
- }
-
- return node;
-}
-
-static void *redis_cluster_command_execute(redisClusterContext *cc,
- struct cmd *command)
-{
- int ret;
- void *reply = NULL;
- cluster_node *node;
- redisContext *c = NULL;
- int error_type;
-
-retry:
-
- node = node_get_by_table(cc, (uint32_t)command->slot_num);
- if(node == NULL)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER, "node get by table error");
- return NULL;
- }
-
- c = ctx_get_by_node(cc, node, cc->timeout, cc->flags);
- if(c == NULL)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER, "ctx get by node is null");
- return NULL;
- }
- else if(c->err)
- {
- node = node_get_witch_connected(cc);
- if(node == NULL)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER, "no reachable node in cluster");
- return NULL;
- }
-
- cc->retry_count ++;
- if(cc->retry_count > cc->max_redirect_count)
- {
- __redisClusterSetError(cc, REDIS_ERR_CLUSTER_TOO_MANY_REDIRECT,
- "too many cluster redirect");
- return NULL;
- }
-
- c = ctx_get_by_node(cc, node, cc->timeout, cc->flags);
- if(c == NULL)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER, "ctx get by node error");
- return NULL;
- }
- else if(c->err)
- {
- __redisClusterSetError(cc, c->err, c->errstr);
- return NULL;
- }
- }
-
-ask_retry:
-
- if (__redisAppendCommand(c,command->cmd, command->clen) != REDIS_OK)
- {
- __redisClusterSetError(cc, c->err, c->errstr);
- return NULL;
- }
-
- reply = __redisBlockForReply(c);
- if(reply == NULL)
- {
- __redisClusterSetError(cc, c->err, c->errstr);
- return NULL;
- }
-
- error_type = cluster_reply_error_type(reply);
- if(error_type > CLUSTER_NOT_ERR && error_type < CLUSTER_ERR_SENTINEL)
- {
- cc->retry_count ++;
- if(cc->retry_count > cc->max_redirect_count)
- {
- __redisClusterSetError(cc, REDIS_ERR_CLUSTER_TOO_MANY_REDIRECT,
- "too many cluster redirect");
- freeReplyObject(reply);
- return NULL;
- }
-
- switch(error_type)
- {
- case CLUSTER_ERR_MOVED:
- freeReplyObject(reply);
- reply = NULL;
- ret = cluster_update_route(cc);
- if(ret != REDIS_OK)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "route update error, please recreate redisClusterContext!");
- return NULL;
- }
-
- goto retry;
-
- break;
- case CLUSTER_ERR_ASK:
- node = node_get_by_ask_error_reply(cc, reply);
- if(node == NULL)
- {
- freeReplyObject(reply);
- return NULL;
- }
-
- freeReplyObject(reply);
- reply = NULL;
-
- c = ctx_get_by_node(cc, node, cc->timeout, cc->flags);
- if(c == NULL)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER, "ctx get by node error");
- return NULL;
- }
- else if(c->err)
- {
- __redisClusterSetError(cc, c->err, c->errstr);
- return NULL;
- }
-
- reply = redisCommand(c, REDIS_COMMAND_ASKING);
- if(reply == NULL)
- {
- __redisClusterSetError(cc, c->err, c->errstr);
- return NULL;
- }
-
- freeReplyObject(reply);
- reply = NULL;
-
- goto ask_retry;
-
- break;
- case CLUSTER_ERR_TRYAGAIN:
- case CLUSTER_ERR_CROSSSLOT:
- case CLUSTER_ERR_CLUSTERDOWN:
- freeReplyObject(reply);
- reply = NULL;
- goto retry;
-
- break;
- default:
-
- break;
- }
- }
-
- return reply;
-}
-
-static int command_pre_fragment(redisClusterContext *cc,
- struct cmd *command, hilist *commands)
-{
-
- struct keypos *kp, *sub_kp;
- uint32_t key_count;
- uint32_t i, j;
- uint32_t idx;
- uint32_t key_len;
- int slot_num = -1;
- struct cmd *sub_command;
- struct cmd **sub_commands = NULL;
- char num_str[12];
- uint8_t num_str_len;
-
-
- if(command == NULL || commands == NULL)
- {
- goto done;
- }
-
- key_count = hiarray_n(command->keys);
-
- sub_commands = hi_zalloc(REDIS_CLUSTER_SLOTS * sizeof(*sub_commands));
- if (sub_commands == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- goto done;
- }
-
- command->frag_seq = hi_alloc(key_count * sizeof(*command->frag_seq));
- if(command->frag_seq == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- goto done;
- }
-
-
- for(i = 0; i < key_count; i ++)
- {
- kp = hiarray_get(command->keys, i);
-
- slot_num = keyHashSlot(kp->start, kp->end - kp->start);
-
- if(slot_num < 0 || slot_num >= REDIS_CLUSTER_SLOTS)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"keyHashSlot return error");
- goto done;
- }
-
- if (sub_commands[slot_num] == NULL) {
- sub_commands[slot_num] = command_get();
- if (sub_commands[slot_num] == NULL) {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- slot_num = -1;
- goto done;
- }
- }
-
- command->frag_seq[i] = sub_command = sub_commands[slot_num];
-
- sub_command->narg++;
-
- sub_kp = hiarray_push(sub_command->keys);
- if (sub_kp == NULL) {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- slot_num = -1;
- goto done;
- }
-
- sub_kp->start = kp->start;
- sub_kp->end = kp->end;
-
- key_len = (uint32_t)(kp->end - kp->start);
-
- sub_command->clen += key_len + uint_len(key_len);
-
- sub_command->slot_num = slot_num;
-
- if (command->type == CMD_REQ_REDIS_MSET) {
- uint32_t len = 0;
- char *p;
-
- for (p = sub_kp->end + 1; !isdigit(*p); p++){}
-
- p = sub_kp->end + 1;
- while(!isdigit(*p))
- {
- p ++;
- }
-
- for (; isdigit(*p); p++) {
- len = len * 10 + (uint32_t)(*p - '0');
- }
-
- len += CRLF_LEN * 2;
- len += (p - sub_kp->end);
- sub_kp->remain_len = len;
- sub_command->clen += len;
- }
- }
-
- for (i = 0; i < REDIS_CLUSTER_SLOTS; i++) { /* prepend command header */
- sub_command = sub_commands[i];
- if (sub_command == NULL) {
- continue;
- }
-
- idx = 0;
- if (command->type == CMD_REQ_REDIS_MGET) {
- //"*%d\r\n$4\r\nmget\r\n"
-
- sub_command->clen += 5*sub_command->narg;
-
- sub_command->narg ++;
-
- hi_itoa(num_str, sub_command->narg);
- num_str_len = (uint8_t)(strlen(num_str));
-
- sub_command->clen += 13 + num_str_len;
-
- sub_command->cmd = hi_zalloc(sub_command->clen * sizeof(*sub_command->cmd));
- if(sub_command->cmd == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- slot_num = -1;
- goto done;
- }
-
- sub_command->cmd[idx++] = '*';
- memcpy(sub_command->cmd + idx, num_str, num_str_len);
- idx += num_str_len;
- memcpy(sub_command->cmd + idx, "\r\n$4\r\nmget\r\n", 12);
- idx += 12;
-
- for(j = 0; j < hiarray_n(sub_command->keys); j ++)
- {
- kp = hiarray_get(sub_command->keys, j);
- key_len = (uint32_t)(kp->end - kp->start);
- hi_itoa(num_str, key_len);
- num_str_len = strlen(num_str);
-
- sub_command->cmd[idx++] = '$';
- memcpy(sub_command->cmd + idx, num_str, num_str_len);
- idx += num_str_len;
- memcpy(sub_command->cmd + idx, CRLF, CRLF_LEN);
- idx += CRLF_LEN;
- memcpy(sub_command->cmd + idx, kp->start, key_len);
- idx += key_len;
- memcpy(sub_command->cmd + idx, CRLF, CRLF_LEN);
- idx += CRLF_LEN;
- }
- } else if (command->type == CMD_REQ_REDIS_DEL) {
- //"*%d\r\n$3\r\ndel\r\n"
-
- sub_command->clen += 5*sub_command->narg;
-
- sub_command->narg ++;
-
- hi_itoa(num_str, sub_command->narg);
- num_str_len = (uint8_t)strlen(num_str);
-
- sub_command->clen += 12 + num_str_len;
-
- sub_command->cmd = hi_zalloc(sub_command->clen * sizeof(*sub_command->cmd));
- if(sub_command->cmd == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- slot_num = -1;
- goto done;
- }
-
- sub_command->cmd[idx++] = '*';
- memcpy(sub_command->cmd + idx, num_str, num_str_len);
- idx += num_str_len;
- memcpy(sub_command->cmd + idx, "\r\n$3\r\ndel\r\n", 11);
- idx += 11;
-
- for(j = 0; j < hiarray_n(sub_command->keys); j ++)
- {
- kp = hiarray_get(sub_command->keys, j);
- key_len = (uint32_t)(kp->end - kp->start);
- hi_itoa(num_str, key_len);
- num_str_len = strlen(num_str);
-
- sub_command->cmd[idx++] = '$';
- memcpy(sub_command->cmd + idx, num_str, num_str_len);
- idx += num_str_len;
- memcpy(sub_command->cmd + idx, CRLF, CRLF_LEN);
- idx += CRLF_LEN;
- memcpy(sub_command->cmd + idx, kp->start, key_len);
- idx += key_len;
- memcpy(sub_command->cmd + idx, CRLF, CRLF_LEN);
- idx += CRLF_LEN;
- }
- } else if (command->type == CMD_REQ_REDIS_MSET) {
- //"*%d\r\n$4\r\nmset\r\n"
-
- sub_command->clen += 3*sub_command->narg;
-
- sub_command->narg *= 2;
-
- sub_command->narg ++;
-
- hi_itoa(num_str, sub_command->narg);
- num_str_len = (uint8_t)strlen(num_str);
-
- sub_command->clen += 13 + num_str_len;
-
- sub_command->cmd = hi_zalloc(sub_command->clen * sizeof(*sub_command->cmd));
- if(sub_command->cmd == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- slot_num = -1;
- goto done;
- }
-
- sub_command->cmd[idx++] = '*';
- memcpy(sub_command->cmd + idx, num_str, num_str_len);
- idx += num_str_len;
- memcpy(sub_command->cmd + idx, "\r\n$4\r\nmset\r\n", 12);
- idx += 12;
-
- for(j = 0; j < hiarray_n(sub_command->keys); j ++)
- {
- kp = hiarray_get(sub_command->keys, j);
- key_len = (uint32_t)(kp->end - kp->start);
- hi_itoa(num_str, key_len);
- num_str_len = strlen(num_str);
-
- sub_command->cmd[idx++] = '$';
- memcpy(sub_command->cmd + idx, num_str, num_str_len);
- idx += num_str_len;
- memcpy(sub_command->cmd + idx, CRLF, CRLF_LEN);
- idx += CRLF_LEN;
- memcpy(sub_command->cmd + idx, kp->start, key_len + kp->remain_len);
- idx += key_len + kp->remain_len;
-
- }
- } else {
- NOT_REACHED();
- }
-
- //printf("len : %d\n", sub_command->clen);
- //print_string_with_length_fix_CRLF(sub_command->cmd, sub_command->clen);
-
- sub_command->type = command->type;
-
- listAddNodeTail(commands, sub_command);
- }
-
-done:
-
- if(sub_commands != NULL)
- {
- hi_free(sub_commands);
- }
-
- if(slot_num >= 0 && commands != NULL
- && listLength(commands) == 1)
- {
- listNode *list_node = listFirst(commands);
- command_destroy(list_node->value);
- listDelNode(commands, list_node);
- if(command->frag_seq)
- {
- hi_free(command->frag_seq);
- command->frag_seq = NULL;
- }
-
- command->slot_num = slot_num;
- }
-
- return slot_num;
-}
-
-static void *command_post_fragment(redisClusterContext *cc,
- struct cmd *command, hilist *commands)
-{
- struct cmd *sub_command;
- listNode *list_node;
- listIter *list_iter;
- redisReply *reply, *sub_reply;
- long long count = 0;
-
- list_iter = listGetIterator(commands, AL_START_HEAD);
- while((list_node = listNext(list_iter)) != NULL)
- {
- sub_command = list_node->value;
- reply = sub_command->reply;
- if(reply == NULL)
- {
- return NULL;
- }
- else if(reply->type == REDIS_REPLY_ERROR)
- {
- return reply;
- }
-
- if (command->type == CMD_REQ_REDIS_MGET) {
- if(reply->type != REDIS_REPLY_ARRAY)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"reply type is error(here only can be array)");
- return NULL;
- }
- }else if(command->type == CMD_REQ_REDIS_DEL){
- if(reply->type != REDIS_REPLY_INTEGER)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"reply type is error(here only can be integer)");
- return NULL;
- }
-
- count += reply->integer;
- }else if(command->type == CMD_REQ_REDIS_MSET){
- if(reply->type != REDIS_REPLY_STATUS ||
- reply->len != 2 || strcmp(reply->str, REDIS_STATUS_OK) != 0)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"reply type is error(here only can be status and ok)");
- return NULL;
- }
- }else {
- NOT_REACHED();
- }
- }
-
- reply = hi_calloc(1,sizeof(*reply));
-
- if (reply == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- return NULL;
- }
-
- if (command->type == CMD_REQ_REDIS_MGET) {
- int i;
- uint32_t key_count;
-
- reply->type = REDIS_REPLY_ARRAY;
-
- key_count = hiarray_n(command->keys);
-
- reply->elements = key_count;
- reply->element = hi_calloc(key_count, sizeof(*reply));
- if (reply->element == NULL) {
- freeReplyObject(reply);
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- return NULL;
- }
-
- for (i = key_count - 1; i >= 0; i--) { /* for each key */
- sub_reply = command->frag_seq[i]->reply; /* get it's reply */
- if (sub_reply == NULL) {
- freeReplyObject(reply);
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"sub reply is null");
- return NULL;
- }
-
- if(sub_reply->type == REDIS_REPLY_STRING)
- {
- reply->element[i] = sub_reply;
- }
- else if(sub_reply->type == REDIS_REPLY_ARRAY)
- {
- if(sub_reply->elements == 0)
- {
- freeReplyObject(reply);
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"sub reply elements error");
- return NULL;
- }
-
- reply->element[i] = sub_reply->element[sub_reply->elements - 1];
- sub_reply->elements --;
- }
- }
- }else if(command->type == CMD_REQ_REDIS_DEL){
- reply->type = REDIS_REPLY_INTEGER;
- reply->integer = count;
- }else if(command->type == CMD_REQ_REDIS_MSET){
- reply->type = REDIS_REPLY_STATUS;
- uint32_t str_len = strlen(REDIS_STATUS_OK);
- reply->str = hi_alloc((str_len + 1) * sizeof(char*));
- if(reply->str == NULL)
- {
- freeReplyObject(reply);
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- return NULL;
- }
-
- reply->len = str_len;
- memcpy(reply->str, REDIS_STATUS_OK, str_len);
- reply->str[str_len] = '\0';
- }else {
- NOT_REACHED();
- }
-
- return reply;
-}
-
-/*
- * Split the command into subcommands by slot
- *
- * Returns slot_num
- * If slot_num < 0 or slot_num >= REDIS_CLUSTER_SLOTS means this function runs error;
- * Otherwise if the commands > 1 , slot_num is the last subcommand slot number.
- */
-static int command_format_by_slot(redisClusterContext *cc,
- struct cmd *command, hilist *commands)
-{
- struct keypos *kp;
- int key_count;
- int slot_num = -1;
-
- if(cc == NULL || commands == NULL ||
- command == NULL ||
- command->cmd == NULL || command->clen <= 0)
- {
- goto done;
- }
-
-
- redis_parse_cmd(command);
- if(command->result == CMD_PARSE_ENOMEM)
- {
- __redisClusterSetError(cc, REDIS_ERR_PROTOCOL, "Parse command error: out of memory");
- goto done;
- }
- else if(command->result != CMD_PARSE_OK)
- {
- __redisClusterSetError(cc, REDIS_ERR_PROTOCOL, command->errstr);
- goto done;
- }
-
- key_count = hiarray_n(command->keys);
-
- if(key_count <= 0)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER, "No keys in command(must have keys for redis cluster mode)");
- goto done;
- }
- else if(key_count == 1)
- {
- kp = hiarray_get(command->keys, 0);
- slot_num = keyHashSlot(kp->start, kp->end - kp->start);
- command->slot_num = slot_num;
-
- goto done;
- }
-
- slot_num = command_pre_fragment(cc, command, commands);
-
-done:
-
- return slot_num;
-}
-
-
-void redisClusterSetMaxRedirect(redisClusterContext *cc, int max_redirect_count)
-{
- if(cc == NULL || max_redirect_count <= 0)
- {
- return;
- }
-
- cc->max_redirect_count = max_redirect_count;
-}
-
-void *redisClusterFormattedCommand(redisClusterContext *cc, char *cmd, int len) {
- redisReply *reply = NULL;
- int slot_num;
- struct cmd *command = NULL, *sub_command;
- hilist *commands = NULL;
- listNode *list_node;
- listIter *list_iter = NULL;
-
- if(cc == NULL)
- {
- return NULL;
- }
-
- if(cc->err)
- {
- cc->err = 0;
- memset(cc->errstr, '\0', strlen(cc->errstr));
- }
-
- command = command_get();
- if(command == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- return NULL;
- }
-
- command->cmd = cmd;
- command->clen = len;
-
- commands = listCreate();
- if(commands == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- goto error;
- }
-
- commands->free = listCommandFree;
-
- slot_num = command_format_by_slot(cc, command, commands);
-
- if(slot_num < 0)
- {
- goto error;
- }
- else if(slot_num >= REDIS_CLUSTER_SLOTS)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"slot_num is out of range");
- goto error;
- }
-
- //all keys belong to one slot
- if(listLength(commands) == 0)
- {
- reply = redis_cluster_command_execute(cc, command);
- goto done;
- }
-
- ASSERT(listLength(commands) != 1);
-
- list_iter = listGetIterator(commands, AL_START_HEAD);
- while((list_node = listNext(list_iter)) != NULL)
- {
- sub_command = list_node->value;
-
- reply = redis_cluster_command_execute(cc, sub_command);
- if(reply == NULL)
- {
- goto error;
- }
- else if(reply->type == REDIS_REPLY_ERROR)
- {
- goto done;
- }
-
- sub_command->reply = reply;
- }
-
- reply = command_post_fragment(cc, command, commands);
-
-done:
-
- command->cmd = NULL;
- command_destroy(command);
-
- if(commands != NULL)
- {
- listRelease(commands);
- }
-
- if(list_iter != NULL)
- {
- listReleaseIterator(list_iter);
- }
-
- cc->retry_count = 0;
-
- return reply;
-
-error:
-
- if(command != NULL)
- {
- command->cmd = NULL;
- command_destroy(command);
- }
-
- if(commands != NULL)
- {
- listRelease(commands);
- }
-
- if(list_iter != NULL)
- {
- listReleaseIterator(list_iter);
- }
-
- cc->retry_count = 0;
-
- return NULL;
-}
-
-void *redisClustervCommand(redisClusterContext *cc, const char *format, va_list ap) {
- redisReply *reply;
- char *cmd;
- int len;
-
- if(cc == NULL)
- {
- return NULL;
- }
-
- len = redisvFormatCommand(&cmd,format,ap);
-
- if (len == -1) {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- return NULL;
- } else if (len == -2) {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"Invalid format string");
- return NULL;
- }
-
- reply = redisClusterFormattedCommand(cc, cmd, len);
-
- free(cmd);
-
- return reply;
-}
-
-void *redisClusterCommand(redisClusterContext *cc, const char *format, ...) {
- va_list ap;
- redisReply *reply = NULL;
-
- va_start(ap,format);
- reply = redisClustervCommand(cc, format, ap);
- va_end(ap);
-
- return reply;
-}
-
-void *redisClusterCommandArgv(redisClusterContext *cc, int argc, const char **argv, const size_t *argvlen) {
- redisReply *reply = NULL;
- char *cmd;
- int len;
-
- len = redisFormatCommandArgv(&cmd,argc,argv,argvlen);
- if (len == -1) {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- return NULL;
- }
-
- reply = redisClusterFormattedCommand(cc, cmd, len);
-
- free(cmd);
-
- return reply;
-}
-
-int redisClusterAppendFormattedCommand(redisClusterContext *cc,
- char *cmd, int len) {
- int slot_num;
- struct cmd *command = NULL, *sub_command;
- hilist *commands = NULL;
- listNode *list_node;
- listIter *list_iter = NULL;
-
- if(cc->requests == NULL)
- {
- cc->requests = listCreate();
- if(cc->requests == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- goto error;
- }
-
- cc->requests->free = listCommandFree;
- }
-
- command = command_get();
- if(command == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- goto error;
- }
-
- command->cmd = cmd;
- command->clen = len;
-
- commands = listCreate();
- if(commands == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- goto error;
- }
-
- commands->free = listCommandFree;
-
- slot_num = command_format_by_slot(cc, command, commands);
-
- if(slot_num < 0)
- {
- goto error;
- }
- else if(slot_num >= REDIS_CLUSTER_SLOTS)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"slot_num is out of range");
- goto error;
- }
-
- //all keys belong to one slot
- if(listLength(commands) == 0)
- {
- if(__redisClusterAppendCommand(cc, command) == REDIS_OK)
- {
- goto done;
- }
- else
- {
- goto error;
- }
- }
-
- ASSERT(listLength(commands) != 1);
-
- list_iter = listGetIterator(commands, AL_START_HEAD);
- while((list_node = listNext(list_iter)) != NULL)
- {
- sub_command = list_node->value;
-
- if(__redisClusterAppendCommand(cc, sub_command) == REDIS_OK)
- {
- continue;
- }
- else
- {
- goto error;
- }
- }
-
-done:
-
- if(command->cmd != NULL)
- {
- command->cmd = NULL;
- }
- else
- {
- goto error;
- }
-
- if(commands != NULL)
- {
- if(listLength(commands) > 0)
- {
- command->sub_commands = commands;
- }
- else
- {
- listRelease(commands);
- }
- }
-
- if(list_iter != NULL)
- {
- listReleaseIterator(list_iter);
- }
-
- listAddNodeTail(cc->requests, command);
-
- return REDIS_OK;
-
-error:
-
- if(command != NULL)
- {
- command->cmd = NULL;
- command_destroy(command);
- }
-
- if(commands != NULL)
- {
- listRelease(commands);
- }
-
- if(list_iter != NULL)
- {
- listReleaseIterator(list_iter);
- }
-
- /* Attention: mybe here we must pop the
- sub_commands that had append to the nodes.
- But now we do not handle it. */
-
- return REDIS_ERR;
-}
-
-
-int redisClustervAppendCommand(redisClusterContext *cc,
- const char *format, va_list ap) {
- int ret;
- char *cmd;
- int len;
-
- len = redisvFormatCommand(&cmd,format,ap);
- if (len == -1) {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- return REDIS_ERR;
- } else if (len == -2) {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,"Invalid format string");
- return REDIS_ERR;
- }
-
- ret = redisClusterAppendFormattedCommand(cc, cmd, len);
-
- free(cmd);
-
- return ret;
-}
-
-int redisClusterAppendCommand(redisClusterContext *cc,
- const char *format, ...) {
-
- int ret;
- va_list ap;
-
- if(cc == NULL || format == NULL)
- {
- return REDIS_ERR;
- }
-
- va_start(ap,format);
- ret = redisClustervAppendCommand(cc, format, ap);
- va_end(ap);
-
- return ret;
-}
-
-int redisClusterAppendCommandArgv(redisClusterContext *cc,
- int argc, const char **argv, const size_t *argvlen) {
- int ret;
- char *cmd;
- int len;
-
- len = redisFormatCommandArgv(&cmd,argc,argv,argvlen);
- if (len == -1) {
- __redisClusterSetError(cc,REDIS_ERR_OOM,"Out of memory");
- return REDIS_ERR;
- }
-
- ret = redisClusterAppendFormattedCommand(cc, cmd, len);
-
- free(cmd);
-
- return ret;
-}
-
-static int redisCLusterSendAll(redisClusterContext *cc)
-{
- dictIterator *di;
- dictEntry *de;
- struct cluster_node *node;
- redisContext *c = NULL;
- int wdone = 0;
-
- if(cc == NULL || cc->nodes == NULL)
- {
- return REDIS_ERR;
- }
-
- di = dictGetIterator(cc->nodes);
- while((de = dictNext(di)) != NULL)
- {
- node = dictGetEntryVal(de);
- if(node == NULL)
- {
- continue;
- }
-
- c = ctx_get_by_node(cc, node, cc->timeout, cc->flags);
- if(c == NULL)
- {
- continue;
- }
-
- if (c->flags & REDIS_BLOCK) {
- /* Write until done */
- do {
- if (redisBufferWrite(c,&wdone) == REDIS_ERR)
- {
- dictReleaseIterator(di);
- return REDIS_ERR;
- }
- } while (!wdone);
- }
- }
-
- dictReleaseIterator(di);
-
- return REDIS_OK;
-}
-
-int redisClusterGetReply(redisClusterContext *cc, void **reply) {
-
- struct cmd *command, *sub_command;
- hilist *commands = NULL;
- listNode *list_command, *list_sub_command;
- listIter *list_iter;
- int slot_num;
- void *sub_reply;
-
- if(cc == NULL || cc->requests == NULL || reply == NULL)
- {
- return REDIS_ERR;
- }
-
- list_command = listFirst(cc->requests);
-
- //no more reply
- if(list_command == NULL)
- {
- *reply = NULL;
- return REDIS_OK;
- }
-
- command = list_command->value;
- if(command == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "command in the requests list is null");
- goto error;
- }
-
- slot_num = command->slot_num;
- if(slot_num >= 0)
- {
- listDelNode(cc->requests, list_command);
- return __redisClusterGetReply(cc, slot_num, reply);
- }
-
- commands = command->sub_commands;
- if(commands == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "sub_commands in command is null");
- goto error;
- }
-
- ASSERT(listLength(commands) != 1);
-
- list_iter = listGetIterator(commands, AL_START_HEAD);
- while((list_sub_command = listNext(list_iter)) != NULL)
- {
- sub_command = list_sub_command->value;
- if(sub_command == NULL)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "sub_command is null");
- goto error;
- }
-
- slot_num = sub_command->slot_num;
- if(slot_num < 0)
- {
- __redisClusterSetError(cc,REDIS_ERR_OTHER,
- "sub_command slot_num is less then zero");
- goto error;
- }
-
- if(__redisClusterGetReply(cc, slot_num, &sub_reply) != REDIS_OK)
- {
- goto error;
- }
-
- sub_command->reply = sub_reply;
- }
-
- *reply = command_post_fragment(cc, command, commands);
- if(*reply == NULL)
- {
- goto error;
- }
-
- listDelNode(cc->requests, list_command);
- return REDIS_OK;
-
-error:
-
- listDelNode(cc->requests, list_command);
- return REDIS_ERR;
-}
-
-void redisCLusterReset(redisClusterContext *cc)
-{
- redisContext *c = NULL;
- int status;
- void *reply;
-
- if(cc == NULL || cc->nodes == NULL)
- {
- return;
- }
-
- redisCLusterSendAll(cc);
-
- do{
- status = redisClusterGetReply(cc, &reply);
- if(status == REDIS_OK)
- {
- freeReplyObject(reply);
- }
- else
- {
- //redisReaderFree(c->reader);
- //c->reader = redisReaderCreate();
- break;
- }
- }
- while(reply != NULL);
-
- if(cc->requests)
- {
- listRelease(cc->requests);
- cc->requests = NULL;
- }
-
- if(cc->need_update_route)
- {
- status = cluster_update_route(cc);
- if(status != REDIS_OK)
- {
- __redisClusterSetError(cc, REDIS_ERR_OTHER,
- "route update error, please recreate redisClusterContext!");
- return;
- }
- cc->need_update_route = 0;
- }
-}
-
-/*############redis cluster async############*/
-
-/* We want the error field to be accessible directly instead of requiring
- * an indirection to the redisContext struct. */
-static void __redisClusterAsyncCopyError(redisClusterAsyncContext *acc) {
- if (!acc)
- return;
-
- redisClusterContext *cc = acc->cc;
- acc->err = cc->err;
- memcpy(acc->errstr, cc->errstr, 128);
-}
-
-static void __redisClusterAsyncSetError(redisClusterAsyncContext *acc,
- int type, const char *str) {
-
- size_t len;
-
- acc->err = type;
- if (str != NULL) {
- len = strlen(str);
- len = len < (sizeof(acc->errstr)-1) ? len : (sizeof(acc->errstr)-1);
- memcpy(acc->errstr,str,len);
- acc->errstr[len] = '\0';
- } else {
- /* Only REDIS_ERR_IO may lack a description! */
- assert(type == REDIS_ERR_IO);
- __redis_strerror_r(errno, acc->errstr, sizeof(acc->errstr));
- }
-}
-
-static redisClusterAsyncContext *redisClusterAsyncInitialize(redisClusterContext *cc) {
- redisClusterAsyncContext *acc;
-
- if(cc == NULL)
- {
- return NULL;
- }
-
- acc = hi_alloc(sizeof(redisClusterAsyncContext));
- if (acc == NULL)
- return NULL;
-
- acc->cc = cc;
-
- acc->err = 0;
- acc->data = NULL;
- acc->adapter = NULL;
- acc->attach_fn = NULL;
-
- acc->onConnect = NULL;
- acc->onDisconnect = NULL;
-
- return acc;
-}
-
-static cluster_async_data *cluster_async_data_get(void)
-{
- cluster_async_data *cad;
-
- cad = hi_alloc(sizeof(cluster_async_data));
- if(cad == NULL)
- {
- return NULL;
- }
-
- cad->acc = NULL;
- cad->node = NULL;
- cad->command = NULL;
- cad->callback = NULL;
- cad->privdata = NULL;
- cad->retry_count = 0;
-
- return cad;
-}
-
-static void cluster_async_data_free(cluster_async_data *cad)
-{
- if(cad == NULL)
- {
- return;
- }
-
- if(cad->command != NULL)
- {
- command_destroy(cad->command);
- }
-
- hi_free(cad);
- cad = NULL;
-}
-
-redisAsyncContext * actx_get_by_node(redisClusterAsyncContext *acc,
- cluster_node *node)
-{
- redisAsyncContext *ac;
-
- if(node == NULL)
- {
- return NULL;
- }
-
- ac = node->acon;
- if(ac != NULL)
- {
- if(ac->c.err == 0)
- {
- return ac;
- }
- }
-
- if(node->host == NULL || node->port <= 0)
- {
- __redisClusterAsyncSetError(acc, REDIS_ERR_OTHER, "node host or port is error");
- return NULL;
- }
-
- ac = redisAsyncConnect(node->host, node->port);
- if(ac == NULL)
- {
- __redisClusterAsyncSetError(acc, REDIS_ERR_OTHER, "node host or port is error");
- return NULL;
- }
-
- if(acc->adapter)
- {
- acc->attach_fn(ac, acc->adapter);
- }
-
- if(acc->onConnect)
- {
- redisAsyncSetConnectCallback(ac, acc->onConnect);
- }
-
- if(acc->onDisconnect)
- {
- redisAsyncSetDisconnectCallback(ac, acc->onDisconnect);
- }
-
- node->acon = ac;
-
- return ac;
-}
-
-static redisAsyncContext *actx_get_after_update_route_by_slot(
- redisClusterAsyncContext *acc, int slot_num)
-{
- int ret;
- redisClusterContext *cc;
- redisAsyncContext *ac;
- cluster_node *node;
-
- if(acc == NULL || slot_num < 0)
- {
- return NULL;
- }
-
- cc = acc->cc;
- if(cc == NULL)
- {
- return NULL;
- }
-
- ret = cluster_update_route(cc);
- if(ret != REDIS_OK)
- {
- __redisClusterAsyncSetError(acc, REDIS_ERR_OTHER,
- "route update error, please recreate redisClusterContext!");
- return NULL;
- }
-
- node = node_get_by_table(cc, (uint32_t)slot_num);
- if(node == NULL)
- {
- __redisClusterAsyncSetError(acc,
- REDIS_ERR_OTHER, "node get by table error");
- return NULL;
- }
-
- ac = actx_get_by_node(acc, node);
- if(ac == NULL)
- {
- __redisClusterAsyncSetError(acc,
- REDIS_ERR_OTHER, "actx get by node error");
- return NULL;
- }
- else if(ac->err)
- {
- __redisClusterAsyncSetError(acc, ac->err, ac->errstr);
- return NULL;
- }
-
- return ac;
-}
-
-redisClusterAsyncContext *redisClusterAsyncConnect(const char *addrs, int flags) {
-
- redisClusterContext *cc;
- redisClusterAsyncContext *acc;
-
- cc = redisClusterConnectNonBlock(addrs, flags);
- if(cc == NULL)
- {
- return NULL;
- }
-
- acc = redisClusterAsyncInitialize(cc);
- if (acc == NULL) {
- redisClusterFree(cc);
- return NULL;
- }
-
- __redisClusterAsyncCopyError(acc);
-
- return acc;
-}
-
-
-int redisClusterAsyncSetConnectCallback(
- redisClusterAsyncContext *acc, redisConnectCallback *fn)
-{
- if (acc->onConnect == NULL) {
- acc->onConnect = fn;
- return REDIS_OK;
- }
- return REDIS_ERR;
-}
-
-int redisClusterAsyncSetDisconnectCallback(
- redisClusterAsyncContext *acc, redisDisconnectCallback *fn)
-{
- if (acc->onDisconnect == NULL) {
- acc->onDisconnect = fn;
- return REDIS_OK;
- }
- return REDIS_ERR;
-}
-
-static void redisClusterAsyncCallback(redisAsyncContext *ac, void *r, void *privdata) {
- int ret;
- redisReply *reply = r;
- cluster_async_data *cad = privdata;
- redisClusterAsyncContext *acc;
- redisClusterContext *cc;
- redisAsyncContext *ac_retry = NULL;
- int error_type;
- cluster_node *node;
- struct cmd *command;
- int64_t now, next;
-
- if(cad == NULL)
- {
- goto error;
- }
-
- acc = cad->acc;
- if(acc == NULL)
- {
- goto error;
- }
-
- cc = acc->cc;
- if(cc == NULL)
- {
- goto error;
- }
-
- command = cad->command;
- if(command == NULL)
- {
- goto error;
- }
-
- if(reply == NULL)
- {
- //Note:
- //I can't decide witch is the best way to deal with connect
- //problem for hiredis cluster async api.
- //But now the way is : when enough null reply for a node,
- //we will update the route after the cluster node timeout.
- //If you have a better idea, please contact with me. Thank you.
- //My email: [email protected]
-
- node = cad->node;
- if(node->acon != NULL)
- {
- node->acon = NULL;
- }
-
- __redisClusterAsyncSetError(acc,
- ac->err, ac->errstr);
-
- if(cc->update_route_time != 0)
- {
- now = hi_usec_now();
- if(now >= cc->update_route_time)
- {
- ret = cluster_update_route(cc);
- if(ret != REDIS_OK)
- {
- __redisClusterAsyncSetError(acc, REDIS_ERR_OTHER,
- "route update error, please recreate redisClusterContext!");
- }
-
- cc->update_route_time = 0LL;
- }
-
- goto done;
- }
-
- node->failure_count ++;
- if(node->failure_count > cc->max_redirect_count)
- {
- char *cluster_timeout_str;
- int cluster_timeout_str_len;
- int cluster_timeout;
-
- node->failure_count = 0;
- if(cc->update_route_time != 0)
- {
- goto done;
- }
-
- cluster_timeout_str = cluster_config_get(cc,
- "cluster-node-timeout", &cluster_timeout_str_len);
- if(cluster_timeout_str == NULL)
- {
- __redisClusterAsyncSetError(acc,
- cc->err, cc->errstr);
- goto done;
- }
-
- cluster_timeout = hi_atoi(cluster_timeout_str,
- cluster_timeout_str_len);
- free(cluster_timeout_str);
- if(cluster_timeout <= 0)
- {
- __redisClusterAsyncSetError(acc,
- REDIS_ERR_OTHER,
- "cluster_timeout_str convert to integer error");
- goto done;
- }
-
- now = hi_usec_now();
- if (now < 0) {
- __redisClusterAsyncSetError(acc,
- REDIS_ERR_OTHER,
- "get now usec time error");
- goto done;
- }
-
- next = now + (cluster_timeout * 1000LL);
-
- cc->update_route_time = next;
-
- }
-
- goto done;
- }
-
- error_type = cluster_reply_error_type(reply);
-
- if(error_type > CLUSTER_NOT_ERR && error_type < CLUSTER_ERR_SENTINEL)
- {
- cad->retry_count ++;
- if(cad->retry_count > cc->max_redirect_count)
- {
- cad->retry_count = 0;
- __redisClusterAsyncSetError(acc,
- REDIS_ERR_CLUSTER_TOO_MANY_REDIRECT,
- "too many cluster redirect");
- goto done;
- }
-
- switch(error_type)
- {
- case CLUSTER_ERR_MOVED:
-
- ac_retry = actx_get_after_update_route_by_slot(acc, command->slot_num);
- if(ac_retry == NULL)
- {
- goto done;
- }
-
- cad->node = node_get_by_table(cc, (uint32_t)command->slot_num);
-
- break;
- case CLUSTER_ERR_ASK:
- {
- node = node_get_by_ask_error_reply(cc, reply);
- if(node == NULL)
- {
- __redisClusterAsyncSetError(acc,
- cc->err, cc->errstr);
- goto done;
- }
-
- ac_retry = actx_get_by_node(acc, node);
- if(ac_retry == NULL)
- {
- __redisClusterAsyncSetError(acc,
- REDIS_ERR_OTHER, "actx get by node error");
- goto done;
- }
- else if(ac_retry->err)
- {
- __redisClusterAsyncSetError(acc,
- ac_retry->err, ac_retry->errstr);
- goto done;
- }
-
- ret = redisAsyncCommand(ac_retry,
- NULL,NULL,REDIS_COMMAND_ASKING);
- if(ret != REDIS_OK)
- {
- goto error;
- }
-
- cad->node = node;
-
- break;
- }
- case CLUSTER_ERR_TRYAGAIN:
- case CLUSTER_ERR_CROSSSLOT:
- case CLUSTER_ERR_CLUSTERDOWN:
-
- ac_retry = ac;
- break;
- default:
-
- goto done;
- break;
- }
-
- goto retry;
- }
-
-done:
-
- if(acc->err)
- {
- cad->callback(acc, NULL, cad->privdata);
- }
- else
- {
- cad->callback(acc, r, cad->privdata);
- }
-
- if(cc->err)
- {
- cc->err = 0;
- memset(cc->errstr, '\0', strlen(cc->errstr));
- }
-
- if(acc->err)
- {
- acc->err = 0;
- memset(acc->errstr, '\0', strlen(acc->errstr));
- }
-
- if(cad != NULL)
- {
- cluster_async_data_free(cad);
- }
-
- return;
-
-retry:
-
- ret = redisAsyncFormattedCommand(ac_retry,
- redisClusterAsyncCallback,cad,command->cmd,command->clen);
- if(ret != REDIS_OK)
- {
- goto error;
- }
-
- return;
-
-error:
-
- if(cad != NULL)
- {
- cluster_async_data_free(cad);
- }
-}
-
-int redisClusterAsyncFormattedCommand(redisClusterAsyncContext *acc,
- redisClusterCallbackFn *fn, void *privdata, char *cmd, int len) {
-
- redisClusterContext *cc;
- int status = REDIS_OK;
- int slot_num;
- cluster_node *node;
- redisAsyncContext *ac;
- struct cmd *command = NULL;
- hilist *commands = NULL;
- cluster_async_data *cad;
-
- if(acc == NULL)
- {
- return REDIS_ERR;
- }
-
- cc = acc->cc;
-
- if(cc->err)
- {
- cc->err = 0;
- memset(cc->errstr, '\0', strlen(cc->errstr));
- }
-
- if(acc->err)
- {
- acc->err = 0;
- memset(acc->errstr, '\0', strlen(acc->errstr));
- }
-
- command = command_get();
- if(command == NULL)
- {
- __redisClusterAsyncSetError(acc,REDIS_ERR_OOM,"Out of memory");
- goto error;
- }
-
- command->cmd = malloc(len*sizeof(*command->cmd));
- if(command->cmd == NULL)
- {
- __redisClusterAsyncSetError(acc,REDIS_ERR_OOM,"Out of memory");
- goto error;
- }
- memcpy(command->cmd, cmd, len);
- command->clen = len;
-
- commands = listCreate();
- if(commands == NULL)
- {
- __redisClusterAsyncSetError(acc,REDIS_ERR_OOM,"Out of memory");
- goto error;
- }
-
- commands->free = listCommandFree;
-
- slot_num = command_format_by_slot(cc, command, commands);
-
- if(slot_num < 0)
- {
- __redisClusterAsyncSetError(acc,
- cc->err, cc->errstr);
- goto error;
- }
- else if(slot_num >= REDIS_CLUSTER_SLOTS)
- {
- __redisClusterAsyncSetError(acc,
- REDIS_ERR_OTHER,"slot_num is out of range");
- goto error;
- }
-
- //all keys not belong to one slot
- if(listLength(commands) > 0)
- {
- ASSERT(listLength(commands) != 1);
-
- __redisClusterAsyncSetError(acc,REDIS_ERR_OTHER,
- "Asynchronous API now not support multi-key command");
- goto error;
- }
-
- node = node_get_by_table(cc, (uint32_t) slot_num);
- if(node == NULL)
- {
- __redisClusterAsyncSetError(acc,
- REDIS_ERR_OTHER, "node get by table error");
- goto error;
- }
-
- ac = actx_get_by_node(acc, node);
- if(ac == NULL)
- {
- __redisClusterAsyncSetError(acc,
- REDIS_ERR_OTHER, "actx get by node error");
- goto error;
- }
- else if(ac->err)
- {
- __redisClusterAsyncSetError(acc, ac->err, ac->errstr);
- goto error;
- }
-
- cad = cluster_async_data_get();
- if(cad == NULL)
- {
- __redisClusterAsyncSetError(acc,REDIS_ERR_OOM,"Out of memory");
- goto error;
- }
-
- cad->acc = acc;
- cad->node = node;
- cad->command = command;
- cad->callback = fn;
- cad->privdata = privdata;
-
- status = redisAsyncFormattedCommand(ac,
- redisClusterAsyncCallback,cad,cmd,len);
- if(status != REDIS_OK)
- {
- goto error;
- }
-
- if(commands != NULL)
- {
- listRelease(commands);
- }
-
- return REDIS_OK;
-
-error:
-
- if(command != NULL)
- {
- command_destroy(command);
- }
-
- if(commands != NULL)
- {
- listRelease(commands);
- }
-
- return REDIS_ERR;
-}
-
-
-int redisClustervAsyncCommand(redisClusterAsyncContext *acc,
- redisClusterCallbackFn *fn, void *privdata, const char *format, va_list ap) {
- int ret;
- char *cmd;
- int len;
-
- if(acc == NULL)
- {
- return REDIS_ERR;
- }
-
- len = redisvFormatCommand(&cmd,format,ap);
- if (len == -1) {
- __redisClusterAsyncSetError(acc,REDIS_ERR_OOM,"Out of memory");
- return REDIS_ERR;
- } else if (len == -2) {
- __redisClusterAsyncSetError(acc,REDIS_ERR_OTHER,"Invalid format string");
- return REDIS_ERR;
- }
-
- ret = redisClusterAsyncFormattedCommand(acc, fn, privdata, cmd, len);
-
- free(cmd);
-
- return ret;
-}
-
-int redisClusterAsyncCommand(redisClusterAsyncContext *acc,
- redisClusterCallbackFn *fn, void *privdata, const char *format, ...) {
- int ret;
- va_list ap;
-
- va_start(ap,format);
- ret = redisClustervAsyncCommand(acc, fn, privdata, format, ap);
- va_end(ap);
-
- return ret;
-}
-
-int redisClusterAsyncCommandArgv(redisClusterAsyncContext *acc,
- redisClusterCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen) {
- int ret;
- char *cmd;
- int len;
-
- len = redisFormatCommandArgv(&cmd,argc,argv,argvlen);
- if (len == -1) {
- __redisClusterAsyncSetError(acc,REDIS_ERR_OOM,"Out of memory");
- return REDIS_ERR;
- }
-
- ret = redisClusterAsyncFormattedCommand(acc, fn, privdata, cmd, len);
-
- free(cmd);
-
- return ret;
-}
-
-void redisClusterAsyncDisconnect(redisClusterAsyncContext *acc) {
-
- redisClusterContext *cc;
- redisAsyncContext *ac;
- dictIterator *di;
- dictEntry *de;
- dict *nodes;
- struct cluster_node *node;
-
- if(acc == NULL)
- {
- return;
- }
-
- cc = acc->cc;
-
- nodes = cc->nodes;
-
- if(nodes == NULL)
- {
- return;
- }
-
- di = dictGetIterator(nodes);
-
- while((de = dictNext(di)) != NULL)
- {
- node = dictGetEntryVal(de);
-
- ac = node->acon;
-
- if(ac == NULL || ac->err)
- {
- continue;
- }
-
- redisAsyncDisconnect(ac);
-
- node->acon = NULL;
- }
-}
-
-void redisClusterAsyncFree(redisClusterAsyncContext *acc)
-{
- redisClusterContext *cc;
-
- if(acc == NULL)
- {
- return;
- }
-
- cc = acc->cc;
-
- redisClusterFree(cc);
-
- hi_free(acc);
-}
-
-int redisClusterEnableSalve(redisClusterContext *cc, int flag, const char *uni_ipfrag)
-{
- if(uni_ipfrag == NULL)
- {
- printf("uni_ipfrag is NULL!\n ");
- return -1;
- }
-
- cc->flags |= flag;
- cc->uni_ipfrag = sdssplitlen(uni_ipfrag, strlen(uni_ipfrag), ",", 1, &(cc->ipfrag_count));
-
- redisReply *reply;
- cluster_node *node, *slave;
- redisContext *c;
- dictEntry *de;
- listNode *list_node;
- listIter *list_iter;
- sds *ipFrag;
- int fragNum;
- char *uniqIP;
- dictIterator *it = dictGetIterator(cc->nodes);
-
- while((de = dictNext(it)) != NULL)
- {
- node = dictGetEntryVal(de);
- if(node == NULL || node->host == NULL || node->slaves == NULL)
- {
- continue;
- }
- list_iter = listGetIterator(node->slaves, AL_START_HEAD);
- while((list_node = listNext(list_iter)) != NULL)
- {
- slave = (cluster_node *)list_node->value;
- c = slave->con;
- if(c == NULL)
- {
- ipFrag = sdssplitlen(slave->host, sdslen(slave->host), ".", 1, &fragNum);
- if(cc->flags & HIRCLUSTER_FLAG_UNIQIP_FRAG_ONE)
- uniqIP = ipFrag[0];
- else if(cc->flags & HIRCLUSTER_FLAG_UNIQIP_FRAG_TWO)
- uniqIP = ipFrag[1];
- else if(cc->flags & HIRCLUSTER_FLAG_UNIQIP_FRAG_THREE)
- uniqIP = ipFrag[2];
- else
- uniqIP = ipFrag[3];
-
- for(int i = 0; i < cc->ipfrag_count; i++)
- {
- if(strcmp(uniqIP, cc->uni_ipfrag[i]) == 0)
- {
- sdsfreesplitres(ipFrag, fragNum);
- c = redisConnect(slave->host, slave->port);
- break;
- }
- }
- if(c->err)
- {
- redisFree(c);
- continue;
- }
- slave->con = c;
-
- }
- reply = redisCommand(c, "READONLY");
- if(reply->type == REDIS_REPLY_ERROR)
- {
- printf("Enable slave for reading fail: %s\n",reply->str);
- }
- freeReplyObject(reply);
- }
- listReleaseIterator(list_iter);
- }
- dictReleaseIterator(it);
- return 0;
-}
-
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hircluster.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hircluster.h
deleted file mode 100644
index 4b3ae00..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hircluster.h
+++ /dev/null
@@ -1,187 +0,0 @@
-#ifndef __HIRCLUSTER_H
-#define __HIRCLUSTER_H
-
-#include "hiredis.h"
-#include "async.h"
-#include "command.h"
-#define HIREDIS_VIP_MAJOR 0
-#define HIREDIS_VIP_MINOR 2
-#define HIREDIS_VIP_PATCH 2
-
-#define REDIS_CLUSTER_SLOTS 16384
-
-#define REDIS_ROLE_NULL 0
-#define REDIS_ROLE_MASTER 1
-#define REDIS_ROLE_SLAVE 2
-
-
-#define HIRCLUSTER_FLAG_NULL 0x0
-/* The flag to decide whether add slave node in
- * redisClusterContext->nodes. This is set in the
- * least significant bit of the flags field in
- * redisClusterContext. (1000000000000) */
-#define HIRCLUSTER_FLAG_ADD_SLAVE 0x1000
-/* The flag to decide whether add open slot
- * for master node. (10000000000000) */
-#define HIRCLUSTER_FLAG_ADD_OPENSLOT 0x2000
-/* The flag to decide whether add open slot
- * for master node. (100000000000000) */
-#define HIRCLUSTER_FLAG_ROUTE_USE_SLOTS 0x4000
-
-/*
-The following flags are used for deciding which part of IP will
-be used when enabling the salve for reading
-*/
-#define HIRCLUSTER_FLAG_UNIQIP_FRAG_ONE 0x100
-#define HIRCLUSTER_FLAG_UNIQIP_FRAG_TWO 0x200
-#define HIRCLUSTER_FLAG_UNIQIP_FRAG_THREE 0x400
-#define HIRCLUSTER_FLAG_UNIQIP_FRAG_FOUR 0x800
-
-struct dict;
-struct hilist;
-
-typedef struct cluster_node
-{
- sds name;
- sds addr;
- sds host;
- int port;
- uint8_t role;
- uint8_t myself; /* myself ? */
- redisContext *con;
- redisAsyncContext *acon;
- struct hilist *slots;
- struct hilist *slaves;
- int failure_count;
- void *data; /* Not used by hiredis */
- struct hiarray *migrating; /* copen_slot[] */
- struct hiarray *importing; /* copen_slot[] */
-}cluster_node;
-
-typedef struct cluster_slot
-{
- uint32_t start;
- uint32_t end;
- cluster_node *node; /* master that this slot region belong to */
-}cluster_slot;
-
-typedef struct copen_slot
-{
- uint32_t slot_num; /* slot number */
- int migrate; /* migrating or importing? */
- sds remote_name; /* name for the node that this slot migrating to/importing from */
- cluster_node *node; /* master that this slot belong to */
-}copen_slot;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Context for a connection to Redis cluster */
-typedef struct redisClusterContext {
- int err; /* Error flags, 0 when there is no error */
- char errstr[128]; /* String representation of error when applicable */
- sds ip;
- sds *uni_ipfrag;
- int ipfrag_count;
- int port;
-
- int flags;
-
- enum redisConnectionType connection_type;
- struct timeval *timeout;
-
- struct hiarray *slots;
-
- struct dict *nodes;
- cluster_node *table[REDIS_CLUSTER_SLOTS];
-
- uint64_t route_version;
-
- int max_redirect_count;
- int retry_count;
-
- struct hilist *requests;
-
- int need_update_route;
- int64_t update_route_time;
-} redisClusterContext;
-
-redisClusterContext *redisClusterConnect(const char *addrs, int flags);
-redisClusterContext *redisClusterConnectWithTimeout(const char *addrs,
- const struct timeval tv, int flags);
-redisClusterContext *redisClusterConnectNonBlock(const char *addrs, int flags);
-
-void redisClusterFree(redisClusterContext *cc);
-
-void redisClusterSetMaxRedirect(redisClusterContext *cc, int max_redirect_count);
-
-void *redisClusterFormattedCommand(redisClusterContext *cc, char *cmd, int len);
-void *redisClustervCommand(redisClusterContext *cc, const char *format, va_list ap);
-void *redisClusterCommand(redisClusterContext *cc, const char *format, ...);
-void *redisClusterCommandArgv(redisClusterContext *cc, int argc, const char **argv, const size_t *argvlen);
-
-redisContext *ctx_get_by_node(redisClusterContext *cc, struct cluster_node *node, const struct timeval *timeout, int flags);
-
-int redisClusterAppendFormattedCommand(redisClusterContext *cc, char *cmd, int len);
-int redisClustervAppendCommand(redisClusterContext *cc, const char *format, va_list ap);
-int redisClusterAppendCommand(redisClusterContext *cc, const char *format, ...);
-int redisClusterAppendCommandArgv(redisClusterContext *cc, int argc, const char **argv, const size_t *argvlen);
-int redisClusterGetReply(redisClusterContext *cc, void **reply);
-void redisCLusterReset(redisClusterContext *cc);
-
-int cluster_update_route(redisClusterContext *cc);
-int test_cluster_update_route(redisClusterContext *cc);
-struct dict *parse_cluster_nodes(redisClusterContext *cc, char *str, int str_len, int flags);
-struct dict *parse_cluster_slots(redisClusterContext *cc, redisReply *reply, int flags);
-
-
-/*############redis cluster async############*/
-
-struct redisClusterAsyncContext;
-
-typedef int (adapterAttachFn)(redisAsyncContext*, void*);
-
-typedef void (redisClusterCallbackFn)(struct redisClusterAsyncContext*, void*, void*);
-
-/* Context for an async connection to Redis */
-typedef struct redisClusterAsyncContext {
-
- redisClusterContext *cc;
-
- /* Setup error flags so they can be used directly. */
- int err;
- char errstr[128]; /* String representation of error when applicable */
-
- /* Not used by hiredis */
- void *data;
-
- void *adapter;
- adapterAttachFn *attach_fn;
-
- /* 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;
-
- /* Called when the first write event was received. */
- redisConnectCallback *onConnect;
-
-} redisClusterAsyncContext;
-
-redisClusterAsyncContext *redisClusterAsyncConnect(const char *addrs, int flags);
-int redisClusterAsyncSetConnectCallback(redisClusterAsyncContext *acc, redisConnectCallback *fn);
-int redisClusterAsyncSetDisconnectCallback(redisClusterAsyncContext *acc, redisDisconnectCallback *fn);
-int redisClusterAsyncFormattedCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, char *cmd, int len);
-int redisClustervAsyncCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, const char *format, va_list ap);
-int redisClusterAsyncCommand(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, const char *format, ...);
-int redisClusterAsyncCommandArgv(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen);
-void redisClusterAsyncDisconnect(redisClusterAsyncContext *acc);
-void redisClusterAsyncFree(redisClusterAsyncContext *acc);
-
-redisAsyncContext *actx_get_by_node(redisClusterAsyncContext *acc, cluster_node *node);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis.c
deleted file mode 100644
index be1401b..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis.c
+++ /dev/null
@@ -1,1021 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
- * Jan-Erik Rediger <janerik at fnordig dot com>
- *
- * 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 <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <assert.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "hiredis.h"
-#include "net.h"
-#include "sds.h"
-
-static redisReply *createReplyObject(int type);
-static void *createStringObject(const redisReadTask *task, char *str, size_t len);
-static void *createArrayObject(const redisReadTask *task, int elements);
-static void *createIntegerObject(const redisReadTask *task, long long value);
-static void *createNilObject(const redisReadTask *task);
-
-/* Default set of functions to build the reply. Keep in mind that such a
- * function returning NULL is interpreted as OOM. */
-static redisReplyObjectFunctions defaultFunctions = {
- createStringObject,
- createArrayObject,
- createIntegerObject,
- createNilObject,
- freeReplyObject
-};
-
-/* Create a reply object */
-static redisReply *createReplyObject(int type) {
- redisReply *r = calloc(1,sizeof(*r));
-
- if (r == NULL)
- return NULL;
-
- r->type = type;
- return r;
-}
-
-/* Free a reply object */
-void freeReplyObject(void *reply) {
- redisReply *r = reply;
- size_t j;
-
- if (r == NULL)
- return;
-
- switch(r->type) {
- case REDIS_REPLY_INTEGER:
- break; /* Nothing to free */
- case REDIS_REPLY_ARRAY:
- if (r->element != NULL) {
- for (j = 0; j < r->elements; j++)
- if (r->element[j] != NULL)
- freeReplyObject(r->element[j]);
- free(r->element);
- }
- break;
- case REDIS_REPLY_ERROR:
- case REDIS_REPLY_STATUS:
- case REDIS_REPLY_STRING:
- if (r->str != NULL)
- free(r->str);
- break;
- }
- free(r);
-}
-
-static void *createStringObject(const redisReadTask *task, char *str, size_t len) {
- redisReply *r, *parent;
- char *buf;
-
- r = createReplyObject(task->type);
- if (r == NULL)
- return NULL;
-
- buf = malloc(len+1);
- if (buf == NULL) {
- freeReplyObject(r);
- return NULL;
- }
-
- assert(task->type == REDIS_REPLY_ERROR ||
- task->type == REDIS_REPLY_STATUS ||
- task->type == REDIS_REPLY_STRING);
-
- /* Copy string value */
- memcpy(buf,str,len);
- buf[len] = '\0';
- r->str = buf;
- r->len = len;
-
- if (task->parent) {
- parent = task->parent->obj;
- assert(parent->type == REDIS_REPLY_ARRAY);
- parent->element[task->idx] = r;
- }
- return r;
-}
-
-static void *createArrayObject(const redisReadTask *task, int elements) {
- redisReply *r, *parent;
-
- r = createReplyObject(REDIS_REPLY_ARRAY);
- if (r == NULL)
- return NULL;
-
- if (elements > 0) {
- r->element = calloc(elements,sizeof(redisReply*));
- if (r->element == NULL) {
- freeReplyObject(r);
- return NULL;
- }
- }
-
- r->elements = elements;
-
- if (task->parent) {
- parent = task->parent->obj;
- assert(parent->type == REDIS_REPLY_ARRAY);
- parent->element[task->idx] = r;
- }
- return r;
-}
-
-static void *createIntegerObject(const redisReadTask *task, long long value) {
- redisReply *r, *parent;
-
- r = createReplyObject(REDIS_REPLY_INTEGER);
- if (r == NULL)
- return NULL;
-
- r->integer = value;
-
- if (task->parent) {
- parent = task->parent->obj;
- assert(parent->type == REDIS_REPLY_ARRAY);
- parent->element[task->idx] = r;
- }
- return r;
-}
-
-static void *createNilObject(const redisReadTask *task) {
- redisReply *r, *parent;
-
- r = createReplyObject(REDIS_REPLY_NIL);
- if (r == NULL)
- return NULL;
-
- if (task->parent) {
- parent = task->parent->obj;
- assert(parent->type == REDIS_REPLY_ARRAY);
- 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(). */
-static uint32_t countDigits(uint64_t v) {
- uint32_t result = 1;
- for (;;) {
- if (v < 10) return result;
- if (v < 100) return result + 1;
- if (v < 1000) return result + 2;
- if (v < 10000) return result + 3;
- v /= 10000U;
- result += 4;
- }
-}
-
-/* Helper that calculates the bulk length given a certain string length. */
-static size_t bulklen(size_t len) {
- return 1+countDigits(len)+2+len+2;
-}
-
-int redisvFormatCommand(char **target, const char *format, va_list ap) {
- const char *c = format;
- char *cmd = NULL; /* final command */
- int pos; /* position in final command */
- sds curarg, newarg; /* current argument */
- int touched = 0; /* was the current argument touched? */
- char **curargv = NULL, **newargv = NULL;
- int argc = 0;
- int totlen = 0;
- int error_type = 0; /* 0 = no error; -1 = memory error; -2 = format error */
- int j;
-
- /* Abort if there is not target to set */
- if (target == NULL)
- return -1;
-
- /* Build the command string accordingly to protocol */
- curarg = sdsempty(); //return a empty sds,eg:str=""
- if (curarg == NULL)
- return -1;
-
- while(*c != '\0') {
- if (*c != '%' || c[1] == '\0') {
- if (*c == ' ') {
- if (touched) {
- newargv = realloc(curargv,sizeof(char*)*(argc+1));
- if (newargv == NULL) goto memory_err;
- curargv = newargv;
- curargv[argc++] = curarg;
- totlen += bulklen(sdslen(curarg));
-
- /* curarg is put in argv so it can be overwritten. */
- curarg = sdsempty();
- if (curarg == NULL) goto memory_err;
- touched = 0;
- }
- } else {
- newarg = sdscatlen(curarg,c,1); //copy len of format to curarg
- if (newarg == NULL) goto memory_err;
- curarg = newarg;
- touched = 1;
- }
- } else {
- char *arg;
- size_t size;
-
- /* Set newarg so it can be checked even if it is not touched. */
- newarg = curarg;
-
- switch(c[1]) {
- case 's':
- arg = va_arg(ap,char*); //va_arg return one arg each time
- size = strlen(arg);
- if (size > 0)
- newarg = sdscatlen(curarg,arg,size);
- break;
- case 'b':
- arg = va_arg(ap,char*);
- size = va_arg(ap,size_t);
- if (size > 0)
- newarg = sdscatlen(curarg,arg,size);
- break;
- case '%':
- newarg = sdscat(curarg,"%");
- break;
- default:
- /* Try to detect printf format */
- {
- static const char intfmts[] = "diouxX";
- static const char flags[] = "#0-+ ";
- char _format[16];
- const char *_p = c+1;
- size_t _l = 0;
- va_list _cpy;
-
- /* Flags */
- while (*_p != '\0' && strchr(flags,*_p) != NULL) _p++;
-
- /* Field width */
- while (*_p != '\0' && isdigit(*_p)) _p++;
-
- /* Precision */
- if (*_p == '.') {
- _p++;
- while (*_p != '\0' && isdigit(*_p)) _p++;
- }
-
- /* Copy va_list before consuming with va_arg */
- va_copy(_cpy,ap);
-
- /* Integer conversion (without modifiers) */
- if (strchr(intfmts,*_p) != NULL) {
- va_arg(ap,int);
- goto fmt_valid;
- }
-
- /* Double conversion (without modifiers) */
- if (strchr("eEfFgGaA",*_p) != NULL) {
- va_arg(ap,double);
- goto fmt_valid;
- }
-
- /* Size: char */
- if (_p[0] == 'h' && _p[1] == 'h') {
- _p += 2;
- if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
- va_arg(ap,int); /* char gets promoted to int */
- goto fmt_valid;
- }
- goto fmt_invalid;
- }
-
- /* Size: short */
- if (_p[0] == 'h') {
- _p += 1;
- if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
- va_arg(ap,int); /* short gets promoted to int */
- goto fmt_valid;
- }
- goto fmt_invalid;
- }
-
- /* Size: long long */
- if (_p[0] == 'l' && _p[1] == 'l') {
- _p += 2;
- if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
- va_arg(ap,long long);
- goto fmt_valid;
- }
- goto fmt_invalid;
- }
-
- /* Size: long */
- if (_p[0] == 'l') {
- _p += 1;
- if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
- va_arg(ap,long);
- goto fmt_valid;
- }
- goto fmt_invalid;
- }
-
- fmt_invalid:
- va_end(_cpy);
- goto format_err;
-
- fmt_valid:
- _l = (_p+1)-c;
- if (_l < sizeof(_format)-2) {
- memcpy(_format,c,_l);
- _format[_l] = '\0';
- newarg = sdscatvprintf(curarg,_format,_cpy);
-
- /* Update current position (note: outer blocks
- * increment c twice so compensate here) */
- c = _p-1;
- }
-
- va_end(_cpy);
- break;
- }
- }
-
- if (newarg == NULL) goto memory_err;
- curarg = newarg;
-
- touched = 1;
- c++;
- }
- c++;
- }
-
- /* Add the last argument if needed */
- if (touched) {
- newargv = realloc(curargv,sizeof(char*)*(argc+1));
- if (newargv == NULL) goto memory_err;
- curargv = newargv;
- curargv[argc++] = curarg;
- totlen += bulklen(sdslen(curarg));
- } else {
- sdsfree(curarg);
- }
-
- /* Clear curarg because it was put in curargv or was free'd. */
- curarg = NULL;
-
- /* Add bytes needed to hold multi bulk count */
- totlen += 1+countDigits(argc)+2;
-
- /* Build the command at protocol level */
- cmd = malloc(totlen+1);
- if (cmd == NULL) goto memory_err;
-
- pos = sprintf(cmd,"*%d\r\n",argc);
- for (j = 0; j < argc; j++) {
- pos += sprintf(cmd+pos,"$%zu\r\n",sdslen(curargv[j]));
- memcpy(cmd+pos,curargv[j],sdslen(curargv[j]));
- pos += sdslen(curargv[j]);
- sdsfree(curargv[j]);
- cmd[pos++] = '\r';
- cmd[pos++] = '\n';
- }
- assert(pos == totlen);
- cmd[pos] = '\0';
-
- free(curargv);
- *target = cmd;
- return totlen;
-
-format_err:
- error_type = -2;
- goto cleanup;
-
-memory_err:
- error_type = -1;
- goto cleanup;
-
-cleanup:
- if (curargv) {
- while(argc--)
- sdsfree(curargv[argc]);
- free(curargv);
- }
-
- sdsfree(curarg);
-
- /* No need to check cmd since it is the last statement that can fail,
- * but do it anyway to be as defensive as possible. */
- if (cmd != NULL)
- free(cmd);
-
- return error_type;
-}
-
-/* Format a command according to the Redis protocol. This function
- * takes a format similar to printf:
- *
- * %s represents a C null terminated string you want to interpolate
- * %b represents a binary safe string
- *
- * 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);
- */
-int redisFormatCommand(char **target, const char *format, ...) {
- va_list ap;
- int len;
- va_start(ap,format);
- len = redisvFormatCommand(target,format,ap);
- va_end(ap);
-
- /* The API says "-1" means bad result, but we now also return "-2" in some
- * cases. Force the return value to always be -1. */
- if (len < 0)
- len = -1;
-
- return len;
-}
-
-/* Format a command according to the Redis 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.
- */
-int redisFormatSdsCommandArgv(sds *target, int argc, const char **argv,
- const size_t *argvlen)
-{
- sds cmd;
- unsigned long long totlen;
- int j;
- size_t len;
-
- /* Abort on a NULL target */
- if (target == NULL)
- return -1;
-
- /* Calculate our total size */
- totlen = 1+countDigits(argc)+2;
- for (j = 0; j < argc; j++) {
- len = argvlen ? argvlen[j] : strlen(argv[j]);
- totlen += bulklen(len);
- }
-
- /* Use an SDS string for command construction */
- cmd = sdsempty();
- if (cmd == NULL)
- return -1;
-
- /* We already know how much storage we need */
- cmd = sdsMakeRoomFor(cmd, totlen);
- if (cmd == NULL)
- return -1;
-
- /* Construct command */
- cmd = sdscatfmt(cmd, "*%i\r\n", argc);
- for (j=0; j < argc; j++) {
- len = argvlen ? argvlen[j] : strlen(argv[j]);
- cmd = sdscatfmt(cmd, "$%T\r\n", len);
- cmd = sdscatlen(cmd, argv[j], len);
- cmd = sdscatlen(cmd, "\r\n", sizeof("\r\n")-1);
- }
-
- assert(sdslen(cmd)==totlen);
-
- *target = cmd;
- return totlen;
-}
-
-void redisFreeSdsCommand(sds cmd) {
- sdsfree(cmd);
-}
-
-/* Format a command according to the Redis 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.
- */
-int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) {
- char *cmd = NULL; /* final command */
- int pos; /* position in final command */
- size_t len;
- int totlen, j;
-
- /* Abort on a NULL target */
- if (target == NULL)
- return -1;
-
- /* Calculate number of bytes needed for the command */
- totlen = 1+countDigits(argc)+2;
- for (j = 0; j < argc; j++) {
- len = argvlen ? argvlen[j] : strlen(argv[j]);
- totlen += bulklen(len);
- }
-
- /* Build the command at protocol level */
- cmd = malloc(totlen+1);
- if (cmd == NULL)
- return -1;
-
- pos = sprintf(cmd,"*%d\r\n",argc);
- for (j = 0; j < argc; j++) {
- len = argvlen ? argvlen[j] : strlen(argv[j]);
- pos += sprintf(cmd+pos,"$%zu\r\n",len);
- memcpy(cmd+pos,argv[j],len);
- pos += len;
- cmd[pos++] = '\r';
- cmd[pos++] = '\n';
- }
- assert(pos == totlen);
- cmd[pos] = '\0';
-
- *target = cmd;
- return totlen;
-}
-
-void redisFreeCommand(char *cmd) {
- free(cmd);
-}
-
-void __redisSetError(redisContext *c, int type, const char *str) {
- size_t len;
-
- c->err = type;
- if (str != NULL) {
- len = strlen(str);
- len = len < (sizeof(c->errstr)-1) ? len : (sizeof(c->errstr)-1);
- memcpy(c->errstr,str,len);
- c->errstr[len] = '\0';
- } else {
- /* Only REDIS_ERR_IO may lack a description! */
- assert(type == REDIS_ERR_IO);
- __redis_strerror_r(errno, c->errstr, sizeof(c->errstr));
- }
-}
-
-redisReader *redisReaderCreate(void) {
- return redisReaderCreateWithFunctions(&defaultFunctions);
-}
-
-static redisContext *redisContextInit(void) {
- redisContext *c;
-
- c = calloc(1,sizeof(redisContext));
- if (c == NULL)
- return NULL;
-
- c->err = 0;
- c->errstr[0] = '\0';
- c->obuf = sdsempty();
- c->reader = redisReaderCreate();
- c->tcp.host = NULL;
- c->tcp.source_addr = NULL;
- c->unix_sock.path = NULL;
- c->timeout = NULL;
-
- if (c->obuf == NULL || c->reader == NULL) {
- redisFree(c);
- return NULL;
- }
-
- return c;
-}
-
-void redisFree(redisContext *c) {
- if (c == NULL)
- return;
- if (c->fd > 0)
- close(c->fd);
- if (c->obuf != NULL)
- sdsfree(c->obuf);
- if (c->reader != NULL)
- redisReaderFree(c->reader);
- if (c->tcp.host)
- free(c->tcp.host);
- if (c->tcp.source_addr)
- free(c->tcp.source_addr);
- if (c->unix_sock.path)
- free(c->unix_sock.path);
- if (c->timeout)
- free(c->timeout);
- free(c);
-}
-
-int redisFreeKeepFd(redisContext *c) {
- int fd = c->fd;
- c->fd = -1;
- redisFree(c);
- return fd;
-}
-
-int redisReconnect(redisContext *c) {
- c->err = 0;
- memset(c->errstr, '\0', strlen(c->errstr));
-
- if (c->fd > 0) {
- close(c->fd);
- }
-
- sdsfree(c->obuf);
- redisReaderFree(c->reader);
-
- c->obuf = sdsempty();
- c->reader = redisReaderCreate();
-
- if (c->connection_type == REDIS_CONN_TCP) {
- return redisContextConnectBindTcp(c, c->tcp.host, c->tcp.port,
- c->timeout, c->tcp.source_addr);
- } else if (c->connection_type == REDIS_CONN_UNIX) {
- return redisContextConnectUnix(c, c->unix_sock.path, c->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");
- }
-
- return REDIS_ERR;
-}
-
-/* Connect to a Redis 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) {
- redisContext *c;
-
- c = redisContextInit();
- if (c == NULL)
- return NULL;
-
- c->flags |= REDIS_BLOCK;
- redisContextConnectTcp(c,ip,port,NULL);
- return c;
-}
-
-redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv) {
- redisContext *c;
-
- c = redisContextInit();
- if (c == NULL)
- return NULL;
-
- c->flags |= REDIS_BLOCK;
- redisContextConnectTcp(c,ip,port,&tv);
- return c;
-}
-
-redisContext *redisConnectNonBlock(const char *ip, int port) {
- redisContext *c;
-
- c = redisContextInit();
- if (c == NULL)
- return NULL;
-
- c->flags &= ~REDIS_BLOCK;
- redisContextConnectTcp(c,ip,port,NULL);
- return c;
-}
-
-redisContext *redisConnectBindNonBlock(const char *ip, int port,
- const char *source_addr) {
- redisContext *c = redisContextInit();
- c->flags &= ~REDIS_BLOCK;
- redisContextConnectBindTcp(c,ip,port,NULL,source_addr);
- return c;
-}
-
-redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
- const char *source_addr) {
- redisContext *c = redisContextInit();
- c->flags &= ~REDIS_BLOCK;
- c->flags |= REDIS_REUSEADDR;
- redisContextConnectBindTcp(c,ip,port,NULL,source_addr);
- return c;
-}
-
-redisContext *redisConnectUnix(const char *path) {
- redisContext *c;
-
- c = redisContextInit();
- if (c == NULL)
- return NULL;
-
- c->flags |= REDIS_BLOCK;
- redisContextConnectUnix(c,path,NULL);
- return c;
-}
-
-redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv) {
- redisContext *c;
-
- c = redisContextInit();
- if (c == NULL)
- return NULL;
-
- c->flags |= REDIS_BLOCK;
- redisContextConnectUnix(c,path,&tv);
- return c;
-}
-
-redisContext *redisConnectUnixNonBlock(const char *path) {
- redisContext *c;
-
- c = redisContextInit();
- if (c == NULL)
- return NULL;
-
- c->flags &= ~REDIS_BLOCK;
- redisContextConnectUnix(c,path,NULL);
- return c;
-}
-
-redisContext *redisConnectFd(int fd) {
- redisContext *c;
-
- c = redisContextInit();
- if (c == NULL)
- return NULL;
-
- c->fd = fd;
- c->flags |= REDIS_BLOCK | REDIS_CONNECTED;
- return c;
-}
-
-/* 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;
-}
-
-/* Enable connection KeepAlive. */
-int redisEnableKeepAlive(redisContext *c) {
- if (redisKeepAlive(c, REDIS_KEEPALIVE_INTERVAL) != REDIS_OK)
- return REDIS_ERR;
- return REDIS_OK;
-}
-
-/* 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 redisContextReadReply to
- * see if there is a reply available. */
-int redisBufferRead(redisContext *c) {
- char buf[1024*16];
- int nread;
-
- /* Return early when the context has seen an error. */
- if (c->err)
- return REDIS_ERR;
-
- nread = read(c->fd,buf,sizeof(buf));
- if (nread == -1) {
- if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
- /* Try again later */
- } else {
- __redisSetError(c,REDIS_ERR_IO,NULL);
- return REDIS_ERR;
- }
- } else if (nread == 0) {
- __redisSetError(c,REDIS_ERR_EOF,"Server closed the connection");
- return REDIS_ERR;
- } else {
- if (redisReaderFeed(c->reader,buf,nread) != REDIS_OK) {
- __redisSetError(c,c->reader->err,c->reader->errstr);
- return REDIS_ERR;
- }
- }
- return REDIS_OK;
-}
-
-/* Write the output buffer to the socket.
- *
- * Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
- * succesfully 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 error occured trying to write and sets
- * c->errstr to hold the appropriate error string.
- */
-int redisBufferWrite(redisContext *c, int *done) {
- int nwritten;
-
- /* Return early when the context has seen an error. */
- if (c->err)
- return REDIS_ERR;
-
- if (sdslen(c->obuf) > 0) {
- nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
- if (nwritten == -1) {
- if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
- /* Try again later */
- } else {
- __redisSetError(c,REDIS_ERR_IO,NULL);
- return REDIS_ERR;
- }
- } else if (nwritten > 0) {
- if (nwritten == (signed)sdslen(c->obuf)) {
- sdsfree(c->obuf);
- c->obuf = sdsempty();
- } else {
- sdsrange(c->obuf,nwritten,-1);
- }
- }
- }
- if (done != NULL) *done = (sdslen(c->obuf) == 0);
- return REDIS_OK;
-}
-
-/* Internal helper function to try and get a reply from the reader,
- * or set an error in the context otherwise. */
-int redisGetReplyFromReader(redisContext *c, void **reply) {
- if (redisReaderGetReply(c->reader,reply) == REDIS_ERR) {
- __redisSetError(c,c->reader->err,c->reader->errstr);
- return REDIS_ERR;
- }
- return REDIS_OK;
-}
-
-int redisGetReply(redisContext *c, void **reply) {
- int wdone = 0;
- void *aux = NULL;
-
- /* Try to read pending replies */
- if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
- return REDIS_ERR;
-
- /* For the blocking context, flush output buffer and read reply */
- if (aux == NULL && c->flags & REDIS_BLOCK) {
- /* Write until done */
- do {
- if (redisBufferWrite(c,&wdone) == REDIS_ERR)
- return REDIS_ERR;
- } while (!wdone);
-
- /* Read until there is a reply */
- do {
- if (redisBufferRead(c) == REDIS_ERR)
- return REDIS_ERR;
- if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
- return REDIS_ERR;
- } while (aux == NULL);
- }
-
- /* Set reply object */
- if (reply != NULL) *reply = aux;
- return REDIS_OK;
-}
-
-
-/* Helper function for the redisAppendCommand* family of functions.
- *
- * Write a formatted command to the output buffer. When this family
- * is used, you need to call redisGetReply yourself to retrieve
- * the reply (or replies in pub/sub).
- */
-int __redisAppendCommand(redisContext *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;
- }
-
- c->obuf = newbuf;
- return REDIS_OK;
-}
-
-int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len) {
-
- if (__redisAppendCommand(c, cmd, len) != REDIS_OK) {
- return REDIS_ERR;
- }
-
- return REDIS_OK;
-}
-
-int redisvAppendCommand(redisContext *c, const char *format, va_list ap) {
- char *cmd;
- int len;
-
- len = redisvFormatCommand(&cmd,format,ap);
- if (len == -1) {
- __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
- return REDIS_ERR;
- } else if (len == -2) {
- __redisSetError(c,REDIS_ERR_OTHER,"Invalid format string");
- return REDIS_ERR;
- }
-
- if (__redisAppendCommand(c,cmd,len) != REDIS_OK) {
- free(cmd);
- return REDIS_ERR;
- }
-
- free(cmd);
- return REDIS_OK;
-}
-
-int redisAppendCommand(redisContext *c, const char *format, ...) {
- va_list ap;
- int ret;
-
- va_start(ap,format);
- ret = redisvAppendCommand(c,format,ap);
- va_end(ap);
- return ret;
-}
-
-int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) {
- sds cmd;
- int len;
-
- len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen);
- if (len == -1) {
- __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
- return REDIS_ERR;
- }
-
- if (__redisAppendCommand(c,cmd,len) != REDIS_OK) {
- sdsfree(cmd);
- return REDIS_ERR;
- }
-
- sdsfree(cmd);
- return REDIS_OK;
-}
-
-/* Helper function for the redisCommand* 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
- * context is non-blocking, the "reply" pointer will not be used and the
- * command is simply appended to the write buffer.
- *
- * Returns the reply when a reply was succesfully retrieved. Returns NULL
- * otherwise. When NULL is returned in a blocking context, the error field
- * in the context will be set.
- */
-static void *__redisBlockForReply(redisContext *c) {
- void *reply;
-
- if (c->flags & REDIS_BLOCK) {
- if (redisGetReply(c,&reply) != REDIS_OK)
- return NULL;
- return reply;
- }
- return NULL;
-}
-
-void *redisvCommand(redisContext *c, const char *format, va_list ap) {
- if (redisvAppendCommand(c,format,ap) != REDIS_OK)
- return NULL;
- return __redisBlockForReply(c);
-}
-
-void *redisCommand(redisContext *c, const char *format, ...) {
- va_list ap;
- void *reply = NULL;
- va_start(ap,format);
- reply = redisvCommand(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)
- return NULL;
- return __redisBlockForReply(c);
-}
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis.h
deleted file mode 100644
index 87f7366..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
- * Jan-Erik Rediger <janerik at fnordig dot com>
- *
- * 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_H
-#define __HIREDIS_H
-#include "read.h"
-#include <stdarg.h> /* for va_list */
-#include <sys/time.h> /* for struct timeval */
-#include <stdint.h> /* uintXX_t, etc */
-#include "sds.h" /* for sds */
-
-#define HIREDIS_MAJOR 0
-#define HIREDIS_MINOR 13
-#define HIREDIS_PATCH 1
-
-/* 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
-
-/* 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
-
-/* 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
-
-/* Flag specific to the async API which means that the context should be clean
- * up as soon as possible. */
-#define REDIS_FREEING 0x8
-
-/* Flag that is set when an async callback is executed. */
-#define REDIS_IN_CALLBACK 0x10
-
-/* Flag that is set when the async context has one or more subscriptions. */
-#define REDIS_SUBSCRIBED 0x20
-
-/* Flag that is set when monitor mode is active */
-#define REDIS_MONITORING 0x40
-
-/* Flag that is set when we should set SO_REUSEADDR before calling bind() */
-#define REDIS_REUSEADDR 0x80
-
-#define REDIS_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
-
-/* strerror_r has two completely different prototypes and behaviors
- * depending on system issues, so we need to operate on the error buffer
- * differently depending on which strerror_r we're using. */
-#ifndef _GNU_SOURCE
-/* "regular" POSIX strerror_r that does the right thing. */
-#define __redis_strerror_r(errno, buf, len) \
- do { \
- strerror_r((errno), (buf), (len)); \
- } while (0)
-#else
-/* "bad" GNU strerror_r we need to clean up after. */
-#define __redis_strerror_r(errno, buf, len) \
- do { \
- char *err_str = strerror_r((errno), (buf), (len)); \
- /* If return value _isn't_ the start of the buffer we passed in, \
- * then GNU strerror_r returned an internal static buffer and we \
- * need to copy the result into our private buffer. */ \
- if (err_str != (buf)) { \
- buf[(len)] = '\0'; \
- strncat((buf), err_str, ((len) - 1)); \
- } \
- } while (0)
-#endif
-
-#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 */
- int len; /* Length of string */
- char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */
- size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
- struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
-} redisReply;
-
-redisReader *redisReaderCreate(void);
-
-/* Function to free the reply objects hiredis 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, ...);
-int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen);
-int 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,
-};
-
-/* Context for a connection to Redis */
-typedef struct redisContext {
- int err; /* Error flags, 0 when there is no error */
- char errstr[128]; /* String representation of error when applicable */
- int fd;
- int flags;
- char *obuf; /* Write buffer */
- redisReader *reader; /* Protocol reader */
-
- enum redisConnectionType connection_type;
- struct timeval *timeout;
-
- struct {
- char *host;
- char *source_addr;
- int port;
- } tcp;
-
- struct {
- char *path;
- } unix_sock;
-} redisContext;
-
-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,
- const char *source_addr);
-redisContext *redisConnectBindNonBlockWithReuse(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(int fd);
-
-/**
- * Reconnect the given context using the saved information.
- *
- * This re-uses the exact same connect options as in the initial connection.
- * host, ip (or path), timeout and bind address are reused,
- * flags are used unmodified from the existing context.
- *
- * Returns REDIS_OK on successfull connect or REDIS_ERR otherwise.
- */
-int redisReconnect(redisContext *c);
-
-int redisSetTimeout(redisContext *c, const struct timeval tv);
-int redisEnableKeepAlive(redisContext *c);
-void redisFree(redisContext *c);
-int redisFreeKeepFd(redisContext *c);
-int redisBufferRead(redisContext *c);
-int redisBufferWrite(redisContext *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);
-
-/* 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);
-
-/* 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);
-
-/* Issue a command to Redis. In a blocking context, it is identical to calling
- * redisAppendCommand, followed by redisGetReply. 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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiutil.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiutil.c
deleted file mode 100644
index d10cdac..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiutil.c
+++ /dev/null
@@ -1,554 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include <sys/time.h>
-#include <sys/types.h>
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-
-#include "hiutil.h"
-
-#ifdef HI_HAVE_BACKTRACE
-# include <execinfo.h>
-#endif
-
-int
-hi_set_blocking(int sd)
-{
- int flags;
-
- flags = fcntl(sd, F_GETFL, 0);
- if (flags < 0) {
- return flags;
- }
-
- return fcntl(sd, F_SETFL, flags & ~O_NONBLOCK);
-}
-
-int
-hi_set_nonblocking(int sd)
-{
- int flags;
-
- flags = fcntl(sd, F_GETFL, 0);
- if (flags < 0) {
- return flags;
- }
-
- return fcntl(sd, F_SETFL, flags | O_NONBLOCK);
-}
-
-int
-hi_set_reuseaddr(int sd)
-{
- int reuse;
- socklen_t len;
-
- reuse = 1;
- len = sizeof(reuse);
-
- return setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &reuse, len);
-}
-
-/*
- * Disable Nagle algorithm on TCP socket.
- *
- * This option helps to minimize transmit latency by disabling coalescing
- * of data to fill up a TCP segment inside the kernel. Sockets with this
- * option must use readv() or writev() to do data transfer in bulk and
- * hence avoid the overhead of small packets.
- */
-int
-hi_set_tcpnodelay(int sd)
-{
- int nodelay;
- socklen_t len;
-
- nodelay = 1;
- len = sizeof(nodelay);
-
- return setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, &nodelay, len);
-}
-
-int
-hi_set_linger(int sd, int timeout)
-{
- struct linger linger;
- socklen_t len;
-
- linger.l_onoff = 1;
- linger.l_linger = timeout;
-
- len = sizeof(linger);
-
- return setsockopt(sd, SOL_SOCKET, SO_LINGER, &linger, len);
-}
-
-int
-hi_set_sndbuf(int sd, int size)
-{
- socklen_t len;
-
- len = sizeof(size);
-
- return setsockopt(sd, SOL_SOCKET, SO_SNDBUF, &size, len);
-}
-
-int
-hi_set_rcvbuf(int sd, int size)
-{
- socklen_t len;
-
- len = sizeof(size);
-
- return setsockopt(sd, SOL_SOCKET, SO_RCVBUF, &size, len);
-}
-
-int
-hi_get_soerror(int sd)
-{
- int status, err;
- socklen_t len;
-
- err = 0;
- len = sizeof(err);
-
- status = getsockopt(sd, SOL_SOCKET, SO_ERROR, &err, &len);
- if (status == 0) {
- errno = err;
- }
-
- return status;
-}
-
-int
-hi_get_sndbuf(int sd)
-{
- int status, size;
- socklen_t len;
-
- size = 0;
- len = sizeof(size);
-
- status = getsockopt(sd, SOL_SOCKET, SO_SNDBUF, &size, &len);
- if (status < 0) {
- return status;
- }
-
- return size;
-}
-
-int
-hi_get_rcvbuf(int sd)
-{
- int status, size;
- socklen_t len;
-
- size = 0;
- len = sizeof(size);
-
- status = getsockopt(sd, SOL_SOCKET, SO_RCVBUF, &size, &len);
- if (status < 0) {
- return status;
- }
-
- return size;
-}
-
-int
-_hi_atoi(uint8_t *line, size_t n)
-{
- int value;
-
- if (n == 0) {
- return -1;
- }
-
- for (value = 0; n--; line++) {
- if (*line < '0' || *line > '9') {
- return -1;
- }
-
- value = value * 10 + (*line - '0');
- }
-
- if (value < 0) {
- return -1;
- }
-
- return value;
-}
-
-void
-_hi_itoa(uint8_t *s, int num)
-{
- uint8_t c;
- uint8_t sign = 0;
-
- if(s == NULL)
- {
- return;
- }
-
- uint32_t len, i;
- len = 0;
-
- if(num < 0)
- {
- sign = 1;
- num = abs(num);
- }
- else if(num == 0)
- {
- s[len++] = '0';
- return;
- }
-
- while(num % 10 || num /10)
- {
- c = num %10 + '0';
- num = num /10;
- s[len+1] = s[len];
- s[len] = c;
- len ++;
- }
-
- if(sign == 1)
- {
- s[len++] = '-';
- }
-
- s[len] = '\0';
-
- for(i = 0; i < len/2; i ++)
- {
- c = s[i];
- s[i] = s[len - i -1];
- s[len - i -1] = c;
- }
-
-}
-
-
-int
-hi_valid_port(int n)
-{
- if (n < 1 || n > UINT16_MAX) {
- return 0;
- }
-
- return 1;
-}
-
-int _uint_len(uint32_t num)
-{
- int n = 0;
-
- if(num == 0)
- {
- return 1;
- }
-
- while(num != 0)
- {
- n ++;
- num /= 10;
- }
-
- return n;
-}
-
-void *
-_hi_alloc(size_t size, const char *name, int line)
-{
- void *p;
-
- ASSERT(size != 0);
-
- p = malloc(size);
-
- if(name == NULL && line == 1)
- {
-
- }
-
- return p;
-}
-
-void *
-_hi_zalloc(size_t size, const char *name, int line)
-{
- void *p;
-
- p = _hi_alloc(size, name, line);
- if (p != NULL) {
- memset(p, 0, size);
- }
-
- return p;
-}
-
-void *
-_hi_calloc(size_t nmemb, size_t size, const char *name, int line)
-{
- return _hi_zalloc(nmemb * size, name, line);
-}
-
-void *
-_hi_realloc(void *ptr, size_t size, const char *name, int line)
-{
- void *p;
-
- ASSERT(size != 0);
-
- p = realloc(ptr, size);
-
- if(name == NULL && line == 1)
- {
-
- }
-
- return p;
-}
-
-void
-_hi_free(void *ptr, const char *name, int line)
-{
- ASSERT(ptr != NULL);
-
- if(name == NULL && line == 1)
- {
-
- }
-
- free(ptr);
-}
-
-void
-hi_stacktrace(int skip_count)
-{
- if(skip_count > 0)
- {
-
- }
-
-#ifdef HI_HAVE_BACKTRACE
- void *stack[64];
- char **symbols;
- int size, i, j;
-
- size = backtrace(stack, 64);
- symbols = backtrace_symbols(stack, size);
- if (symbols == NULL) {
- return;
- }
-
- skip_count++; /* skip the current frame also */
-
- for (i = skip_count, j = 0; i < size; i++, j++) {
- printf("[%d] %s\n", j, symbols[i]);
- }
-
- free(symbols);
-#endif
-}
-
-void
-hi_stacktrace_fd(int fd)
-{
- if(fd > 0)
- {
-
- }
-#ifdef HI_HAVE_BACKTRACE
- void *stack[64];
- int size;
-
- size = backtrace(stack, 64);
- backtrace_symbols_fd(stack, size, fd);
-#endif
-}
-
-void
-hi_assert(const char *cond, const char *file, int line, int panic)
-{
-
- printf("File: %s Line: %d: %s\n", file, line, cond);
-
- if (panic) {
- hi_stacktrace(1);
- abort();
- }
- abort();
-}
-
-int
-_vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
-{
- int n;
-
- n = vsnprintf(buf, size, fmt, args);
-
- /*
- * The return value is the number of characters which would be written
- * into buf not including the trailing '\0'. If size is == 0 the
- * function returns 0.
- *
- * On error, the function also returns 0. This is to allow idiom such
- * as len += _vscnprintf(...)
- *
- * See: http://lwn.net/Articles/69419/
- */
- if (n <= 0) {
- return 0;
- }
-
- if (n < (int) size) {
- return n;
- }
-
- return (int)(size - 1);
-}
-
-int
-_scnprintf(char *buf, size_t size, const char *fmt, ...)
-{
- va_list args;
- int n;
-
- va_start(args, fmt);
- n = _vscnprintf(buf, size, fmt, args);
- va_end(args);
-
- return n;
-}
-
-/*
- * Send n bytes on a blocking descriptor
- */
-ssize_t
-_hi_sendn(int sd, const void *vptr, size_t n)
-{
- size_t nleft;
- ssize_t nsend;
- const char *ptr;
-
- ptr = vptr;
- nleft = n;
- while (nleft > 0) {
- nsend = send(sd, ptr, nleft, 0);
- if (nsend < 0) {
- if (errno == EINTR) {
- continue;
- }
- return nsend;
- }
- if (nsend == 0) {
- return -1;
- }
-
- nleft -= (size_t)nsend;
- ptr += nsend;
- }
-
- return (ssize_t)n;
-}
-
-/*
- * Recv n bytes from a blocking descriptor
- */
-ssize_t
-_hi_recvn(int sd, void *vptr, size_t n)
-{
- size_t nleft;
- ssize_t nrecv;
- char *ptr;
-
- ptr = vptr;
- nleft = n;
- while (nleft > 0) {
- nrecv = recv(sd, ptr, nleft, 0);
- if (nrecv < 0) {
- if (errno == EINTR) {
- continue;
- }
- return nrecv;
- }
- if (nrecv == 0) {
- break;
- }
-
- nleft -= (size_t)nrecv;
- ptr += nrecv;
- }
-
- return (ssize_t)(n - nleft);
-}
-
-/*
- * Return the current time in microseconds since Epoch
- */
-int64_t
-hi_usec_now(void)
-{
- struct timeval now;
- int64_t usec;
- int status;
-
- status = gettimeofday(&now, NULL);
- if (status < 0) {
- return -1;
- }
-
- usec = (int64_t)now.tv_sec * 1000000LL + (int64_t)now.tv_usec;
-
- return usec;
-}
-
-/*
- * Return the current time in milliseconds since Epoch
- */
-int64_t
-hi_msec_now(void)
-{
- return hi_usec_now() / 1000LL;
-}
-
-void print_string_with_length(char *s, size_t len)
-{
- char *token;
- for(token = s; token <= s + len; token ++)
- {
- printf("%c", *token);
- }
- printf("\n");
-}
-
-void print_string_with_length_fix_CRLF(char *s, size_t len)
-{
- char *token;
- for(token = s; token < s + len; token ++)
- {
- if(*token == CR)
- {
- printf("\\r");
- }
- else if(*token == LF)
- {
- printf("\\n");
- }
- else
- {
- printf("%c", *token);
- }
- }
- printf("\n");
-}
-
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiutil.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiutil.h
deleted file mode 100644
index d9e1ddb..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiutil.h
+++ /dev/null
@@ -1,265 +0,0 @@
-#ifndef __HIUTIL_H_
-#define __HIUTIL_H_
-
-#include <stdarg.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#define HI_OK 0
-#define HI_ERROR -1
-#define HI_EAGAIN -2
-#define HI_ENOMEM -3
-
-typedef int rstatus_t; /* return type */
-
-#define LF (uint8_t) 10
-#define CR (uint8_t) 13
-#define CRLF "\x0d\x0a"
-#define CRLF_LEN (sizeof("\x0d\x0a") - 1)
-
-#define NELEMS(a) ((sizeof(a)) / sizeof((a)[0]))
-
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-
-#define SQUARE(d) ((d) * (d))
-#define VAR(s, s2, n) (((n) < 2) ? 0.0 : ((s2) - SQUARE(s)/(n)) / ((n) - 1))
-#define STDDEV(s, s2, n) (((n) < 2) ? 0.0 : sqrt(VAR((s), (s2), (n))))
-
-#define HI_INET4_ADDRSTRLEN (sizeof("255.255.255.255") - 1)
-#define HI_INET6_ADDRSTRLEN \
- (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") - 1)
-#define HI_INET_ADDRSTRLEN MAX(HI_INET4_ADDRSTRLEN, HI_INET6_ADDRSTRLEN)
-#define HI_UNIX_ADDRSTRLEN \
- (sizeof(struct sockaddr_un) - offsetof(struct sockaddr_un, sun_path))
-
-#define HI_MAXHOSTNAMELEN 256
-
-/*
- * Length of 1 byte, 2 bytes, 4 bytes, 8 bytes and largest integral
- * type (uintmax_t) in ascii, including the null terminator '\0'
- *
- * From stdint.h, we have:
- * # define UINT8_MAX (255)
- * # define UINT16_MAX (65535)
- * # define UINT32_MAX (4294967295U)
- * # define UINT64_MAX (__UINT64_C(18446744073709551615))
- */
-#define HI_UINT8_MAXLEN (3 + 1)
-#define HI_UINT16_MAXLEN (5 + 1)
-#define HI_UINT32_MAXLEN (10 + 1)
-#define HI_UINT64_MAXLEN (20 + 1)
-#define HI_UINTMAX_MAXLEN HI_UINT64_MAXLEN
-
-/*
- * Make data 'd' or pointer 'p', n-byte aligned, where n is a power of 2
- * of 2.
- */
-#define HI_ALIGNMENT sizeof(unsigned long) /* platform word */
-#define HI_ALIGN(d, n) (((d) + (n - 1)) & ~(n - 1))
-#define HI_ALIGN_PTR(p, n) \
- (void *) (((uintptr_t) (p) + ((uintptr_t) n - 1)) & ~((uintptr_t) n - 1))
-
-
-
-#define str3icmp(m, c0, c1, c2) \
- ((m[0] == c0 || m[0] == (c0 ^ 0x20)) && \
- (m[1] == c1 || m[1] == (c1 ^ 0x20)) && \
- (m[2] == c2 || m[2] == (c2 ^ 0x20)))
-
-#define str4icmp(m, c0, c1, c2, c3) \
- (str3icmp(m, c0, c1, c2) && (m[3] == c3 || m[3] == (c3 ^ 0x20)))
-
-#define str5icmp(m, c0, c1, c2, c3, c4) \
- (str4icmp(m, c0, c1, c2, c3) && (m[4] == c4 || m[4] == (c4 ^ 0x20)))
-
-#define str6icmp(m, c0, c1, c2, c3, c4, c5) \
- (str5icmp(m, c0, c1, c2, c3, c4) && (m[5] == c5 || m[5] == (c5 ^ 0x20)))
-
-#define str7icmp(m, c0, c1, c2, c3, c4, c5, c6) \
- (str6icmp(m, c0, c1, c2, c3, c4, c5) && \
- (m[6] == c6 || m[6] == (c6 ^ 0x20)))
-
-#define str8icmp(m, c0, c1, c2, c3, c4, c5, c6, c7) \
- (str7icmp(m, c0, c1, c2, c3, c4, c5, c6) && \
- (m[7] == c7 || m[7] == (c7 ^ 0x20)))
-
-#define str9icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8) \
- (str8icmp(m, c0, c1, c2, c3, c4, c5, c6, c7) && \
- (m[8] == c8 || m[8] == (c8 ^ 0x20)))
-
-#define str10icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9) \
- (str9icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8) && \
- (m[9] == c9 || m[9] == (c9 ^ 0x20)))
-
-#define str11icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) \
- (str10icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9) && \
- (m[10] == c10 || m[10] == (c10 ^ 0x20)))
-
-#define str12icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) \
- (str11icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) && \
- (m[11] == c11 || m[11] == (c11 ^ 0x20)))
-
-#define str13icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12) \
- (str12icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) && \
- (m[12] == c12 || m[12] == (c12 ^ 0x20)))
-
-#define str14icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) \
- (str13icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12) && \
- (m[13] == c13 || m[13] == (c13 ^ 0x20)))
-
-#define str15icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14) \
- (str14icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) && \
- (m[14] == c14 || m[14] == (c14 ^ 0x20)))
-
-#define str16icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15) \
- (str15icmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14) && \
- (m[15] == c15 || m[15] == (c15 ^ 0x20)))
-
-
-
-/*
- * Wrapper to workaround well known, safe, implicit type conversion when
- * invoking system calls.
- */
-#define hi_gethostname(_name, _len) \
- gethostname((char *)_name, (size_t)_len)
-
-#define hi_atoi(_line, _n) \
- _hi_atoi((uint8_t *)_line, (size_t)_n)
-#define hi_itoa(_line, _n) \
- _hi_itoa((uint8_t *)_line, (int)_n)
-
-#define uint_len(_n) \
- _uint_len((uint32_t)_n)
-
-
-int hi_set_blocking(int sd);
-int hi_set_nonblocking(int sd);
-int hi_set_reuseaddr(int sd);
-int hi_set_tcpnodelay(int sd);
-int hi_set_linger(int sd, int timeout);
-int hi_set_sndbuf(int sd, int size);
-int hi_set_rcvbuf(int sd, int size);
-int hi_get_soerror(int sd);
-int hi_get_sndbuf(int sd);
-int hi_get_rcvbuf(int sd);
-
-int _hi_atoi(uint8_t *line, size_t n);
-void _hi_itoa(uint8_t *s, int num);
-
-int hi_valid_port(int n);
-
-int _uint_len(uint32_t num);
-
-
-/*
- * Memory allocation and free wrappers.
- *
- * These wrappers enables us to loosely detect double free, dangling
- * pointer access and zero-byte alloc.
- */
-#define hi_alloc(_s) \
- _hi_alloc((size_t)(_s), __FILE__, __LINE__)
-
-#define hi_zalloc(_s) \
- _hi_zalloc((size_t)(_s), __FILE__, __LINE__)
-
-#define hi_calloc(_n, _s) \
- _hi_calloc((size_t)(_n), (size_t)(_s), __FILE__, __LINE__)
-
-#define hi_realloc(_p, _s) \
- _hi_realloc(_p, (size_t)(_s), __FILE__, __LINE__)
-
-#define hi_free(_p) do { \
- _hi_free(_p, __FILE__, __LINE__); \
- (_p) = NULL; \
-} while (0)
-
-void *_hi_alloc(size_t size, const char *name, int line);
-void *_hi_zalloc(size_t size, const char *name, int line);
-void *_hi_calloc(size_t nmemb, size_t size, const char *name, int line);
-void *_hi_realloc(void *ptr, size_t size, const char *name, int line);
-void _hi_free(void *ptr, const char *name, int line);
-
-
-#define hi_strndup(_s, _n) \
- strndup((char *)(_s), (size_t)(_n));
-
-/*
- * Wrappers to send or receive n byte message on a blocking
- * socket descriptor.
- */
-#define hi_sendn(_s, _b, _n) \
- _hi_sendn(_s, _b, (size_t)(_n))
-
-#define hi_recvn(_s, _b, _n) \
- _hi_recvn(_s, _b, (size_t)(_n))
-
-/*
- * Wrappers to read or write data to/from (multiple) buffers
- * to a file or socket descriptor.
- */
-#define hi_read(_d, _b, _n) \
- read(_d, _b, (size_t)(_n))
-
-#define hi_readv(_d, _b, _n) \
- readv(_d, _b, (int)(_n))
-
-#define hi_write(_d, _b, _n) \
- write(_d, _b, (size_t)(_n))
-
-#define hi_writev(_d, _b, _n) \
- writev(_d, _b, (int)(_n))
-
-ssize_t _hi_sendn(int sd, const void *vptr, size_t n);
-ssize_t _hi_recvn(int sd, void *vptr, size_t n);
-
-/*
- * Wrappers for defining custom assert based on whether macro
- * HI_ASSERT_PANIC or HI_ASSERT_LOG was defined at the moment
- * ASSERT was called.
- */
-#ifdef HI_ASSERT_PANIC
-
-#define ASSERT(_x) do { \
- if (!(_x)) { \
- hi_assert(#_x, __FILE__, __LINE__, 1); \
- } \
-} while (0)
-
-#define NOT_REACHED() ASSERT(0)
-
-#elif HI_ASSERT_LOG
-
-#define ASSERT(_x) do { \
- if (!(_x)) { \
- hi_assert(#_x, __FILE__, __LINE__, 0); \
- } \
-} while (0)
-
-#define NOT_REACHED() ASSERT(0)
-
-#else
-
-#define ASSERT(_x)
-
-#define NOT_REACHED()
-
-#endif
-
-void hi_assert(const char *cond, const char *file, int line, int panic);
-void hi_stacktrace(int skip_count);
-void hi_stacktrace_fd(int fd);
-
-int _scnprintf(char *buf, size_t size, const char *fmt, ...);
-int _vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
-int64_t hi_usec_now(void);
-int64_t hi_msec_now(void);
-
-void print_string_with_length(char *s, size_t len);
-void print_string_with_length_fix_CRLF(char *s, size_t len);
-
-uint16_t crc16(const char *buf, int len);
-
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/net.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/net.c
deleted file mode 100644
index 60a2dc7..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/net.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/* Extracted from anet.c to work properly with Hiredis error reporting.
- *
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
- * Jan-Erik Rediger <janerik at fnordig dot com>
- *
- * 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 <sys/types.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <netdb.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <poll.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#include "net.h"
-#include "sds.h"
-
-/* Defined in hiredis.c */
-void __redisSetError(redisContext *c, int type, const char *str);
-
-static void redisContextCloseFd(redisContext *c) {
- if (c && c->fd >= 0) {
- close(c->fd);
- c->fd = -1;
- }
-}
-
-static void __redisSetErrorFromErrno(redisContext *c, int type, const char *prefix) {
- char buf[128] = { 0 };
- size_t len = 0;
-
- if (prefix != NULL)
- len = snprintf(buf,sizeof(buf),"%s: ",prefix);
- __redis_strerror_r(errno, (char *)(buf + len), sizeof(buf) - len);
- __redisSetError(c,type,buf);
-}
-
-static int redisSetReuseAddr(redisContext *c) {
- int on = 1;
- if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
- redisContextCloseFd(c);
- return REDIS_ERR;
- }
- return REDIS_OK;
-}
-
-static int redisCreateSocket(redisContext *c, int type) {
- int s;
- if ((s = socket(type, SOCK_STREAM, 0)) == -1) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
- return REDIS_ERR;
- }
- c->fd = s;
- if (type == AF_INET) {
- if (redisSetReuseAddr(c) == REDIS_ERR) {
- return REDIS_ERR;
- }
- }
- return REDIS_OK;
-}
-
-static int redisSetBlocking(redisContext *c, int blocking) {
- int flags;
-
- /* Set the socket nonblocking.
- * 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)");
- redisContextCloseFd(c);
- return REDIS_ERR;
- }
-
- if (blocking)
- flags &= ~O_NONBLOCK;
- else
- flags |= O_NONBLOCK;
-
- if (fcntl(c->fd, F_SETFL, flags) == -1) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)");
- redisContextCloseFd(c);
- return REDIS_ERR;
- }
- return REDIS_OK;
-}
-
-int redisKeepAlive(redisContext *c, int interval) {
- int val = 1;
- int fd = c->fd;
-
- if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1){
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
- return REDIS_ERR;
- }
-
- val = interval;
-
-#ifdef _OSX
- if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &val, sizeof(val)) < 0) {
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
- return REDIS_ERR;
- }
-#else
-#if defined(__GLIBC__) && !defined(__FreeBSD_kernel__)
- val = interval;
- if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) {
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
- return REDIS_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;
- }
-
- val = 3;
- if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) {
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
- return REDIS_ERR;
- }
-#endif
-#endif
-
- return REDIS_OK;
-}
-
-static int redisSetTcpNoDelay(redisContext *c) {
- int yes = 1;
- if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)");
- redisContextCloseFd(c);
- return REDIS_ERR;
- }
- return REDIS_OK;
-}
-
-#define __MAX_MSEC (((LONG_MAX) - 999) / 1000)
-
-static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) {
- struct pollfd wfd[1];
- long msec;
-
- msec = -1;
- wfd[0].fd = c->fd;
- wfd[0].events = POLLOUT;
-
- /* Only use timeout when not NULL. */
- if (timeout != NULL) {
- if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
- __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
- redisContextCloseFd(c);
- return REDIS_ERR;
- }
-
- msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);
-
- if (msec < 0 || msec > INT_MAX) {
- msec = INT_MAX;
- }
- }
-
- if (errno == EINPROGRESS) {
- int res;
-
- if ((res = poll(wfd, 1, msec)) == -1) {
- __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
- redisContextCloseFd(c);
- return REDIS_ERR;
- } else if (res == 0) {
- errno = ETIMEDOUT;
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
- redisContextCloseFd(c);
- return REDIS_ERR;
- }
-
- if (redisCheckSocketError(c) != REDIS_OK)
- return REDIS_ERR;
-
- return REDIS_OK;
- }
-
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
- redisContextCloseFd(c);
- return REDIS_ERR;
-}
-
-int redisCheckSocketError(redisContext *c) {
- int err = 0;
- 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;
- }
-
- if (err) {
- errno = err;
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
- return REDIS_ERR;
- }
-
- return REDIS_OK;
-}
-
-int redisContextSetTimeout(redisContext *c, const struct timeval tv) {
- if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv)) == -1) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_RCVTIMEO)");
- return REDIS_ERR;
- }
- if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv)) == -1) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_SNDTIMEO)");
- return REDIS_ERR;
- }
- return REDIS_OK;
-}
-
-static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
- const struct timeval *timeout,
- const char *source_addr) {
- int s, 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 reuses = 0;
-
- c->connection_type = REDIS_CONN_TCP;
- c->tcp.port = port;
-
- /* We need to take possession of the passed parameters
- * to make them reusable for a reconnect.
- * We also carefully check we don't free data we already own,
- * as in the case of the reconnect method.
- *
- * This is a bit ugly, but atleast it works and doesn't leak memory.
- **/
- if (c->tcp.host != addr) {
- if (c->tcp.host)
- free(c->tcp.host);
-
- c->tcp.host = strdup(addr);
- }
-
- if (timeout) {
- if (c->timeout != timeout) {
- if (c->timeout == NULL)
- c->timeout = malloc(sizeof(struct timeval));
-
- memcpy(c->timeout, timeout, sizeof(struct timeval));
- }
- } else {
- if (c->timeout)
- free(c->timeout);
- c->timeout = NULL;
- }
-
- if (source_addr == NULL) {
- free(c->tcp.source_addr);
- c->tcp.source_addr = NULL;
- } else if (c->tcp.source_addr != source_addr) {
- free(c->tcp.source_addr);
- c->tcp.source_addr = strdup(source_addr);
- }
-
- snprintf(_port, 6, "%d", port);
- memset(&hints,0,sizeof(hints));
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
-
- /* Try with IPv6 if no IPv4 address was found. We do it in this order since
- * in a Redis client you can't afford to test if you have IPv6 connectivity
- * as this would add latency to every connect. Otherwise a more sensible
- * route could be: Use IPv6 if both addresses are available and there is IPv6
- * connectivity. */
- if ((rv = getaddrinfo(c->tcp.host,_port,&hints,&servinfo)) != 0) {
- hints.ai_family = AF_INET6;
- if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) {
- __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv));
- return REDIS_ERR;
- }
- }
- for (p = servinfo; p != NULL; p = p->ai_next) {
-addrretry:
- if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1)
- continue;
-
- c->fd = s;
- if (redisSetBlocking(c,0) != REDIS_OK)
- goto error;
- if (c->tcp.source_addr) {
- int bound = 0;
- /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */
- 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);
- goto error;
- }
-
- if (reuseaddr) {
- n = 1;
- if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*) &n,
- sizeof(n)) < 0) {
- goto error;
- }
- }
-
- for (b = bservinfo; b != NULL; b = b->ai_next) {
- if (bind(s,b->ai_addr,b->ai_addrlen) != -1) {
- bound = 1;
- break;
- }
- }
- freeaddrinfo(bservinfo);
- if (!bound) {
- char buf[128];
- snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno));
- __redisSetError(c,REDIS_ERR_OTHER,buf);
- goto error;
- }
- }
- if (connect(s,p->ai_addr,p->ai_addrlen) == -1) {
- if (errno == EHOSTUNREACH) {
- redisContextCloseFd(c);
- continue;
- } else if (errno == EINPROGRESS && !blocking) {
- /* This is ok. */
- } else if (errno == EADDRNOTAVAIL && reuseaddr) {
- if (++reuses >= REDIS_CONNECT_RETRIES) {
- goto error;
- } else {
- goto addrretry;
- }
- } else {
- if (redisContextWaitReady(c,c->timeout) != REDIS_OK)
- goto error;
- }
- }
- if (blocking && redisSetBlocking(c,1) != REDIS_OK)
- goto error;
- if (redisSetTcpNoDelay(c) != REDIS_OK)
- goto error;
-
- c->flags |= REDIS_CONNECTED;
- rv = REDIS_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);
- goto error;
- }
-
-error:
- rv = REDIS_ERR;
-end:
- freeaddrinfo(servinfo);
- return rv; // Need to return REDIS_OK if alright
-}
-
-int redisContextConnectTcp(redisContext *c, const char *addr, int port,
- const struct timeval *timeout) {
- return _redisContextConnectTcp(c, addr, port, timeout, NULL);
-}
-
-int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
- const struct timeval *timeout,
- const char *source_addr) {
- return _redisContextConnectTcp(c, addr, port, timeout, source_addr);
-}
-
-int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) {
- int blocking = (c->flags & REDIS_BLOCK);
- struct sockaddr_un sa;
-
- if (redisCreateSocket(c,AF_LOCAL) < 0)
- return REDIS_ERR;
- if (redisSetBlocking(c,0) != REDIS_OK)
- return REDIS_ERR;
-
- c->connection_type = REDIS_CONN_UNIX;
- if (c->unix_sock.path != path)
- c->unix_sock.path = strdup(path);
-
- if (timeout) {
- if (c->timeout != timeout) {
- if (c->timeout == NULL)
- c->timeout = malloc(sizeof(struct timeval));
-
- memcpy(c->timeout, timeout, sizeof(struct timeval));
- }
- } else {
- if (c->timeout)
- free(c->timeout);
- c->timeout = NULL;
- }
-
- sa.sun_family = AF_LOCAL;
- strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1);
- if (connect(c->fd, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
- if (errno == EINPROGRESS && !blocking) {
- /* This is ok. */
- } else {
- if (redisContextWaitReady(c,c->timeout) != REDIS_OK)
- return REDIS_ERR;
- }
- }
-
- /* Reset socket to be blocking after connect(2). */
- if (blocking && redisSetBlocking(c,1) != REDIS_OK)
- return REDIS_ERR;
-
- c->flags |= REDIS_CONNECTED;
- return REDIS_OK;
-}
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/net.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/net.h
deleted file mode 100644
index 2f1a0bf..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/net.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Extracted from anet.c to work properly with Hiredis error reporting.
- *
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
- * Jan-Erik Rediger <janerik at fnordig dot com>
- *
- * 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 __NET_H
-#define __NET_H
-
-#include "hiredis.h"
-
-#if defined(__sun)
-#define AF_LOCAL AF_UNIX
-#endif
-
-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,
- 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);
-
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/nodes.conf b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/nodes.conf
deleted file mode 100644
index 7c4ea80..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/nodes.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-f96f0662d3c50384e668ef6df676e871917a5aff 10.0.6.80:9002 master - 0 1492834044282 2 connected 5461-10922
-bfaf1a0f69b7515bb95036934b0075e1cc8b518f 10.0.6.81:9003 slave 06104510f3c34b74eb80bad1e30a7ab672b53936 0 1492834045288 6 connected
-06104510f3c34b74eb80bad1e30a7ab672b53936 10.0.6.80:9003 master - 0 1492834046294 3 connected 10923-16383
-072681d61fd13b0304a950baf9421df00cb75a58 10.0.6.81:9002 slave f96f0662d3c50384e668ef6df676e871917a5aff 0 1492834047301 5 connected
-a05dd2db40133a969bfaa1eb475755f08ff9cd6f 10.0.6.81:9001 slave 39dde973a9a3e054943eca5edcbc440b8d5bb317 0 1492834042267 4 connected
-39dde973a9a3e054943eca5edcbc440b8d5bb317 10.0.6.80:9001 myself,master - 0 0 1 connected 0-5460
-vars currentEpoch 6 lastVoteEpoch 0
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/read.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/read.c
deleted file mode 100644
index df1a467..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/read.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * 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 <string.h>
-#include <stdlib.h>
-#ifndef _MSC_VER
-#include <unistd.h>
-#endif
-#include <assert.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "read.h"
-#include "sds.h"
-
-static void __redisReaderSetError(redisReader *r, int type, const char *str) {
- size_t len;
-
- if (r->reply != NULL && r->fn && r->fn->freeObject) {
- r->fn->freeObject(r->reply);
- r->reply = NULL;
- }
-
- /* Clear input buffer on errors. */
- if (r->buf != NULL) {
- sdsfree(r->buf);
- r->buf = NULL;
- r->pos = r->len = 0;
- }
-
- /* Reset task stack. */
- r->ridx = -1;
-
- /* Set error. */
- r->err = type;
- len = strlen(str);
- len = len < (sizeof(r->errstr)-1) ? len : (sizeof(r->errstr)-1);
- memcpy(r->errstr,str,len);
- r->errstr[len] = '\0';
-}
-
-static size_t chrtos(char *buf, size_t size, char byte) {
- size_t len = 0;
-
- switch(byte) {
- case '\\':
- case '"':
- len = snprintf(buf,size,"\"\\%c\"",byte);
- break;
- case '\n': len = snprintf(buf,size,"\"\\n\""); break;
- case '\r': len = snprintf(buf,size,"\"\\r\""); break;
- case '\t': len = snprintf(buf,size,"\"\\t\""); break;
- case '\a': len = snprintf(buf,size,"\"\\a\""); break;
- case '\b': len = snprintf(buf,size,"\"\\b\""); break;
- default:
- if (isprint(byte))
- len = snprintf(buf,size,"\"%c\"",byte);
- else
- len = snprintf(buf,size,"\"\\x%02x\"",(unsigned char)byte);
- break;
- }
-
- return len;
-}
-
-static void __redisReaderSetErrorProtocolByte(redisReader *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);
-}
-
-static void __redisReaderSetErrorOOM(redisReader *r) {
- __redisReaderSetError(r,REDIS_ERR_OOM,"Out of memory");
-}
-
-static char *readBytes(redisReader *r, unsigned int bytes) {
- char *p;
- if (r->len-r->pos >= bytes) {
- p = r->buf+r->pos;
- r->pos += bytes;
- return p;
- }
- return NULL;
-}
-
-/* Find pointer to \r\n. */
-static char *seekNewline(char *s, size_t len) {
- int pos = 0;
- int _len = len-1;
-
- /* Position should be < len-1 because the character at "pos" should be
- * followed by a \n. Note that strchr cannot be used because it doesn't
- * allow to search a limited length and the buffer that is being searched
- * might not have a trailing NULL character. */
- while (pos < _len) {
- while(pos < _len && s[pos] != '\r') pos++;
- if (s[pos] != '\r') {
- /* Not found. */
- return NULL;
- } else {
- if (s[pos+1] == '\n') {
- /* Found. */
- return s+pos;
- } else {
- /* Continue searching. */
- pos++;
- }
- }
- }
- return NULL;
-}
-
-/* Read a long long value starting at *s, under the assumption that it will be
- * terminated by \r\n. Ambiguously returns -1 for unexpected input. */
-static long long readLongLong(char *s) {
- long long v = 0;
- int dec, mult = 1;
- char c;
-
- if (*s == '-') {
- mult = -1;
- s++;
- } else if (*s == '+') {
- mult = 1;
- s++;
- }
-
- while ((c = *(s++)) != '\r') {
- dec = c - '0';
- if (dec >= 0 && dec < 10) {
- v *= 10;
- v += dec;
- } else {
- /* Should not happen... */
- return -1;
- }
- }
-
- return mult*v;
-}
-
-static char *readLine(redisReader *r, int *_len) {
- char *p, *s;
- int len;
-
- p = r->buf+r->pos;
- s = seekNewline(p,(r->len-r->pos));
- if (s != NULL) {
- len = s-(r->buf+r->pos);
- r->pos += len+2; /* skip \r\n */
- if (_len) *_len = len;
- return p;
- }
- return NULL;
-}
-
-static void moveToNextTask(redisReader *r) {
- redisReadTask *cur, *prv;
- while (r->ridx >= 0) {
- /* Return a.s.a.p. when the stack is now empty. */
- if (r->ridx == 0) {
- r->ridx--;
- return;
- }
-
- cur = &(r->rstack[r->ridx]);
- prv = &(r->rstack[r->ridx-1]);
- assert(prv->type == REDIS_REPLY_ARRAY);
- if (cur->idx == prv->elements-1) {
- r->ridx--;
- } else {
- /* Reset the type because the next item can be anything */
- assert(cur->idx < prv->elements);
- cur->type = -1;
- cur->elements = -1;
- cur->idx++;
- return;
- }
- }
-}
-
-static int processLineItem(redisReader *r) {
- redisReadTask *cur = &(r->rstack[r->ridx]);
- void *obj;
- char *p;
- int len;
-
- if ((p = readLine(r,&len)) != NULL) {
- if (cur->type == REDIS_REPLY_INTEGER) {
- if (r->fn && r->fn->createInteger)
- obj = r->fn->createInteger(cur,readLongLong(p));
- else
- obj = (void*)REDIS_REPLY_INTEGER;
- } else {
- /* Type will be error or status. */
- if (r->fn && r->fn->createString)
- obj = r->fn->createString(cur,p,len);
- else
- obj = (void*)(size_t)(cur->type);
- }
-
- if (obj == NULL) {
- __redisReaderSetErrorOOM(r);
- return REDIS_ERR;
- }
-
- /* Set reply if this is the root object. */
- if (r->ridx == 0) r->reply = obj;
- moveToNextTask(r);
- return REDIS_OK;
- }
-
- return REDIS_ERR;
-}
-
-static int processBulkItem(redisReader *r) {
- redisReadTask *cur = &(r->rstack[r->ridx]);
- void *obj = NULL;
- char *p, *s;
- long len;
- unsigned long bytelen;
- int success = 0;
-
- p = r->buf+r->pos;
- s = seekNewline(p,r->len-r->pos);
- if (s != NULL) {
- p = r->buf+r->pos;
- bytelen = s-(r->buf+r->pos)+2; /* include \r\n */
- len = readLongLong(p);
-
- if (len < 0) {
- /* The nil object can always be created. */
- if (r->fn && r->fn->createNil)
- obj = r->fn->createNil(cur);
- else
- obj = (void*)REDIS_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 (r->fn && r->fn->createString)
- obj = r->fn->createString(cur,s+2,len);
- else
- obj = (void*)REDIS_REPLY_STRING;
- success = 1;
- }
- }
-
- /* Proceed when obj was created. */
- if (success) {
- if (obj == NULL) {
- __redisReaderSetErrorOOM(r);
- return REDIS_ERR;
- }
-
- r->pos += bytelen;
-
- /* Set reply if this is the root object. */
- if (r->ridx == 0) r->reply = obj;
- moveToNextTask(r);
- return REDIS_OK;
- }
- }
-
- return REDIS_ERR;
-}
-
-static int processMultiBulkItem(redisReader *r) {
- redisReadTask *cur = &(r->rstack[r->ridx]);
- void *obj;
- char *p;
- long elements;
- int root = 0;
-
- /* Set error for nested multi bulks with depth > 7 */
- if (r->ridx == 8) {
- __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
- "No support for nested multi bulk replies with depth > 7");
- return REDIS_ERR;
- }
-
- if ((p = readLine(r,NULL)) != NULL) {
- elements = readLongLong(p);
- root = (r->ridx == 0);
-
- if (elements == -1) {
- if (r->fn && r->fn->createNil)
- obj = r->fn->createNil(cur);
- else
- obj = (void*)REDIS_REPLY_NIL;
-
- if (obj == NULL) {
- __redisReaderSetErrorOOM(r);
- return REDIS_ERR;
- }
-
- moveToNextTask(r);
- } else {
- if (r->fn && r->fn->createArray)
- obj = r->fn->createArray(cur,elements);
- else
- obj = (void*)REDIS_REPLY_ARRAY;
-
- if (obj == NULL) {
- __redisReaderSetErrorOOM(r);
- return REDIS_ERR;
- }
-
- /* Modify task stack when there are more than 0 elements. */
- if (elements > 0) {
- cur->elements = elements;
- cur->obj = obj;
- r->ridx++;
- r->rstack[r->ridx].type = -1;
- r->rstack[r->ridx].elements = -1;
- r->rstack[r->ridx].idx = 0;
- r->rstack[r->ridx].obj = NULL;
- r->rstack[r->ridx].parent = cur;
- r->rstack[r->ridx].privdata = r->privdata;
- } else {
- moveToNextTask(r);
- }
- }
-
- /* Set reply if this is the root object. */
- if (root) r->reply = obj;
- return REDIS_OK;
- }
-
- return REDIS_ERR;
-}
-
-static int processItem(redisReader *r) {
- redisReadTask *cur = &(r->rstack[r->ridx]);
- char *p;
-
- /* check if we need to read type */
- if (cur->type < 0) {
- if ((p = readBytes(r,1)) != NULL) {
- switch (p[0]) {
- case '-':
- cur->type = REDIS_REPLY_ERROR;
- break;
- case '+':
- cur->type = REDIS_REPLY_STATUS;
- break;
- case ':':
- cur->type = REDIS_REPLY_INTEGER;
- break;
- case '$':
- cur->type = REDIS_REPLY_STRING;
- break;
- case '*':
- cur->type = REDIS_REPLY_ARRAY;
- break;
- default:
- __redisReaderSetErrorProtocolByte(r,*p);
- return REDIS_ERR;
- }
- } else {
- /* could not consume 1 byte */
- return REDIS_ERR;
- }
- }
-
- /* process typed item */
- switch(cur->type) {
- case REDIS_REPLY_ERROR:
- case REDIS_REPLY_STATUS:
- case REDIS_REPLY_INTEGER:
- return processLineItem(r);
- case REDIS_REPLY_STRING:
- return processBulkItem(r);
- case REDIS_REPLY_ARRAY:
- return processMultiBulkItem(r);
- default:
- assert(NULL);
- return REDIS_ERR; /* Avoid warning. */
- }
-}
-
-redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn) {
- redisReader *r;
-
- r = calloc(sizeof(redisReader),1);
- if (r == NULL)
- return NULL;
-
- r->err = 0;
- r->errstr[0] = '\0';
- r->fn = fn;
- r->buf = sdsempty();
- r->maxbuf = REDIS_READER_MAX_BUF;
- if (r->buf == NULL) {
- free(r);
- return NULL;
- }
-
- r->ridx = -1;
- return r;
-}
-
-void redisReaderFree(redisReader *r) {
- if (r->reply != NULL && r->fn && r->fn->freeObject)
- r->fn->freeObject(r->reply);
- if (r->buf != NULL)
- sdsfree(r->buf);
- free(r);
-}
-
-int redisReaderFeed(redisReader *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;
-
- /* Copy the provided buffer. */
- if (buf != NULL && len >= 1) {
- /* Destroy internal buffer when it is empty and is quite large. */
- if (r->len == 0 && r->maxbuf != 0 && sdsavail(r->buf) > r->maxbuf) {
- sdsfree(r->buf);
- r->buf = sdsempty();
- r->pos = 0;
-
- /* r->buf should not be NULL since we just free'd a larger one. */
- assert(r->buf != NULL);
- }
-
- newbuf = sdscatlen(r->buf,buf,len);
- if (newbuf == NULL) {
- __redisReaderSetErrorOOM(r);
- return REDIS_ERR;
- }
-
- r->buf = newbuf;
- r->len = sdslen(r->buf);
- }
-
- return REDIS_OK;
-}
-
-int redisReaderGetReply(redisReader *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;
-
- /* When the buffer is empty, there will never be a reply. */
- if (r->len == 0)
- return REDIS_OK;
-
- /* Set first item to process when the stack is empty. */
- if (r->ridx == -1) {
- r->rstack[0].type = -1;
- r->rstack[0].elements = -1;
- r->rstack[0].idx = -1;
- r->rstack[0].obj = NULL;
- r->rstack[0].parent = NULL;
- r->rstack[0].privdata = r->privdata;
- r->ridx = 0;
- }
-
- /* Process items in reply. */
- while (r->ridx >= 0)
- if (processItem(r) != REDIS_OK)
- break;
-
- /* Return ASAP when an error occurred. */
- if (r->err)
- return REDIS_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) {
- sdsrange(r->buf,r->pos,-1);
- r->pos = 0;
- r->len = sdslen(r->buf);
- }
-
- /* Emit a reply when there is one. */
- if (r->ridx == -1) {
- if (reply != NULL)
- *reply = r->reply;
- r->reply = NULL;
- }
- return REDIS_OK;
-}
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/read.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/read.h
deleted file mode 100644
index 088c979..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/read.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * 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_READ_H
-#define __HIREDIS_READ_H
-#include <stdio.h> /* for size_t */
-
-#define REDIS_ERR -1
-#define REDIS_OK 0
-
-/* When an error occurs, the err flag in a context is set to hold the type of
- * error that occured. REDIS_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_OTHER 2 /* Everything else... */
-#if 1 //shenzheng 2015-8-10 redis cluster
-#define REDIS_ERR_CLUSTER_TOO_MANY_REDIRECT 6
-#endif //shenzheng 2015-8-10 redis cluster
-
-#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_READER_MAX_BUF (1024*16) /* Default max unused reader buffer. */
-
-#if 1 //shenzheng 2015-8-22 redis cluster
-#define REDIS_ERROR_MOVED "MOVED"
-#define REDIS_ERROR_ASK "ASK"
-#define REDIS_ERROR_TRYAGAIN "TRYAGAIN"
-#define REDIS_ERROR_CROSSSLOT "CROSSSLOT"
-#define REDIS_ERROR_CLUSTERDOWN "CLUSTERDOWN"
-
-#define REDIS_STATUS_OK "OK"
-#endif //shenzheng 2015-9-24 redis cluster
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct redisReadTask {
- int type;
- int 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 */
- void *privdata; /* user-settable arbitrary field */
-} redisReadTask;
-
-typedef struct redisReplyObjectFunctions {
- void *(*createString)(const redisReadTask*, char*, size_t);
- void *(*createArray)(const redisReadTask*, int);
- void *(*createInteger)(const redisReadTask*, long long);
- void *(*createNil)(const redisReadTask*);
- void (*freeObject)(void*);
-} redisReplyObjectFunctions;
-
-typedef struct redisReader {
- int err; /* Error flags, 0 when there is no error */
- char errstr[128]; /* String representation of error when applicable */
-
- char *buf; /* Read buffer */
- size_t pos; /* Buffer cursor */
- size_t len; /* Buffer length */
- size_t maxbuf; /* Max length of unused buffer */
-
- redisReadTask rstack[9];
- int ridx; /* Index of current read task */
- void *reply; /* Temporary reply pointer */
-
- redisReplyObjectFunctions *fn;
- void *privdata;
-} redisReader;
-
-/* 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);
-
-/* Backwards compatibility, can be removed on big version bump. */
-#define redisReplyReaderCreate redisReaderCreate
-#define redisReplyReaderFree redisReaderFree
-#define redisReplyReaderFeed redisReaderFeed
-#define redisReplyReaderGetReply redisReaderGetReply
-#define redisReplyReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p))
-#define redisReplyReaderGetObject(_r) (((redisReader*)(_r))->reply)
-#define redisReplyReaderGetError(_r) (((redisReader*)(_r))->errstr)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/redis.conf b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/redis.conf
deleted file mode 100644
index 30f7784..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/redis.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-include /home/redis_cluster/redis-node/redis_comm.conf
-port 9001
-pidfile /home/redis_cluster/redis-node/9001/redis.pid
-dir /home/redis_cluster/redis-node/9001
-logfile /home/redis_cluster/redis-node/9001/redis.log
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/redis_comm.conf b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/redis_comm.conf
deleted file mode 100644
index 6af2a9b..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/redis_comm.conf
+++ /dev/null
@@ -1,254 +0,0 @@
-#是否将redis服务器作为守护进程运行
-#默认为否
-daemonize yes
-
-#集群节点信息文件
-cluster-config-file nodes.conf
-
-#tcp listen() backlog 长度
-#除了修改这里,还需要修改 /proc/sys/net/core/somaxconn
-#中的tcp_max_syn_backlog
-tcp-backlog 16384
-
-#指定监听IP
-bind 10.0.6.80
-#unix进程间通信配置
-#默认不开启
-#unixsocket /tmp/redis.sock
-#unixsocketperm 700
-
-#客户端连接超时时间,单位是秒,
-#时间内未与服务器进行交互则关闭连接
-#默认不超时
-timeout 60
-
-#客户端保活时间,单位为秒,每隔一段时间会发送SO_KEEPALIVE信号给
-#客户端,默认不开启,开启时推荐为60秒
-tcp-keepalive 0
-
-#日志等级,共有四个debug,verbose,notice,warning,
-#从前到后日志详细度越低,默认开启notice
-loglevel notice
-
-#数据库数量
-databases 16
-
-#配置数据内容持久化到本地,格式为:
-# save <seconds> <changes>
-#参数含义为在指定秒数内发生了至少指定次数的变化后就持久化数据到本地
-#当不需要持久化时可以配置 save ""
-save ""
-#save 900 1
-#save 300 10
-#save 60 10000
-
-#当持久化失败时,是否停止接受客户端写入指令
-#默认开启
-stop-writes-on-bgsave-error no
-
-#是否压缩持久化到本地的数据
-#默认开启
-rdbcompression no
-
-#是否开启RDB文件校验
-#开启会导致保存和读取时大约10%的性能损耗
-rdbchecksum no
-
-#本地持久化数据库文件名
-dbfilename dump.rdb
-
-#指定跟从的主节点
-# slaveof <masterip> <masterport>
-
-#主节点密码
-# masterauth <master-password>
-
-#当运行于从节点模式时如果数据同步正在进行中,或者是与主节点断开连接时,可以选择两种运行模式
-#默认是对客户端请求回复旧数据
-#另一种是回复错误信息"SYNC with master in progress"
-slave-serve-stale-data yes
-
-#运行于从节点模式时是否只读,默认只读
-slave-read-only yes
-
-#新的从节点加入集群时需要跟主节点同步数据,此时有两种做法,
-#一种是主节点将数据持久化到本地,再通过网络传输到从节点
-#一种是主节点直接开一个连接将数据传输到从节点。
-#默认是第一种,第二种在磁盘读写慢而网络快时效果更好。
-repl-diskless-sync no
-
-#在开启repl-diskless-sync时,可以选择延迟开启传输任务,等待更多的从节点同步请求。
-#时间单位为秒,默认5秒
-repl-diskless-sync-delay 5
-
-#从节点向主节点发送ping的时间间隔,
-#单位是秒,默认为10
-repl-ping-slave-period 10
-
-#主从节点交互超时,默认为60秒
-repl-timeout 60
-
-#是否开启TCP无延迟模式
-#开启时,redis会将数据拼接成一个更大的TCP数据包再发送,在默认设置下,会在从节点处造成最多40毫秒的延迟
-#默认为关闭,但在主从节点间距离远或者网络较拥塞的情况下开启效果更好
-repl-disable-tcp-nodelay no
-
-#从节点缓存大小
-#当从节点与主节点断开连接时,主节点的同步数据会写入到缓存中,
-#这样从节点重新连接时就不需要重新同步,只需获取缓存中的数据即可
-repl-backlog-size 1mb
-
-#从节点缓存释放时间
-#当一段时间内主节点不再有从节点连接时,会将缓存空间释放,
-#单位为秒,置0时则永不释放,默认3600
-repl-backlog-ttl 3600
-
-#从节点优先度
-#从节点优先度越低,则在主节点挂掉后被选为主节点的优先度越高
-#设置为0时则永远不会被选为主节点,默认为100
-slave-priority 100
-
-#可以设置主节点在未拥有N个从节点时不接受写入指令,例如
-# min-slaves-to-write 3
-# min-slaves-max-lag 10
-#表示在接收到写入指令的10秒内如果没有达到3个从节点时就抛弃该指令
-#当N为0时,表示关闭该限制,默认为
-min-slaves-to-write 0
-min-slaves-max-lag 10
-
-#是否需要密码
-#格式 requirepass <password>
-
-#指令重命名
-#可以通过将指令重命名来提高redis服务器的安全性,如
-#rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
-#可以将指令重命名为空字符串来禁止该指令,如
-#rename-command CONFIG ""
-
-#最大客户端连接数
-#默认为10000,超过时会向新连接发送"max number of clients reached"
-maxclients 10000
-
-#最大使用内存
-#格式 maxmemory <bytes> 8G
-maxmemory 5gb
-
-#key淘汰策略
-# volatile-lru -> remove the key with an expire set using an LRU algorithm
-# allkeys-lru -> remove any key according to the LRU algorithm
-# volatile-random -> remove a random key with an expire set
-# allkeys-random -> remove a random key, any key
-# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
-# noeviction -> don't expire at all, just return an error on write operations
-#默认为不淘汰
-maxmemory-policy volatile-lru
-
-#为了节省内存和提高效率,key淘汰时使用的LRU算法是近似算法
-#每次会选择一个子集进行淘汰,子集大小默认为5,
-#子集大小为10时结果与LRU算法类似,但会消耗更多CPU
-#子集大小为3时速度快当精确度低
-maxmemory-samples 5
-
-#是否开启appendonly模式
-#开启appendonly模式会将指令持久化到本地,在服务重启时会读取该文件
-#恢复到重启前状态,默认不开启。
-appendonly no
-
-#appendfile的文件名,默认为appendonly.aof
-appendfilename "appendonly.aof"
-
-#将缓存指令写入到本地的策略,一共有三种
-# no: don't fsync, just let the OS flush the data when it wants. Faster.
-# always: fsync after every write to the append only log. Slow, Safest.
-# everysec: fsync only one time every second. Compromise.
-#默认为
-appendfsync everysec
-
-#当触发fsync()进行I/O操作时如果有另外的如BGSAVE或BGREWRITEAOF在
-#进行磁盘操作的话可能会导致阻塞,因此需要开启该选项
-#该选项开启时相当于appendfsync模式设置为no。
-#为了确保持久性,该选项默认不开启,除非遇到延迟问题
-no-appendfsync-on-rewrite no
-
-#AOF文件自动重写
-#当AOF文件增长超过指定的百分比时,就会触发AOF重写
-#重写的大小和百分比都在改选项指定
-#百分比设置为0时表示不自动重写
-auto-aof-rewrite-percentage 100
-auto-aof-rewrite-min-size 64mb
-
-#AOF文件可能会出现末尾被截断的情况
-#此时在将AOF数据读取到内存时有两种操作
-#一种是读取尽可能多的数据,并将该情况记录到日志中
-#另一种是不读取,返回一个错误并不重启服务
-#默认是开启读取
-aof-load-truncated yes
-
-#lua脚本最长允许运行时间
-lua-time-limit 5000
-
-#开启集群模式
-cluster-enabled yes
-
-#节点超时时间,单位毫秒
-cluster-node-timeout 15000
-
-#主节点在发生故障触发故障转移时,需要从节点计算其数据的新鲜度,
-#首先从节点间会交换信息确定各自的新鲜程度排序,然后决定从节点执行故障转移的优先度
-#第二个方案是每个从节点计算各自与主节点的最迟交互时间,当该时间超过下面公式计算结果时就不会被选为故障转移的节点
-#(node-timeout * slave-validity-factor)+ repl-ping-slave-period
-#slave-validity-factor默认为10
-#slave-validity-factor 10
-
-#当从节点所属的主节点存在多个从节点,且集群存在孤立的主节点时,
-#从节点可以自动迁移到孤立的主节点下,这要求旧的主节点的从节点数量超过该选项cluster-migration-barrier指定的值
-#该选项默认为1
-cluster-migration-barrier 1
-
-#默认情况下,当存在哈希槽未被分配到节点中时,整个集群都不会接受任何指令
-#如果想要让部分拥有已被分配的哈希槽的节点继续工作,可以将该选项关闭
-cluster-require-full-coverage no
-
-#慢指令日志
-#当指令运行时间超过给定时间时就会被记录到慢指令日志
-#单位是微妙
-slowlog-log-slower-than 10000
-#慢指令日志长度
-slowlog-max-len 128
-
-#延迟监视阈值
-#默认为0,单位是毫秒
-latency-monitor-threshold 0
-
-#哈希表在下列指定大小内时,redis会采用一种紧凑的方式来存储,而不是真正的哈希表结构
-hash-max-ziplist-entries 512
-hash-max-ziplist-value 64
-
-#列表在下列指定大小内时,redis会采用一种紧凑的方式来存储,而不是真正的哈希表结构
-list-max-ziplist-entries 512
-list-max-ziplist-value 64
-
-#集合大小,含义同上
-set-max-intset-entries 512
-
-#有序集合大小,含义同上
-zset-max-ziplist-entries 128
-zset-max-ziplist-value 64
-
-#HyperLogLog稀疏表示的字节限制,含义同上
-#默认为3000
-hll-sparse-max-bytes 3000
-
-#客户端读取缓存大小限制
-#格式 client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
-#当到达hard limit时会立刻断开连接,或者当持续soft seconds超越soft limit时也会断开连接
-client-output-buffer-limit normal 0 0 0
-client-output-buffer-limit slave 256mb 64mb 60
-client-output-buffer-limit pubsub 32mb 8mb 60
-
-#处理后台任务频率,频率越高响应速度越快,但CPU消耗更大
-#默认是10,取值范围是1到500。
-hz 50
-
-#每32MB数据产生就会自动触发fsync
-aof-rewrite-incremental-fsync yes
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/sds.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/sds.c
deleted file mode 100644
index 3b1cefc..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/sds.c
+++ /dev/null
@@ -1,1095 +0,0 @@
-/* SDS (Simple Dynamic Strings), A C dynamic strings library.
- *
- * Copyright (c) 2006-2014, Salvatore Sanfilippo <antirez at gmail dot com>
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-
-#include "sds.h"
-
-/* Create a new sds string with the content specified by the 'init' pointer
- * and 'initlen'.
- * If NULL is used for 'init' the string is initialized with zero bytes.
- *
- * The string is always null-termined (all the sds strings are, always) so
- * even if you create an sds string with:
- *
- * mystring = sdsnewlen("abc",3");
- *
- * You can print the string with printf() as there is an implicit \0 at the
- * end of the string. However the string is binary safe and can contain
- * \0 characters in the middle, as the length is stored in the sds header. */
-sds sdsnewlen(const void *init, size_t initlen) {
- struct sdshdr *sh;
-
- if (init) {
- sh = malloc(sizeof *sh+initlen+1);
- } else {
- sh = calloc(sizeof *sh+initlen+1,1);
- }
- if (sh == NULL) return NULL;
- sh->len = initlen;
- sh->free = 0;
- if (initlen && init)
- memcpy(sh->buf, init, initlen);
- sh->buf[initlen] = '\0';
- return (char*)sh->buf;
-}
-
-/* Create an empty (zero length) sds string. Even in this case the string
- * always has an implicit null term. */
-sds sdsempty(void) {
- return sdsnewlen("",0);
-}
-
-/* Create a new sds string starting from a null termined C string. */
-sds sdsnew(const char *init) {
- size_t initlen = (init == NULL) ? 0 : strlen(init);
- return sdsnewlen(init, initlen);
-}
-
-/* Duplicate an sds string. */
-sds sdsdup(const sds s) {
- return sdsnewlen(s, sdslen(s));
-}
-
-/* Free an sds string. No operation is performed if 's' is NULL. */
-void sdsfree(sds s) {
- if (s == NULL) return;
- free(s-sizeof(struct sdshdr));
-}
-
-/* Set the sds string length to the length as obtained with strlen(), so
- * considering as content only up to the first null term character.
- *
- * This function is useful when the sds string is hacked manually in some
- * way, like in the following example:
- *
- * s = sdsnew("foobar");
- * s[2] = '\0';
- * sdsupdatelen(s);
- * printf("%d\n", sdslen(s));
- *
- * The output will be "2", but if we comment out the call to sdsupdatelen()
- * the output will be "6" as the string was modified but the logical length
- * remains 6 bytes. */
-void sdsupdatelen(sds s) {
- struct sdshdr *sh = (void*) (s-sizeof *sh);
- int reallen = strlen(s);
- sh->free += (sh->len-reallen);
- sh->len = reallen;
-}
-
-/* Modify an sds string on-place to make it empty (zero length).
- * However all the existing buffer is not discarded but set as free space
- * so that next append operations will not require allocations up to the
- * number of bytes previously available. */
-void sdsclear(sds s) {
- struct sdshdr *sh = (void*) (s-sizeof *sh);
- sh->free += sh->len;
- sh->len = 0;
- sh->buf[0] = '\0';
-}
-
-/* Enlarge the free space at the end of the sds string so that the caller
- * is sure that after calling this function can overwrite up to addlen
- * bytes after the end of the string, plus one more byte for nul term.
- *
- * Note: this does not change the *length* of the sds string as returned
- * by sdslen(), but only the free buffer space we have. */
-sds sdsMakeRoomFor(sds s, size_t addlen) {
- struct sdshdr *sh, *newsh;
- size_t free = sdsavail(s);
- size_t len, newlen;
-
- if (free >= addlen) return s;
- len = sdslen(s);
- sh = (void*) (s-sizeof *sh);
- newlen = (len+addlen);
- if (newlen < SDS_MAX_PREALLOC)
- newlen *= 2;
- else
- newlen += SDS_MAX_PREALLOC;
- newsh = realloc(sh, sizeof *newsh+newlen+1);
- if (newsh == NULL) return NULL;
-
- newsh->free = newlen - len;
- return newsh->buf;
-}
-
-/* Reallocate the sds string so that it has no free space at the end. The
- * contained string remains not altered, but next concatenation operations
- * will require a reallocation.
- *
- * After the call, the passed sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdsRemoveFreeSpace(sds s) {
- struct sdshdr *sh;
-
- sh = (void*) (s-sizeof *sh);
- sh = realloc(sh, sizeof *sh+sh->len+1);
- sh->free = 0;
- return sh->buf;
-}
-
-/* Return the total size of the allocation of the specifed sds string,
- * including:
- * 1) The sds header before the pointer.
- * 2) The string.
- * 3) The free buffer at the end if any.
- * 4) The implicit null term.
- */
-size_t sdsAllocSize(sds s) {
- struct sdshdr *sh = (void*) (s-sizeof *sh);
-
- return sizeof(*sh)+sh->len+sh->free+1;
-}
-
-/* Increment the sds length and decrements the left free space at the
- * end of the string according to 'incr'. Also set the null term
- * in the new end of the string.
- *
- * This function is used in order to fix the string length after the
- * user calls sdsMakeRoomFor(), writes something after the end of
- * the current string, and finally needs to set the new length.
- *
- * Note: it is possible to use a negative increment in order to
- * right-trim the string.
- *
- * Usage example:
- *
- * Using sdsIncrLen() and sdsMakeRoomFor() it is possible to mount the
- * following schema, to cat bytes coming from the kernel to the end of an
- * sds string without copying into an intermediate buffer:
- *
- * oldlen = sdslen(s);
- * s = sdsMakeRoomFor(s, BUFFER_SIZE);
- * nread = read(fd, s+oldlen, BUFFER_SIZE);
- * ... check for nread <= 0 and handle it ...
- * sdsIncrLen(s, nread);
- */
-void sdsIncrLen(sds s, int incr) {
- struct sdshdr *sh = (void*) (s-sizeof *sh);
-
- assert(sh->free >= incr);
- sh->len += incr;
- sh->free -= incr;
- assert(sh->free >= 0);
- s[sh->len] = '\0';
-}
-
-/* Grow the sds to have the specified length. Bytes that were not part of
- * the original length of the sds will be set to zero.
- *
- * if the specified length is smaller than the current length, no operation
- * is performed. */
-sds sdsgrowzero(sds s, size_t len) {
- struct sdshdr *sh = (void*) (s-sizeof *sh);
- size_t totlen, curlen = sh->len;
-
- if (len <= curlen) return s;
- s = sdsMakeRoomFor(s,len-curlen);
- if (s == NULL) return NULL;
-
- /* Make sure added region doesn't contain garbage */
- sh = (void*)(s-sizeof *sh);
- memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */
- totlen = sh->len+sh->free;
- sh->len = len;
- sh->free = totlen-sh->len;
- return s;
-}
-
-/* Append the specified binary-safe string pointed by 't' of 'len' bytes to the
- * end of the specified sds string 's'.
- *
- * After the call, the passed sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdscatlen(sds s, const void *t, size_t len) {
- struct sdshdr *sh;
- size_t curlen = sdslen(s);
-
- s = sdsMakeRoomFor(s,len); //add space to s->buf
- if (s == NULL) return NULL;
- sh = (void*) (s-sizeof *sh);
- memcpy(s+curlen, t, len);
- sh->len = curlen+len;
- sh->free = sh->free-len;
- s[curlen+len] = '\0';
- return s;
-}
-
-/* Append the specified null termianted C string to the sds string 's'.
- *
- * After the call, the passed sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdscat(sds s, const char *t) {
- return sdscatlen(s, t, strlen(t));
-}
-
-/* Append the specified sds 't' to the existing sds 's'.
- *
- * After the call, the modified sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdscatsds(sds s, const sds t) {
- return sdscatlen(s, t, sdslen(t));
-}
-
-/* Destructively modify the sds string 's' to hold the specified binary
- * safe string pointed by 't' of length 'len' bytes. */
-sds sdscpylen(sds s, const char *t, size_t len) {
- struct sdshdr *sh = (void*) (s-sizeof *sh);
- size_t totlen = sh->free+sh->len;
-
- if (totlen < len) {
- s = sdsMakeRoomFor(s,len-sh->len);
- if (s == NULL) return NULL;
- sh = (void*) (s-sizeof *sh);
- totlen = sh->free+sh->len;
- }
- memcpy(s, t, len);
- s[len] = '\0';
- sh->len = len;
- sh->free = totlen-len;
- return s;
-}
-
-/* Like sdscpylen() but 't' must be a null-termined string so that the length
- * of the string is obtained with strlen(). */
-sds sdscpy(sds s, const char *t) {
- return sdscpylen(s, t, strlen(t));
-}
-
-/* Helper for sdscatlonglong() doing the actual number -> string
- * conversion. 's' must point to a string with room for at least
- * SDS_LLSTR_SIZE bytes.
- *
- * The function returns the lenght of the null-terminated string
- * representation stored at 's'. */
-#define SDS_LLSTR_SIZE 21
-int sdsll2str(char *s, long long value) {
- char *p, aux;
- unsigned long long v;
- size_t l;
-
- /* Generate the string representation, this method produces
- * an reversed string. */
- v = (value < 0) ? -value : value;
- p = s;
- do {
- *p++ = '0'+(v%10);
- v /= 10;
- } while(v);
- if (value < 0) *p++ = '-';
-
- /* Compute length and add null term. */
- l = p-s;
- *p = '\0';
-
- /* Reverse the string. */
- p--;
- while(s < p) {
- aux = *s;
- *s = *p;
- *p = aux;
- s++;
- p--;
- }
- return l;
-}
-
-/* Identical sdsll2str(), but for unsigned long long type. */
-int sdsull2str(char *s, unsigned long long v) {
- char *p, aux;
- size_t l;
-
- /* Generate the string representation, this method produces
- * an reversed string. */
- p = s;
- do {
- *p++ = '0'+(v%10);
- v /= 10;
- } while(v);
-
- /* Compute length and add null term. */
- l = p-s;
- *p = '\0';
-
- /* Reverse the string. */
- p--;
- while(s < p) {
- aux = *s;
- *s = *p;
- *p = aux;
- s++;
- p--;
- }
- return l;
-}
-
-/* Like sdscatpritf() but gets va_list instead of being variadic. */
-sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
- va_list cpy;
- char *buf, *t;
- size_t buflen = 16;
-
- while(1) {
- buf = malloc(buflen);
- if (buf == NULL) return NULL;
- buf[buflen-2] = '\0';
- va_copy(cpy,ap);
- vsnprintf(buf, buflen, fmt, cpy);
- if (buf[buflen-2] != '\0') {
- free(buf);
- buflen *= 2;
- continue;
- }
- break;
- }
- t = sdscat(s, buf);
- free(buf);
- return t;
-}
-
-/* Append to the sds string 's' a string obtained using printf-alike format
- * specifier.
- *
- * After the call, the modified sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call.
- *
- * Example:
- *
- * s = sdsnew("Sum is: ");
- * s = sdscatprintf(s,"%d+%d = %d",a,b,a+b);
- *
- * Often you need to create a string from scratch with the printf-alike
- * format. When this is the need, just use sdsempty() as the target string:
- *
- * s = sdscatprintf(sdsempty(), "... your format ...", args);
- */
-sds sdscatprintf(sds s, const char *fmt, ...) {
- va_list ap;
- char *t;
- va_start(ap, fmt);
- t = sdscatvprintf(s,fmt,ap);
- va_end(ap);
- return t;
-}
-
-/* This function is similar to sdscatprintf, but much faster as it does
- * not rely on sprintf() family functions implemented by the libc that
- * are often very slow. Moreover directly handling the sds string as
- * new data is concatenated provides a performance improvement.
- *
- * However this function only handles an incompatible subset of printf-alike
- * format specifiers:
- *
- * %s - C String
- * %S - SDS string
- * %i - signed int
- * %I - 64 bit signed integer (long long, int64_t)
- * %u - unsigned int
- * %U - 64 bit unsigned integer (unsigned long long, uint64_t)
- * %T - A size_t variable.
- * %% - Verbatim "%" character.
- */
-sds sdscatfmt(sds s, char const *fmt, ...) {
- struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
- size_t initlen = sdslen(s);
- const char *f = fmt;
- int i;
- va_list ap;
-
- va_start(ap,fmt);
- f = fmt; /* Next format specifier byte to process. */
- i = initlen; /* Position of the next byte to write to dest str. */
- while(*f) {
- char next, *str;
- int l;
- long long num;
- unsigned long long unum;
-
- /* Make sure there is always space for at least 1 char. */
- if (sh->free == 0) {
- s = sdsMakeRoomFor(s,1);
- sh = (void*) (s-(sizeof(struct sdshdr)));
- }
-
- switch(*f) {
- case '%':
- next = *(f+1);
- f++;
- switch(next) {
- case 's':
- case 'S':
- str = va_arg(ap,char*);
- l = (next == 's') ? strlen(str) : sdslen(str);
- if (sh->free < l) {
- s = sdsMakeRoomFor(s,l);
- sh = (void*) (s-(sizeof(struct sdshdr)));
- }
- memcpy(s+i,str,l);
- sh->len += l;
- sh->free -= l;
- i += l;
- break;
- case 'i':
- case 'I':
- if (next == 'i')
- num = va_arg(ap,int);
- else
- num = va_arg(ap,long long);
- {
- char buf[SDS_LLSTR_SIZE];
- l = sdsll2str(buf,num);
- if (sh->free < l) {
- s = sdsMakeRoomFor(s,l);
- sh = (void*) (s-(sizeof(struct sdshdr)));
- }
- memcpy(s+i,buf,l);
- sh->len += l;
- sh->free -= l;
- i += l;
- }
- break;
- case 'u':
- case 'U':
- case 'T':
- if (next == 'u')
- unum = va_arg(ap,unsigned int);
- else if(next == 'U')
- unum = va_arg(ap,unsigned long long);
- else
- unum = (unsigned long long)va_arg(ap,size_t);
- {
- char buf[SDS_LLSTR_SIZE];
- l = sdsull2str(buf,unum);
- if (sh->free < l) {
- s = sdsMakeRoomFor(s,l);
- sh = (void*) (s-(sizeof(struct sdshdr)));
- }
- memcpy(s+i,buf,l);
- sh->len += l;
- sh->free -= l;
- i += l;
- }
- break;
- default: /* Handle %% and generally %<unknown>. */
- s[i++] = next;
- sh->len += 1;
- sh->free -= 1;
- break;
- }
- break;
- default:
- s[i++] = *f;
- sh->len += 1;
- sh->free -= 1;
- break;
- }
- f++;
- }
- va_end(ap);
-
- /* Add null-term */
- s[i] = '\0';
- return s;
-}
-
-
-/* Remove the part of the string from left and from right composed just of
- * contiguous characters found in 'cset', that is a null terminted C string.
- *
- * After the call, the modified sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call.
- *
- * Example:
- *
- * s = sdsnew("AA...AA.a.aa.aHelloWorld :::");
- * s = sdstrim(s,"A. :");
- * printf("%s\n", s);
- *
- * Output will be just "Hello World".
- */
-void sdstrim(sds s, const char *cset) {
- struct sdshdr *sh = (void*) (s-sizeof *sh);
- char *start, *end, *sp, *ep;
- size_t len;
-
- sp = start = s;
- ep = end = s+sdslen(s)-1;
- while(sp <= end && strchr(cset, *sp)) sp++;
- while(ep > start && strchr(cset, *ep)) ep--;
- len = (sp > ep) ? 0 : ((ep-sp)+1);
- if (sh->buf != sp) memmove(sh->buf, sp, len);
- sh->buf[len] = '\0';
- sh->free = sh->free+(sh->len-len);
- sh->len = len;
-}
-
-/* Turn the string into a smaller (or equal) string containing only the
- * substring specified by the 'start' and 'end' indexes.
- *
- * start and end can be negative, where -1 means the last character of the
- * string, -2 the penultimate character, and so forth.
- *
- * The interval is inclusive, so the start and end characters will be part
- * of the resulting string.
- *
- * The string is modified in-place.
- *
- * Example:
- *
- * s = sdsnew("Hello World");
- * sdsrange(s,1,-1); => "ello World"
- */
-void sdsrange(sds s, int start, int end) {
- struct sdshdr *sh = (void*) (s-sizeof *sh);
- size_t newlen, len = sdslen(s);
-
- if (len == 0) return;
- if (start < 0) {
- start = len+start;
- if (start < 0) start = 0;
- }
- if (end < 0) {
- end = len+end;
- if (end < 0) end = 0;
- }
- newlen = (start > end) ? 0 : (end-start)+1;
- if (newlen != 0) {
- if (start >= (signed)len) {
- newlen = 0;
- } else if (end >= (signed)len) {
- end = len-1;
- newlen = (start > end) ? 0 : (end-start)+1;
- }
- } else {
- start = 0;
- }
- if (start && newlen) memmove(sh->buf, sh->buf+start, newlen);
- sh->buf[newlen] = 0;
- sh->free = sh->free+(sh->len-newlen);
- sh->len = newlen;
-}
-
-/* Apply tolower() to every character of the sds string 's'. */
-void sdstolower(sds s) {
- int len = sdslen(s), j;
-
- for (j = 0; j < len; j++) s[j] = tolower(s[j]);
-}
-
-/* Apply toupper() to every character of the sds string 's'. */
-void sdstoupper(sds s) {
- int len = sdslen(s), j;
-
- for (j = 0; j < len; j++) s[j] = toupper(s[j]);
-}
-
-/* Compare two sds strings s1 and s2 with memcmp().
- *
- * Return value:
- *
- * 1 if s1 > s2.
- * -1 if s1 < s2.
- * 0 if s1 and s2 are exactly the same binary string.
- *
- * If two strings share exactly the same prefix, but one of the two has
- * additional characters, the longer string is considered to be greater than
- * the smaller one. */
-int sdscmp(const sds s1, const sds s2) {
- size_t l1, l2, minlen;
- int cmp;
-
- l1 = sdslen(s1);
- l2 = sdslen(s2);
- minlen = (l1 < l2) ? l1 : l2;
- cmp = memcmp(s1,s2,minlen);
- if (cmp == 0) return l1-l2;
- return cmp;
-}
-
-/* Split 's' with separator in 'sep'. An array
- * of sds strings is returned. *count will be set
- * by reference to the number of tokens returned.
- *
- * On out of memory, zero length string, zero length
- * separator, NULL is returned.
- *
- * Note that 'sep' is able to split a string using
- * a multi-character separator. For example
- * sdssplit("foo_-_bar","_-_"); will return two
- * elements "foo" and "bar".
- *
- * This version of the function is binary-safe but
- * requires length arguments. sdssplit() is just the
- * same function but for zero-terminated strings.
- */
-sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count) {
- int elements = 0, slots = 5, start = 0, j;
- sds *tokens;
-
- if (seplen < 1 || len < 0) return NULL;
-
- tokens = malloc(sizeof(sds)*slots);
- if (tokens == NULL) return NULL;
-
- if (len == 0) {
- *count = 0;
- return tokens;
- }
- for (j = 0; j < (len-(seplen-1)); j++) {
- /* make sure there is room for the next element and the final one */
- if (slots < elements+2) {
- sds *newtokens;
-
- slots *= 2;
- newtokens = realloc(tokens,sizeof(sds)*slots);
- if (newtokens == NULL) goto cleanup;
- tokens = newtokens;
- }
- /* search the separator */
- if ((seplen == 1 && *(s+j) == sep[0]) || (memcmp(s+j,sep,seplen) == 0)) {
- tokens[elements] = sdsnewlen(s+start,j-start);
- if (tokens[elements] == NULL) goto cleanup;
- elements++;
- start = j+seplen;
- j = j+seplen-1; /* skip the separator */
- }
- }
- /* Add the final element. We are sure there is room in the tokens array. */
- tokens[elements] = sdsnewlen(s+start,len-start);
- if (tokens[elements] == NULL) goto cleanup;
- elements++;
- *count = elements;
- return tokens;
-
-cleanup:
- {
- int i;
- for (i = 0; i < elements; i++) sdsfree(tokens[i]);
- free(tokens);
- *count = 0;
- return NULL;
- }
-}
-
-/* Free the result returned by sdssplitlen(), or do nothing if 'tokens' is NULL. */
-void sdsfreesplitres(sds *tokens, int count) {
- if (!tokens) return;
- while(count--)
- sdsfree(tokens[count]);
- free(tokens);
-}
-
-/* Create an sds string from a long long value. It is much faster than:
- *
- * sdscatprintf(sdsempty(),"%lld\n", value);
- */
-sds sdsfromlonglong(long long value) {
- char buf[32], *p;
- unsigned long long v;
-
- v = (value < 0) ? -value : value;
- p = buf+31; /* point to the last character */
- do {
- *p-- = '0'+(v%10);
- v /= 10;
- } while(v);
- if (value < 0) *p-- = '-';
- p++;
- return sdsnewlen(p,32-(p-buf));
-}
-
-/* Append to the sds string "s" an escaped string representation where
- * all the non-printable characters (tested with isprint()) are turned into
- * escapes in the form "\n\r\a...." or "\x<hex-number>".
- *
- * After the call, the modified sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdscatrepr(sds s, const char *p, size_t len) {
- s = sdscatlen(s,"\"",1);
- while(len--) {
- switch(*p) {
- case '\\':
- case '"':
- s = sdscatprintf(s,"\\%c",*p);
- break;
- case '\n': s = sdscatlen(s,"\\n",2); break;
- case '\r': s = sdscatlen(s,"\\r",2); break;
- case '\t': s = sdscatlen(s,"\\t",2); break;
- case '\a': s = sdscatlen(s,"\\a",2); break;
- case '\b': s = sdscatlen(s,"\\b",2); break;
- default:
- if (isprint(*p))
- s = sdscatprintf(s,"%c",*p);
- else
- s = sdscatprintf(s,"\\x%02x",(unsigned char)*p);
- break;
- }
- p++;
- }
- return sdscatlen(s,"\"",1);
-}
-
-/* Helper function for sdssplitargs() that returns non zero if 'c'
- * is a valid hex digit. */
-int is_hex_digit(char c) {
- return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
- (c >= 'A' && c <= 'F');
-}
-
-/* Helper function for sdssplitargs() that converts a hex digit into an
- * integer from 0 to 15 */
-int hex_digit_to_int(char c) {
- switch(c) {
- case '0': return 0;
- case '1': return 1;
- case '2': return 2;
- case '3': return 3;
- case '4': return 4;
- case '5': return 5;
- case '6': return 6;
- case '7': return 7;
- case '8': return 8;
- case '9': return 9;
- case 'a': case 'A': return 10;
- case 'b': case 'B': return 11;
- case 'c': case 'C': return 12;
- case 'd': case 'D': return 13;
- case 'e': case 'E': return 14;
- case 'f': case 'F': return 15;
- default: return 0;
- }
-}
-
-/* Split a line into arguments, where every argument can be in the
- * following programming-language REPL-alike form:
- *
- * foo bar "newline are supported\n" and "\xff\x00otherstuff"
- *
- * The number of arguments is stored into *argc, and an array
- * of sds is returned.
- *
- * The caller should free the resulting array of sds strings with
- * sdsfreesplitres().
- *
- * Note that sdscatrepr() is able to convert back a string into
- * a quoted string in the same format sdssplitargs() is able to parse.
- *
- * The function returns the allocated tokens on success, even when the
- * input string is empty, or NULL if the input contains unbalanced
- * quotes or closed quotes followed by non space characters
- * as in: "foo"bar or "foo'
- */
-sds *sdssplitargs(const char *line, int *argc) {
- const char *p = line;
- char *current = NULL;
- char **vector = NULL;
-
- *argc = 0;
- while(1) {
- /* skip blanks */
- while(*p && isspace(*p)) p++;
- if (*p) {
- /* get a token */
- int inq=0; /* set to 1 if we are in "quotes" */
- int insq=0; /* set to 1 if we are in 'single quotes' */
- int done=0;
-
- if (current == NULL) current = sdsempty();
- while(!done) {
- if (inq) {
- if (*p == '\\' && *(p+1) == 'x' &&
- is_hex_digit(*(p+2)) &&
- is_hex_digit(*(p+3)))
- {
- unsigned char byte;
-
- byte = (hex_digit_to_int(*(p+2))*16)+
- hex_digit_to_int(*(p+3));
- current = sdscatlen(current,(char*)&byte,1);
- p += 3;
- } else if (*p == '\\' && *(p+1)) {
- char c;
-
- p++;
- switch(*p) {
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- case 'b': c = '\b'; break;
- case 'a': c = '\a'; break;
- default: c = *p; break;
- }
- current = sdscatlen(current,&c,1);
- } else if (*p == '"') {
- /* closing quote must be followed by a space or
- * nothing at all. */
- if (*(p+1) && !isspace(*(p+1))) goto err;
- done=1;
- } else if (!*p) {
- /* unterminated quotes */
- goto err;
- } else {
- current = sdscatlen(current,p,1);
- }
- } else if (insq) {
- if (*p == '\\' && *(p+1) == '\'') {
- p++;
- current = sdscatlen(current,"'",1);
- } else if (*p == '\'') {
- /* closing quote must be followed by a space or
- * nothing at all. */
- if (*(p+1) && !isspace(*(p+1))) goto err;
- done=1;
- } else if (!*p) {
- /* unterminated quotes */
- goto err;
- } else {
- current = sdscatlen(current,p,1);
- }
- } else {
- switch(*p) {
- case ' ':
- case '\n':
- case '\r':
- case '\t':
- case '\0':
- done=1;
- break;
- case '"':
- inq=1;
- break;
- case '\'':
- insq=1;
- break;
- default:
- current = sdscatlen(current,p,1);
- break;
- }
- }
- if (*p) p++;
- }
- /* add the token to the vector */
- vector = realloc(vector,((*argc)+1)*sizeof(char*));
- vector[*argc] = current;
- (*argc)++;
- current = NULL;
- } else {
- /* Even on empty input string return something not NULL. */
- if (vector == NULL) vector = malloc(sizeof(void*));
- return vector;
- }
- }
-
-err:
- while((*argc)--)
- sdsfree(vector[*argc]);
- free(vector);
- if (current) sdsfree(current);
- *argc = 0;
- return NULL;
-}
-
-/* Modify the string substituting all the occurrences of the set of
- * characters specified in the 'from' string to the corresponding character
- * in the 'to' array.
- *
- * For instance: sdsmapchars(mystring, "ho", "01", 2)
- * will have the effect of turning the string "hello" into "0ell1".
- *
- * The function returns the sds string pointer, that is always the same
- * as the input pointer since no resize is needed. */
-sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen) {
- size_t j, i, l = sdslen(s);
-
- for (j = 0; j < l; j++) {
- for (i = 0; i < setlen; i++) {
- if (s[j] == from[i]) {
- s[j] = to[i];
- break;
- }
- }
- }
- return s;
-}
-
-/* Join an array of C strings using the specified separator (also a C string).
- * Returns the result as an sds string. */
-sds sdsjoin(char **argv, int argc, char *sep, size_t seplen) {
- sds join = sdsempty();
- int j;
-
- for (j = 0; j < argc; j++) {
- join = sdscat(join, argv[j]);
- if (j != argc-1) join = sdscatlen(join,sep,seplen);
- }
- return join;
-}
-
-/* Like sdsjoin, but joins an array of SDS strings. */
-sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) {
- sds join = sdsempty();
- int j;
-
- for (j = 0; j < argc; j++) {
- join = sdscatsds(join, argv[j]);
- if (j != argc-1) join = sdscatlen(join,sep,seplen);
- }
- return join;
-}
-
-#ifdef SDS_TEST_MAIN
-#include <stdio.h>
-#include "testhelp.h"
-
-int main(void) {
- {
- struct sdshdr *sh;
- sds x = sdsnew("foo"), y;
-
- test_cond("Create a string and obtain the length",
- sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0)
-
- sdsfree(x);
- x = sdsnewlen("foo",2);
- test_cond("Create a string with specified length",
- sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0)
-
- x = sdscat(x,"bar");
- test_cond("Strings concatenation",
- sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0);
-
- x = sdscpy(x,"a");
- test_cond("sdscpy() against an originally longer string",
- sdslen(x) == 1 && memcmp(x,"a\0",2) == 0)
-
- x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk");
- test_cond("sdscpy() against an originally shorter string",
- sdslen(x) == 33 &&
- memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0)
-
- sdsfree(x);
- x = sdscatprintf(sdsempty(),"%d",123);
- test_cond("sdscatprintf() seems working in the base case",
- sdslen(x) == 3 && memcmp(x,"123\0",4) ==0)
-
- sdsfree(x);
- x = sdsnew("xxciaoyyy");
- sdstrim(x,"xy");
- test_cond("sdstrim() correctly trims characters",
- sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0)
-
- y = sdsdup(x);
- sdsrange(y,1,1);
- test_cond("sdsrange(...,1,1)",
- sdslen(y) == 1 && memcmp(y,"i\0",2) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,1,-1);
- test_cond("sdsrange(...,1,-1)",
- sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,-2,-1);
- test_cond("sdsrange(...,-2,-1)",
- sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,2,1);
- test_cond("sdsrange(...,2,1)",
- sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,1,100);
- test_cond("sdsrange(...,1,100)",
- sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,100,100);
- test_cond("sdsrange(...,100,100)",
- sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
-
- sdsfree(y);
- sdsfree(x);
- x = sdsnew("foo");
- y = sdsnew("foa");
- test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0)
-
- sdsfree(y);
- sdsfree(x);
- x = sdsnew("bar");
- y = sdsnew("bar");
- test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0)
-
- sdsfree(y);
- sdsfree(x);
- x = sdsnew("aar");
- y = sdsnew("bar");
- test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0)
-
- sdsfree(y);
- sdsfree(x);
- x = sdsnewlen("\a\n\0foo\r",7);
- y = sdscatrepr(sdsempty(),x,sdslen(x));
- test_cond("sdscatrepr(...data...)",
- memcmp(y,"\"\\a\\n\\x00foo\\r\"",15) == 0)
-
- {
- int oldfree;
-
- sdsfree(x);
- x = sdsnew("0");
- sh = (void*) (x-(sizeof(struct sdshdr)));
- test_cond("sdsnew() free/len buffers", sh->len == 1 && sh->free == 0);
- x = sdsMakeRoomFor(x,1);
- sh = (void*) (x-(sizeof(struct sdshdr)));
- test_cond("sdsMakeRoomFor()", sh->len == 1 && sh->free > 0);
- oldfree = sh->free;
- x[1] = '1';
- sdsIncrLen(x,1);
- test_cond("sdsIncrLen() -- content", x[0] == '0' && x[1] == '1');
- test_cond("sdsIncrLen() -- len", sh->len == 2);
- test_cond("sdsIncrLen() -- free", sh->free == oldfree-1);
- }
- }
- test_report()
- return 0;
-}
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/sds.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/sds.h
deleted file mode 100644
index 19a2abd..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/sds.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* SDS (Simple Dynamic Strings), A C dynamic strings library.
- *
- * Copyright (c) 2006-2014, Salvatore Sanfilippo <antirez at gmail dot com>
- * 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 __SDS_H
-#define __SDS_H
-
-#define SDS_MAX_PREALLOC (1024*1024)
-
-#include <sys/types.h>
-#include <stdarg.h>
-#ifdef _MSC_VER
-#include "win32.h"
-#endif
-
-typedef char *sds;
-
-struct sdshdr {
- int len;
- int free;
- char buf[];
-};
-
-static inline size_t sdslen(const sds s) {
- struct sdshdr *sh = (struct sdshdr *)(s-sizeof *sh);
- return sh->len;
-}
-
-static inline size_t sdsavail(const sds s) {
- struct sdshdr *sh = (struct sdshdr *)(s-sizeof *sh);
- return sh->free;
-}
-
-sds sdsnewlen(const void *init, size_t initlen);
-sds sdsnew(const char *init);
-sds sdsempty(void);
-size_t sdslen(const sds s);
-sds sdsdup(const sds s);
-void sdsfree(sds s);
-size_t sdsavail(const sds s);
-sds sdsgrowzero(sds s, size_t len);
-sds sdscatlen(sds s, const void *t, size_t len);
-sds sdscat(sds s, const char *t);
-sds sdscatsds(sds s, const sds t);
-sds sdscpylen(sds s, const char *t, size_t len);
-sds sdscpy(sds s, const char *t);
-
-sds sdscatvprintf(sds s, const char *fmt, va_list ap);
-#ifdef __GNUC__
-sds sdscatprintf(sds s, const char *fmt, ...)
- __attribute__((format(printf, 2, 3)));
-#else
-sds sdscatprintf(sds s, const char *fmt, ...);
-#endif
-
-sds sdscatfmt(sds s, char const *fmt, ...);
-void sdstrim(sds s, const char *cset);
-void sdsrange(sds s, int start, int end);
-void sdsupdatelen(sds s);
-void sdsclear(sds s);
-int sdscmp(const sds s1, const sds s2);
-sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count);
-void sdsfreesplitres(sds *tokens, int count);
-void sdstolower(sds s);
-void sdstoupper(sds s);
-sds sdsfromlonglong(long long value);
-sds sdscatrepr(sds s, const char *p, size_t len);
-sds *sdssplitargs(const char *line, int *argc);
-sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
-sds sdsjoin(char **argv, int argc, char *sep, size_t seplen);
-sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);
-
-/* Low level functions exposed to the user API */
-sds sdsMakeRoomFor(sds s, size_t addlen);
-void sdsIncrLen(sds s, int incr);
-sds sdsRemoveFreeSpace(sds s);
-size_t sdsAllocSize(sds s);
-
-#endif
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/test.c b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/test.c
deleted file mode 100644
index 8fde554..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/test.c
+++ /dev/null
@@ -1,806 +0,0 @@
-#include "fmacros.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <sys/time.h>
-#include <assert.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <limits.h>
-
-#include "hiredis.h"
-#include "net.h"
-
-enum connection_type {
- CONN_TCP,
- CONN_UNIX,
- CONN_FD
-};
-
-struct config {
- enum connection_type type;
-
- struct {
- const char *host;
- int port;
- struct timeval timeout;
- } tcp;
-
- struct {
- const char *path;
- } unix;
-};
-
-/* The following lines make up our testing "framework" :) */
-static int tests = 0, fails = 0;
-#define test(_s) { printf("#%02d ", ++tests); printf(_s); }
-#define test_cond(_c) if(_c) printf("\033[0;32mPASSED\033[0;0m\n"); else {printf("\033[0;31mFAILED\033[0;0m\n"); fails++;}
-
-static long long usec(void) {
- struct timeval tv;
- gettimeofday(&tv,NULL);
- return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
-}
-
-/* The assert() calls below have side effects, so we need assert()
- * even if we are compiling without asserts (-DNDEBUG). */
-#ifdef NDEBUG
-#undef assert
-#define assert(e) (void)(e)
-#endif
-
-static redisContext *select_database(redisContext *c) {
- redisReply *reply;
-
- /* Switch to DB 9 for testing, now that we know we can chat. */
- reply = redisCommand(c,"SELECT 9");
- assert(reply != NULL);
- freeReplyObject(reply);
-
- /* Make sure the DB is emtpy */
- reply = redisCommand(c,"DBSIZE");
- assert(reply != NULL);
- if (reply->type == REDIS_REPLY_INTEGER && reply->integer == 0) {
- /* Awesome, DB 9 is empty and we can continue. */
- freeReplyObject(reply);
- } else {
- printf("Database #9 is not empty, test can not continue\n");
- exit(1);
- }
-
- return c;
-}
-
-static int disconnect(redisContext *c, int keep_fd) {
- redisReply *reply;
-
- /* Make sure we're on DB 9. */
- reply = redisCommand(c,"SELECT 9");
- assert(reply != NULL);
- freeReplyObject(reply);
- reply = redisCommand(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 -1;
-}
-
-static redisContext *connect(struct config config) {
- redisContext *c = NULL;
-
- if (config.type == CONN_TCP) {
- c = redisConnect(config.tcp.host, config.tcp.port);
- } else if (config.type == CONN_UNIX) {
- c = redisConnectUnix(config.unix.path);
- } else if (config.type == CONN_FD) {
- /* Create a dummy connection just to get an fd to inherit */
- redisContext *dummy_ctx = redisConnectUnix(config.unix.path);
- if (dummy_ctx) {
- int fd = disconnect(dummy_ctx, 1);
- printf("Connecting to inherited fd %d\n", fd);
- c = redisConnectFd(fd);
- }
- } else {
- assert(NULL);
- }
-
- if (c == NULL) {
- printf("Connection error: can't allocate redis context\n");
- exit(1);
- } else if (c->err) {
- printf("Connection error: %s\n", c->errstr);
- redisFree(c);
- exit(1);
- }
-
- return select_database(c);
-}
-
-static void test_format_commands(void) {
- char *cmd;
- int len;
-
- test("Format command without interpolation: ");
- len = redisFormatCommand(&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));
- free(cmd);
-
- test("Format command with %%s string interpolation: ");
- len = redisFormatCommand(&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));
- free(cmd);
-
- test("Format command with %%s and an empty string: ");
- len = redisFormatCommand(&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));
- free(cmd);
-
- test("Format command with an empty string in between proper interpolations: ");
- len = redisFormatCommand(&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));
- free(cmd);
-
- test("Format command with %%b string interpolation: ");
- len = redisFormatCommand(&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));
- free(cmd);
-
- test("Format command with %%b and an empty string: ");
- len = redisFormatCommand(&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));
- free(cmd);
-
- test("Format command with literal %%: ");
- len = redisFormatCommand(&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));
- free(cmd);
-
- /* Vararg width depends on the type. These tests make sure that the
- * width is correctly determined using the format and subsequent varargs
- * can correctly be interpolated. */
-#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"); \
- 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)); \
- 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"); \
- 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)); \
- free(cmd); \
-} while(0)
-
- INTEGER_WIDTH_TEST("d", int);
- INTEGER_WIDTH_TEST("hhd", char);
- INTEGER_WIDTH_TEST("hd", short);
- INTEGER_WIDTH_TEST("ld", long);
- INTEGER_WIDTH_TEST("lld", long long);
- INTEGER_WIDTH_TEST("u", unsigned int);
- INTEGER_WIDTH_TEST("hhu", unsigned char);
- INTEGER_WIDTH_TEST("hu", unsigned short);
- INTEGER_WIDTH_TEST("lu", unsigned long);
- INTEGER_WIDTH_TEST("llu", unsigned long long);
- FLOAT_WIDTH_TEST(float);
- FLOAT_WIDTH_TEST(double);
-
- test("Format command with invalid printf format: ");
- len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3);
- test_cond(len == -1);
-
- const char *argv[3];
- argv[0] = "SET";
- argv[1] = "foo\0xxx";
- argv[2] = "bar";
- size_t lens[3] = { 3, 7, 3 };
- int argc = 3;
-
- test("Format command by passing argc/argv without lengths: ");
- len = redisFormatCommandArgv(&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));
- free(cmd);
-
- test("Format command by passing argc/argv with lengths: ");
- len = redisFormatCommandArgv(&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));
- free(cmd);
-}
-
-static void test_append_formatted_commands(struct config config) {
- redisContext *c;
- redisReply *reply;
- char *cmd;
- int len;
-
- c = connect(config);
-
- test("Append format command: ");
-
- len = redisFormatCommand(&cmd, "SET foo bar");
-
- test_cond(redisAppendFormattedCommand(c, cmd, len) == REDIS_OK);
-
- assert(redisGetReply(c, (void*)&reply) == REDIS_OK);
-
- free(cmd);
- freeReplyObject(reply);
-
- disconnect(c, 0);
-}
-
-static void test_reply_reader(void) {
- redisReader *reader;
- void *reply;
- 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 &&
- strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0);
- redisReaderFree(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 &&
- strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0);
- redisReaderFree(reader);
-
- test("Set error on nested multi bulks with depth > 7: ");
- reader = redisReaderCreate();
-
- for (i = 0; i < 9; i++) {
- redisReaderFeed(reader,(char*)"*1\r\n",4);
- }
-
- ret = redisReaderGetReply(reader,NULL);
- test_cond(ret == REDIS_ERR &&
- strncasecmp(reader->errstr,"No support for",14) == 0);
- redisReaderFree(reader);
-
- test("Works with NULL functions for reply: ");
- reader = redisReaderCreate();
- 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);
-
- test("Works when a single newline (\\r\\n) covers two calls to feed: ");
- reader = redisReaderCreate();
- 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);
-
- test("Don't reset state after protocol error: ");
- reader = redisReaderCreate();
- 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);
-
- /* 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);
- freeReplyObject(reply);
- redisReaderFree(reader);
-}
-
-static void test_free_null(void) {
- void *redisContext = NULL;
- void *reply = NULL;
-
- test("Don't fail when redisFree is passed a NULL value: ");
- redisFree(redisContext);
- test_cond(redisContext == NULL);
-
- test("Don't fail when freeReplyObject is passed a NULL value: ");
- freeReplyObject(reply);
- test_cond(reply == NULL);
-}
-
-static void test_blocking_connection_errors(void) {
- redisContext *c;
-
- test("Returns error when host cannot be resolved: ");
- c = redisConnect((char*)"idontexist.test", 6379);
- test_cond(c->err == REDIS_ERR_OTHER &&
- (strcmp(c->errstr,"Name or service not known") == 0 ||
- strcmp(c->errstr,"Can't resolve: idontexist.test") == 0 ||
- strcmp(c->errstr,"nodename nor servname provided, or not known") == 0 ||
- strcmp(c->errstr,"No address associated with hostname") == 0 ||
- strcmp(c->errstr,"Temporary failure in name resolution") == 0 ||
- strcmp(c->errstr,"no address associated with name") == 0));
- redisFree(c);
-
- test("Returns error when the port is not open: ");
- c = redisConnect((char*)"localhost", 1);
- test_cond(c->err == REDIS_ERR_IO &&
- strcmp(c->errstr,"Connection refused") == 0);
- redisFree(c);
-
- test("Returns error when the unix 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);
-}
-
-static void test_blocking_connection(struct config config) {
- redisContext *c;
- redisReply *reply;
-
- c = connect(config);
-
- test("Is able to deliver commands: ");
- reply = redisCommand(c,"PING");
- test_cond(reply->type == REDIS_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 &&
- strcasecmp(reply->str,"ok") == 0)
- freeReplyObject(reply);
-
- test("%%s String interpolation works: ");
- reply = redisCommand(c,"SET %s %s","foo","hello world");
- freeReplyObject(reply);
- reply = redisCommand(c,"GET foo");
- test_cond(reply->type == REDIS_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);
- freeReplyObject(reply);
- reply = redisCommand(c,"GET foo");
- test_cond(reply->type == REDIS_REPLY_STRING &&
- memcmp(reply->str,"hello\x00world",11) == 0)
-
- test("Binary reply length is correct: ");
- test_cond(reply->len == 11)
- freeReplyObject(reply);
-
- test("Can parse nil replies: ");
- reply = redisCommand(c,"GET nokey");
- test_cond(reply->type == REDIS_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)
- 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 &&
- reply->elements == 2 &&
- !memcmp(reply->element[0]->str,"bar",3) &&
- !memcmp(reply->element[1]->str,"foo",3))
- freeReplyObject(reply);
-
- /* 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 &&
- reply->elements == 2 &&
- reply->element[0]->type == REDIS_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 &&
- strcasecmp(reply->element[1]->str,"pong") == 0);
- freeReplyObject(reply);
-
- disconnect(c, 0);
-}
-
-static void test_blocking_connection_timeouts(struct config config) {
- redisContext *c;
- redisReply *reply;
- ssize_t s;
- const char *cmd = "DEBUG SLEEP 3\r\n";
- struct timeval tv;
-
- c = connect(config);
- test("Successfully completes a command when the timeout is not exceeded: ");
- reply = redisCommand(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);
- freeReplyObject(reply);
- disconnect(c, 0);
-
- c = connect(config);
- test("Does not return a reply when the command times out: ");
- s = write(c->fd, cmd, strlen(cmd));
- tv.tv_sec = 0;
- tv.tv_usec = 10000;
- redisSetTimeout(c, tv);
- reply = redisCommand(c, "GET foo");
- test_cond(s > 0 && reply == NULL && c->err == REDIS_ERR_IO && strcmp(c->errstr, "Resource temporarily unavailable") == 0);
- freeReplyObject(reply);
-
- test("Reconnect properly reconnects after a timeout: ");
- redisReconnect(c);
- reply = redisCommand(c, "PING");
- test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0);
- freeReplyObject(reply);
-
- test("Reconnect properly uses owned parameters: ");
- config.tcp.host = "foo";
- config.unix.path = "foo";
- redisReconnect(c);
- reply = redisCommand(c, "PING");
- test_cond(reply != NULL && reply->type == REDIS_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;
- void *_reply;
- int major, minor;
-
- /* Connect to target given by config. */
- c = connect(config);
- {
- /* Find out Redis version to determine the path for the next test */
- const char *field = "redis_version:";
- char *p, *eptr;
-
- reply = redisCommand(c,"INFO");
- p = strstr(reply->str,field);
- major = strtol(p+strlen(field),&eptr,10);
- p = eptr+1; /* char next to the first "." */
- minor = strtol(p,&eptr,10);
- freeReplyObject(reply);
- }
-
- test("Returns I/O error when the connection is lost: ");
- reply = redisCommand(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);
- freeReplyObject(reply);
- } else {
- test_cond(reply == NULL);
- }
-
- /* On 2.0, QUIT will cause the connection to be closed immediately and
- * the read(2) for the reply on QUIT will set the error to EOF.
- * 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 &&
- strcmp(c->errstr,"Server closed the connection") == 0);
- redisFree(c);
-
- c = connect(config);
- test("Returns I/O error on socket timeout: ");
- struct timeval tv = { 0, 1000 };
- assert(redisSetTimeout(c,tv) == REDIS_OK);
- test_cond(redisGetReply(c,&_reply) == REDIS_ERR &&
- c->err == REDIS_ERR_IO && errno == EAGAIN);
- redisFree(c);
-}
-
-static void test_invalid_timeout_errors(struct config config) {
- redisContext *c;
-
- test("Set error when an invalid timeout usec value is given to redisConnectWithTimeout: ");
-
- config.tcp.timeout.tv_sec = 0;
- config.tcp.timeout.tv_usec = 10000001;
-
- c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
-
- test_cond(c->err == REDIS_ERR_IO);
- redisFree(c);
-
- test("Set error when an invalid timeout sec value is given to redisConnectWithTimeout: ");
-
- config.tcp.timeout.tv_sec = (((LONG_MAX) - 999) / 1000) + 1;
- config.tcp.timeout.tv_usec = 0;
-
- c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
-
- test_cond(c->err == REDIS_ERR_IO);
- redisFree(c);
-}
-
-static void test_throughput(struct config config) {
- redisContext *c = connect(config);
- redisReply **replies;
- int i, num;
- long long t1, t2;
-
- test("Throughput:\n");
- for (i = 0; i < 500; i++)
- freeReplyObject(redisCommand(c,"LPUSH mylist foo"));
-
- num = 1000;
- replies = malloc(sizeof(redisReply*)*num);
- t1 = usec();
- for (i = 0; i < num; i++) {
- replies[i] = redisCommand(c,"PING");
- assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS);
- }
- t2 = usec();
- for (i = 0; i < num; i++) freeReplyObject(replies[i]);
- free(replies);
- printf("\t(%dx PING: %.3fs)\n", num, (t2-t1)/1000000.0);
-
- replies = malloc(sizeof(redisReply*)*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);
- assert(replies[i] != NULL && replies[i]->elements == 500);
- }
- t2 = usec();
- for (i = 0; i < num; i++) freeReplyObject(replies[i]);
- free(replies);
- printf("\t(%dx LRANGE with 500 elements: %.3fs)\n", num, (t2-t1)/1000000.0);
-
- num = 10000;
- replies = malloc(sizeof(redisReply*)*num);
- for (i = 0; i < num; i++)
- redisAppendCommand(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);
- }
- t2 = usec();
- for (i = 0; i < num; i++) freeReplyObject(replies[i]);
- free(replies);
- printf("\t(%dx PING (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0);
-
- replies = malloc(sizeof(redisReply*)*num);
- for (i = 0; i < num; i++)
- redisAppendCommand(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(replies[i] != NULL && replies[i]->elements == 500);
- }
- t2 = usec();
- for (i = 0; i < num; i++) freeReplyObject(replies[i]);
- free(replies);
- printf("\t(%dx LRANGE with 500 elements (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) {
-// ((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) {
-// ((void)c);
-// /* Shift to detect execution order */
-// __test_callback_flags <<= 8;
-// __test_callback_flags |= (long)privdata;
-// if (reply) freeReplyObject(reply);
-// }
-//
-// static redisContext *__connect_nonblock() {
-// /* Reset callback flags */
-// __test_callback_flags = 0;
-// return redisConnectNonBlock("127.0.0.1", port, NULL);
-// }
-//
-// static void test_nonblocking_connection() {
-// redisContext *c;
-// int wdone = 0;
-//
-// test("Calls command callback when command is issued: ");
-// c = __connect_nonblock();
-// redisSetCommandCallback(c,__test_callback,(void*)1);
-// redisCommand(c,"PING");
-// test_cond(__test_callback_flags == 1);
-// redisFree(c);
-//
-// test("Calls disconnect callback on redisDisconnect: ");
-// c = __connect_nonblock();
-// redisSetDisconnectCallback(c,__test_callback,(void*)2);
-// redisDisconnect(c);
-// test_cond(__test_callback_flags == 2);
-// redisFree(c);
-//
-// test("Calls disconnect callback and free callback on redisFree: ");
-// c = __connect_nonblock();
-// redisSetDisconnectCallback(c,__test_callback,(void*)2);
-// redisSetFreeCallback(c,__test_callback,(void*)4);
-// redisFree(c);
-// test_cond(__test_callback_flags == ((2 << 8) | 4));
-//
-// test("redisBufferWrite against empty write buffer: ");
-// c = __connect_nonblock();
-// test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1);
-// redisFree(c);
-//
-// test("redisBufferWrite against not yet connected fd: ");
-// c = __connect_nonblock();
-// redisCommand(c,"PING");
-// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
-// strncmp(c->error,"write:",6) == 0);
-// redisFree(c);
-//
-// test("redisBufferWrite against closed fd: ");
-// c = __connect_nonblock();
-// redisCommand(c,"PING");
-// redisDisconnect(c);
-// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
-// strncmp(c->error,"write:",6) == 0);
-// redisFree(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");
-//
-// /* Write output buffer */
-// wdone = 0;
-// while(!wdone) {
-// usleep(500);
-// redisBufferWrite(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);
-// }
-// test_cond(__test_callback_flags == 0x010203);
-// redisFree(c);
-//
-// test("redisDisconnect 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);
-// test_cond(__test_callback_flags == 0x0201);
-// redisFree(c);
-// }
-
-int main(int argc, char **argv) {
- struct config cfg = {
- .tcp = {
- .host = "127.0.0.1",
- .port = 6379
- },
- .unix = {
- .path = "/tmp/redis.sock"
- }
- };
- int throughput = 1;
- int test_inherit_fd = 1;
-
- /* Ignore broken pipe signal (for I/O error tests). */
- signal(SIGPIPE, SIG_IGN);
-
- /* Parse command line options. */
- argv++; argc--;
- while (argc) {
- if (argc >= 2 && !strcmp(argv[0],"-h")) {
- argv++; argc--;
- cfg.tcp.host = argv[0];
- } else if (argc >= 2 && !strcmp(argv[0],"-p")) {
- argv++; argc--;
- cfg.tcp.port = atoi(argv[0]);
- } else if (argc >= 2 && !strcmp(argv[0],"-s")) {
- argv++; argc--;
- cfg.unix.path = argv[0];
- } else if (argc >= 1 && !strcmp(argv[0],"--skip-throughput")) {
- throughput = 0;
- } else if (argc >= 1 && !strcmp(argv[0],"--skip-inherit-fd")) {
- test_inherit_fd = 0;
- } else {
- fprintf(stderr, "Invalid argument: %s\n", argv[0]);
- exit(1);
- }
- argv++; argc--;
- }
-
- test_format_commands();
- test_reply_reader();
- test_blocking_connection_errors();
- test_free_null();
-
- printf("\nTesting against TCP connection (%s:%d):\n", cfg.tcp.host, cfg.tcp.port);
- cfg.type = CONN_TCP;
- test_blocking_connection(cfg);
- test_blocking_connection_timeouts(cfg);
- test_blocking_io_errors(cfg);
- test_invalid_timeout_errors(cfg);
- test_append_formatted_commands(cfg);
- if (throughput) test_throughput(cfg);
-
- printf("\nTesting against Unix socket connection (%s):\n", cfg.unix.path);
- cfg.type = CONN_UNIX;
- test_blocking_connection(cfg);
- test_blocking_connection_timeouts(cfg);
- test_blocking_io_errors(cfg);
- if (throughput) test_throughput(cfg);
-
- if (test_inherit_fd) {
- printf("\nTesting against inherited fd (%s):\n", cfg.unix.path);
- cfg.type = CONN_FD;
- test_blocking_connection(cfg);
- }
-
-
- if (fails) {
- printf("*** %d TESTS FAILED ***\n", fails);
- return 1;
- }
-
- printf("ALL TESTS PASSED\n");
- return 0;
-}
diff --git a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/win32.h b/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/win32.h
deleted file mode 100644
index 1a27c18..0000000
--- a/src/support/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/hiredis-master-9fa9f2149e5256efadb54ab89aa6cb3e9caa9b50/win32.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef _WIN32_HELPER_INCLUDE
-#define _WIN32_HELPER_INCLUDE
-#ifdef _MSC_VER
-
-#ifndef inline
-#define inline __inline
-#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
-#endif \ No newline at end of file