This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 307e235827e8717dbe3eda81ae5bf56a1a91de05
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Fri Feb 10 23:30:30 2023 +0100

    Fix a performance issue when file reading are monitored in a JavaFX window.
    It was caused by the "HTTP range" not forwarded by the channel wrapper.
---
 .../apache/sis/internal/gui/io/FileAccessItem.java | 17 +++++++-
 .../sis/internal/storage/io/ByteRangeChannel.java  | 46 ++++++++++++++++++++++
 .../sis/internal/storage/io/ChannelDataInput.java  |  4 +-
 .../internal/storage/io/FileCacheByteChannel.java  |  5 ++-
 4 files changed, 67 insertions(+), 5 deletions(-)

diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/io/FileAccessItem.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/io/FileAccessItem.java
index 328c516af9..15b088352b 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/io/FileAccessItem.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/io/FileAccessItem.java
@@ -40,6 +40,7 @@ import javafx.util.Duration;
 import org.apache.sis.measure.Range;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.collection.RangeSet;
+import org.apache.sis.internal.storage.io.ByteRangeChannel;
 
 
 /**
@@ -420,7 +421,7 @@ final class FileAccessItem implements Runnable, 
EventHandler<ActionEvent> {
     /**
      * Wrapper around a {@link SeekableByteChannel} which will observe the 
ranges of bytes read or written.
      */
-    final class Observer implements SeekableByteChannel {
+    final class Observer extends ByteRangeChannel {
         /**
          * The channel doing the actual read or write operations.
          */
@@ -434,6 +435,20 @@ final class FileAccessItem implements Runnable, 
EventHandler<ActionEvent> {
             fileSize = channel.size();
         }
 
+        /**
+         * Specifies a range of bytes which is expected to be read.
+         * This method may do nothing if the backed channel does not support 
this operation.
+         *
+         * @param  lower  position (inclusive) of the first byte to be 
requested.
+         * @param  upper  position (exclusive) of the last byte to be 
requested.
+         */
+        @Override
+        public void rangeOfInterest(final long lower, final long upper) {
+            if (channel instanceof ByteRangeChannel) {
+                ((ByteRangeChannel) channel).rangeOfInterest(lower, upper);
+            }
+        }
+
         /**
          * Forwards to the wrapped channel and report the range of bytes read.
          */
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ByteRangeChannel.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ByteRangeChannel.java
new file mode 100644
index 0000000000..c8e19cd0c7
--- /dev/null
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ByteRangeChannel.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.storage.io;
+
+import java.nio.channels.SeekableByteChannel;
+
+
+/**
+ * A byte channel where the range of bytes to read can be specified as a hint.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.4
+ * @since   1.4
+ */
+public abstract class ByteRangeChannel implements SeekableByteChannel {
+    /**
+     * Creates a new channel.
+     */
+    protected ByteRangeChannel() {
+    }
+
+    /**
+     * Specifies a range of bytes which is expected to be read.
+     * The range of bytes is only a hint and may be ignored, depending on 
subclasses.
+     * Reading more bytes than specified is okay, only potentially less 
efficient.
+     * It is okay for this method to do nothing.
+     *
+     * @param  lower  position (inclusive) of the first byte to be requested.
+     * @param  upper  position (exclusive) of the last byte to be requested.
+     */
+    public abstract void rangeOfInterest(long lower, long upper);
+}
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelDataInput.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelDataInput.java
index ec18853ec8..e6d89bcde7 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelDataInput.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelDataInput.java
@@ -960,10 +960,10 @@ public class ChannelDataInput extends ChannelData {
      * @param  upper  position (exclusive) of the last byte to be requested.
      */
     public final void rangeOfInterest(long lower, long upper) {
-        if (channel instanceof FileCacheByteChannel) {
+        if (channel instanceof ByteRangeChannel) {
             lower = Math.addExact(lower, channelOffset);
             upper = Math.addExact(upper, channelOffset);
-            ((FileCacheByteChannel) channel).rangeOfInterest(lower, upper);
+            ((ByteRangeChannel) channel).rangeOfInterest(lower, upper);
         }
     }
 
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/FileCacheByteChannel.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/FileCacheByteChannel.java
index 5edbffec53..5fc3577808 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/FileCacheByteChannel.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/FileCacheByteChannel.java
@@ -59,7 +59,7 @@ import static 
org.apache.sis.internal.storage.StoreUtilities.LOGGER;
  * @version 1.4
  * @since   1.4
  */
-public abstract class FileCacheByteChannel implements SeekableByteChannel {
+public abstract class FileCacheByteChannel extends ByteRangeChannel {
     /**
      * Size of the transfer buffer, in number of bytes.
      */
@@ -488,7 +488,8 @@ public abstract class FileCacheByteChannel implements 
SeekableByteChannel {
      * @param  lower  position (inclusive) of the first byte to be requested.
      * @param  upper  position (exclusive) of the last byte to be requested.
      */
-    final synchronized void rangeOfInterest(final long lower, final long 
upper) {
+    @Override
+    public final synchronized void rangeOfInterest(final long lower, final 
long upper) {
         if (upper > lower) {
             rangesOfInterest.add(lower, upper);
         }

Reply via email to