IsmReader extends NativeReader<WindowedValue<IsmRecord<V>>> { @Override public abstract IsmPrefixReaderIterator iterator() throws IOException;  static Closeable setSideInputReadContext(SideInputReadCounter readCounter); static SideInputReadCounter getCurrentSideInputCounter(); @Override abstract IsmPrefixReaderIterator iterator(); abstract IsmPrefixReaderIterator overKeyComponents(List<?> keyComponents); abstract IsmPrefixReaderIterator overKeyComponents(
      List<?> keyComponents, int shardId, RandomAccessData keyBytes); abstract boolean isInitialized(); abstract boolean isEmpty(); abstract ResourceId getResourceId(); abstract IsmRecordCoder<V> getCoder(); @Override String toString();  }
@Test public void testReadKeyThatEncodesToEmptyByteArray() throws Exception { File tmpFile = tmpFolder.newFile(); IsmRecordCoder<Void> coder = IsmRecordCoder.of(1, 0, ImmutableList.<Coder<?>>of(VoidCoder.of()), VoidCoder.of()); IsmSink<Void> sink = new IsmSink<>( FileSystems.matchNewResource(tmpFile.getPath(), false), coder, BLOOM_FILTER_SIZE_LIMIT); IsmRecord<Void> element = IsmRecord.of(Arrays.asList((Void) null), (Void) null); try (SinkWriter<WindowedValue<IsmRecord<Void>>> writer = sink.writer()) { writer.add(new ValueInEmptyWindows<>(element)); } Cache< IsmShardKey, WeightedValue<NavigableMap<RandomAccessData, WindowedValue<IsmRecord<Void>>>>> cache = CacheBuilder.newBuilder() .weigher(Weighers.fixedWeightKeys(1)) .maximumWeight(10_000) .build(); IsmReader<Void> reader = new IsmReaderImpl<>( FileSystems.matchSingleFileSpec(tmpFile.getAbsolutePath()).resourceId(), coder, cache); IsmReader<Void>.IsmPrefixReaderIterator iterator = reader.iterator(); assertTrue(iterator.start()); assertEquals( coder.structuralValue(element), coder.structuralValue(iterator.getCurrent().getValue())); }