Source:
<code>private int readWithFilter(int[] positions, int positionCount) throws IOException { <START> int streamPosition = 0; <END> for (int i = 0; i < positionCount; i++) { int position = positions[i]; if (position > streamPosition) { skip(position - streamPosition); streamPosition = position; } if (presentStream != null && !presentStream.nextBit()) { if ((nonDeterministicFilter && filter.testNull()) || nullsAllowed) { if (outputRequired) { values[outputPositionCount] = dictionaryBlock.getPositionCount() - 1; } outputPositions[outputPositionCount] = position; outputPositionCount++; } } else { int index = toIntExact(dataStream.next()); int maxCodePointCount = getMaxCodePointCount(streamDescriptor.getOrcType()); int length = isCharType() ? maxCodePointCount : stripeDictionaryLength[index]; if (inDictionaryStream != null && !inDictionaryStream.nextBit()) { index += stripeDictionarySize; } if (filter.testLength(length)) { int currentPosLength = dictionaryBlock.getSliceLength(index); Slice data = dictionaryBlock.getSlice(index, 0, currentPosLength); if (isCharType() && length != currentPosLength) { data = Chars.padSpaces(data, streamDescriptor.getOrcType().getLength().get()); } if (filter.testBytes(data.getBytes(), 0, length)) { if (outputRequired) { values[outputPositionCount] = index; } outputPositions[outputPositionCount] = position; outputPositionCount++; } } } streamPosition++; if (filter != null) { outputPositionCount -= filter.getPrecedingPositionsToFail(); int succeedingPositionsToFail = filter.getSucceedingPositionsToFail(); if (succeedingPositionsToFail > 0) { int positionsToSkip = 0; for (int j = 0; j < succeedingPositionsToFail; j++) { i++; int nextPosition = positions[i]; positionsToSkip += 1 + nextPosition - streamPosition; streamPosition = nextPosition + 1; } skip(positionsToSkip); } } } return streamPosition; }</code><technical_language>add outputPositionsReadOnly logic</technical_language>

Target:
private int readWithFilter(int[] positions, int positionCount) throws IOException { int streamPosition = 0; for (int i = 0; i < positionCount; i++) { int position = positions[i]; if (position > streamPosition) { skip(position - streamPosition); streamPosition = position; } if (presentStream != null && !presentStream.nextBit()) { if ((nonDeterministicFilter && filter.testNull()) || nullsAllowed) { if (outputRequired) { values[outputPositionCount] = dictionaryBlock.getPositionCount() - 1; } outputPositions[outputPositionCount] = position; outputPositionCount++; } } else { boolean inRowDictionary = inDictionaryStream != null && !inDictionaryStream.nextBit(); int rawIndex = toIntExact(dataStream.next()); int index = inRowDictionary ? stripeDictionarySize + rawIndex : rawIndex; int length; if (isCharType) { length = maxCodePointCount; } else { length = inRowDictionary ? rowGroupDictionaryLength[rawIndex] : stripeDictionaryLength[rawIndex]; } if (filter.testLength(length)) { int currentPosLength = dictionaryBlock.getSliceLength(index); Slice data = dictionaryBlock.getSlice(index, 0, currentPosLength); if (isCharType && length != currentPosLength) { data = Chars.padSpaces(data, maxCodePointCount); } if (filter.testBytes(data.getBytes(), 0, length)) { if (outputRequired) { values[outputPositionCount] = index; } outputPositions[outputPositionCount] = position; outputPositionCount++; } } } streamPosition++; if (filter != null) { outputPositionCount -= filter.getPrecedingPositionsToFail(); int succeedingPositionsToFail = filter.getSucceedingPositionsToFail(); if (succeedingPositionsToFail > 0) { int positionsToSkip = 0; for (int j = 0; j < succeedingPositionsToFail; j++) { i++; int nextPosition = positions[i]; positionsToSkip += 1 + nextPosition - streamPosition; streamPosition = nextPosition + 1; } skip(positionsToSkip); } } } return streamPosition; }