/** * Copyright 2015 Eediom 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 org.araqne.logdb.query.command; import java.net.InetAddress; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.araqne.logdb.QueryCommand; import org.araqne.logdb.Row; import org.araqne.logdb.RowBatch; import org.araqne.logdb.ThreadSafe; public class Prev extends QueryCommand implements ThreadSafe { private Object lock = new Object(); private String[] inFields; private String[] outFields; private Object[] oldValues; public Prev(String[] inFields) { this.inFields = inFields; this.outFields = new String[inFields.length]; this.oldValues = new Object[inFields.length]; for (int i = 0; i < inFields.length; i++) this.outFields[i] = "prev_" + inFields[i]; } @Override public String getName() { return "prev"; } @Override public void onPush(Row row) { synchronized (lock) { addPrevFields(row); } pushPipe(row); } @Override public void onPush(RowBatch rowBatch) { synchronized (lock) { if (rowBatch.selectedInUse) { for (int i = 0; i < rowBatch.size; i++) { int p = rowBatch.selected[i]; Row row = rowBatch.rows[p]; addPrevFields(row); } } else { for (int i = 0; i < rowBatch.size; i++) { Row row = rowBatch.rows[i]; addPrevFields(row); } } } pushPipe(rowBatch); } private void addPrevFields(Row row) { for (int i = 0; i < inFields.length; i++) { String inField = inFields[i]; String outField = outFields[i]; row.put(outField, copy(oldValues[i])); oldValues[i] = copy(row.get(inField)); } } @SuppressWarnings("unchecked") private Object copy(Object o) { if (o == null) return null; // return immutable object as is, otherwise, clone. if (o instanceof String) { return o; } else if (o instanceof Number) { return o; } else if (o instanceof Date) { return ((Date) o).clone(); } else if (o instanceof InetAddress) { return o; } else if (o instanceof Map) { Map<String, Object> m = (Map<String, Object>) o; Map<String, Object> n = new HashMap<String, Object>(); for (String key : m.keySet()) { n.put(key, copy(m.get(key))); } return n; } else if (o instanceof Collection) { List<Object> n = new ArrayList<Object>(); for (Object c : (Collection<?>) o) { n.add(copy(c)); } return n; } else if (o instanceof Boolean) { return o; } else { return o; } } }