blob: 89eebdf5ad4f737c2d10c486fb0ea6098b29d0a2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.cassandra.index.internal;
import java.util.List;
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.db.marshal.CollectionType;
import org.apache.cassandra.db.marshal.CompositeType;
import org.apache.cassandra.index.internal.composites.*;
import org.apache.cassandra.index.internal.keys.KeysIndex;
import org.apache.cassandra.schema.IndexMetadata;
public interface CassandraIndexFunctions
{
/**
*
* @param baseCfs
* @param indexMetadata
* @return
*/
public CassandraIndex newIndexInstance(ColumnFamilyStore baseCfs, IndexMetadata indexMetadata);
/**
* Returns the type of the the values in the index. For most columns this is simply its type, but for collections
* it depends on whether the index is on the collection name/value element or on a frozen collection
* @param indexedColumn
* @return
*/
default AbstractType<?> getIndexedValueType(ColumnDefinition indexedColumn)
{
return indexedColumn.type;
}
/**
* Add the clustering columns for a specific type of index table to the a CFMetaData.Builder (which is being
* used to construct the index table's CFMetadata. In the default implementation, the clustering columns of the
* index table hold the partition key and clustering columns of the base table. This is overridden in several cases:
* * When the indexed value is itself a clustering column, in which case, we only need store the base table's
* *other* clustering values in the index - the indexed value being the index table's partition key
* * When the indexed value is a collection value, in which case we also need to capture the cell path from the base
* table
* * In a KEYS index (for thrift/compact storage/static column indexes), where only the base partition key is
* held in the index table.
*
* Called from indexCfsMetadata
* @param builder
* @param baseMetadata
* @param cfDef
* @return
*/
default CFMetaData.Builder addIndexClusteringColumns(CFMetaData.Builder builder,
CFMetaData baseMetadata,
ColumnDefinition cfDef)
{
for (ColumnDefinition def : baseMetadata.clusteringColumns())
builder.addClusteringColumn(def.name, def.type);
return builder;
}
/*
* implementations providing specializations for the built in index types
*/
static final CassandraIndexFunctions KEYS_INDEX_FUNCTIONS = new CassandraIndexFunctions()
{
public CassandraIndex newIndexInstance(ColumnFamilyStore baseCfs, IndexMetadata indexMetadata)
{
return new KeysIndex(baseCfs, indexMetadata);
}
};
static final CassandraIndexFunctions REGULAR_COLUMN_INDEX_FUNCTIONS = new CassandraIndexFunctions()
{
public CassandraIndex newIndexInstance(ColumnFamilyStore baseCfs, IndexMetadata indexMetadata)
{
return new RegularColumnIndex(baseCfs, indexMetadata);
}
};
static final CassandraIndexFunctions CLUSTERING_COLUMN_INDEX_FUNCTIONS = new CassandraIndexFunctions()
{
public CassandraIndex newIndexInstance(ColumnFamilyStore baseCfs, IndexMetadata indexMetadata)
{
return new ClusteringColumnIndex(baseCfs, indexMetadata);
}
public CFMetaData.Builder addIndexClusteringColumns(CFMetaData.Builder builder,
CFMetaData baseMetadata,
ColumnDefinition columnDef)
{
List<ColumnDefinition> cks = baseMetadata.clusteringColumns();
for (int i = 0; i < columnDef.position(); i++)
{
ColumnDefinition def = cks.get(i);
builder.addClusteringColumn(def.name, def.type);
}
for (int i = columnDef.position() + 1; i < cks.size(); i++)
{
ColumnDefinition def = cks.get(i);
builder.addClusteringColumn(def.name, def.type);
}
return builder;
}
};
static final CassandraIndexFunctions PARTITION_KEY_INDEX_FUNCTIONS = new CassandraIndexFunctions()
{
public CassandraIndex newIndexInstance(ColumnFamilyStore baseCfs, IndexMetadata indexMetadata)
{
return new PartitionKeyIndex(baseCfs, indexMetadata);
}
};
static final CassandraIndexFunctions COLLECTION_KEY_INDEX_FUNCTIONS = new CassandraIndexFunctions()
{
public CassandraIndex newIndexInstance(ColumnFamilyStore baseCfs, IndexMetadata indexMetadata)
{
return new CollectionKeyIndex(baseCfs, indexMetadata);
}
public AbstractType<?> getIndexedValueType(ColumnDefinition indexedColumn)
{
return ((CollectionType) indexedColumn.type).nameComparator();
}
};
static final CassandraIndexFunctions COLLECTION_VALUE_INDEX_FUNCTIONS = new CassandraIndexFunctions()
{
public CassandraIndex newIndexInstance(ColumnFamilyStore baseCfs, IndexMetadata indexMetadata)
{
return new CollectionValueIndex(baseCfs, indexMetadata);
}
public AbstractType<?> getIndexedValueType(ColumnDefinition indexedColumn)
{
return ((CollectionType)indexedColumn.type).valueComparator();
}
public CFMetaData.Builder addIndexClusteringColumns(CFMetaData.Builder builder,
CFMetaData baseMetadata,
ColumnDefinition columnDef)
{
for (ColumnDefinition def : baseMetadata.clusteringColumns())
builder.addClusteringColumn(def.name, def.type);
// collection key
builder.addClusteringColumn("cell_path", ((CollectionType)columnDef.type).nameComparator());
return builder;
}
};
static final CassandraIndexFunctions COLLECTION_ENTRY_INDEX_FUNCTIONS = new CassandraIndexFunctions()
{
public CassandraIndex newIndexInstance(ColumnFamilyStore baseCfs, IndexMetadata indexMetadata)
{
return new CollectionEntryIndex(baseCfs, indexMetadata);
}
public AbstractType<?> getIndexedValueType(ColumnDefinition indexedColumn)
{
CollectionType colType = (CollectionType)indexedColumn.type;
return CompositeType.getInstance(colType.nameComparator(), colType.valueComparator());
}
};
}