
com.dell.doradus.service.spider.ScalarFieldUpdater Maven / Gradle / Ivy
/*
* Copyright (C) 2014 Dell, 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.dell.doradus.service.spider;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.dell.doradus.common.CommonDefs;
import com.dell.doradus.common.DBObject;
import com.dell.doradus.common.FieldDefinition;
import com.dell.doradus.common.Utils;
import com.dell.doradus.fieldanalyzer.FieldAnalyzer;
/**
* Manages updates for an SV or MV scalar field.
*/
public class ScalarFieldUpdater extends FieldUpdater {
protected ScalarFieldUpdater(SpiderTransaction dbTran, ObjectUpdater objUpdater, DBObject dbObj, String fieldName) {
super(dbTran, objUpdater, dbObj, fieldName);
} // constructor
// Add scalar value to object record; add term columns for indexed tokens.
@Override
public void addValuesForField() {
FieldDefinition fieldDef = m_tableDef.getFieldDef(m_fieldName);
if (fieldDef == null || !fieldDef.isCollection()) {
addSVScalar();
} else {
addMVScalar();
}
} // addMutationsForField
@Override
public boolean updateValuesForField(String currentValue) {
boolean bUpdated = false;
FieldDefinition fieldDef = m_tableDef.getFieldDef(m_fieldName);
if (fieldDef == null || !fieldDef.isCollection()) {
bUpdated = updateSVScalar(currentValue);
} else {
bUpdated = updateMVScalar(currentValue);
}
return bUpdated;
} // updateValuesForField
// Delete term columns for indexed tokens for this scalar's fields.
@Override
public void deleteValuesForField() {
deleteTermColumns(m_dbObj.getFieldValue(m_fieldName));
} // deleteValuesForField
// Merge the given current, remove, and new MV field values into a new set.
public static Set mergeMVFieldValues(Collection currValueSet,
Collection removeValueSet,
Collection newValueSet) {
Set resultSet = new HashSet<>();
if (currValueSet != null) {
resultSet.addAll(currValueSet);
}
if (removeValueSet != null) {
resultSet.removeAll(removeValueSet);
}
if (newValueSet != null) {
resultSet.addAll(newValueSet);
}
return resultSet;
} // mergeMVFieldValues
///// Private methods
// Add a reference to this field's name.
private void addFieldReference() {
m_dbTran.addFieldReferences(m_tableDef, Arrays.asList(new String[]{m_fieldName}));
} // addFieldReference
// Add references to the given terms for used for this field.
private void addFieldTermReferences(Set termSet) {
Map> fieldTermRefsMap = new HashMap>();
fieldTermRefsMap.put(m_fieldName, termSet);
m_dbTran.addTermReferences(m_tableDef, m_tableDef.getShardNumber(m_dbObj), fieldTermRefsMap);
} // addFieldTermReferences
// Add new MV scalar field.
private void addMVScalar() {
Set values = new HashSet<>(m_dbObj.getFieldValues(m_fieldName));
String fieldValue = Utils.concatenate(values, CommonDefs.MV_SCALAR_SEP_CHAR);
m_dbTran.addScalarValueColumn(m_tableDef, m_dbObj.getObjectID(), m_fieldName, fieldValue);
addTermColumns(fieldValue);
} // addMVScalar
// Add new SV scalar field.
private void addSVScalar() {
String fieldValue = m_dbObj.getFieldValue(m_fieldName);
m_dbTran.addScalarValueColumn(m_tableDef, m_dbObj.getObjectID(), m_fieldName, fieldValue);
addTermColumns(fieldValue);
} // addSVScalar
// Add all Terms columns needed for our scalar field.
private void addTermColumns(String fieldValue) {
Set termSet = tokenize(fieldValue);
indexTerms(termSet);
addFieldTermReferences(termSet);
addFieldReference();
} // addTermColumns
// Tokenize the given field with the appropriate analyzer and add Terms columns for each term.
private void indexTerms(Set termSet) {
for (String term : termSet) {
m_dbTran.addTermIndexColumn(m_tableDef, m_dbObj, m_fieldName, term);
}
} // indexTerms
private void deleteTermColumns(String fieldValue) {
unindexTerms(fieldValue);
// Nothing to do for field or term references
} // deleteTermColumns
// Delete all Terms columns for terms belonging to the given field value.
private void unindexTerms(String fieldValue) {
for (String term : tokenize(fieldValue)) {
unindexTerm(term);
}
} // unindexTerms
// Delete the Terms column that indexes the given term.
private void unindexTerm(String term) {
m_dbTran.deleteTermIndexColumn(m_tableDef, m_dbObj, m_fieldName, term);
} // unindexTerm
// Tokenize the given field value with the appropriate analyzer.
private Set tokenize(String fieldValue) {
FieldAnalyzer analyzer = FieldAnalyzer.findAnalyzer(m_tableDef, m_fieldName);
return analyzer.extractTerms(fieldValue);
} // tokenize
// Replace our SV scalar's value.
private boolean updateSVScalar(String currentValue) {
String newValue = m_dbObj.getFieldValue(m_fieldName);
boolean bUpdated = false;
if (Utils.isEmpty(newValue)) {
if (!Utils.isEmpty(currentValue)) {
m_dbTran.deleteScalarValueColumn(m_tableDef, m_dbObj.getObjectID(), m_fieldName);
unindexTerms(currentValue);
bUpdated = true;
}
} else if (!newValue.equals(currentValue)) {
updateScalarReplaceValue(currentValue, newValue);
bUpdated = true;
}
return bUpdated;
} // updateSVScalar
// Process add- and remove-values for our MV scalar. The current value is in the form:
// ~
// where ~ is the MV value separator.
private boolean updateMVScalar(String currentValue) {
boolean bUpdated = false;
Set currentValues = Utils.split(currentValue, CommonDefs.MV_SCALAR_SEP_CHAR);
Set newValueSet = mergeMVFieldValues(currentValues,
m_dbObj.getRemoveValues(m_fieldName),
m_dbObj.getFieldValues(m_fieldName));
String newValue = Utils.concatenate(newValueSet, CommonDefs.MV_SCALAR_SEP_CHAR);
if (!newValue.equals(currentValue)) {
if (newValue.length() == 0) {
m_dbTran.deleteScalarValueColumn(m_tableDef, m_dbObj.getObjectID(), m_fieldName);
unindexTerms(currentValue);
} else {
updateScalarReplaceValue(currentValue, newValue);
}
bUpdated = true;
}
return bUpdated;
} // updateMVScalar
// Replace our scalar's value with the given one, adding and removing terms as needed.
// This works for both SV and MV scalar fields
private void updateScalarReplaceValue(String currentValue, String newValue) {
m_dbTran.addScalarValueColumn(m_tableDef, m_dbObj.getObjectID(), m_fieldName, newValue);
Set currTermSet = tokenize(Utils.isEmpty(currentValue) ? "" : currentValue);
Set newTermSet = tokenize(newValue);
for (String term : currTermSet) {
if (!newTermSet.remove(term)) {
unindexTerm(term);
}
}
indexTerms(newTermSet);
addFieldTermReferences(newTermSet);
if (Utils.isEmpty(currentValue)) {
addFieldReference();
}
} // updateScalarReplaceValue
} // class ScalarFieldUpdater
© 2015 - 2025 Weber Informatics LLC | Privacy Policy