// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.server.index;

import com.google.gerrit.server.query.DataSource;
import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryParseException;

import java.io.IOException;

/**
 * Secondary index implementation for arbitrary documents.
 * <p>
 * Documents are inserted into the index and are queried by converting special
 * {@link com.google.gerrit.server.query.Predicate} instances into index-aware
 * predicates that use the index search results as a source.
 * <p>
 * Implementations must be thread-safe and should batch inserts/updates where
 * appropriate.
 */
public interface Index<K, V> {
  /** @return the schema version used by this index. */
  Schema<V> getSchema();

  /** Stop and await termination of all executor threads */
  void stop();

  /** Close this index. */
  void close();

  /**
   * Update a document in the index.
   * <p>
   * Semantically equivalent to deleting the document and reinserting it with
   * new field values. A document that does not already exist is created. Results
   * may not be immediately visible to searchers, but should be visible within a
   * reasonable amount of time.
   *
   * @param obj document object
   *
   * @throws IOException
   */
  void replace(V obj) throws IOException;

  /**
   * Delete a document from the index by key.
   *
   * @param key document key
   *
   * @throws IOException
   */
  void delete(K key) throws IOException;

  /**
   * Delete all documents from the index.
   *
   * @throws IOException
   */
  void deleteAll() throws IOException;

  /**
   * Convert the given operator predicate into a source searching the index and
   * returning only the documents matching that predicate.
   * <p>
   * This method may be called multiple times for variations on the same
   * predicate or multiple predicate subtrees in the course of processing a
   * single query, so it should not have any side effects (e.g. starting a
   * search in the background).
   *
   * @param p the predicate to match. Must be a tree containing only AND, OR,
   *     or NOT predicates as internal nodes, and {@link IndexPredicate}s as
   *     leaves.
   * @param opts query options not implied by the predicate, such as start and
   *     limit.
   * @return a source of documents matching the predicate, returned in a
   *     defined order depending on the type of documents.
   *
   * @throws QueryParseException if the predicate could not be converted to an
   *     indexed data source.
   */
  DataSource<V> getSource(Predicate<V> p, QueryOptions opts)
      throws QueryParseException;

  /**
   * Mark whether this index is up-to-date and ready to serve reads.
   *
   * @param ready whether the index is ready
   * @throws IOException
   */
  void markReady(boolean ready) throws IOException;
}
