blob: 557151205b7e2e25e2337a88f5166ab34ad0fdfa [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.phoenix.hbase.index.builder;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.client.Increment;
import org.apache.hadoop.hbase.client.Mutation;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.phoenix.coprocessor.BaseScannerRegionObserver.ReplayWrite;
import org.apache.phoenix.hbase.index.covered.IndexCodec;
import org.apache.phoenix.hbase.index.covered.IndexMetaData;
import org.apache.phoenix.hbase.index.covered.NonTxIndexBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Basic implementation of the {@link IndexBuilder} that doesn't do any actual work of indexing.
* <p>
* You should extend this class, rather than implementing IndexBuilder directly to maintain compatability going forward.
* <p>
* Generally, you should consider using one of the implemented IndexBuilders (e.g {@link NonTxIndexBuilder}) as there is
* a lot of work required to keep an index table up-to-date.
*/
public abstract class BaseIndexBuilder implements IndexBuilder {
public static final String CODEC_CLASS_NAME_KEY = "org.apache.hadoop.hbase.index.codec.class";
private static final Logger LOGGER = LoggerFactory.getLogger(BaseIndexBuilder.class);
protected boolean stopped;
protected RegionCoprocessorEnvironment env;
protected IndexCodec codec;
@Override
public void extendBaseIndexBuilderInstead() {}
@Override
public void setup(RegionCoprocessorEnvironment env) throws IOException {
this.env = env;
// setup the phoenix codec. Generally, this will just be in standard one, but abstracting here
// so we can use it later when generalizing covered indexes
Configuration conf = env.getConfiguration();
Class<? extends IndexCodec> codecClass = conf.getClass(CODEC_CLASS_NAME_KEY, null, IndexCodec.class);
try {
Constructor<? extends IndexCodec> meth = codecClass.getDeclaredConstructor(new Class[0]);
meth.setAccessible(true);
this.codec = meth.newInstance();
this.codec.initialize(conf, env.getRegion().getRegionInfo().getTable().getName());
} catch (Exception e) {
throw new IOException(e);
}
}
@Override
public void batchStarted(MiniBatchOperationInProgress<Mutation> miniBatchOp, IndexMetaData context) throws IOException {
// noop
}
@Override
public IndexMetaData getIndexMetaData(MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
return IndexMetaData.NULL_INDEX_META_DATA;
}
@Override
public void batchCompleted(MiniBatchOperationInProgress<Mutation> miniBatchOp) {
// noop
}
/**
* By default, we always attempt to index the mutation. Commonly this can be slow (because the framework spends the
* time to do the indexing, only to realize that you don't need it) or not ideal (if you want to turn on/off
* indexing on a table without completely reloading it).
*
* @throws IOException
*/
@Override
public boolean isEnabled(Mutation m) {
// ask the codec to see if we should even attempt indexing
return this.codec.isEnabled(m);
}
@Override
public boolean isAtomicOp(Mutation m) {
return false;
}
@Override
public List<Mutation> executeAtomicOp(Increment inc) throws IOException {
return null;
}
/**
* Exposed for testing!
*
* @param codec
* codec to use for this instance of the builder
*/
public void setIndexCodecForTesting(IndexCodec codec) {
this.codec = codec;
}
@Override
public Collection<Pair<Mutation, byte[]>> getIndexUpdateForFilteredRows(Collection<Cell> filtered, IndexMetaData context)
throws IOException {
throw new UnsupportedOperationException();
}
@Override
public void stop(String why) {
LOGGER.debug("Stopping because: " + why);
this.stopped = true;
}
@Override
public boolean isStopped() {
return this.stopped;
}
@Override
public ReplayWrite getReplayWrite(Mutation m) {
return null;
}
public RegionCoprocessorEnvironment getEnv() {
return this.env;
}
}