/* * 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.db.composites; import java.io.DataInput; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Comparator; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; import org.apache.cassandra.cql3.CQL3Row; import org.apache.cassandra.cql3.ColumnIdentifier; import org.apache.cassandra.db.Cell; import org.apache.cassandra.db.ColumnSerializer; import org.apache.cassandra.db.OnDiskAtom; import org.apache.cassandra.db.filter.IDiskAtomFilter; import org.apache.cassandra.db.filter.NamesQueryFilter; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.CollectionType; import org.apache.cassandra.db.marshal.ColumnToCollectionType; import org.apache.cassandra.io.ISerializer; import org.apache.cassandra.io.IVersionedSerializer; /** * The type of CellNames. * * In the same way that a CellName is a Composite, a CellNameType is a CType, but * with a number of method specific to cell names. * * On top of the dichotomy simple/truly-composite of composites, cell names comes * in 2 variants: "dense" and "sparse". The sparse ones are CellName where one of * the component (the last or second-to-last for collections) is used to store the * CQL3 column name. Dense are those for which it's not the case. * * In other words, we have 4 types of CellName/CellNameType which correspond to the * 4 type of table layout that we need to distinguish: * 1. Simple (non-truly-composite) dense: this is the dynamic thrift CFs whose * comparator is not composite. * 2. Composite dense: this is the dynamic thrift CFs with a CompositeType comparator. * 3. Simple (non-truly-composite) sparse: this is the thrift static CFs (that * don't have a composite comparator). * 4. Composite sparse: this is the CQL3 layout (note that this is the only one that * support collections). */ public interface CellNameType extends CType { /** * Whether or not the cell names for this type are dense. */ public boolean isDense(); /** * The number of clustering columns for the table this is the type of. */ public int clusteringPrefixSize(); /** * A builder for the clustering prefix. */ public CBuilder prefixBuilder(); /** * The prefix to use for static columns. * * Note that create() methods below for creating CellName automatically handle static columns already * for convenience, and so there is not need to pass this prefix for them. There is few other cases * where we need the prefix directly however. */ public Composite staticPrefix(); /** * Whether or not there is some collections defined in this type. */ public boolean hasCollections(); /** * Whether or not this type layout support collections. */ public boolean supportCollections(); /** * The type of the collections (or null if the type does not have any non-frozen collections). */ public ColumnToCollectionType collectionType(); /** * Return the new type obtained by adding/updating to the new collection type for the provided column name * to this type. */ public CellNameType addOrUpdateCollection(ColumnIdentifier columnName, CollectionType newCollection); /** * Returns a new CellNameType that is equivalent to this one but with one * of the subtype replaced by the provided new type. */ @Override public CellNameType setSubtype(int position, AbstractType<?> newType); /** * Creates a row marker for the CQL3 having the provided clustering prefix. * * Note that this is only valid for CQL3 tables (isCompound() and !isDense()) and should * only be called for them. */ public CellName rowMarker(Composite prefix); /** * Creates a new CellName given a clustering prefix and a CQL3 column. * * Note that for dense types, the column can be null as a shortcut for designing the only * COMPACT_VALUE column of the table. */ public CellName create(Composite prefix, ColumnDefinition column); /** * Creates a new collection CellName given a clustering prefix, a CQL3 column and the collection element. */ public CellName create(Composite prefix, ColumnDefinition column, ByteBuffer collectionElement); /** * Convenience method to create cell names given its components. * * This is equivalent to CType#make() but return a full cell name (and thus * require all the components of the name). */ public CellName makeCellName(Object... components); /** * Deserialize a Composite from a ByteBuffer. * * This is equilvalent to CType#fromByteBuffer but assumes the buffer is a full cell * name. This is meant for thrift/cql2 to convert the fully serialized buffer we * get from the clients. */ public CellName cellFromByteBuffer(ByteBuffer bb); /** * Creates a new CQL3Row builder for this type. See CQL3Row for details. */ public CQL3Row.Builder CQL3RowBuilder(CFMetaData metadata, long now); // The two following methods are used to pass the declared regular column names (in CFMetaData) // to the CellNameType. This is only used for optimization sake, see SparseCellNameType. public void addCQL3Column(ColumnIdentifier id); public void removeCQL3Column(ColumnIdentifier id); /** * Creates a new Deserializer. This is used by AtomDeserializer to do incremental and on-demand * deserialization of the on disk atoms. See AtomDeserializer for details. */ public Deserializer newDeserializer(DataInput in); /* * Same as in CType, follows a number of per-CellNameType instances for the Comparator and Serializer used * throughout the code (those that require full CellName versus just Composite). */ // Ultimately, those might be split into an IVersionedSerializer and an ISSTableSerializer public ISerializer<CellName> cellSerializer(); public Comparator<Cell> columnComparator(boolean isRightNative); public Comparator<Object> asymmetricColumnComparator(boolean isRightNative); public Comparator<Cell> columnReverseComparator(); public Comparator<OnDiskAtom> onDiskAtomComparator(); public ColumnSerializer columnSerializer(); public OnDiskAtom.Serializer onDiskAtomSerializer(); public IVersionedSerializer<NamesQueryFilter> namesQueryFilterSerializer(); public IVersionedSerializer<IDiskAtomFilter> diskAtomFilterSerializer(); public interface Deserializer { /** * Whether this deserializer is done or not, i.e. whether we're reached the end of row marker. */ public boolean hasNext() throws IOException; /** * Whether or not some name has been read but not consumed by readNext. */ public boolean hasUnprocessed() throws IOException; /** * Compare the next name to read to the provided Composite. * This does not consume the next name. */ public int compareNextTo(Composite composite) throws IOException; /** * Actually consume the next name and return it. */ public Composite readNext() throws IOException; /** * Skip the next name (consuming it). */ public void skipNext() throws IOException; } }