Пример #1
0
grn_rc
grn_snip_add_cond(grn_ctx *ctx, grn_snip *snip,
                  const char *keyword, unsigned int keyword_len,
                  const char *opentag, unsigned int opentag_len,
                  const char *closetag, unsigned int closetag_len)
{
  grn_rc rc;
  int copy_tag;
  snip_cond *cond;
  unsigned int norm_blen;

  if (!snip || !keyword || !keyword_len || snip->cond_len >= MAX_SNIP_COND_COUNT) {
    return GRN_INVALID_ARGUMENT;
  }
  cond = snip->cond + snip->cond_len;
  if ((rc = grn_snip_cond_init(ctx, cond, keyword, keyword_len,
                               snip->encoding, snip->normalizer, snip->flags))) {
    return rc;
  }
  grn_string_get_normalized(ctx, cond->keyword, NULL, &norm_blen, NULL);
  if (norm_blen > snip->width) {
    grn_snip_cond_close(ctx, cond);
    return GRN_INVALID_ARGUMENT;
  }

  copy_tag = snip->flags & GRN_SNIP_COPY_TAG;
  rc = grn_snip_cond_set_tag(ctx,
                             &(cond->opentag), &(cond->opentag_len),
                             opentag, opentag_len,
                             snip->defaultopentag, snip->defaultopentag_len,
                             copy_tag);
  if (rc) {
    grn_snip_cond_close(ctx, cond);
    return rc;
  }

  rc = grn_snip_cond_set_tag(ctx,
                             &(cond->closetag), &(cond->closetag_len),
                             closetag, closetag_len,
                             snip->defaultclosetag, snip->defaultclosetag_len,
                             copy_tag);
  if (rc) {
    if (opentag && copy_tag) {
      GRN_FREE((void *)cond->opentag);
    }
    grn_snip_cond_close(ctx, cond);
    return rc;
  }

  snip->cond_len++;
  return GRN_SUCCESS;
}
Пример #2
0
/* TODO: delete overlapping logic with exec_query */
static grn_rc
scan_query(grn_ctx *ctx, grn_query *q, grn_str *nstr, grn_id section, grn_cell *c, snip_cond **sc,
           grn_operator op, int flags, int *found, int *score)
{
  int _found = 0, _score = 0;
  grn_cell *e, *ope = NIL;
  grn_operator op0 = GRN_OP_OR, *opp = &op0, op1 = q->default_op;
  while (c != NIL) {
    POP(e, c);
    switch (e->header.type) {
    case GRN_CELL_OP :
      if (opp == &op0 && e->u.op.op == GRN_OP_BUT) {
        POP(e, c);
      } else {
        ope = e;
        op1 = ope->u.op.op;
      }
      continue;
    case GRN_CELL_STR :
      if (ope != NIL) {
        q->opt.mode = ope->u.op.mode == -1 ? q->default_mode : ope->u.op.mode;
        q->opt.max_interval = q->opt.similarity_threshold = ope->u.op.option;
        if (!q->opt.weight_vector) {
          q->opt.vector_size = ope->u.op.weight + q->weight_offset;
        }
      } else {
        q->opt.mode = q->default_mode;
        q->opt.max_interval = DEFAULT_MAX_INTERVAL;
        q->opt.similarity_threshold = DEFAULT_SIMILARITY_THRESHOLD;
        if (!q->opt.weight_vector) {
          q->opt.vector_size = DEFAULT_WEIGHT + q->weight_offset;
        }
      }
      if ((flags & GRN_QUERY_SCAN_ALLOCCONDS)) {
        grn_rc rc;
        /* NOTE: GRN_SNIP_NORMALIZE = GRN_QUERY_SCAN_NORMALIZE */
        if ((rc = grn_snip_cond_init(ctx, *sc, e->u.b.value, e->u.b.size,
                                     q->encoding, flags & GRN_SNIP_NORMALIZE))) {
          return rc;
        }
      } else {
        grn_snip_cond_reinit(*sc);
      }
      scan_keyword(*sc, nstr, section, *opp, &q->opt, &_found, &_score);
      (*sc)++;
      break;
    case GRN_CELL_LIST :
      scan_query(ctx, q, nstr, section, e, sc, *opp, flags, &_found, &_score);
      break;
    default :
      GRN_LOG(ctx, GRN_LOG_NOTICE, "invalid object assigned in query! (%d)", e->header.type);
      break;
    }
    opp = &op1;
    ope = NIL;
    op1 = q->default_op;
  }
  switch (op) {
  case GRN_OP_OR :
    *found |= _found;
    *score += _score;
    break;
  case GRN_OP_AND :
    *found &= _found;
    *score += _score;
    break;
  case GRN_OP_BUT :
    *found &= !_found;
    break;
  case GRN_OP_ADJUST :
    *score += _score;
    break;
  default :
    break;
  }
  return GRN_SUCCESS;
}