Improve some Byte Array Handling Spots (#55844) (#55856)

Some small memory-saving improvements in `byte[]` handling.
This commit is contained in:
Armin Braun 2020-04-28 16:38:48 +02:00 committed by GitHub
parent 47d252424b
commit 51a94102e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 35 deletions

View File

@ -23,14 +23,13 @@ import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.cluster.AbstractDiffable; import org.elasticsearch.cluster.AbstractDiffable;
import org.elasticsearch.cluster.Diff; import org.elasticsearch.cluster.Diff;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.index.mapper.DateFieldMapper; import org.elasticsearch.index.mapper.DateFieldMapper;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.mapper.DocumentMapper; import org.elasticsearch.index.mapper.DocumentMapper;
import java.io.IOException; import java.io.IOException;
@ -97,8 +96,8 @@ public class MappingMetadata extends AbstractDiffable<MappingMetadata> {
public MappingMetadata(String type, Map<String, Object> mapping) throws IOException { public MappingMetadata(String type, Map<String, Object> mapping) throws IOException {
this.type = type; this.type = type;
XContentBuilder mappingBuilder = XContentFactory.jsonBuilder().map(mapping); this.source = new CompressedXContent(
this.source = new CompressedXContent(BytesReference.bytes(mappingBuilder)); (builder, params) -> builder.mapContents(mapping), XContentType.JSON, ToXContent.EMPTY_PARAMS);
Map<String, Object> withoutType = mapping; Map<String, Object> withoutType = mapping;
if (mapping.size() == 1 && mapping.containsKey(type)) { if (mapping.size() == 1 && mapping.containsKey(type)) {
withoutType = (Map<String, Object>) mapping.get(type); withoutType = (Map<String, Object>) mapping.get(type);

View File

@ -19,6 +19,7 @@
package org.elasticsearch.common.bytes; package org.elasticsearch.common.bytes;
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefIterator; import org.apache.lucene.util.BytesRefIterator;
import org.elasticsearch.common.io.stream.BytesStream; import org.elasticsearch.common.io.stream.BytesStream;
@ -61,7 +62,7 @@ public interface BytesReference extends Comparable<BytesReference>, ToXContentFr
if (bytesRef.offset == 0 && bytesRef.length == bytesRef.bytes.length) { if (bytesRef.offset == 0 && bytesRef.length == bytesRef.bytes.length) {
return bytesRef.bytes; return bytesRef.bytes;
} }
return BytesRef.deepCopyOf(bytesRef).bytes; return ArrayUtil.copyOfSubArray(bytesRef.bytes, bytesRef.offset, bytesRef.offset + bytesRef.length);
} }
/** /**

View File

@ -22,6 +22,7 @@ package org.elasticsearch.common.compress;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
@ -32,6 +33,7 @@ import org.elasticsearch.common.xcontent.XContentType;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.zip.CRC32; import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream; import java.util.zip.CheckedOutputStream;
@ -45,19 +47,9 @@ import java.util.zip.CheckedOutputStream;
public final class CompressedXContent { public final class CompressedXContent {
private static int crc32(BytesReference data) { private static int crc32(BytesReference data) {
OutputStream dummy = new OutputStream() {
@Override
public void write(int b) throws IOException {
// no-op
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
// no-op
}
};
CRC32 crc32 = new CRC32(); CRC32 crc32 = new CRC32();
try { try {
data.writeTo(new CheckedOutputStream(dummy, crc32)); data.writeTo(new CheckedOutputStream(Streams.NULL_OUTPUT_STREAM, crc32));
} catch (IOException bogus) { } catch (IOException bogus) {
// cannot happen // cannot happen
throw new Error(bogus); throw new Error(bogus);
@ -124,7 +116,7 @@ public final class CompressedXContent {
} }
public CompressedXContent(String str) throws IOException { public CompressedXContent(String str) throws IOException {
this(new BytesArray(new BytesRef(str))); this(new BytesArray(str.getBytes(StandardCharsets.UTF_8)));
} }
/** Return the compressed bytes. */ /** Return the compressed bytes. */

View File

@ -51,6 +51,19 @@ public abstract class Streams {
public static final int BUFFER_SIZE = 1024 * 8; public static final int BUFFER_SIZE = 1024 * 8;
/**
* OutputStream that just throws all the bytes away
*/
public static final OutputStream NULL_OUTPUT_STREAM = new OutputStream() {
@Override
public void write(int b) {
// no-op
}
@Override
public void write(byte[] b, int off, int len) {
// no-op
}
};
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// Copy methods for java.io.InputStream / java.io.OutputStream // Copy methods for java.io.InputStream / java.io.OutputStream
@ -209,7 +222,7 @@ public abstract class Streams {
* Fully consumes the input stream, throwing the bytes away. Returns the number of bytes consumed. * Fully consumes the input stream, throwing the bytes away. Returns the number of bytes consumed.
*/ */
public static long consumeFully(InputStream inputStream) throws IOException { public static long consumeFully(InputStream inputStream) throws IOException {
return copy(inputStream, new NullOutputStream()); return copy(inputStream, NULL_OUTPUT_STREAM);
} }
public static List<String> readAllLines(InputStream input) throws IOException { public static List<String> readAllLines(InputStream input) throws IOException {
@ -384,20 +397,4 @@ public abstract class Streams {
} }
} }
} }
/**
* OutputStream that just throws all the bytes away
*/
static class NullOutputStream extends OutputStream {
@Override
public void write(int b) {
}
@Override
public void write(byte[] b, int off, int len) {
}
}
} }