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

fanningpj pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko-http.git


The following commit(s) were added to refs/heads/main by this push:
     new 03f128907 use optimised ByteString.asInputStream (#539)
03f128907 is described below

commit 03f128907cf55ff2e1777ee0b6fc75d58c7188b9
Author: PJ Fanning <[email protected]>
AuthorDate: Thu Apr 25 11:38:22 2024 +0200

    use optimised ByteString.asInputStream (#539)
    
    * use optimised ByteString.asInputStream
    
    Update Http2FrameHpackSupport.scala
    
    Update ByteStringInputStream.scala
    
    revert Http2FrameHpackSupport change
    
    Update ByteStringInputStream.scala
    
    Update ByteStringInputStream.scala
    
    * optimise ByteStringInputStream.scala
    
    Update ByteStringInputStream.scala
    
    Update ByteStringInputStream.scala
    
    * make byteStringInputStreamMethodTypeOpt a val
    
    * refactor
    
    * avoid getOrElse
---
 .../engine/http2/hpack/ByteStringInputStream.scala | 40 +++++++++++++++++-----
 1 file changed, 31 insertions(+), 9 deletions(-)

diff --git 
a/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/hpack/ByteStringInputStream.scala
 
b/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/hpack/ByteStringInputStream.scala
index f3b3dc5a3..53161e694 100644
--- 
a/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/hpack/ByteStringInputStream.scala
+++ 
b/http-core/src/main/scala/org/apache/pekko/http/impl/engine/http2/hpack/ByteStringInputStream.scala
@@ -14,6 +14,9 @@
 package org.apache.pekko.http.impl.engine.http2.hpack
 
 import java.io.{ ByteArrayInputStream, InputStream }
+import java.lang.invoke.{ MethodHandles, MethodType }
+
+import scala.util.Try
 
 import org.apache.pekko
 import pekko.annotation.InternalApi
@@ -24,13 +27,32 @@ import pekko.util.ByteString.ByteString1C
 @InternalApi
 private[http2] object ByteStringInputStream {
 
-  def apply(bs: ByteString): InputStream =
-    bs match {
-      case cs: ByteString1C =>
-        // TODO optimise, ByteString needs to expose InputStream (esp if array 
backed, nice!)
-        new ByteArrayInputStream(cs.toArrayUnsafe())
-      case _ =>
-        // NOTE: We actually measured recently, and compact + use array was 
pretty good usually
-        apply(bs.compact)
-    }
+  private val byteStringInputStreamMethodTypeOpt = Try {
+    val lookup = MethodHandles.publicLookup()
+    val inputStreamMethodType = MethodType.methodType(classOf[InputStream])
+    lookup.findVirtual(classOf[ByteString], "asInputStream", 
inputStreamMethodType)
+  }.toOption
+
+  def apply(bs: ByteString): InputStream = bs match {
+    case cs: ByteString1C =>
+      getInputStreamUnsafe(cs)
+    case _ =>
+      if (byteStringInputStreamMethodTypeOpt.isDefined) {
+        
byteStringInputStreamMethodTypeOpt.get.invoke(bs).asInstanceOf[InputStream]
+      } else {
+        legacyConvert(bs.compact)
+      }
+  }
+
+  private def legacyConvert(bs: ByteString): InputStream = bs match {
+    case cs: ByteString1C =>
+      getInputStreamUnsafe(cs)
+    case _ =>
+      // NOTE: We actually measured recently, and compact + use array was 
pretty good usually
+      legacyConvert(bs.compact)
+  }
+
+  private def getInputStreamUnsafe(bs: ByteString): InputStream =
+    new ByteArrayInputStream(bs.toArrayUnsafe())
+
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to