/**
* Copyright 2013-2014 Recruit Technologies Co., Ltd. and contributors
* (see CONTRIBUTORS.md)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. A copy of the
* License is distributed with this work in the LICENSE.md file. You may
* also obtain a copy of the License from
*
* 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 org.gennai.gungnir.topology.operator.slide;
import static org.gennai.gungnir.GungnirConst.*;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
public class MemoryWindowStorage implements WindowStorage {
private static final long serialVersionUID = SERIAL_VERSION_UID;
private static class Container {
private List<List<Object>> tuples = Lists.newArrayList();
private List<Integer> timeKeyIndex = Lists.newArrayList();
}
private Map<Object, Container> tuplesMap;
@Override
public void open(String topologyId, String operatorName) {
tuplesMap = Maps.newHashMap();
}
@Override
public void put(Object key, List<Object> values) {
Container container = tuplesMap.get(key);
if (container == null) {
container = new Container();
tuplesMap.put(key, container);
}
container.tuples.add(values);
}
@Override
public void put(Object key, Date timeKey, List<Object> values) {
Container container = tuplesMap.get(key);
if (container == null) {
container = new Container();
tuplesMap.put(key, container);
}
container.tuples.add(values);
container.timeKeyIndex.add((int) TimeUnit.MILLISECONDS.toSeconds(timeKey.getTime()));
}
@Override
public List<List<Object>> get(Object key, int count) {
Container container = tuplesMap.get(key);
if (container == null) {
return null;
}
if (container.tuples.size() <= count) {
return null;
}
List<List<Object>> tuples = Lists.newArrayList(container.tuples.subList(0,
container.tuples.size() - count));
container.tuples = Lists.newArrayList(container.tuples.subList(container.tuples.size() - count,
container.tuples.size()));
return tuples;
}
@Override
public List<List<Object>> get(Object key, Date timeKey) {
Container container = tuplesMap.get(key);
if (container == null) {
return null;
}
int index = Collections.binarySearch(container.timeKeyIndex,
(int) TimeUnit.MILLISECONDS.toSeconds(timeKey.getTime()));
if (index < 0) {
index *= -1;
index--;
}
if (index == 0) {
return null;
}
if (index >= container.tuples.size()) {
List<List<Object>> tuples = container.tuples;
container.tuples = Lists.newArrayList();
container.timeKeyIndex = Lists.newArrayList();
return tuples;
}
List<List<Object>> tuples = Lists.newArrayList(container.tuples.subList(0, index));
container.tuples = Lists.newArrayList(container.tuples.subList(index, container.tuples.size()));
container.timeKeyIndex = Lists.newArrayList(container.timeKeyIndex.subList(index,
container.timeKeyIndex.size()));
return tuples;
}
@Override
public void close() {
}
}