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
| 7772 | * deleting the current element of the data structure is safe, while removing |
| 7773 | * the key you are iterating is not safe. */ |
| 7774 | int RM_ScanKey(RedisModuleKey *key, RedisModuleScanCursor *cursor, RedisModuleScanKeyCB fn, void *privdata) { |
| 7775 | if (key == NULL || key->value == NULL) { |
| 7776 | errno = EINVAL; |
| 7777 | return 0; |
| 7778 | } |
| 7779 | dict *ht = NULL; |
| 7780 | robj *o = key->value; |
| 7781 | if (o->type == OBJ_SET) { |
| 7782 | if (o->encoding == OBJ_ENCODING_HT) |
| 7783 | ht = o->ptr; |
| 7784 | } else if (o->type == OBJ_HASH) { |
| 7785 | if (o->encoding == OBJ_ENCODING_HT) |
| 7786 | ht = o->ptr; |
| 7787 | } else if (o->type == OBJ_ZSET) { |
| 7788 | if (o->encoding == OBJ_ENCODING_SKIPLIST) |
| 7789 | ht = ((zset *)o->ptr)->dict; |
| 7790 | } else { |
| 7791 | errno = EINVAL; |
| 7792 | return 0; |
| 7793 | } |
| 7794 | if (cursor->done) { |
| 7795 | errno = ENOENT; |
| 7796 | return 0; |
| 7797 | } |
| 7798 | int ret = 1; |
| 7799 | if (ht) { |
| 7800 | ScanKeyCBData data = { key, privdata, fn }; |
| 7801 | cursor->cursor = dictScan(ht, cursor->cursor, moduleScanKeyCallback, NULL, &data); |
| 7802 | if (cursor->cursor == 0) { |
| 7803 | cursor->done = 1; |
| 7804 | ret = 0; |
| 7805 | } |
| 7806 | } else if (o->type == OBJ_SET && o->encoding == OBJ_ENCODING_INTSET) { |
| 7807 | int pos = 0; |
| 7808 | int64_t ll; |
| 7809 | while(intsetGet(o->ptr,pos++,&ll)) { |
| 7810 | robj *field = createObject(OBJ_STRING,sdsfromlonglong(ll)); |
| 7811 | fn(key, field, NULL, privdata); |
| 7812 | decrRefCount(field); |
| 7813 | } |
| 7814 | cursor->cursor = 1; |
| 7815 | cursor->done = 1; |
| 7816 | ret = 0; |
| 7817 | } else if (o->type == OBJ_HASH || o->type == OBJ_ZSET) { |
| 7818 | unsigned char *p = ziplistIndex(o->ptr,0); |
| 7819 | unsigned char *vstr; |
| 7820 | unsigned int vlen; |
| 7821 | long long vll; |
| 7822 | while(p) { |
| 7823 | ziplistGet(p,&vstr,&vlen,&vll); |
| 7824 | robj *field = (vstr != NULL) ? |
| 7825 | createStringObject((char*)vstr,vlen) : |
| 7826 | createObject(OBJ_STRING,sdsfromlonglong(vll)); |
| 7827 | p = ziplistNext(o->ptr,p); |
| 7828 | ziplistGet(p,&vstr,&vlen,&vll); |
| 7829 | robj *value = (vstr != NULL) ? |
| 7830 | createStringObject((char*)vstr,vlen) : |
| 7831 | createObject(OBJ_STRING,sdsfromlonglong(vll)); |
nothing calls this directly
no test coverage detected