/*
* Copyright (c) 2011-2015 EPFL DATA Laboratory
* Copyright (c) 2014-2015 The Squall Collaboration (see NOTICE)
*
* All rights reserved.
*
* 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 ch.epfl.data.squall.storage;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import ch.epfl.data.squall.operators.AggregateOperator;
import ch.epfl.data.squall.types.Type;
import ch.epfl.data.squall.utilities.SystemParameters;
public class AggregationStore<V> extends KeyValueStore<Object, V> {
private static final long serialVersionUID = 1L;
private static Logger LOG = Logger.getLogger(AggregationStore.class);
private boolean _singleEntry;
private final Type _wrapper;
private final AggregateOperator _outerAggOp;
private static final String SINGLE_ENTRY_KEY = "SEK"; /* Single entry key */
// private static final int FINAL_AGGREGATION_TIMEOUT = 10000; /* msecs */
public AggregationStore(AggregateOperator outerAggOp, Type wrapper,
Map map, boolean singleEntry) {
super(singleEntry ? 1 : SystemParameters.getInt(map,
"STORAGE_MEMORY_SIZE_MB"), map);
_wrapper = wrapper;
_outerAggOp = outerAggOp;
_singleEntry = singleEntry;
if (wrapper != null)
super.setTypeConversion(_wrapper);
LOG.info("Initialized Aggregation Storage with uniqId = " + getUniqId());
}
@Override
public ArrayList<V> access(Object... data) {
return _singleEntry ? super.__access(false, SINGLE_ENTRY_KEY) : super
.__access(false, data);
}
public void addContent(AggregationStore storage) {
// Now aggregate
final Set keySet = storage.keySet();
for (final Iterator it = keySet.iterator(); it.hasNext();) {
final Object key = it.next();
V newValue = (V) storage.access(key).get(0);
final ArrayList<V> list = super.__access(false, key);
if (list == null)
super.onInsert(key, newValue);
else {
final V oldValue = list.get(0);
newValue = (V) _outerAggOp.runAggregateFunction(oldValue,
newValue);
super.update(key, oldValue, newValue);
}
}
}
@Override
public boolean contains(Object... data) {
return _singleEntry ? super.contains(SINGLE_ENTRY_KEY) : super
.contains(data);
}
@Override
public boolean equals(BasicStore store) {
return super.equals(store);
}
public V getInitialValue() {
return (V) _wrapper.getInitialValue();
}
@Override
public void onInsert(Object... data) {
if (_singleEntry)
super.onInsert(SINGLE_ENTRY_KEY, data);
else
super.onInsert(data);
}
@Override
public void printStore(PrintStream stream, boolean printStorage) {
super.printStore(stream, printStorage);
}
@Override
public void reset() {
super.reset();
}
@Override
public void setSingleEntry(boolean singleEntry) {
this._singleEntry = singleEntry;
}
@Override
public V update(Object... data) {
final Object obj = data[0];
final Object key = _singleEntry ? SINGLE_ENTRY_KEY : data[1];
V value, newValue;
final ArrayList<V> list = super.__access(false, key);
if (list == null) {
value = getInitialValue();
super.onInsert(key, value);
} else
value = list.get(0);
if (obj instanceof List)
newValue = (V) _outerAggOp.runAggregateFunction(value,
(List<String>) obj);
else
newValue = (V) _outerAggOp.runAggregateFunction(value, obj);
super.__update(false, key, value, newValue);
return newValue;
}
}