/**
   * This helper method handles the case when a tuple is being removed from the table, before the
   * row has actually been removed from the table. All indexes on the table are updated to remove
   * the row.
   *
   * @param tblFileInfo details of the table being updated
   * @param ptup the tuple about to be removed from the table
   */
  private void removeRowFromIndexes(TableInfo tblFileInfo, PageTuple ptup) {

    logger.debug(
        "Removing tuple " + ptup + " from indexes for table " + tblFileInfo.getTableName());

    // Iterate over the indexes in the table.
    TableSchema schema = tblFileInfo.getSchema();
    for (ColumnRefs indexDef : schema.getIndexes().values()) {
      TupleLiteral idxTup =
          IndexUtils.makeSearchKeyValue(indexDef, ptup, /* findExactTuple */ true);

      logger.debug("Removing tuple " + idxTup + " from index " + indexDef.getIndexName());

      try {
        IndexInfo indexInfo = indexManager.openIndex(tblFileInfo, indexDef.getIndexName());

        TupleFile tupleFile = indexInfo.getTupleFile();

        PageTuple idxPageTup = IndexUtils.findTupleInIndex(idxTup, tupleFile);
        if (idxPageTup == null) {
          throw new IllegalStateException(
              "Can't find tuple in " + "index corresponding to table's tuple.");
        }

        tupleFile.deleteTuple(idxPageTup);
      } catch (IOException e) {
        throw new EventDispatchException(
            "Couldn't update index "
                + indexDef.getIndexName()
                + " for table "
                + tblFileInfo.getTableName());
      }
    }
  }
Example #2
0
  @Override
  public boolean indexAccessible(final IndexInfo ii) {
    /* If the following conditions yield true, the index is accessed:
     * - all query terms are statically available
     * - no FTTimes option is specified
     * - explicitly set case, diacritics and stemming match options do not
     *   conflict with index options. */
    data = ii.ic.data;
    final MetaData md = data.meta;
    final FTOpt fto = ftt.opt;

    /* Index will be applied if no explicit match options have been set
     * that conflict with the index options. As a consequence, though, index-
     * based querying might yield other results than sequential scanning. */
    if (occ != null
        || fto.cs != null && md.casesens == (fto.cs == FTCase.INSENSITIVE)
        || fto.isSet(DC) && md.diacritics != fto.is(DC)
        || fto.isSet(ST) && md.stemming != fto.is(ST)
        || fto.ln != null && !fto.ln.equals(md.language)) return false;

    // adopt database options to tokenizer
    fto.copy(md);

    // estimate costs if text is not known at compile time
    if (tokens == null) {
      ii.costs = Math.max(2, data.meta.size / 30);
      return true;
    }

    // summarize number of hits; break loop if no hits are expected
    final FTLexer ft = new FTLexer(fto);
    ii.costs = 0;
    for (byte[] t : tokens) {
      ft.init(t);
      while (ft.hasNext()) {
        final byte[] tok = ft.nextToken();
        if (fto.sw != null && fto.sw.contains(tok)) continue;

        if (fto.is(WC)) {
          // don't use index if one of the terms starts with a wildcard
          t = ft.get();
          if (t[0] == '.') return false;
          // don't use index if certain characters or more than 1 dot are found
          int d = 0;
          for (final byte w : t) {
            if (w == '{' || w == '\\' || w == '.' && ++d > 1) return false;
          }
        }
        // favor full-text index requests over exact queries
        final int costs = data.costs(ft);
        if (costs != 0) ii.costs += Math.max(2, costs / 100);
      }
    }
    return true;
  }
Example #3
0
 @Override
 public boolean indexAccessible(final IndexInfo ii) throws QueryException {
   int costs = 0;
   final ExprList el = new ExprList(exprs.length);
   for (final Expr expr : exprs) {
     // check if expression can be rewritten, and if access is not sequential
     if (!expr.indexAccessible(ii)) return false;
     // skip expressions without results
     if (ii.costs == 0) continue;
     costs += ii.costs;
     el.add(ii.expr);
   }
   // use summarized costs for estimation
   ii.costs = costs;
   // no expressions means no costs: expression will later be ignored
   ii.expr = el.size() == 1 ? el.get(0) : new Union(info, el.finish());
   return true;
 }
 @Test
 public void testReadFromConfigEntry() throws Exception {
   final IndexInfo info =
       IndexInfo.fromConfigEntry(
           stringMap("batch_import.node_index.foo", "exact:file").entrySet().iterator().next());
   assertEquals("node_index", info.elementType);
   assertEquals("foo", info.indexName);
   assertEquals("exact", info.indexType);
   assertEquals("file", info.indexFileName);
 }
  /**
   * This helper method handles the case when a tuple is being added to the table, after the row has
   * already been added to the table. All indexes on the table are updated to include the new row.
   *
   * @param tblFileInfo details of the table being updated
   * @param ptup the new tuple that was inserted into the table
   */
  private void addRowToIndexes(TableInfo tblFileInfo, PageTuple ptup) {
    logger.debug("Adding tuple " + ptup + " to indexes for table " + tblFileInfo.getTableName());

    // Iterate over the indexes in the table.
    TableSchema schema = tblFileInfo.getSchema();
    for (ColumnRefs indexDef : schema.getIndexes().values()) {
      TupleLiteral idxTup;
      try {
        IndexInfo indexInfo = indexManager.openIndex(tblFileInfo, indexDef.getIndexName());

        TupleFile tupleFile = indexInfo.getTupleFile();

        TableConstraintType constraintType = indexDef.getConstraintType();
        if (constraintType != null && constraintType.isUnique()) {
          // Check if the index already has a tuple with this value.
          idxTup = IndexUtils.makeSearchKeyValue(indexDef, ptup, /* findExactTuple */ false);

          if (IndexUtils.findTupleInIndex(idxTup, tupleFile) != null) {
            // Adding this row would violate the unique index.
            throw new IllegalStateException(
                "Unique index " + "already contains a tuple with this value.");
          }
        }

        idxTup = IndexUtils.makeSearchKeyValue(indexDef, ptup, /* findExactTuple */ true);

        logger.debug("Adding tuple " + idxTup + " to index " + indexDef.getIndexName());

        tupleFile.addTuple(idxTup);
      } catch (IOException e) {
        throw new EventDispatchException(
            "Couldn't update index "
                + indexDef.getIndexName()
                + " for table "
                + tblFileInfo.getTableName(),
            e);
      }
    }
  }
  /**
   * This method is used to pass an algorithm decorator factory that is used for tracing (for
   * example). See {@link #checkedRules(Object, Object[], IRuntimeEnv)} for full documentation
   *
   * @param target target object
   * @param params parameters of a test
   * @param env environment
   * @param decoratorFactory a decorator factory that will decorate an objects that are used to
   *     calculate a rule
   * @return iterator over <b>rule indexes</b> - integer iterator.
   * @see #checkedRules(Object, Object[], IRuntimeEnv)
   */
  protected final IIntIterator checkedRules(
      Object target,
      Object[] params,
      IRuntimeEnv env,
      DefaultAlgorithmDecoratorFactory decoratorFactory) {

    // Select rules set using indexed mode
    //
    //        ICondition[] conditions = table.getConditionRows();

    IIntIterator iterator = null;
    int conditionNumber = info.fromCondition;

    if (indexRoot == null) {
      iterator = info.makeRuleIterator();
    } else {

      ARuleIndex index = indexRoot;

      for (; conditionNumber <= info.toCondition; conditionNumber++) {
        index = decoratorFactory.create(index, table.getCondition(conditionNumber));

        Object testValue =
            evaluateTestValue(table.getCondition(conditionNumber), target, params, env);

        DecisionTableRuleNode node = index.findNode(testValue);

        if (!node.hasIndex()) {
          iterator = node.getRulesIterator();
          conditionNumber += 1;
          break;
        }

        index = node.getNextIndex();
      }
    }

    for (; conditionNumber <= info.toCondition; conditionNumber++) {

      ICondition condition = table.getCondition(conditionNumber);
      IConditionEvaluator evaluator = evaluators[conditionNumber];

      IIntSelector sel = evaluator.getSelector(condition, target, params, env);
      sel = decoratorFactory.create(sel, condition);

      iterator = iterator.select(sel);
    }

    return iterator;
  }
Example #7
0
  @Override
  public boolean indexAccessible(final IndexInfo ii) throws QueryException {
    final int es = exprs.length;
    final boolean[] ng = new boolean[es];
    int costs = 0;
    for (final FTExpr expr : exprs) {
      if (!expr.indexAccessible(ii)) return false;
      // use worst costs for estimation, as all index results may need to be scanned
      if (costs < ii.costs) costs = ii.costs;
    }

    ii.costs = costs;
    negated = ng;
    return true;
  }