/**
* AnalyzerBeans
* Copyright (C) 2014 Neopost - Customer Information Management
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.eobjects.analyzer.storage;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.eobjects.analyzer.data.InputRow;
import org.eobjects.analyzer.util.ImmutableEntry;
/**
* Default {@link RowAnnotationFactory} instance. Stores up to 1000 rows in an
* in memory annotation.
*/
public class InMemoryRowAnnotationFactory extends AbstractRowAnnotationFactory implements RowAnnotationFactory {
private static final long serialVersionUID = 1L;
// contains annotations, mapped to row-ids
private final Map<RowAnnotation, Set<Integer>> _annotatedRows = new ConcurrentHashMap<RowAnnotation, Set<Integer>>();
// contains row id's mapped to rows mapped to distinct counts
private final Map<Integer, Map.Entry<InputRow, Integer>> _distinctCounts = new ConcurrentHashMap<Integer, Map.Entry<InputRow, Integer>>();
public InMemoryRowAnnotationFactory() {
this(1000);
}
public InMemoryRowAnnotationFactory(int storedRowsThreshold) {
super(storedRowsThreshold);
}
protected int getInMemoryRowCount(RowAnnotation annotation) {
Set<Integer> rows = _annotatedRows.get(annotation);
if (rows == null) {
return 0;
}
return rows.size();
}
@Override
protected void resetRows(RowAnnotation annotation) {
_annotatedRows.remove(annotation);
}
@Override
protected int getDistinctCount(InputRow row) {
return _distinctCounts.get(row.getId()).getValue();
}
@Override
protected void storeRowAnnotation(int rowId, RowAnnotation annotation) {
Set<Integer> rowIds = getRowIds(annotation);
rowIds.add(rowId);
}
private Set<Integer> getRowIds(RowAnnotation annotation) {
Set<Integer> rowIds = _annotatedRows.get(annotation);
if (rowIds == null) {
rowIds = Collections.synchronizedSet(new LinkedHashSet<Integer>());
_annotatedRows.put(annotation, rowIds);
}
return rowIds;
}
@Override
protected void storeRowValues(int rowId, InputRow row, int distinctCount) {
_distinctCounts.put(rowId, new ImmutableEntry<InputRow, Integer>(row, distinctCount));
}
@Override
public InputRow[] getRows(RowAnnotation annotation) {
Set<Integer> rowIds = _annotatedRows.get(annotation);
if (rowIds == null) {
return new InputRow[0];
}
InputRow[] rows = new InputRow[rowIds.size()];
int i = 0;
for (Integer rowId : rowIds) {
rows[i] = _distinctCounts.get(rowId).getKey();
i++;
}
return rows;
}
@Override
public void transferAnnotations(RowAnnotation from, RowAnnotation to) {
final int rowCountToAdd = from.getRowCount();
((RowAnnotationImpl) to).incrementRowCount(rowCountToAdd);
}
}