use of io.questdb.cairo.map.MapKey in project questdb by bluestreak01.
the class GroupByRecordCursorFactory method getCursor.
@Override
public RecordCursor getCursor(SqlExecutionContext executionContext) throws SqlException {
dataMap.clear();
final RecordCursor baseCursor = base.getCursor(executionContext);
try {
Function.init(recordFunctions, baseCursor, executionContext);
final Record baseRecord = baseCursor.getRecord();
final int n = groupByFunctions.size();
while (baseCursor.hasNext()) {
executionContext.getSqlExecutionInterruptor().checkInterrupted();
final MapKey key = dataMap.withKey();
mapSink.copy(baseRecord, key);
MapValue value = key.createValue();
GroupByUtils.updateFunctions(groupByFunctions, n, value, baseRecord);
}
cursor.of(baseCursor, dataMap.getCursor());
// init all record function for this cursor, in case functions require metadata and/or symbol tables
return cursor;
} catch (Throwable e) {
baseCursor.close();
throw e;
}
}
use of io.questdb.cairo.map.MapKey in project questdb by bluestreak01.
the class AbstractSampleByFillRecordCursorFactory method getCursor.
@Override
public RecordCursor getCursor(SqlExecutionContext executionContext) throws SqlException {
final RecordCursor baseCursor = base.getCursor(executionContext);
final SqlExecutionInterruptor interruptor = executionContext.getSqlExecutionInterruptor();
try {
map.clear();
// This factory fills gaps in data. To do that we
// have to know all possible key values. Essentially, every time
// we sample we return same set of key values with different
// aggregation results and timestamp
int n = groupByFunctions.size();
final Record baseCursorRecord = baseCursor.getRecord();
while (baseCursor.hasNext()) {
interruptor.checkInterrupted();
MapKey key = map.withKey();
mapSink.copy(baseCursorRecord, key);
MapValue value = key.createValue();
if (value.isNew()) {
// timestamp is always stored in value field 0
value.putLong(0, Numbers.LONG_NaN);
// this would set values for when keys are not found right away
for (int i = 0; i < n; i++) {
groupByFunctions.getQuick(i).setNull(value);
}
}
}
// empty map? this means that base cursor was empty
if (map.size() == 0) {
baseCursor.close();
return EmptyTableNoSizeRecordCursor.INSTANCE;
}
// because we pass base cursor twice we have to go back to top
// for the second run
baseCursor.toTop();
boolean next = baseCursor.hasNext();
// we know base cursor has value
assert next;
return initFunctionsAndCursor(executionContext, baseCursor);
} catch (Throwable ex) {
baseCursor.close();
throw ex;
}
}
use of io.questdb.cairo.map.MapKey in project questdb by bluestreak01.
the class AbstractSampleByFillValueRecordCursor method hasNext.
@Override
public boolean hasNext() {
//
if (mapCursor.hasNext()) {
// next() will return record that uses current map position
return refreshRecord();
}
if (baseRecord == null) {
return false;
}
// key map has been flushed
// before we build another one we need to check
// for timestamp gaps
// what is the next timestamp we are expecting?
long expectedLocalEpoch = timestampSampler.nextTimestamp(nextSampleLocalEpoch);
// is data timestamp ahead of next expected timestamp?
if (expectedLocalEpoch < localEpoch) {
this.sampleLocalEpoch = expectedLocalEpoch;
this.nextSampleLocalEpoch = expectedLocalEpoch;
// reset iterator on map and stream contents
return refreshMapCursor();
}
long next = timestampSampler.nextTimestamp(localEpoch);
this.sampleLocalEpoch = localEpoch;
this.nextSampleLocalEpoch = localEpoch;
// looks like we need to populate key map
int n = groupByFunctions.size();
while (true) {
long timestamp = getBaseRecordTimestamp();
if (timestamp < next) {
adjustDSTInFlight(timestamp - tzOffset);
final MapKey key = map.withKey();
keyMapSink.copy(baseRecord, key);
final MapValue value = key.findValue();
assert value != null;
if (value.getLong(0) != localEpoch) {
value.putLong(0, localEpoch);
GroupByUtils.updateNew(groupByFunctions, n, value, baseRecord);
} else {
GroupByUtils.updateExisting(groupByFunctions, n, value, baseRecord);
}
// carry on with the loop if we still have data
if (base.hasNext()) {
interruptor.checkInterrupted();
continue;
}
// we ran out of data, make sure hasNext() returns false at the next
// opportunity, after we stream map that is.
baseRecord = null;
} else {
// timestamp changed, make sure we keep the value of 'lastTimestamp'
// unchanged. Timestamp columns uses this variable
// When map is exhausted we would assign 'next' to 'lastTimestamp'
// and build another map
timestamp = adjustDST(timestamp, n, null, next);
if (timestamp != Long.MIN_VALUE) {
nextSamplePeriod(timestamp);
}
}
return refreshMapCursor();
}
}
use of io.questdb.cairo.map.MapKey in project questdb by bluestreak01.
the class AbstractSampleByFillValueRecordCursor method updateValueWhenClockMovesBack.
@Override
protected void updateValueWhenClockMovesBack(MapValue value, int n) {
final MapKey key = map.withKey();
keyMapSink.copy(baseRecord, key);
super.updateValueWhenClockMovesBack(key.createValue(), n);
}
use of io.questdb.cairo.map.MapKey in project questdb by bluestreak01.
the class SampleByFillNoneRecordCursor method hasNext.
@Override
public boolean hasNext() {
if (mapCursor.hasNext()) {
return true;
}
if (baseRecord == null) {
return false;
}
this.map.clear();
this.sampleLocalEpoch = this.localEpoch;
long next = timestampSampler.nextTimestamp(this.localEpoch);
// looks like we need to populate key map
// at the start of this loop 'lastTimestamp' will be set to timestamp
// of first record in base cursor
int n = groupByFunctions.size();
do {
long timestamp = getBaseRecordTimestamp();
if (timestamp < next) {
adjustDSTInFlight(timestamp - tzOffset);
final MapKey key = map.withKey();
keyMapSink.copy(baseRecord, key);
GroupByUtils.updateFunctions(groupByFunctions, n, key.createValue(), baseRecord);
interruptor.checkInterrupted();
} else {
// map value is conditional and only required when clock goes back
// we override base method for when this happens
// see: updateValueWhenClockMovesBack()
timestamp = adjustDST(timestamp, n, null, next);
if (timestamp != Long.MIN_VALUE) {
nextSamplePeriod(timestamp);
return createMapCursor();
}
}
} while (base.hasNext());
// we ran out of data, make sure hasNext() returns false at the next
// opportunity, after we stream map that is.
baseRecord = null;
return createMapCursor();
}
Aggregations