com.kolibrifx.plovercrest.server.streams.folds.FoldStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of plovercrest-server Show documentation
Show all versions of plovercrest-server Show documentation
Plovercrest server library.
The newest version!
/*
* Copyright (c) 2010-2017, KolibriFX AS. Licensed under the Apache License, version 2.0.
*/
package com.kolibrifx.plovercrest.server.streams.folds;
import java.util.ArrayDeque;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicLong;
import com.kolibrifx.plovercrest.client.PlovercrestException;
import com.kolibrifx.plovercrest.client.TableMetadata;
import com.kolibrifx.plovercrest.server.internal.folds.FoldReader;
import com.kolibrifx.plovercrest.server.internal.folds.FoldReaderSetup;
import com.kolibrifx.plovercrest.server.internal.folds.FoldWriter;
import com.kolibrifx.plovercrest.server.internal.folds.Timestamped;
import com.kolibrifx.plovercrest.server.internal.streams.NullStreamObserver;
import com.kolibrifx.plovercrest.server.streams.PollableReader;
import com.kolibrifx.plovercrest.server.streams.Stream;
import com.kolibrifx.plovercrest.server.streams.StreamObserver;
import com.kolibrifx.plovercrest.server.streams.StreamWriter;
public class FoldStream implements Stream {
private final List> inputs;
private final TableMetadata metadata;
private final CombinatorStrategy combinatorStrategy;
private final FoldSetup setup;
private final Class elementClass;
private final String name;
public FoldStream(final String name,
final Class elementClass,
final List> inputs,
final TableMetadata metadata,
final CombinatorStrategy combinatorStrategy,
final FoldSetup setup) {
this.name = name;
this.elementClass = elementClass;
this.inputs = inputs;
this.metadata = metadata;
this.combinatorStrategy = combinatorStrategy;
this.setup = setup;
}
@Override
public PollableReader createReaderFromTimestamp(final long timestamp, final StreamObserver observer) {
final Queue> outputQueue = new ArrayDeque<>();
final FoldWriter foldWriter = new FoldWriter() {
@Override
public void write(final long timestamp, final T value) {
outputQueue.add(new Timestamped<>(timestamp, value));
}
};
//final long adjustedTimestamp = setup.seekTakePrevious(timestamp, inputs);
final FoldReaderSetup params = setup.setupReader(timestamp, foldWriter, inputs);
return new FoldReader(timestamp, combinatorStrategy, observer, params.getInputs(),
params.getFoldCallback(), outputQueue);
}
@Override
public PollableReader createReaderFromIndex(final long index, final StreamObserver observer) {
throw new PlovercrestException("Index queries is not supported");
}
@Override
public StreamWriter getWriter() {
throw new PlovercrestException("Fold stream are read-only");
}
@Override
public long getFirstTimestamp() {
final AtomicLong timestamp = new AtomicLong();
final PollableReader reader = createReaderFromTimestamp(0, (ts, index, el) -> timestamp.set(ts));
if (reader.poll()) {
return timestamp.get();
} else {
return -1;
}
}
@Override
public long getLastTimestamp() {
return setup.getLastOutputTimestamp(inputs, combinatorStrategy);
}
@Override
public long getDataLengthInBytes() {
return 0;
}
@Override
public long getEntryCount() {
return -1;
}
@Override
public TableMetadata getMetadata() {
return metadata;
}
@Override
public long getLastValidTimestamp() {
long result = Long.MAX_VALUE;
for (final Stream> input : inputs) {
result = Math.min(result, input.getLastValidTimestamp());
}
return result;
}
@Override
public boolean isFrozen() {
return false;
}
@Override
public boolean delete() {
return false;
}
@Override
public boolean rename(final String newName) {
return false;
}
@Override
public String getName() {
return name;
}
@Override
public Class getElementClass() {
return elementClass;
}
@Override
public long seekPreviousTimestamp(final long targetTimestamp) {
final long lastTimestamp = getLastTimestamp();
if (lastTimestamp < 0) {
return -1;
}
final AtomicLong observed = new AtomicLong();
final long adjustedTimestamp = Math.min(targetTimestamp, lastTimestamp);
final PollableReader reader = createReaderFromTimestamp(adjustedTimestamp, new NullStreamObserver() {
@Override
public void onObserve(final long timestamp, final long index, final T element) {
observed.set(timestamp);
}
});
if (reader.poll()) {
return observed.get();
} else {
// FIXME: can happen due to createReaderFromTimestamp() not seeking backwards properly.
// Returning the target instead of -1 is a workaround.
//return -1;
return adjustedTimestamp;
}
}
}