package net.openhft.chronicle.engine.server.internal;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.engine.api.column.ColumnView;
import net.openhft.chronicle.engine.api.column.ColumnViewInternal;
import net.openhft.chronicle.engine.api.column.Row;
import net.openhft.chronicle.network.connection.CoreFields;
import net.openhft.chronicle.wire.ValueIn;
import net.openhft.chronicle.wire.WireIn;
import net.openhft.chronicle.wire.WireOut;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiConsumer;
import static net.openhft.chronicle.engine.api.column.RemoteColumnView.EventId.*;
import static net.openhft.chronicle.network.connection.CoreFields.reply;
/**
* @author Rob Austin.
*/
class ColumnViewHandler extends AbstractHandler {
private final CspManager cspManager;
@NotNull
AtomicLong nextToken = new AtomicLong();
ColumnViewHandler(CspManager cspManager) {
this.cspManager = cspManager;
}
private final StringBuilder eventName = new StringBuilder();
private ColumnViewInternal columnView;
@Nullable
private WireIn inWire = null;
@Nullable
private Map<String, Object> oldRow = new HashMap<String, Object>();
@NotNull
private Map<String, Object> newRow = new HashMap<String, Object>();
private long tid;
@NotNull
private List<ColumnView.MarshableFilter> filtersList = new ArrayList<>();
@NotNull
private List<ColumnView.MarshableFilter> keysList = new ArrayList<>();
@NotNull
private ColumnView.SortedFilter sortedFilter = new ColumnView.SortedFilter();
private final BiConsumer<WireIn, Long> dataConsumer = new BiConsumer<WireIn, Long>() {
@SuppressWarnings("ConstantConditions")
@Override
public void accept(WireIn wireIn, Long inputTid) {
eventName.setLength(0);
@NotNull final ValueIn valueIn = inWire.readEventName(eventName);
try {
outWire.writeDocument(true, wire -> outWire.writeEventName(CoreFields.tid).int64(tid));
writeData(inWire, out -> {
if (columns.contentEquals(eventName)) {
skipValue(valueIn);
outWire.writeEventName(reply).object(columnView.columns());
return;
}
if (rowCount.contentEquals(eventName)) {
@Nullable ColumnViewInternal.SortedFilter filters = valueIn.object(ColumnViewInternal.SortedFilter.class);
int count = columnView.rowCount(filters == null ?
new ColumnViewInternal.SortedFilter() : filters);
outWire.writeEventName(reply).int32(count);
return;
}
if (changedRow.contentEquals(eventName)) {
valueIn.marshallable(wire -> {
newRow.clear();
oldRow.clear();
wire.read(changedRow.params()[0]).object(newRow, Map.class);
wire.read(changedRow.params()[1]).object(oldRow, Map.class);
final int result = columnView.changedRow(newRow, oldRow);
outWire.writeEventName(reply).int32(result);
});
return;
}
if (canDeleteRows.contentEquals(eventName)) {
skipValue(valueIn);
outWire.writeEventName(reply).bool(columnView.canDeleteRows());
return;
}
if (containsRowWithKey.contentEquals(eventName)) {
keysList.clear();
@Nullable final List keys = valueIn.object(keysList, List.class);
final boolean result = columnView.containsRowWithKey(keys);
outWire.writeEventName(reply).bool(result);
return;
}
if (iterator.contentEquals(eventName)) {
valueIn.marshallable(sortedFilter);
long token = nextToken.incrementAndGet();
final long cid = cspManager.createProxy("ColumnViewIterator", token);
@NotNull final Iterator<? extends Row> iterator = columnView.iterator(sortedFilter);
cspManager.storeObject(cid, iterator);
//});
return;
}
throw new IllegalStateException("unsupported event=" + eventName);
});
} catch (Exception e) {
Jvm.warn().on(getClass(), e);
}
}
};
public void process(WireIn in, @NotNull WireOut out, ColumnViewInternal view, long tid) {
setOutWire(out);
try {
this.inWire = in;
this.outWire = out;
this.columnView = view;
this.tid = tid;
dataConsumer.accept(in, tid);
} catch (Exception e) {
Jvm.warn().on(getClass(), "", e);
}
}
}