diff options
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java | 31 | ||||
-rw-r--r-- | jdisc_core/src/main/java/com/yahoo/jdisc/handler/UnsafeContentInputStream.java | 60 |
2 files changed, 61 insertions, 30 deletions
diff --git a/container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java b/container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java index b92bf68e099..b0b88bf8190 100644 --- a/container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java @@ -12,7 +12,6 @@ import com.yahoo.container.jdisc.RequestHandlerTestDriver; import com.yahoo.container.protect.Error; import com.yahoo.io.IOUtils; import com.yahoo.net.HostName; -import com.yahoo.search.handler.SearchHandler; import com.yahoo.search.searchchain.config.test.SearchChainConfigurerTestCase; import com.yahoo.slime.Inspector; import com.yahoo.slime.SlimeUtils; @@ -20,6 +19,7 @@ import com.yahoo.test.json.JsonTestHelper; import org.assertj.core.api.Assertions; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -28,11 +28,12 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.util.HashMap; import java.util.Map; +import java.util.Random; import static com.yahoo.jdisc.http.HttpRequest.Method.GET; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; @@ -52,7 +53,6 @@ public class JSONSearchHandlerTestCase { private static final String selfHostname = HostName.getLocalhost(); private static String tempDir = ""; - private static String configId = null; private static final String uri = "http://localhost?"; private static final String JSON_CONTENT_TYPE = "application/json"; @@ -67,7 +67,7 @@ public class JSONSearchHandlerTestCase { public void startUp() throws IOException { File cfgDir = tempfolder.newFolder("SearchHandlerTestCase"); tempDir = cfgDir.getAbsolutePath(); - configId = "dir:" + tempDir; + String configId = "dir:" + tempDir; IOUtils.copyDirectory(new File(testDir), cfgDir, 1); // make configs active generateComponentsConfigForActive(); @@ -535,4 +535,27 @@ public class JSONSearchHandlerTestCase { assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), "Application/JSON; charset=utf-8"), jsonResult); } + private static String createBenchmarkRequest(int num) { + Random rand = new Random(); + StringBuilder sb = new StringBuilder("{\"yql\": \"select id from vectors where {targetHits:10, approximate:true}nearestNeighbor(vector,q);\", \"input.query(q)\":["); + sb.append(rand.nextDouble()); + for (int i=1; i < num; i++) { + sb.append(','); + sb.append(rand.nextDouble()); + } + sb.append("]}"); + return sb.toString(); + } + @Ignore + public void benchmarkJsonParsing() { + String request = createBenchmarkRequest(768); + for (int i=0; i < 10000; i++) { + RequestHandlerTestDriver.MockResponseHandler responseHandler = + driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, request, JSON_CONTENT_TYPE); + String response = responseHandler.readAll(); + assertEquals(200, responseHandler.getStatus()); + assertFalse(response.isEmpty()); + } + } + } diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/UnsafeContentInputStream.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/UnsafeContentInputStream.java index 3855f053b76..731e28b556c 100644 --- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/UnsafeContentInputStream.java +++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/UnsafeContentInputStream.java @@ -19,7 +19,7 @@ import java.util.Objects; public class UnsafeContentInputStream extends InputStream { private final ReadableContentChannel content; - private ByteBuffer buf = ByteBuffer.allocate(0); + private ByteBuffer currBuf = ByteBuffer.allocate(0); private byte [] marked; private int readSinceMarked; @@ -34,13 +34,10 @@ public class UnsafeContentInputStream extends InputStream { @Override public int read() { - while (buf != null && buf.remaining() == 0) { - buf = content.read(); - } - if (buf == null) { - return -1; - } - byte b = buf.get(); + fetchNonEmptyBuffer(); + if (currBuf == null) return -1; + + byte b = currBuf.get(); if (marked != null) { if (readSinceMarked < marked.length) { marked[readSinceMarked++] = b; @@ -51,34 +48,45 @@ public class UnsafeContentInputStream extends InputStream { return ((int)b) & 0xFF; } + private boolean fetchNonEmptyBuffer() { + while (currBuf != null && currBuf.remaining() == 0) { + currBuf = content.read(); + } + return (currBuf != null && currBuf.hasRemaining()); + } + @Override public int read(byte buf[], int off, int len) { Objects.requireNonNull(buf, "buf"); if (off < 0 || len < 0 || len > buf.length - off) { throw new IndexOutOfBoundsException(); } - if (len == 0) { - return 0; - } - int c = read(); - if (c == -1) { - return -1; + if (len == 0) return 0; + + if ( ! fetchNonEmptyBuffer() ) return -1; + int read = 0; + while ((available() > 0) && fetchNonEmptyBuffer() && ((len - read) > 0)) { + int toRead = Math.min(currBuf.remaining(), (len - read)); + currBuf.get(buf, off + read, toRead); + read += toRead; } - buf[off] = (byte)c; - int cnt = 1; - for (; cnt < len && available() > 0; ++cnt) { - if ((c = read()) == -1) { - break; + if (marked != null) { + if (readSinceMarked + len < marked.length) { + for (int i=0; i < len; i++) { + marked[readSinceMarked++] = buf[off+i]; + } + } else { + marked = null; } - buf[off + cnt] = (byte)c; + } - return cnt; + return read; } @Override public int available() { - if (buf != null && buf.remaining() > 0) { - return buf.remaining(); + if (currBuf != null && currBuf.remaining() > 0) { + return currBuf.remaining(); } return content.available(); } @@ -102,11 +110,11 @@ public class UnsafeContentInputStream extends InputStream { if (marked == null) { throw new IOException("mark has not been called, or too much has been read since marked."); } - ByteBuffer newBuf = ByteBuffer.allocate(readSinceMarked + buf.remaining()); + ByteBuffer newBuf = ByteBuffer.allocate(readSinceMarked + currBuf.remaining()); newBuf.put(marked, 0, readSinceMarked); - newBuf.put(buf); + newBuf.put(currBuf); newBuf.flip(); - buf = newBuf; + currBuf = newBuf; marked = null; } |