Scan api that allows a module to scan the elements in a hash, set or sorted set key * * Callback for scan implementation. * * void scan_callback(RedisModuleKey *key, RedisModuleString* field, RedisModuleString* value, void *privdata); * * - key - the redis key context provided to for the scan. * - field - field name, owned by the caller and need to be retained if used * after this fu
| 7967 | * deleting the current element of the data structure is safe, while removing |
| 7968 | * the key you are iterating is not safe. */ |
| 7969 | int RM_ScanKey(RedisModuleKey *key, RedisModuleScanCursor *cursor, RedisModuleScanKeyCB fn, void *privdata) { |
| 7970 | if (key == NULL || key->value == NULL) { |
| 7971 | errno = EINVAL; |
| 7972 | return 0; |
| 7973 | } |
| 7974 | dict *ht = NULL; |
| 7975 | robj *o = key->value; |
| 7976 | if (o->type == OBJ_SET) { |
| 7977 | if (o->encoding == OBJ_ENCODING_HT) |
| 7978 | ht = (dict*)ptrFromObj(o); |
| 7979 | } else if (o->type == OBJ_HASH) { |
| 7980 | if (o->encoding == OBJ_ENCODING_HT) |
| 7981 | ht = (dict*)ptrFromObj(o); |
| 7982 | } else if (o->type == OBJ_ZSET) { |
| 7983 | if (o->encoding == OBJ_ENCODING_SKIPLIST) |
| 7984 | ht = ((zset *)ptrFromObj(o))->dict; |
| 7985 | } else { |
| 7986 | errno = EINVAL; |
| 7987 | return 0; |
| 7988 | } |
| 7989 | if (cursor->done) { |
| 7990 | errno = ENOENT; |
| 7991 | return 0; |
| 7992 | } |
| 7993 | int ret = 1; |
| 7994 | if (ht) { |
| 7995 | ScanKeyCBData data = { key, privdata, fn }; |
| 7996 | cursor->cursor = dictScan(ht, cursor->cursor, moduleScanKeyCallback, NULL, &data); |
| 7997 | if (cursor->cursor == 0) { |
| 7998 | cursor->done = 1; |
| 7999 | ret = 0; |
| 8000 | } |
| 8001 | } else if (o->type == OBJ_SET && o->encoding == OBJ_ENCODING_INTSET) { |
| 8002 | int pos = 0; |
| 8003 | int64_t ll; |
| 8004 | while(intsetGet((intset*)ptrFromObj(o),pos++,&ll)) { |
| 8005 | robj *field = createObject(OBJ_STRING,sdsfromlonglong(ll)); |
| 8006 | fn(key, field, NULL, privdata); |
| 8007 | decrRefCount(field); |
| 8008 | } |
| 8009 | cursor->cursor = 1; |
| 8010 | cursor->done = 1; |
| 8011 | ret = 0; |
| 8012 | } else if (o->type == OBJ_HASH || o->type == OBJ_ZSET) { |
| 8013 | unsigned char *p = ziplistIndex((unsigned char*)ptrFromObj(o),0); |
| 8014 | unsigned char *vstr; |
| 8015 | unsigned int vlen; |
| 8016 | long long vll; |
| 8017 | while(p) { |
| 8018 | ziplistGet(p,&vstr,&vlen,&vll); |
| 8019 | robj *field = (vstr != NULL) ? |
| 8020 | createStringObject((char*)vstr,vlen) : |
| 8021 | createObject(OBJ_STRING,sdsfromlonglong(vll)); |
| 8022 | p = ziplistNext((unsigned char*)ptrFromObj(o),p); |
| 8023 | ziplistGet(p,&vstr,&vlen,&vll); |
| 8024 | robj *value = (vstr != NULL) ? |
| 8025 | createStringObject((char*)vstr,vlen) : |
| 8026 | createObject(OBJ_STRING,sdsfromlonglong(vll)); |
nothing calls this directly
no test coverage detected