org.apache.cassandra.index.internal

## Class CassandraIndex

- java.lang.Object
- - org.apache.cassandra.index.internal.CassandraIndex

All Implemented Interfaces:
  Index

Direct Known Subclasses:
  ClusteringColumnIndex, CollectionKeyIndexBase, CollectionValueIndex, KeysIndex, PartitionKeyIndex, RegularColumnIndex

    public abstract class CassandraIndex
    extends java.lang.Object
    implements Index

Index implementation which indexes the values for a single column in the base table and which stores its index data in a local, hidden table.

### Nested Class Summary

### Nested classes/interfaces inherited from interface org.apache.cassandra.index.Index

`Index.CollatedViewIndexBuildingSupport, Index.IndexBuildingSupport, Index.Indexer, Index.Searcher`

### Field Summary

Fields
`ColumnFamilyStore` `baseCfs`
`protected CassandraIndexFunctions` `functions`
`protected ColumnFamilyStore` `indexCfs`
`protected ColumnDefinition` `indexedColumn`
`protected IndexMetadata` `metadata`

### Fields inherited from interface org.apache.cassandra.index.Index

`INDEX_BUILDER_SUPPORT`

### Constructor Summary

Constructors
`protected` `CassandraIndex(ColumnFamilyStore baseCfs, IndexMetadata indexDef)`

### Method Summary

All Methods Static Methods Instance Methods Abstract Methods Concrete Methods
`protected abstract CBuilder` `buildIndexClusteringPrefix(java.nio.ByteBuffer partitionKey, ClusteringPrefix prefix, CellPath path)` Used to construct an the clustering for an entry in the index table based on values from the base data.
`AbstractType<?>` `customExpressionValueType()` If the index supports custom search expressions using the SELECT * FROM table WHERE expr(index_name, expression) syntax, this method should return the expected type of the expression argument.
`abstract IndexEntry` `decodeEntry(DecoratedKey indexedValue, Row indexEntry)` Used at search time to convert a row in the index table into a simple struct containing the values required to retrieve the corresponding row from the base table.
`void` `deleteStaleEntry(DecoratedKey indexKey, Clustering indexClustering, DeletionTime deletion, OpOrder.Group opGroup)` Specific to internal indexes, this is called by a searcher when it encounters a stale entry in the index
`boolean` `dependsOn(ColumnDefinition column)` Called to determine whether this index targets a specific column.
`java.util.Optional<ColumnFamilyStore>` `getBackingTable()` If the index implementation uses a local table to store its index data this method should return a handle to it.
`java.util.concurrent.Callable<java.lang.Void>` `getBlockingFlushTask()` Return a task which performs a blocking flush of the index's data to persistent storage.
`long` `getEstimatedResultRows()` Return an estimate of the number of results this index is expected to return for any given query that it can be used to answer.
`ColumnFamilyStore` `getIndexCfs()`
`ClusteringComparator` `getIndexComparator()`
`ColumnDefinition` `getIndexedColumn()`
`protected abstract java.nio.ByteBuffer` `getIndexedValue(java.nio.ByteBuffer partitionKey, Clustering clustering, CellPath path, java.nio.ByteBuffer cellValue)` Extract the value to be inserted into the index from the components of the base data
`IndexMetadata` `getIndexMetadata()` Returns the IndexMetadata which configures and defines the index instance.
`java.util.concurrent.Callable<?>` `getInitializationTask()` Return a task to perform any initialization work when a new index instance is created.
`java.util.concurrent.Callable<?>` `getInvalidateTask()` Return a task which invalidates the index, indicating it should no longer be considered usable.
`java.util.concurrent.Callable<?>` `getMetadataReloadTask(IndexMetadata indexDef)` Return a task to reload the internal metadata of an index.
`RowFilter` `getPostIndexQueryFilter(RowFilter filter)` Transform an initial RowFilter into the filter that will still need to applied to a set of Rows after the index has performed it's initial scan.
`java.util.concurrent.Callable<?>` `getTruncateTask(long truncatedAt)` Return a task to truncate the index with the specified truncation timestamp.
`static CFMetaData` `indexCfsMetadata(CFMetaData baseCfsMetadata, IndexMetadata indexMetadata)` Construct the CFMetadata for an index table, the clustering columns in the index table vary dependent on the kind of the indexed value.
`Index.Indexer` `indexerFor(DecoratedKey key, PartitionColumns columns, int nowInSec, OpOrder.Group opGroup, IndexTransaction.Type transactionType)` Creates an new `Indexer` object for updates to a given partition.
`abstract boolean` `isStale(Row row, java.nio.ByteBuffer indexValue, int nowInSec)` Check whether a value retrieved from an index is still valid by comparing it to current row from the base table.
`static CassandraIndex` `newIndex(ColumnFamilyStore baseCfs, IndexMetadata indexMetadata)` Factory method for new CassandraIndex instances
`java.util.function.BiFunction<PartitionIterator,ReadCommand,PartitionIterator>` `postProcessorFor(ReadCommand command)` No post processing of query results, just return them unchanged
`void` `register(IndexRegistry registry)` An index must be registered in order to be able to either subscribe to update events on the base table and/or to provide Searcher functionality for reads.
`Index.Searcher` `searcherFor(ReadCommand command)` Factory method for query time search helper.
`boolean` `shouldBuildBlocking()` Return true if this index can be built or rebuilt when the index manager determines it is necessary.
`boolean` `supportsExpression(ColumnDefinition column, Operator operator)` Called to determine whether this index can provide a searcher to execute a query on the supplied column using the specified operator.
`protected boolean` `supportsOperator(ColumnDefinition indexedColumn, Operator operator)` Returns true if an index of this type can support search predicates of the form [column] OPERATOR [value]
`void` `validate(PartitionUpdate update)` Called at write time to ensure that values present in the update are valid according to the rules of all registered indexes which will process it.
`void` `validate(ReadCommand command)` Used to validate the various parameters of a supplied ReadCommand, this is called prior to execution.

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Methods inherited from interface org.apache.cassandra.index.Index

`getBuildTaskSupport, getFlushObserver, getPreJoinTask`

### Field Detail

#### baseCfs

    public final ColumnFamilyStore baseCfs

#### metadata

    protected IndexMetadata metadata

#### indexCfs

    protected ColumnFamilyStore indexCfs

#### indexedColumn

    protected ColumnDefinition indexedColumn

#### functions

    protected CassandraIndexFunctions functions

### Constructor Detail

#### CassandraIndex

    protected CassandraIndex(ColumnFamilyStore baseCfs,
                             IndexMetadata indexDef)

### Method Detail

#### supportsOperator

    protected boolean supportsOperator(ColumnDefinition indexedColumn,
                                       Operator operator)

Returns true if an index of this type can support search predicates of the form [column] OPERATOR [value]

Parameters:
  `indexedColumn` -
  `operator` -
Returns:

#### buildIndexClusteringPrefix

    protected abstract CBuilder buildIndexClusteringPrefix(java.nio.ByteBuffer partitionKey,
                                                           ClusteringPrefix prefix,
                                                           CellPath path)

Used to construct an the clustering for an entry in the index table based on values from the base data. The clustering columns in the index table encode the values required to retrieve the correct data from the base table and varies depending on the kind of the indexed column. See indexCfsMetadata for more details Used whenever a row in the index table is written or deleted.

Parameters:
  `partitionKey` - from the base data being indexed
  `prefix` - from the base data being indexed
  `path` - from the base data being indexed
Returns:
  a clustering prefix to be used to insert into the index table

#### decodeEntry

    public abstract IndexEntry decodeEntry(DecoratedKey indexedValue,
                                           Row indexEntry)

Used at search time to convert a row in the index table into a simple struct containing the values required to retrieve the corresponding row from the base table.

Parameters:
  `indexedValue` - the partition key of the indexed table (i.e. the value that was indexed)
  `indexEntry` - a row from the index table
Returns:

#### isStale

    public abstract boolean isStale(Row row,
                                    java.nio.ByteBuffer indexValue,
                                    int nowInSec)

Check whether a value retrieved from an index is still valid by comparing it to current row from the base table. Used at read time to identify out of date index entries so that they can be excluded from search results and repaired

Parameters:
  `row` - the current row from the primary data table
  `indexValue` - the value we retrieved from the index
  `nowInSec` -
Returns:
  true if the index is out of date and the entry should be dropped

#### getIndexedValue

    protected abstract java.nio.ByteBuffer getIndexedValue(java.nio.ByteBuffer partitionKey,
                                                           Clustering clustering,
                                                           CellPath path,
                                                           java.nio.ByteBuffer cellValue)

Extract the value to be inserted into the index from the components of the base data

Parameters:
  `partitionKey` - from the primary data
  `clustering` - from the primary data
  `path` - from the primary data
  `cellValue` - from the primary data
Returns:
  a ByteBuffer containing the value to be inserted in the index. This will be used to make the partition key in the index table

#### getIndexedColumn

    public ColumnDefinition getIndexedColumn()

#### getIndexComparator

    public ClusteringComparator getIndexComparator()

#### getIndexCfs

    public ColumnFamilyStore getIndexCfs()

#### register

    public void register(IndexRegistry registry)

Description copied from interface: `Index`
An index must be registered in order to be able to either subscribe to update events on the base table and/or to provide Searcher functionality for reads. The double dispatch involved here, where the Index actually performs its own registration by calling back to the supplied IndexRegistry's own registerIndex method, is to make the decision as to whether or not to register an index belong to the implementation, not the manager.

Specified by:
  `register` in interface `Index`
Parameters:
  `registry` - the index registry to register the instance with

#### getInitializationTask

    public java.util.concurrent.Callable<?> getInitializationTask()

Description copied from interface: `Index`
Return a task to perform any initialization work when a new index instance is created. This may involve costly operations such as (re)building the index, and is performed asynchronously by SecondaryIndexManager

Specified by:
  `getInitializationTask` in interface `Index`
Returns:
  a task to perform any necessary initialization work

#### getIndexMetadata

    public IndexMetadata getIndexMetadata()

Description copied from interface: `Index`
Returns the IndexMetadata which configures and defines the index instance. This should be the same object passed as the argument to setIndexMetadata.

Specified by:
  `getIndexMetadata` in interface `Index`
Returns:
  the index's metadata

#### getBackingTable

    public java.util.Optional<ColumnFamilyStore> getBackingTable()

Description copied from interface: `Index`
If the index implementation uses a local table to store its index data this method should return a handle to it. If not, an empty Optional should be returned. Typically, this is useful for the built-in Index implementations.

Specified by:
  `getBackingTable` in interface `Index`
Returns:
  an Optional referencing the Index's backing storage table if it has one, or Optional.empty() if not.

#### getBlockingFlushTask

    public java.util.concurrent.Callable<java.lang.Void> getBlockingFlushTask()

Description copied from interface: `Index`
Return a task which performs a blocking flush of the index's data to persistent storage.

Specified by:
  `getBlockingFlushTask` in interface `Index`
Returns:
  task to be executed by the index manager to perform the flush.

#### getInvalidateTask

    public java.util.concurrent.Callable<?> getInvalidateTask()

Description copied from interface: `Index`
Return a task which invalidates the index, indicating it should no longer be considered usable. This should include an clean up and releasing of resources required when dropping an index.

Specified by:
  `getInvalidateTask` in interface `Index`
Returns:
  task to be executed by the index manager to invalidate the index.

#### getMetadataReloadTask

    public java.util.concurrent.Callable<?> getMetadataReloadTask(IndexMetadata indexDef)

Description copied from interface: `Index`
Return a task to reload the internal metadata of an index. Called when the base table metadata is modified or when the configuration of the Index is updated Implementations should return a task which performs any necessary work to be done due to updating the configuration(s) such as (re)building etc. This task is performed asynchronously by SecondaryIndexManager

Specified by:
  `getMetadataReloadTask` in interface `Index`
Returns:
  task to be executed by the index manager during a reload

#### validate

    public void validate(ReadCommand command)
                  throws InvalidRequestException

Description copied from interface: `Index`
Used to validate the various parameters of a supplied ReadCommand, this is called prior to execution. In theory, any command instance may be checked by any Index instance, but in practice the index will be the one returned by a call to the getIndex(ColumnFamilyStore cfs) method on the supplied command. Custom index implementations should perform any validation of query expressions here and throw a meaningful InvalidRequestException when any expression or other parameter is invalid.

Specified by:
  `validate` in interface `Index`
Parameters:
  `command` - a ReadCommand whose parameters are to be verified
Throws:
  `InvalidRequestException` - if the details of the command fail to meet the index's validation rules

#### getTruncateTask

    public java.util.concurrent.Callable<?> getTruncateTask(long truncatedAt)

Description copied from interface: `Index`
Return a task to truncate the index with the specified truncation timestamp. Called when the base table is truncated.

Specified by:
  `getTruncateTask` in interface `Index`
Parameters:
  `truncatedAt` - timestamp of the truncation operation. This will be the same timestamp used in the truncation of the base table.
Returns:
  task to be executed by the index manager when the base table is truncated.

#### shouldBuildBlocking

    public boolean shouldBuildBlocking()

Description copied from interface: `Index`
Return true if this index can be built or rebuilt when the index manager determines it is necessary. Returning false enables the index implementation (or some other component) to control if and when SSTable data is incorporated into the index. This is called by SecondaryIndexManager in buildIndexBlocking, buildAllIndexesBlocking and rebuildIndexesBlocking where a return value of false causes the index to be exluded from the set of those which will process the SSTable data.

Specified by:
  `shouldBuildBlocking` in interface `Index`
Returns:
  if the index should be included in the set which processes SSTable data, false otherwise.

#### dependsOn

    public boolean dependsOn(ColumnDefinition column)

Description copied from interface: `Index`
Called to determine whether this index targets a specific column. Used during schema operations such as when dropping or renaming a column, to check if the index will be affected by the change. Typically, if an index answers that it does depend upon a column, then schema operations on that column are not permitted until the index is dropped or altered.

Specified by:
  `dependsOn` in interface `Index`
Parameters:
  `column` - the column definition to check
Returns:
  true if the index depends on the supplied column being present; false if the column may be safely dropped or modified without adversely affecting the index

#### supportsExpression

    public boolean supportsExpression(ColumnDefinition column,
                                      Operator operator)

Description copied from interface: `Index`
Called to determine whether this index can provide a searcher to execute a query on the supplied column using the specified operator. This forms part of the query validation done before a CQL select statement is executed.

Specified by:
  `supportsExpression` in interface `Index`
Parameters:
  `column` - the target column of a search query predicate
  `operator` - the operator of a search query predicate
Returns:
  true if this index is capable of supporting such expressions, false otherwise

#### customExpressionValueType

    public AbstractType<?> customExpressionValueType()

Description copied from interface: `Index`
If the index supports custom search expressions using the SELECT * FROM table WHERE expr(index_name, expression) syntax, this method should return the expected type of the expression argument. For example, if the index supports custom expressions as Strings, calls to this method should return UTF8Type.instance. If the index implementation does not support custom expressions, then it should return null.

Specified by:
  `customExpressionValueType` in interface `Index`
Returns:
  an the type of custom index expressions supported by this index, or an null if custom expressions are not supported.

#### getEstimatedResultRows

    public long getEstimatedResultRows()

Description copied from interface: `Index`
Return an estimate of the number of results this index is expected to return for any given query that it can be used to answer. Used in conjunction with indexes() and supportsExpression() to determine the most selective index for a given ReadCommand. Additionally, this is also used by StorageProxy.estimateResultsPerRange to calculate the initial concurrency factor for range requests

Specified by:
  `getEstimatedResultRows` in interface `Index`
Returns:
  the estimated average number of results a Searcher may return for any given query

#### postProcessorFor

    public java.util.function.BiFunction<PartitionIterator,ReadCommand,PartitionIterator> postProcessorFor(ReadCommand command)

No post processing of query results, just return them unchanged

Specified by:
  `postProcessorFor` in interface `Index`

#### getPostIndexQueryFilter

    public RowFilter getPostIndexQueryFilter(RowFilter filter)

Description copied from interface: `Index`
Transform an initial RowFilter into the filter that will still need to applied to a set of Rows after the index has performed it's initial scan. Used in ReadCommand#executeLocal to reduce the amount of filtering performed on the results of the index query.

Specified by:
  `getPostIndexQueryFilter` in interface `Index`
Parameters:
  `filter` - the intial filter belonging to a ReadCommand
Returns:
  the (hopefully) reduced filter that would still need to be applied after the index was used to narrow the initial result set

#### searcherFor

    public Index.Searcher searcherFor(ReadCommand command)

Description copied from interface: `Index`
Factory method for query time search helper.

Specified by:
  `searcherFor` in interface `Index`
Parameters:
  `command` - the read command being executed
Returns:
  an Searcher with which to perform the supplied command

#### validate

    public void validate(PartitionUpdate update)
                  throws InvalidRequestException

Description copied from interface: `Index`
Called at write time to ensure that values present in the update are valid according to the rules of all registered indexes which will process it. The partition key as well as the clustering and cell values for each row in the update may be checked by index implementations

Specified by:
  `validate` in interface `Index`
Parameters:
  `update` - PartitionUpdate containing the values to be validated by registered Index implementations
Throws:
  `InvalidRequestException`

#### indexerFor

    public Index.Indexer indexerFor(DecoratedKey key,
                                    PartitionColumns columns,
                                    int nowInSec,
                                    OpOrder.Group opGroup,
                                    IndexTransaction.Type transactionType)

Description copied from interface: `Index`
Creates an new `Indexer` object for updates to a given partition.

Specified by:
  `indexerFor` in interface `Index`
Parameters:
  `key` - key of the partition being modified
  `columns` - the regular and static columns the created indexer will have to deal with. This can be empty as an update might only contain partition, range and row deletions, but the indexer is guaranteed to not get any cells for a column that is not part of `columns`.
  `nowInSec` - current time of the update operation
  `opGroup` - operation group spanning the update operation
  `transactionType` - indicates what kind of update is being performed on the base data i.e. a write time insert/update/delete or the result of compaction
Returns:
  the newly created indexer or `null` if the index is not interested by the update (this could be because the index doesn't care about that particular partition, doesn't care about that type of transaction, ...).

#### deleteStaleEntry

    public void deleteStaleEntry(DecoratedKey indexKey,
                                 Clustering indexClustering,
                                 DeletionTime deletion,
                                 OpOrder.Group opGroup)

Specific to internal indexes, this is called by a searcher when it encounters a stale entry in the index

Parameters:
  `indexKey` - the partition key in the index table
  `indexClustering` - the clustering in the index table
  `deletion` - deletion timestamp etc
  `opGroup` - the operation under which to perform the deletion

#### indexCfsMetadata

    public static final CFMetaData indexCfsMetadata(CFMetaData baseCfsMetadata,
                                                    IndexMetadata indexMetadata)

Construct the CFMetadata for an index table, the clustering columns in the index table vary dependent on the kind of the indexed value.

Parameters:
  `baseCfsMetadata` -
  `indexMetadata` -
Returns:

#### newIndex

    public static CassandraIndex newIndex(ColumnFamilyStore baseCfs,
                                          IndexMetadata indexMetadata)

Factory method for new CassandraIndex instances

Parameters:
  `baseCfs` -
  `indexMetadata` -
Returns: