From 6b4ada85fbb0c209559d51ff9f01b72bc8697fa5 Mon Sep 17 00:00:00 2001 From: Santiago Pericasgeertsen Date: Wed, 17 Jan 2024 09:30:34 -0500 Subject: [PATCH] Some write optimizations for buffers and lazy initialization of headers. Fixed problem in FixedBufferData constructor. Signed-off-by: Santiago Pericasgeertsen --- .../buffers/CompositeArrayBufferData.java | 16 +++++++++-- .../buffers/CompositeListBufferData.java | 9 ++++++- .../common/buffers/FixedBufferData.java | 4 +-- .../java/io/helidon/http/HeadersImpl.java | 27 ++++++++++++------- 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/common/buffers/src/main/java/io/helidon/common/buffers/CompositeArrayBufferData.java b/common/buffers/src/main/java/io/helidon/common/buffers/CompositeArrayBufferData.java index c9d33a6cccd..cf9492a721c 100644 --- a/common/buffers/src/main/java/io/helidon/common/buffers/CompositeArrayBufferData.java +++ b/common/buffers/src/main/java/io/helidon/common/buffers/CompositeArrayBufferData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Oracle and/or its affiliates. + * Copyright (c) 2022, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; -class CompositeArrayBufferData extends ReadOnlyBufferData { +class CompositeArrayBufferData extends ReadOnlyBufferData implements CompositeBufferData { private final BufferData[] data; CompositeArrayBufferData(BufferData[] data) { @@ -38,6 +38,13 @@ public BufferData rewind() { @Override public void writeTo(OutputStream out) { + if (data.length == 1) { + BufferData datum = data[0]; + if (!(datum instanceof CompositeBufferData)) { + datum.writeTo(out); + return; + } + } copy().writeTo(out); } @@ -260,4 +267,9 @@ public int get(int index) { public String toString() { return "comp-array: a=" + available(); } + + @Override + public CompositeBufferData add(BufferData bufferData) { + throw new UnsupportedOperationException("Add not supported for " + getClass().getSimpleName() + " buffer"); + } } diff --git a/common/buffers/src/main/java/io/helidon/common/buffers/CompositeListBufferData.java b/common/buffers/src/main/java/io/helidon/common/buffers/CompositeListBufferData.java index bf5fcdaefec..66a405b73e4 100644 --- a/common/buffers/src/main/java/io/helidon/common/buffers/CompositeListBufferData.java +++ b/common/buffers/src/main/java/io/helidon/common/buffers/CompositeListBufferData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Oracle and/or its affiliates. + * Copyright (c) 2022, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,6 +56,13 @@ public BufferData rewind() { @Override public void writeTo(OutputStream out) { + if (data.size() == 1) { + BufferData datum = data.get(0); + if (!(datum instanceof CompositeBufferData)) { + datum.writeTo(out); + return; + } + } copy().writeTo(out); } diff --git a/common/buffers/src/main/java/io/helidon/common/buffers/FixedBufferData.java b/common/buffers/src/main/java/io/helidon/common/buffers/FixedBufferData.java index fcf1dd7e2db..5da3918c37c 100644 --- a/common/buffers/src/main/java/io/helidon/common/buffers/FixedBufferData.java +++ b/common/buffers/src/main/java/io/helidon/common/buffers/FixedBufferData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Oracle and/or its affiliates. + * Copyright (c) 2022, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ class FixedBufferData implements BufferData { FixedBufferData(byte[] bytes, int position, int length) { this.bytes = bytes; this.length = length; - this.writePosition = length; + this.writePosition = position + length; this.readPosition = position; } diff --git a/http/http/src/main/java/io/helidon/http/HeadersImpl.java b/http/http/src/main/java/io/helidon/http/HeadersImpl.java index 5cfc73718bc..f11c6de17a6 100644 --- a/http/http/src/main/java/io/helidon/http/HeadersImpl.java +++ b/http/http/src/main/java/io/helidon/http/HeadersImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023 Oracle and/or its affiliates. + * Copyright (c) 2022, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,10 +34,11 @@ class HeadersImpl> implements WritableHeaders { Optimization for most commonly used header names */ private final Header[] knownHeaders = new Header[KNOWN_HEADER_SIZE]; - // custom (unknown) headers are slower - private final Map customHeaders = new HashMap<>(); private IntSet knownHeaderIndices = new IntSet(KNOWN_HEADER_SIZE); + // custom (unknown) headers are slower + private Map customHeaders = null; + HeadersImpl() { } @@ -85,7 +86,7 @@ public Header get(HeaderName name) { @Override public int size() { - return customHeaders.size() + knownHeaderIndices.size(); + return (customHeaders == null ? 0 : customHeaders.size()) + knownHeaderIndices.size(); } @Override @@ -167,7 +168,7 @@ public T set(Header header) { } int index = name.index(); if (index == -1) { - customHeaders.put(name, usedHeader); + customHeaders().put(name, usedHeader); } else { knownHeaders[index] = usedHeader; knownHeaderIndices.add(index); @@ -179,7 +180,7 @@ public T set(Header header) { public T clear() { Arrays.fill(knownHeaders, null); knownHeaderIndices = new IntSet(KNOWN_HEADER_SIZE); - customHeaders.clear(); + customHeaders().clear(); return (T) this; } @@ -231,8 +232,9 @@ public Header doRemove(HeaderName name) { knownHeaderIndices.remove(index); return value; } - return customHeaders.remove(name); + return customHeaders().remove(name); } + private Header find(HeaderName name) { int index = name.index(); @@ -240,11 +242,18 @@ private Header find(HeaderName name) { return knownHeaders[index]; } - return customHeaders.get(name); + return customHeaders().get(name); + } + + private Map customHeaders() { + if (customHeaders == null) { + customHeaders = new HashMap<>(); + } + return customHeaders; } private class HeaderIterator implements Iterator
{ - private final boolean noCustom = customHeaders.isEmpty(); + private final boolean noCustom = (customHeaders == null || customHeaders.isEmpty()); private boolean inKnown = true; private int last = -1;