package mil.nga.giat.geowave.core.store.index;
import java.io.Closeable;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import mil.nga.giat.geowave.core.index.ByteArrayId;
import mil.nga.giat.geowave.core.store.base.DataStoreEntryInfo.FieldInfo;
import mil.nga.giat.geowave.core.store.base.Writer;
import mil.nga.giat.geowave.core.store.filter.DistributableFilterList;
import mil.nga.giat.geowave.core.store.filter.DistributableQueryFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class BaseSecondaryIndexDataStore<MutationType> implements
SecondaryIndexDataStore,
Closeable
{
private final static Logger LOGGER = LoggerFactory.getLogger(BaseSecondaryIndexDataStore.class);
protected final Map<String, Writer<MutationType>> writerCache = new HashMap<>();
protected final static byte[] EMPTY_VALUE = new byte[0];
public BaseSecondaryIndexDataStore() {}
@Override
public void storeJoinEntry(
final ByteArrayId secondaryIndexId,
final ByteArrayId indexedAttributeValue,
final ByteArrayId adapterId,
final ByteArrayId indexedAttributeFieldId,
final ByteArrayId primaryIndexId,
final ByteArrayId primaryIndexRowId,
final ByteArrayId attributeVisibility ) {
try {
final Writer<MutationType> writer = getWriter(secondaryIndexId);
if (writer != null) {
writer.write(buildJoinMutation(
indexedAttributeValue.getBytes(),
adapterId.getBytes(),
indexedAttributeFieldId.getBytes(),
primaryIndexId.getBytes(),
primaryIndexRowId.getBytes(),
attributeVisibility.getBytes()));
}
}
catch (final Exception e) {
LOGGER.error(
"Unable to build secondary index row mutation.",
e);
}
}
@Override
public void storeEntry(
final ByteArrayId secondaryIndexId,
final ByteArrayId indexedAttributeValue,
final ByteArrayId adapterId,
final ByteArrayId indexedAttributeFieldId,
final ByteArrayId dataId,
final ByteArrayId attributeVisibility,
final List<FieldInfo<?>> attributes ) {
try {
final Writer<MutationType> writer = getWriter(secondaryIndexId);
if (writer != null) {
for (final FieldInfo<?> indexedAttribute : attributes) {
writer.write(buildMutation(
indexedAttributeValue.getBytes(),
adapterId.getBytes(),
indexedAttributeFieldId.getBytes(),
dataId.getBytes(),
indexedAttribute.getDataValue().getId().getBytes(),
indexedAttribute.getWrittenValue(),
indexedAttribute.getVisibility()));
}
}
}
catch (final Exception e) {
LOGGER.error(
"Unable to build secondary index row mutation.",
e);
}
}
protected static DistributableQueryFilter getFilter(
final List<DistributableQueryFilter> constraints ) {
final DistributableQueryFilter filter;
if (constraints.isEmpty()) {
filter = null;
}
else if (constraints.size() == 1) {
filter = constraints.get(0);
}
else {
filter = new DistributableFilterList(
false,
constraints);
}
return filter;
}
@Override
public void deleteJoinEntry(
final ByteArrayId secondaryIndexId,
final ByteArrayId indexedAttributeValue,
final ByteArrayId adapterId,
final ByteArrayId indexedAttributeFieldId,
final ByteArrayId primaryIndexId,
final ByteArrayId primaryIndexRowId ) {
try {
final Writer<MutationType> writer = getWriter(secondaryIndexId);
if (writer != null) {
writer.write(buildJoinDeleteMutation(
indexedAttributeValue.getBytes(),
adapterId.getBytes(),
indexedAttributeFieldId.getBytes(),
primaryIndexId.getBytes(),
primaryIndexRowId.getBytes()));
}
}
catch (final Exception e) {
LOGGER.error(
"Failed to delete from secondary index.",
e);
}
}
@Override
public void deleteEntry(
final ByteArrayId secondaryIndexId,
final ByteArrayId indexedAttributeValue,
final ByteArrayId adapterId,
final ByteArrayId indexedAttributeFieldId,
final ByteArrayId dataId,
final List<FieldInfo<?>> attributes ) {
try {
final Writer<MutationType> writer = getWriter(secondaryIndexId);
if (writer != null) {
for (FieldInfo<?> attribute : attributes) {
writer.write(buildFullDeleteMutation(
indexedAttributeValue.getBytes(),
adapterId.getBytes(),
indexedAttributeFieldId.getBytes(),
dataId.getBytes(),
attribute.getDataValue().getId().getBytes()));
}
}
}
catch (final Exception e) {
LOGGER.error(
"Failed to delete from secondary index.",
e);
}
}
@Override
public void removeAll() {
close();
writerCache.clear();
}
@Override
public void close() {
for (final Writer<MutationType> writer : writerCache.values()) {
try {
writer.close();
}
catch (final IOException e) {
LOGGER.warn(
"Unable to close secondary index writer",
e);
}
}
writerCache.clear();
}
@Override
public void flush() {
close();
}
protected abstract MutationType buildJoinMutation(
final byte[] secondaryIndexRowId,
final byte[] adapterId,
final byte[] indexedAttributeFieldId,
final byte[] primaryIndexId,
final byte[] primaryIndexRowId,
final byte[] attributeVisibility )
throws IOException;
protected abstract MutationType buildMutation(
final byte[] secondaryIndexRowId,
final byte[] adapterId,
final byte[] indexedAttributeFieldId,
final byte[] dataId,
final byte[] fieldId,
final byte[] fieldValue,
final byte[] fieldVisibility )
throws IOException;
protected abstract MutationType buildJoinDeleteMutation(
final byte[] secondaryIndexRowId,
final byte[] adapterId,
final byte[] indexedAttributeFieldId,
final byte[] primaryIndexId,
final byte[] primaryIndexRowId )
throws IOException;
protected abstract MutationType buildFullDeleteMutation(
final byte[] secondaryIndexRowId,
final byte[] adapterId,
final byte[] indexedAttributeFieldId,
final byte[] dataId,
final byte[] fieldId )
throws IOException;
protected abstract Writer<MutationType> getWriter(
ByteArrayId secondaryIndexId );
}