/* * Copyright 2014, Stratio. * * 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.stratio.cassandra.index.service; import com.stratio.cassandra.util.ByteBufferUtils; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.db.DecoratedKey; import org.apache.cassandra.dht.IPartitioner; import org.apache.cassandra.dht.Token; import org.apache.cassandra.dht.Token.TokenFactory; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.Field.Store; import org.apache.lucene.document.StringField; import org.apache.lucene.index.Term; import org.apache.lucene.search.*; import org.apache.lucene.util.BytesRef; import java.io.IOException; import java.nio.ByteBuffer; /** * {@link TokenMapper} to be used when any {@link IPartitioner} when there is not a more specific implementation. It * indexes the token raw binary value as a Lucene string field. * * @author Andres de la Pena <adelapena@stratio.com> */ public class TokenMapperGeneric extends TokenMapper { public static final String FIELD_NAME = "_token_generic"; // The Lucene field name private final TokenFactory factory; // The partitioner token factory /** Returns a new {@link TokenMapperGeneric}. */ public TokenMapperGeneric(CFMetaData metadata) { super(metadata); factory = DatabaseDescriptor.getPartitioner().getTokenFactory(); } /** {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public void addFields(Document document, DecoratedKey partitionKey) { ByteBuffer bb = factory.toByteArray(partitionKey.getToken()); String serialized = ByteBufferUtils.toString(bb); Field field = new StringField(FIELD_NAME, serialized, Store.YES); document.add(field); } /** {@inheritDoc} */ @Override protected Query makeQuery(Token lower, Token upper, boolean includeLower, boolean includeUpper) { return new TokenRangeQuery(lower, upper, includeLower, includeUpper, this); } /** {@inheritDoc} */ @Override public Query query(Token token) { BytesRef ref = bytesRef(token); Term term = new Term(FIELD_NAME, ref); return new TermQuery(term); } /** {@inheritDoc} */ @Override public SortField[] sortFields() { return new SortField[]{new SortField(FIELD_NAME, new FieldComparatorSource() { @Override public FieldComparator<?> newComparator(String field, int hits, int sort, boolean reversed) throws IOException { return new TokenMapperGenericSorter(TokenMapperGeneric.this, hits, field); } })}; } /** * Returns the Cassandra {@link Token} represented by the specified Lucene {@link BytesRef}. * * @param bytesRef A Lucene {@link BytesRef} representation of a Cassandra {@link Token}. * @return The Cassandra {@link Token} represented by the specified Lucene {@link BytesRef}. */ Token token(BytesRef bytesRef) { String string = bytesRef.utf8ToString(); ByteBuffer bb = ByteBufferUtils.fromString(string); return factory.fromByteArray(bb); } /** * Returns the Lucene {@link BytesRef} represented by the specified Cassandra {@link Token}. * * @param token A Cassandra {@link Token}. * @return The Lucene {@link BytesRef} represented by the specified Cassandra {@link Token}. */ @SuppressWarnings("unchecked") public BytesRef bytesRef(Token token) { ByteBuffer bb = factory.toByteArray(token); byte[] bytes = ByteBufferUtils.asArray(bb); return new BytesRef(bytes); } }