/**
* Copyright 2013 Cloudera Inc.
*
* 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.cloudera.cdk.data.hbase.impl;
import com.cloudera.cdk.data.DatasetIOException;
import com.cloudera.cdk.data.spi.ReaderWriterState;
import com.google.common.base.Preconditions;
import java.io.IOException;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.HTablePool;
public class BaseEntityBatch<E> implements EntityBatch<E> {
private final HTableInterface table;
private final EntityMapper<E> entityMapper;
private final HBaseClientTemplate clientTemplate;
private ReaderWriterState state;
/**
* Checks an HTable out of the HTablePool and modifies it to take advantage of
* batch puts. This is very useful when performing many consecutive puts.
*
* @param clientTemplate
* The client template to use
* @param entityMapper
* The EntityMapper to use for mapping
* @param pool
* The HBase table pool
* @param tableName
* The name of the HBase table
* @param writeBufferSize
* The batch buffer size in bytes.
*/
public BaseEntityBatch(HBaseClientTemplate clientTemplate,
EntityMapper<E> entityMapper, HTablePool pool, String tableName,
long writeBufferSize) {
this.table = pool.getTable(tableName);
this.table.setAutoFlush(false);
this.clientTemplate = clientTemplate;
this.entityMapper = entityMapper;
this.state = ReaderWriterState.NEW;
/**
* If the writeBufferSize is less than the currentBufferSize, then the
* buffer will get flushed automatically by HBase. This should never happen,
* since we're getting a fresh table out of the pool, and the writeBuffer
* should be empty.
*/
try {
table.setWriteBufferSize(writeBufferSize);
} catch (IOException e) {
throw new DatasetIOException("Error flushing commits for table ["
+ table + "]", e);
}
}
/**
* Checks an HTable out of the HTablePool and modifies it to take advantage of
* batch puts using the default writeBufferSize (2MB). This is very useful
* when performing many consecutive puts.
*
* @param clientTemplate
* The client template to use
* @param entityMapper
* The EntityMapper to use for mapping
* @param pool
* The HBase table pool
* @param tableName
* The name of the HBase table
*/
public BaseEntityBatch(HBaseClientTemplate clientTemplate,
EntityMapper<E> entityMapper, HTablePool pool, String tableName) {
this.table = pool.getTable(tableName);
this.table.setAutoFlush(false);
this.clientTemplate = clientTemplate;
this.entityMapper = entityMapper;
this.state = ReaderWriterState.NEW;
}
@Override
public void open() {
Preconditions.checkState(state.equals(ReaderWriterState.NEW),
"Unable to open a writer from state:%s", state);
state = ReaderWriterState.OPEN;
}
@Override
public void put(E entity) {
Preconditions.checkState(state.equals(ReaderWriterState.OPEN),
"Attempt to write to a writer in state:%s", state);
PutAction putAction = entityMapper.mapFromEntity(entity);
clientTemplate.put(putAction, table);
}
@Override
public void write(E entity) {
put(entity);
}
@Override
public void flush() {
Preconditions.checkState(state.equals(ReaderWriterState.OPEN),
"Attempt to flush a writer in state:%s", state);
try {
table.flushCommits();
} catch (IOException e) {
throw new DatasetIOException("Error flushing commits for table ["
+ table + "]", e);
}
}
@Override
public void close() {
if (state.equals(ReaderWriterState.OPEN)) {
try {
table.flushCommits();
table.setAutoFlush(true);
table.close();
} catch (IOException e) {
throw new DatasetIOException("Error closing table [" + table + "]", e);
}
state = ReaderWriterState.CLOSED;
}
}
@Override
public boolean isOpen() {
return state.equals(ReaderWriterState.OPEN);
}
}