Skip to content

Commit

Permalink
Merge branch 'unstable' into RELEASE_5
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnSully committed Oct 16, 2019
2 parents 0a0c214 + f5210a8 commit 2f65aa2
Show file tree
Hide file tree
Showing 28 changed files with 561 additions and 404 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ FROM ubuntu:18.04

RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -qqy \
build-essential nasm autotools-dev autoconf libjemalloc-dev tcl tcl-dev uuid-dev \
build-essential nasm autotools-dev autoconf libcurl4-openssl-dev libjemalloc-dev tcl tcl-dev uuid-dev \
&& apt-get clean

CMD make
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ On the same hardware KeyDB can perform twice as many queries per second as Redis
Why fork Redis?
---------------

KeyDB has a different philosophy on how the codebase should evolve. We feel that ease of use, high performance, and a "batteries included" approach is the best way to create a good user experience. While we have great respect for the Redis maintainers it is our opinion that the Redis approach focusses too much on simplicity of the code base at the expense of complexity for the user. This results in the need for external components and workarounds to solve common problems - resulting in more complexity overall.
KeyDB has a different philosophy on how the codebase should evolve. We feel that ease of use, high performance, and a "batteries included" approach is the best way to create a good user experience. While we have great respect for the Redis maintainers it is our opinion that the Redis approach focuses too much on simplicity of the code base at the expense of complexity for the user. This results in the need for external components and workarounds to solve common problems - resulting in more complexity overall.

Because of this difference of opinion features which are right for KeyDB may not be appropriate for Redis. A fork allows us to explore this new development path and implement features which may never be a part of Redis. KeyDB keeps in sync with upstream Redis changes, and where applicable we upstream bug fixes and changes. It is our hope that the two projects can continue to grow and learn from each other.

Expand Down
18 changes: 11 additions & 7 deletions src/anet.c
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ static int anetV6Only(char *err, int s) {
return ANET_OK;
}

static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backlog, int fReusePort)
static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backlog, int fReusePort, int fFirstListen)
{
int s = -1, rv;
char _port[6]; /* strlen("65535") */
Expand All @@ -498,8 +498,12 @@ static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backl

if (af == AF_INET6 && anetV6Only(err,s) == ANET_ERR) goto error;
if (anetSetReuseAddr(err,s) == ANET_ERR) goto error;
if (fReusePort && anetSetReusePort(err,s) == ANET_ERR) goto error;
if (anetListen(err,s,p->ai_addr,p->ai_addrlen,backlog) == ANET_ERR) s = ANET_ERR;
if (fReusePort && !fFirstListen && anetSetReusePort(err,s) == ANET_ERR) goto error;
if (anetListen(err,s,p->ai_addr,p->ai_addrlen,backlog) == ANET_ERR) {
s = ANET_ERR;
goto end;
}
if (fReusePort && fFirstListen && anetSetReusePort(err,s) == ANET_ERR) goto error;
goto end;
}
if (p == NULL) {
Expand All @@ -515,14 +519,14 @@ static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backl
return s;
}

int anetTcpServer(char *err, int port, char *bindaddr, int backlog, int fReusePort)
int anetTcpServer(char *err, int port, char *bindaddr, int backlog, int fReusePort, int fFirstListen)
{
return _anetTcpServer(err, port, bindaddr, AF_INET, backlog, fReusePort);
return _anetTcpServer(err, port, bindaddr, AF_INET, backlog, fReusePort, fFirstListen);
}

int anetTcp6Server(char *err, int port, char *bindaddr, int backlog, int fReusePort)
int anetTcp6Server(char *err, int port, char *bindaddr, int backlog, int fReusePort, int fFirstListen)
{
return _anetTcpServer(err, port, bindaddr, AF_INET6, backlog, fReusePort);
return _anetTcpServer(err, port, bindaddr, AF_INET6, backlog, fReusePort, fFirstListen);
}

int anetUnixServer(char *err, char *path, mode_t perm, int backlog)
Expand Down
4 changes: 2 additions & 2 deletions src/anet.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ int anetUnixNonBlockConnect(char *err, char *path);
int anetRead(int fd, char *buf, int count);
int anetResolve(char *err, char *host, char *ipbuf, size_t ipbuf_len);
int anetResolveIP(char *err, char *host, char *ipbuf, size_t ipbuf_len);
int anetTcpServer(char *err, int port, char *bindaddr, int backlog, int fReusePort);
int anetTcp6Server(char *err, int port, char *bindaddr, int backlog, int fReusePort);
int anetTcpServer(char *err, int port, char *bindaddr, int backlog, int fReusePort, int fFirstListen);
int anetTcp6Server(char *err, int port, char *bindaddr, int backlog, int fReusePort, int fFirstListen);
int anetUnixServer(char *err, char *path, mode_t perm, int backlog);
int anetTcpAccept(char *err, int serversock, char *ip, size_t ip_len, int *port);
int anetUnixAccept(char *err, int serversock);
Expand Down
2 changes: 1 addition & 1 deletion src/aof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,7 @@ client *createFakeClient(void) {
c->flags = 0;
c->fPendingAsyncWrite = FALSE;
c->btype = BLOCKED_NONE;
/* We set the fake client as a slave waiting for the synchronization
/* We set the fake client as a replica waiting for the synchronization
* so that Redis will not try to send replies to this client. */
c->replstate = SLAVE_STATE_WAIT_BGSAVE_START;
c->reply = listCreate();
Expand Down
4 changes: 2 additions & 2 deletions src/blocked.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ void replyToBlockedClientTimedOut(client *c) {

/* Mass-unblock clients because something changed in the instance that makes
* blocking no longer safe. For example clients blocked in list operations
* in an instance which turns from master to slave is unsafe, so this function
* is called when a master turns into a slave.
* in an instance which turns from master to replica is unsafe, so this function
* is called when a master turns into a replica.
*
* The semantics is to send an -UNBLOCKED error to the client, disconnecting
* it at the same time. */
Expand Down
2 changes: 1 addition & 1 deletion src/cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ void clusterInit(void) {
}

if (listenToPort(g_pserver->port+CLUSTER_PORT_INCR,
g_pserver->cfd,&g_pserver->cfd_count, 0 /*fReusePort*/) == C_ERR)
g_pserver->cfd,&g_pserver->cfd_count, 0 /*fReusePort*/, 0 /*fFirstListen*/) == C_ERR)
{
exit(1);
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ configEnum aof_fsync_enum[] = {
/* Output buffer limits presets. */
clientBufferLimitsConfig clientBufferLimitsDefaults[CLIENT_TYPE_OBUF_COUNT] = {
{0, 0, 0}, /* normal */
{1024*1024*256, 1024*1024*64, 60}, /* slave */
{1024*1024*256, 1024*1024*64, 60}, /* replica */
{1024*1024*32, 1024*1024*8, 60} /* pubsub */
};

Expand Down
49 changes: 41 additions & 8 deletions src/db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ static robj *lookupKey(redisDb *db, robj *key, int flags) {
* LOOKUP_NOTOUCH: don't alter the last access time of the key.
*
* Note: this function also returns NULL if the key is logically expired
* but still existing, in case this is a slave, since this API is called only
* but still existing, in case this is a replica, since this API is called only
* for read operations. Even if the key expiry is master-driven, we can
* correctly report a key is expired on slaves even if the master is lagging
* expiring our key via DELs in the replication link. */
Expand All @@ -133,7 +133,7 @@ robj_roptr lookupKeyReadWithFlags(redisDb *db, robj *key, int flags) {
return NULL;
}

/* However if we are in the context of a slave, expireIfNeeded() will
/* However if we are in the context of a replica, expireIfNeeded() will
* not really try to expire the key, it only returns information
* about the "logical" status of the key: key expiring is up to the
* master in order to have a consistent view of master's data set.
Expand Down Expand Up @@ -344,7 +344,7 @@ robj *dbRandomKey(redisDb *db) {
if (allvolatile && listLength(g_pserver->masters) && --maxtries == 0) {
/* If the DB is composed only of keys with an expire set,
* it could happen that all the keys are already logically
* expired in the slave, so the function cannot stop because
* expired in the replica, so the function cannot stop because
* expireIfNeeded() is false, nor it can stop because
* dictGetRandomKey() returns NULL (there are keys to return).
* To prevent the infinite loop we do some tries, but if there
Expand Down Expand Up @@ -1227,6 +1227,39 @@ int removeExpireCore(redisDb *db, robj *key, dictEntry *de) {
return 1;
}

int removeSubkeyExpire(redisDb *db, robj *key, robj *subkey) {
dictEntry *de = dictFind(db->pdict,ptrFromObj(key));
serverAssertWithInfo(NULL,key,de != NULL);

robj *val = (robj*)dictGetVal(de);
if (!val->FExpires())
return 0;

auto itr = db->setexpire->find((sds)dictGetKey(de));
serverAssert(itr != db->setexpire->end());
serverAssert(itr->key() == (sds)dictGetKey(de));
if (!itr->FFat())
return 0;

int found = 0;
for (auto subitr : *itr)
{
if (subitr.subkey() == nullptr)
continue;
if (sdscmp((sds)subitr.subkey(), szFromObj(subkey)) == 0)
{
itr->erase(subitr);
found = 1;
break;
}
}

if (itr->pfatentry()->size() == 0)
removeExpireCore(db, key, de);

return found;
}

/* Set an expire to the specified key. If the expire is set in the context
* of an user calling a command 'c' is the client, otherwise 'c' is set
* to NULL. The 'when' parameter is the absolute unix time in milliseconds
Expand Down Expand Up @@ -1335,7 +1368,7 @@ expireEntry *getExpire(redisDb *db, robj_roptr key) {
* to all the slaves and the AOF file if enabled.
*
* This way the key expiry is centralized in one place, and since both
* AOF and the master->slave link guarantee operation ordering, everything
* AOF and the master->replica link guarantee operation ordering, everything
* will be consistent even if we allow write operations against expiring
* keys. */
void propagateExpire(redisDb *db, robj *key, int lazy) {
Expand Down Expand Up @@ -1393,10 +1426,10 @@ int keyIsExpired(redisDb *db, robj *key) {
* is via lookupKey*() family of functions.
*
* The behavior of the function depends on the replication role of the
* instance, because slave instances do not expire keys, they wait
* instance, because replica instances do not expire keys, they wait
* for DELs from the master for consistency matters. However even
* slaves will try to have a coherent return value for the function,
* so that read commands executed in the slave side will be able to
* so that read commands executed in the replica side will be able to
* behave like if the key is expired even if still present (because the
* master has yet to propagate the DEL).
*
Expand All @@ -1409,9 +1442,9 @@ int keyIsExpired(redisDb *db, robj *key) {
int expireIfNeeded(redisDb *db, robj *key) {
if (!keyIsExpired(db,key)) return 0;

/* If we are running in the context of a slave, instead of
/* If we are running in the context of a replica, instead of
* evicting the expired key from the database, we return ASAP:
* the slave key expiration is controlled by the master that will
* the replica key expiration is controlled by the master that will
* send us synthesized DEL operations for expired keys.
*
* Still we try to return the right information to the caller,
Expand Down
4 changes: 2 additions & 2 deletions src/evict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,8 @@ size_t freeMemoryGetNotCountedMemory(void) {

listRewind(g_pserver->slaves,&li);
while((ln = listNext(&li))) {
client *slave = (client*)listNodeValue(ln);
overhead += getClientOutputBufferMemoryUsage(slave);
client *replica = (client*)listNodeValue(ln);
overhead += getClientOutputBufferMemoryUsage(replica);
}
}
if (g_pserver->aof_state != AOF_OFF) {
Expand Down
Loading

0 comments on commit 2f65aa2

Please sign in to comment.