+/* Get the value from a ziplist encoded hash, identified by field.
+ * Returns -1 when the field cannot be found. */
+int hashTypeGetFromZiplist(robj *o, robj *field,
+ unsigned char **vstr,
+ unsigned int *vlen,
+ long long *vll)
+{
+ unsigned char *zl, *fptr = NULL, *vptr = NULL;
+ int ret;
+
+ redisAssert(o->encoding == REDIS_ENCODING_ZIPLIST);
+
+ field = getDecodedObject(field);
+
+ zl = o->ptr;
+ fptr = ziplistIndex(zl, ZIPLIST_HEAD);
+ if (fptr != NULL) {
+ fptr = ziplistFind(fptr, field->ptr, sdslen(field->ptr), 1);
+ if (fptr != NULL) {
+ /* Grab pointer to the value (fptr points to the field) */
+ vptr = ziplistNext(zl, fptr);
+ redisAssert(vptr != NULL);
+ }
+ }
+
+ decrRefCount(field);
+
+ if (vptr != NULL) {
+ ret = ziplistGet(vptr, vstr, vlen, vll);
+ redisAssert(ret);
+ return 0;
+ }
+
+ return -1;
+}
+
+/* Get the value from a hash table encoded hash, identified by field.
+ * Returns -1 when the field cannot be found. */
+int hashTypeGetFromHashTable(robj *o, robj *field, robj **value) {
+ dictEntry *de;
+
+ redisAssert(o->encoding == REDIS_ENCODING_HT);
+
+ de = dictFind(o->ptr, field);
+ if (de == NULL) return -1;
+ *value = dictGetVal(de);
+ return 0;
+}
+
+/* Higher level function of hashTypeGet*() that always returns a Redis
+ * object (either new or with refcount incremented), so that the caller
+ * can retain a reference or call decrRefCount after the usage.
+ *
+ * The lower level function can prevent copy on write so it is
+ * the preferred way of doing read operations. */
+robj *hashTypeGetObject(robj *o, robj *field) {