|
1 | 1 | /**
|
2 | 2 | * Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending
|
3 | 3 | */
|
4 |
| -package io.deephaven.parquet.base.util; |
| 4 | +package io.deephaven.util.channel; |
5 | 5 |
|
6 | 6 | import io.deephaven.base.RAPriQueue;
|
7 | 7 | import io.deephaven.base.verify.Assert;
|
8 | 8 | import io.deephaven.base.verify.Require;
|
9 | 9 | import io.deephaven.hash.KeyedObjectHashMap;
|
10 | 10 | import io.deephaven.hash.KeyedObjectKey;
|
| 11 | +import io.deephaven.util.annotations.FinalDefault; |
11 | 12 | import org.jetbrains.annotations.NotNull;
|
12 | 13 | import org.jetbrains.annotations.Nullable;
|
13 | 14 |
|
14 | 15 | import java.io.IOException;
|
| 16 | +import java.net.URI; |
15 | 17 | import java.nio.ByteBuffer;
|
16 | 18 | import java.nio.channels.SeekableByteChannel;
|
17 | 19 | import java.nio.file.Path;
|
|
22 | 24 | */
|
23 | 25 | public class CachedChannelProvider implements SeekableChannelsProvider {
|
24 | 26 |
|
| 27 | + public interface ContextHolder { |
| 28 | + void setContext(SeekableChannelContext channelContext); |
| 29 | + |
| 30 | + @FinalDefault |
| 31 | + default void clearContext() { |
| 32 | + setContext(null); |
| 33 | + } |
| 34 | + } |
| 35 | + |
25 | 36 | private final SeekableChannelsProvider wrappedProvider;
|
26 | 37 | private final int maximumPooledCount;
|
27 | 38 |
|
@@ -52,13 +63,27 @@ public CachedChannelProvider(@NotNull final SeekableChannelsProvider wrappedProv
|
52 | 63 | }
|
53 | 64 |
|
54 | 65 | @Override
|
55 |
| - public SeekableByteChannel getReadChannel(@NotNull final Path path) throws IOException { |
56 |
| - final String pathKey = path.toAbsolutePath().toString(); |
| 66 | + public SeekableChannelContext makeContext() { |
| 67 | + return wrappedProvider.makeContext(); |
| 68 | + } |
| 69 | + |
| 70 | + @Override |
| 71 | + public boolean isCompatibleWith(@NotNull final SeekableChannelContext channelContext) { |
| 72 | + return wrappedProvider.isCompatibleWith(channelContext); |
| 73 | + } |
| 74 | + |
| 75 | + @Override |
| 76 | + public SeekableByteChannel getReadChannel(@NotNull final SeekableChannelContext channelContext, |
| 77 | + @NotNull final URI uri) |
| 78 | + throws IOException { |
| 79 | + final String uriString = uri.toString(); |
57 | 80 | final KeyedObjectHashMap<String, PerPathPool> channelPool = channelPools.get(ChannelType.Read);
|
58 |
| - final CachedChannel result = tryGetPooledChannel(pathKey, channelPool); |
59 |
| - return result == null |
60 |
| - ? new CachedChannel(wrappedProvider.getReadChannel(path), ChannelType.Read, pathKey) |
| 81 | + final CachedChannel result = tryGetPooledChannel(uriString, channelPool); |
| 82 | + final CachedChannel channel = result == null |
| 83 | + ? new CachedChannel(wrappedProvider.getReadChannel(channelContext, uri), ChannelType.Read, uriString) |
61 | 84 | : result.position(0);
|
| 85 | + channel.setContext(channelContext); |
| 86 | + return channel; |
62 | 87 | }
|
63 | 88 |
|
64 | 89 | @Override
|
@@ -125,10 +150,15 @@ private long advanceClock() {
|
125 | 150 | return logicalClock = 1;
|
126 | 151 | }
|
127 | 152 |
|
| 153 | + @Override |
| 154 | + public void close() { |
| 155 | + wrappedProvider.close(); |
| 156 | + } |
| 157 | + |
128 | 158 | /**
|
129 | 159 | * {@link SeekableByteChannel Channel} wrapper for pooled usage.
|
130 | 160 | */
|
131 |
| - private class CachedChannel implements SeekableByteChannel { |
| 161 | + private class CachedChannel implements SeekableByteChannel, ContextHolder { |
132 | 162 |
|
133 | 163 | private final SeekableByteChannel wrappedChannel;
|
134 | 164 | private final ChannelType channelType;
|
@@ -163,7 +193,7 @@ public long position() throws IOException {
|
163 | 193 | }
|
164 | 194 |
|
165 | 195 | @Override
|
166 |
| - public SeekableByteChannel position(final long newPosition) throws IOException { |
| 196 | + public CachedChannel position(final long newPosition) throws IOException { |
167 | 197 | Require.eqTrue(isOpen, "isOpen");
|
168 | 198 | wrappedChannel.position(newPosition);
|
169 | 199 | return this;
|
@@ -196,12 +226,20 @@ public boolean isOpen() {
|
196 | 226 | public void close() throws IOException {
|
197 | 227 | Require.eqTrue(isOpen, "isOpen");
|
198 | 228 | isOpen = false;
|
| 229 | + clearContext(); |
199 | 230 | returnPoolableChannel(this);
|
200 | 231 | }
|
201 | 232 |
|
202 | 233 | private void dispose() throws IOException {
|
203 | 234 | wrappedChannel.close();
|
204 | 235 | }
|
| 236 | + |
| 237 | + @Override |
| 238 | + public final void setContext(@Nullable final SeekableChannelContext channelContext) { |
| 239 | + if (wrappedChannel instanceof ContextHolder) { |
| 240 | + ((ContextHolder) wrappedChannel).setContext(channelContext); |
| 241 | + } |
| 242 | + } |
205 | 243 | }
|
206 | 244 |
|
207 | 245 | /**
|
|
0 commit comments