int UniquePushIVCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { if (argc < 4) { return RedisModule_WrongArity(ctx); } RedisModule_AutoMemory(ctx); // open the key and make sure it is indeed a Hash and not empty RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ | REDISMODULE_WRITE); int type = RedisModule_KeyType(key); if (type != REDISMODULE_KEYTYPE_EMPTY && RedisModule_ModuleTypeGetType(key) != UniqueType) { return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); } unique *unique; if (type == REDISMODULE_KEYTYPE_EMPTY) { unique = uniqueCreate(); RedisModule_ModuleTypeSetValue(key,UniqueType,unique); } else { unique = RedisModule_ModuleTypeGetValue(key); } sds skey, sval; size_t skeylen, svallen; const char *pkey; unsigned int lvec = argc-3; pkey = RedisModule_StringPtrLen(argv[2], &skeylen); svallen = lvec *8; skey = sdsnewlen(pkey, skeylen); sval = sdsnewlen(NULL, svallen); long long *vec = (long long*)sval; int i; for (i=3; i<argc; i++) { if (REDISMODULE_OK != RedisModule_StringToLongLong(argv[i], vec+i-3)) { return RedisModule_WrongArity(ctx); } } int n = uniquePush(unique, skey, sval, merge_int64); if (n == -1) { RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); } else { RedisModule_ReplyWithLongLong(ctx, n); } RedisModule_ReplicateVerbatim(ctx); return REDISMODULE_OK; }
static int UniquePushCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, mergefn fn) { if (argc != 4) { return RedisModule_WrongArity(ctx); } RedisModule_AutoMemory(ctx); // open the key and make sure it is indeed a Hash and not empty RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ | REDISMODULE_WRITE); int type = RedisModule_KeyType(key); if (type != REDISMODULE_KEYTYPE_EMPTY && RedisModule_ModuleTypeGetType(key) != UniqueType) { return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); } unique *unique; if (type == REDISMODULE_KEYTYPE_EMPTY) { unique = uniqueCreate(); RedisModule_ModuleTypeSetValue(key,UniqueType,unique); } else { unique = RedisModule_ModuleTypeGetValue(key); } sds skey, sval; size_t skeylen, svallen; const char *pkey, *pval; pkey = RedisModule_StringPtrLen(argv[2], &skeylen); pval = RedisModule_StringPtrLen(argv[3], &svallen); skey = sdsnewlen(pkey, skeylen); sval = sdsnewlen(pval, svallen); int n = uniquePush(unique, skey, sval, fn); if (n == -1) { RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); } else { RedisModule_ReplyWithLongLong(ctx, n); } RedisModule_ReplicateVerbatim(ctx); return REDISMODULE_OK; }
void *UniqueTypeRdbLoad(RedisModuleIO *rdb, int encver) { if (encver != 0) { /* RedisModule_Log("warning","Can't load data with version %d", encver);*/ return NULL; } uint64_t elements = RedisModule_LoadUnsigned(rdb); unique *unique = uniqueCreate(); char *pkey, *pval; size_t lkey, lval; sds key, val; while(elements--) { pkey = RedisModule_LoadStringBuffer(rdb, &lkey); pval = RedisModule_LoadStringBuffer(rdb, &lval); key = sdsnewlen(pkey, lkey); val = sdsnewlen(pval, lval); RedisModule_Free(pkey); RedisModule_Free(pval); uniquePush(unique, key, val, retain_new); } return unique; }
// note: src (tgt) will be indexed to their x + 1 (y+1). static double distance( unsigned int *src, unsigned int *tgt, unsigned int x, unsigned int y, double *weight, dictionary *dict, double *scores ){ if (!x){ return (double) y; } if (!y){ return (double) x; } unsigned int swapCount, targetCharCount,i,j; double delScore, insScore, subScore, swapScore; unsigned int score_ceil = x + y; /* intialize matrix start values */ scores[0] = score_ceil; scores[1 * (y + 2) + 0] = score_ceil; scores[0 * (y + 2) + 1] = score_ceil; scores[1 * (y + 2) + 1] = 0; uniquePush(dict,src[0]); uniquePush(dict,tgt[0]); /* work loops */ /* i = src index */ /* j = tgt index */ for(i=1;i<=x;i++){ uniquePush(dict,src[i]); scores[(i+1) * (y + 2) + 1] = i; scores[(i+1) * (y + 2) + 0] = score_ceil; swapCount = 0; for(j=1;j<=y;j++){ if(i == 1) { uniquePush(dict,tgt[j]); scores[1 * (y + 2) + (j + 1)] = j; scores[0 * (y + 2) + (j + 1)] = score_ceil; } targetCharCount = dict->value[which(dict, tgt[j-1])]; swapScore = scores[targetCharCount * (y + 2) + swapCount] + (i - targetCharCount - 1 + j - swapCount) * weight[3]; if(src[i-1] != tgt[j-1]){ subScore = scores[i * (y + 2) + j] + weight[2]; insScore = scores[(i+1) * (y + 2) + j] + weight[1]; delScore = scores[i * (y + 2) + (j + 1)] + weight[0]; scores[(i+1) * (y + 2) + (j + 1)] = MIN(swapScore, MIN(delScore, MIN(insScore, subScore) )); } else { swapCount = j; scores[(i+1) * (y + 2) + (j + 1)] = MIN(scores[i * (y + 2) + j], swapScore); } } dict->value[which(dict,src[i-1])] = i; } double score = scores[(x+1) * (y + 2) + (y + 1)]; reset_dictionary(dict); return score; }