コード例 #1
0
void SpellCheck_SendReplyOnTerm(RedisModuleCtx *ctx, char *term, size_t len, RS_Suggestions *s,
                                uint64_t totalDocNumber) {
#define TERM "TERM"
  RedisModule_ReplyWithArray(ctx, 3);
  RedisModule_ReplyWithStringBuffer(ctx, TERM, strlen(TERM));
  RedisModule_ReplyWithStringBuffer(ctx, term, len);

  RS_Suggestion **suggestions = spellCheck_GetSuggestions(s);

  for (int i = 0; i < array_len(suggestions); ++i) {
    if (suggestions[i]->score == -1) {
      suggestions[i]->score = 0;
    } else {
      if (totalDocNumber > 0) {
        suggestions[i]->score = (suggestions[i]->score) / totalDocNumber;
      }
    }
  }

  qsort(suggestions, array_len(suggestions), sizeof(RS_Suggestion *), RS_SuggestionCompare);

  if (array_len(suggestions) == 0) {
    // no results found, we return an empty array
    RedisModule_ReplyWithArray(ctx, 0);
  } else {
    RedisModule_ReplyWithArray(ctx, array_len(suggestions));
    for (int i = 0; i < array_len(suggestions); ++i) {
      RedisModule_ReplyWithArray(ctx, 2);
      RedisModule_ReplyWithDouble(ctx, suggestions[i]->score);
      RedisModule_ReplyWithStringBuffer(ctx, suggestions[i]->suggestion, suggestions[i]->len);
    }
  }

  array_free_ex(suggestions, RS_SuggestionFree(*(RS_Suggestion **)ptr));
}
コード例 #2
0
ファイル: unique.c プロジェクト: neverlee/unique
int UniqueGetAllCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
    if (argc != 2) {
        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);

    int type = RedisModule_KeyType(key);
    if (type == REDISMODULE_KEYTYPE_EMPTY) {
        RedisModule_ReplyWithNull(ctx);
        return REDISMODULE_OK;
    }

    if (RedisModule_ModuleTypeGetType(key) != UniqueType) { 
        return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE);
    }

    unique *unique = RedisModule_ModuleTypeGetValue(key);
    
    size_t len = uniqueLen(unique);
    RedisModule_ReplyWithArray(ctx, len*2);
    size_t i;
    listIter *it = listGetIterator(unique->l, AL_START_HEAD);
    listNode *node;
    for (node = listNext(it), i=0; node && i<len; node = listNext(it),i++) {
        dictEntry *en = node->value;
        RedisModule_ReplyWithStringBuffer(ctx, en->key, sdslen(en->key));
        RedisModule_ReplyWithStringBuffer(ctx, en->v.val, sdslen(en->v.val));
    }
    return REDISMODULE_OK;
}
コード例 #3
0
ファイル: helloworld.c プロジェクト: Xwuming/misc
/* HELLO.LEFTPAD str len ch
 * This is an implementation of the infamous LEFTPAD function, that
 * was at the center of an issue with the npm modules system in March 2016.
 *
 * LEFTPAD is a good example of using a Redis Modules API called
 * "pool allocator", that was a famous way to allocate memory in yet another
 * open source project, the Apache web server.
 *
 * The concept is very simple: there is memory that is useful to allocate
 * only in the context of serving a request, and must be freed anyway when
 * the callback implementing the command returns. So in that case the module
 * does not need to retain a reference to these allocations, it is just
 * required to free the memory before returning. When this is the case the
 * module can call RedisModule_PoolAlloc() instead, that works like malloc()
 * but will automatically free the memory when the module callback returns.
 *
 * Note that PoolAlloc() does not necessarily require AutoMemory to be
 * active. */
int HelloLeftPad_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
    RedisModule_AutoMemory(ctx); /* Use automatic memory management. */
    long long padlen;

    if (argc != 4) return RedisModule_WrongArity(ctx);

    if ((RedisModule_StringToLongLong(argv[2],&padlen) != REDISMODULE_OK) ||
        (padlen< 0)) {
        return RedisModule_ReplyWithError(ctx,"ERR invalid padding length");
    }
    size_t strlen, chlen;
    const char *str = RedisModule_StringPtrLen(argv[1], &strlen);
    const char *ch = RedisModule_StringPtrLen(argv[3], &chlen);

    /* If the string is already larger than the target len, just return
     * the string itself. */
    if (strlen >= padlen)
        return RedisModule_ReplyWithString(ctx,argv[1]);

    /* Padding must be a single character in this simple implementation. */
    if (chlen != 1)
        return RedisModule_ReplyWithError(ctx,
            "ERR padding must be a single char");

    /* Here we use our pool allocator, for our throw-away allocation. */
    padlen -= strlen;
    char *buf = RedisModule_PoolAlloc(ctx,padlen+strlen);
    for (size_t j = 0; j < padlen; j++) buf[j] = *ch;
    memcpy(buf+padlen,str,strlen);

    RedisModule_ReplyWithStringBuffer(ctx,buf,padlen+strlen);
    return REDISMODULE_OK;
}
コード例 #4
0
ファイル: unique.c プロジェクト: neverlee/unique
static void PopReplyFV(RedisModuleCtx *ctx, sds skey, sds sval) {
    int i, n = sdslen(sval)/8;
    RedisModule_ReplyWithArray(ctx, 1+n);
    RedisModule_ReplyWithStringBuffer(ctx, skey, sdslen(skey));
    long long *pvec = (long long*)sval;
    for (i=0; i<n; i++) {
        RedisModule_ReplyWithLongLong(ctx, pvec[i]);
    }
}
コード例 #5
0
/* Serialize all the tags in the index to the redis client */
void TagIndex_SerializeValues(TagIndex *idx, RedisModuleCtx *ctx) {
  TrieMapIterator *it = TrieMap_Iterate(idx->values, "", 0);

  char *str;
  tm_len_t slen;
  void *ptr;
  RedisModule_ReplyWithArray(ctx, REDISMODULE_POSTPONED_ARRAY_LEN);
  long long count = 0;
  while (TrieMapIterator_Next(it, &str, &slen, &ptr)) {
    ++count;
    RedisModule_ReplyWithStringBuffer(ctx, str, slen);
  }

  RedisModule_ReplySetArrayLength(ctx, count);

  TrieMapIterator_Free(it);
}
コード例 #6
0
static bool SpellCheck_ReplyTermSuggestions(SpellCheckCtx *scCtx, char *term, size_t len,
                                            t_fieldMask fieldMask) {

  // searching the term on the term trie, if its there we just return false
  // because there is no need to return suggestions on it.
  if (SpellCheck_IsTermExistsInTrie(scCtx->sctx->spec->terms, term, len, NULL)) {
    if (scCtx->fullScoreInfo) {
      // if a full score info is requested we need to send information that
      // we found the term as is on the index
      RedisModule_ReplyWithArray(scCtx->sctx->redisCtx, 3);
      RedisModule_ReplyWithStringBuffer(scCtx->sctx->redisCtx, TERM, strlen(TERM));
      RedisModule_ReplyWithStringBuffer(scCtx->sctx->redisCtx, term, len);
      RedisModule_ReplyWithStringBuffer(scCtx->sctx->redisCtx, FOUND_TERM_IN_INDEX,
                                        strlen(FOUND_TERM_IN_INDEX));
      return true;
    } else {
      return false;
    }
  }

  // searching the term on the exclude list, if its there we just return false
  // because there is no need to return suggestions on it.
  for (int i = 0; i < array_len(scCtx->excludeDict); ++i) {
    RedisModuleKey *k = NULL;
    Trie *t =
        SpellCheck_OpenDict(scCtx->sctx->redisCtx, scCtx->excludeDict[i], REDISMODULE_READ, &k);
    if (t == NULL) {
      continue;
    }
    if (SpellCheck_IsTermExistsInTrie(t, term, len, NULL)) {
      RedisModule_CloseKey(k);
      return false;
    }
    RedisModule_CloseKey(k);
  }

  RS_Suggestions *s = RS_SuggestionsCreate();

  SpellCheck_FindSuggestions(scCtx, scCtx->sctx->spec->terms, term, len, fieldMask, s, 1);

  // sorting results by score

  // searching the term on the include list for more suggestions.
  for (int i = 0; i < array_len(scCtx->includeDict); ++i) {
    RedisModuleKey *k = NULL;
    Trie *t =
        SpellCheck_OpenDict(scCtx->sctx->redisCtx, scCtx->includeDict[i], REDISMODULE_READ, &k);
    if (t == NULL) {
      continue;
    }
    SpellCheck_FindSuggestions(scCtx, t, term, len, fieldMask, s, 0);
    RedisModule_CloseKey(k);
  }

  SpellCheck_SendReplyOnTerm(scCtx->sctx->redisCtx, term, len, s,
                             (!scCtx->fullScoreInfo) ? scCtx->sctx->spec->docs.size - 1 : 0);

  RS_SuggestionsFree(s);

  return true;
}
コード例 #7
0
ファイル: unique.c プロジェクト: neverlee/unique
static void PopReplyString(RedisModuleCtx *ctx, sds skey, sds sval) {
    RedisModule_ReplyWithArray(ctx, 2);
    RedisModule_ReplyWithStringBuffer(ctx, skey, sdslen(skey));
    RedisModule_ReplyWithStringBuffer(ctx, sval, sdslen(sval));
}