summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2010-03-16 16:09:58 +0100
committerantirez <antirez@gmail.com>2010-03-16 16:09:58 +0100
commit78409a0f84f63630ad49ba4dba4467b523bc6c55 (patch)
tree309d7644212a39dd9ed7688d1f1da54ea4d6ce8a
parent6d4fb107b24cb4ce5c25be5c1cb3fa223a70940a (diff)
downloadredis-78409a0f84f63630ad49ba4dba4467b523bc6c55.tar.gz
HKEYS / HVALS / HGETALL
-rw-r--r--redis-cli.c3
-rw-r--r--redis.c86
2 files changed, 83 insertions, 6 deletions
diff --git a/redis-cli.c b/redis-cli.c
index 93d80caa5..d2273db0e 100644
--- a/redis-cli.c
+++ b/redis-cli.c
@@ -149,6 +149,9 @@ static struct redisCommand cmdTable[] = {
{"hget",3,REDIS_CMD_BULK},
{"hdel",3,REDIS_CMD_BULK},
{"hlen",2,REDIS_CMD_INLINE},
+ {"hkeys",2,REDIS_CMD_INLINE},
+ {"hvals",2,REDIS_CMD_INLINE},
+ {"hgetall",2,REDIS_CMD_INLINE},
{NULL,0,0}
};
diff --git a/redis.c b/redis.c
index 8a22cd45f..e5f2350d6 100644
--- a/redis.c
+++ b/redis.c
@@ -686,6 +686,9 @@ static void hlenCommand(redisClient *c);
static void zremrangebyrankCommand(redisClient *c);
static void zunionCommand(redisClient *c);
static void zinterCommand(redisClient *c);
+static void hkeysCommand(redisClient *c);
+static void hvalsCommand(redisClient *c);
+static void hgetallCommand(redisClient *c);
/*================================= Globals ================================= */
@@ -748,6 +751,9 @@ static struct redisCommand cmdTable[] = {
{"hget",hgetCommand,3,REDIS_CMD_BULK,1,1,1},
{"hdel",hdelCommand,3,REDIS_CMD_BULK,1,1,1},
{"hlen",hlenCommand,2,REDIS_CMD_INLINE,1,1,1},
+ {"hkeys",hkeysCommand,2,REDIS_CMD_INLINE,1,1,1},
+ {"hvals",hvalsCommand,2,REDIS_CMD_INLINE,1,1,1},
+ {"hgetall",hgetallCommand,2,REDIS_CMD_INLINE,1,1,1},
{"incrby",incrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM,1,1,1},
{"decrby",decrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM,1,1,1},
{"getset",getsetCommand,3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,1,1,1},
@@ -2714,7 +2720,7 @@ static void decrRefCount(void *obj) {
case REDIS_SET: freeSetObject(o); break;
case REDIS_ZSET: freeZsetObject(o); break;
case REDIS_HASH: freeHashObject(o); break;
- default: redisAssert(0 != 0); break;
+ default: redisAssert(0); break;
}
if (server.vm_enabled) pthread_mutex_lock(&server.obj_freelist_mutex);
if (listLength(server.objfreelist) > REDIS_OBJFREELIST_MAX ||
@@ -3212,7 +3218,7 @@ static int rdbSaveObject(FILE *fp, robj *o) {
dictReleaseIterator(di);
}
} else {
- redisAssert(0 != 0);
+ redisAssert(0);
}
return 0;
}
@@ -3432,7 +3438,7 @@ static robj *rdbLoadIntegerObject(FILE *fp, int enctype) {
val = (int32_t)v;
} else {
val = 0; /* anti-warning */
- redisAssert(0!=0);
+ redisAssert(0);
}
return createObject(REDIS_STRING,sdscatprintf(sdsempty(),"%lld",val));
}
@@ -3471,7 +3477,7 @@ static robj *rdbLoadStringObject(FILE*fp) {
case REDIS_RDB_ENC_LZF:
return tryObjectSharing(rdbLoadLzfStringObject(fp));
default:
- redisAssert(0!=0);
+ redisAssert(0);
}
}
@@ -3593,7 +3599,7 @@ static robj *rdbLoadObject(int type, FILE *fp) {
}
}
} else {
- redisAssert(0 != 0);
+ redisAssert(0);
}
return o;
}
@@ -5917,6 +5923,74 @@ static void hlenCommand(redisClient *c) {
addReplyUlong(c,len);
}
+#define REDIS_GETALL_KEYS 1
+#define REDIS_GETALL_VALS 2
+static void genericHgetallCommand(redisClient *c, int flags) {
+ robj *o, *lenobj;
+ unsigned long count = 0;
+
+ if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullmultibulk)) == NULL
+ || checkType(c,o,REDIS_HASH)) return;
+
+ lenobj = createObject(REDIS_STRING,NULL);
+ addReply(c,lenobj);
+ decrRefCount(lenobj);
+
+ if (o->encoding == REDIS_ENCODING_ZIPMAP) {
+ unsigned char *p = zipmapRewind(o->ptr);
+ unsigned char *field, *val;
+ unsigned int flen, vlen;
+
+ while((p = zipmapNext(p,&field,&flen,&val,&vlen)) != NULL) {
+ robj *aux;
+
+ if (flags & REDIS_GETALL_KEYS) {
+ aux = createStringObject((char*)field,flen);
+ addReplyBulk(c,aux);
+ decrRefCount(aux);
+ count++;
+ }
+ if (flags & REDIS_GETALL_VALS) {
+ aux = createStringObject((char*)val,vlen);
+ addReplyBulk(c,aux);
+ decrRefCount(aux);
+ count++;
+ }
+ }
+ } else {
+ dictIterator *di = dictGetIterator(o->ptr);
+ dictEntry *de;
+
+ while((de = dictNext(di)) != NULL) {
+ robj *fieldobj = dictGetEntryKey(de);
+ robj *valobj = dictGetEntryVal(de);
+
+ if (flags & REDIS_GETALL_KEYS) {
+ addReplyBulk(c,fieldobj);
+ count++;
+ }
+ if (flags & REDIS_GETALL_VALS) {
+ addReplyBulk(c,valobj);
+ count++;
+ }
+ }
+ dictReleaseIterator(di);
+ }
+ lenobj->ptr = sdscatprintf(sdsempty(),"*%lu\r\n",count);
+}
+
+static void hkeysCommand(redisClient *c) {
+ genericHgetallCommand(c,REDIS_GETALL_KEYS);
+}
+
+static void hvalsCommand(redisClient *c) {
+ genericHgetallCommand(c,REDIS_GETALL_VALS);
+}
+
+static void hgetallCommand(redisClient *c) {
+ genericHgetallCommand(c,REDIS_GETALL_KEYS|REDIS_GETALL_VALS);
+}
+
static void convertToRealHash(robj *o) {
unsigned char *key, *val, *p, *zm = o->ptr;
unsigned int klen, vlen;
@@ -7675,7 +7749,7 @@ static int rewriteAppendOnlyFile(char *filename) {
dictReleaseIterator(di);
}
} else {
- redisAssert(0 != 0);
+ redisAssert(0);
}
/* Save the expire time */
if (expiretime != -1) {