/*
* Copyright (c) 2015 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.db.client.impl;
import com.emc.storageos.db.client.model.DataObject;
import com.emc.storageos.db.client.model.NamedURI;
import com.netflix.astyanax.ColumnListMutation;
import com.netflix.astyanax.model.Column;
import com.netflix.astyanax.model.ColumnFamily;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
public class AggregateDbIndex extends DbIndex<IndexColumnName> {
private boolean groupGlobal;
private String[] groupBy;
private Map<String, ColumnField> groupByFields;
AggregateDbIndex(ColumnFamily<String, IndexColumnName> indexCF) {
super(indexCF);
}
AggregateDbIndex(ColumnFamily<String, IndexColumnName> indexCF, String groupBy, boolean global) {
super(indexCF);
this.groupGlobal = global;
if (StringUtils.isEmpty(groupBy)) {
this.groupBy = new String[0];
groupByFields = new HashMap<>();
}
else {
this.groupBy = groupBy.split(",");
groupByFields = new HashMap<>(this.groupBy.length);
}
}
void addGroupByField(ColumnField field) {
groupByFields.put(field.getName(), field);
}
Map<String, ColumnField> getGroupByFields() {
return Collections.unmodifiableMap(groupByFields);
}
String[] getGroupBy() {
return Arrays.copyOf(groupBy, groupBy.length);
}
boolean isGroupedGlobal() {
return groupGlobal;
}
@Override
boolean addColumn(String recordKey, CompositeColumnName column, Object value,
String className, RowMutator mutator, Integer ttl, DataObject obj) {
IndexColumnName indexEntry = new IndexColumnName(fieldName, recordKey, (UUID) null);
if (groupGlobal) {
ColumnListMutation<IndexColumnName> indexColList =
mutator.getIndexColumnList(indexCF, className);
ColumnValue.setColumn(indexColList, indexEntry, value, ttl);
}
for (String field : groupBy) {
ColumnField colField = groupByFields.get(field);
if (colField != null && obj.isInitialized(field)) {
Object groupValue = ColumnField.getFieldValue(colField, obj);
if (groupValue != null) {
ColumnListMutation<IndexColumnName> indexColList =
mutator.getIndexColumnList(indexCF, getRowKey(className, groupValue));
ColumnValue.setColumn(indexColList, indexEntry, value, ttl);
}
}
}
return true;
}
@Override
boolean removeColumn(String recordKey, Column<CompositeColumnName> column,
String className, RowMutator mutator,
Map<String, List<Column<CompositeColumnName>>> fieldColumnMap) {
IndexColumnName indexField = new IndexColumnName(fieldName, recordKey, column.getName().getTimeUUID());
if (groupGlobal) {
mutator.getIndexColumnList(indexCF, className).deleteColumn(indexField);
}
for (String group : groupBy) {
ColumnField field = groupByFields.get(group);
List<Column<CompositeColumnName>> groupByColumns = fieldColumnMap.get(field.getName());
if (groupByColumns != null) {
for (Column<CompositeColumnName> groupByCol : groupByColumns) {
Object groupValue = ColumnValue.getPrimitiveColumnValue(groupByCol, field.getPropertyDescriptor());
if (groupValue != null) {
mutator.getIndexColumnList(indexCF, getRowKey(className, groupValue)).
deleteColumn(indexField);
}
}
}
}
return true;
}
@Override
boolean removeColumn(String recordKey, Column<CompositeColumnName> column,
String className, RowMutator mutator,
Map<String, List<Column<CompositeColumnName>>> fieldColumnMap,
DataObject obj) {
IndexColumnName indexField = new IndexColumnName(fieldName, recordKey, (UUID) null);
for (String group : groupBy) {
ColumnField field = groupByFields.get(group);
List<Column<CompositeColumnName>> groupByColumns = fieldColumnMap.get(field.getName());
if (groupByColumns != null) {
Object latestValue = null;
if (obj != null) {
latestValue = ColumnField.getFieldValue(field, obj);
}
for (Column<CompositeColumnName> groupByCol : groupByColumns) {
Object groupValue = ColumnValue.getPrimitiveColumnValue(groupByCol, field.getPropertyDescriptor());
if (groupValue != null && !groupValue.equals(latestValue)) {
mutator.getIndexColumnList(indexCF, getRowKey(className, groupValue)).
deleteColumn(indexField);
}
}
}
}
return true;
}
String getRowKey(String className, Object value) {
if (value instanceof NamedURI) {
return String.format("%s:%s", className, ((NamedURI) value).getURI().toString());
} else {
return String.format("%s:%s", className, value.toString());
}
}
@Override
public boolean needConsistency() {
return false;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder("DecommisionedDbIndex class");
builder.append("\t");
builder.append(super.toString());
builder.append("\n");
return builder.toString();
}
}