From f64e6364158e6d047fe5c9d481e95db3287b5009 Mon Sep 17 00:00:00 2001 From: kimchy Date: Sat, 9 Oct 2010 03:06:01 +0200 Subject: [PATCH] add xcontent string that will allow to speed up json/smile serialization --- .../common/xcontent/XContentBuilder.java | 318 ++++++++++++++++-- .../common/xcontent/XContentGenerator.java | 22 ++ .../common/xcontent/XContentString.java | 32 ++ .../xcontent/json/JsonXContentGenerator.java | 59 +++- 4 files changed, 396 insertions(+), 35 deletions(-) create mode 100644 modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentString.java diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java index 248f2f4fcfa..9bbd5f68f20 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java @@ -103,6 +103,12 @@ public final class XContentBuilder { return this; } + public XContentBuilder startObject(XContentString name) throws IOException { + field(name); + startObject(); + return this; + } + public XContentBuilder startObject() throws IOException { generator.writeStartObject(); return this; @@ -122,6 +128,15 @@ public final class XContentBuilder { return this; } + public XContentBuilder array(XContentString name, String... values) throws IOException { + startArray(name); + for (String value : values) { + value(value); + } + endArray(); + return this; + } + public XContentBuilder array(String name, Object... values) throws IOException { startArray(name); for (Object value : values) { @@ -131,12 +146,27 @@ public final class XContentBuilder { return this; } + public XContentBuilder array(XContentString name, Object... values) throws IOException { + startArray(name); + for (Object value : values) { + value(value); + } + endArray(); + return this; + } + public XContentBuilder startArray(String name) throws IOException { field(name); startArray(); return this; } + public XContentBuilder startArray(XContentString name) throws IOException { + field(name); + startArray(); + return this; + } + public XContentBuilder startArray() throws IOException { generator.writeStartArray(); return this; @@ -147,6 +177,23 @@ public final class XContentBuilder { return this; } + public XContentBuilder field(XContentString name) throws IOException { + if (fieldCaseConversion == FieldCaseConversion.UNDERSCORE) { + if (cachedStringBuilder == null) { + cachedStringBuilder = new StringBuilder(); + } + generator.writeFieldName(Strings.toUnderscoreCase(name.getValue(), cachedStringBuilder)); + } else if (fieldCaseConversion == FieldCaseConversion.CAMELCASE) { + if (cachedStringBuilder == null) { + cachedStringBuilder = new StringBuilder(); + } + generator.writeFieldName(Strings.toCamelCase(name.getValue(), cachedStringBuilder)); + } else { + generator.writeFieldName(name); + } + return this; + } + public XContentBuilder field(String name) throws IOException { if (fieldCaseConversion == FieldCaseConversion.UNDERSCORE) { if (cachedStringBuilder == null) { @@ -173,6 +220,16 @@ public final class XContentBuilder { return this; } + public XContentBuilder field(XContentString name, char[] value, int offset, int length) throws IOException { + field(name); + if (value == null) { + generator.writeNull(); + } else { + generator.writeString(value, offset, length); + } + return this; + } + public XContentBuilder field(String name, String value) throws IOException { field(name); if (value == null) { @@ -183,53 +240,108 @@ public final class XContentBuilder { return this; } + public XContentBuilder field(XContentString name, String value) throws IOException { + field(name); + if (value == null) { + generator.writeNull(); + } else { + generator.writeString(value); + } + return this; + } + public XContentBuilder field(String name, Integer value) throws IOException { return field(name, value.intValue()); } + public XContentBuilder field(XContentString name, Integer value) throws IOException { + return field(name, value.intValue()); + } + public XContentBuilder field(String name, int value) throws IOException { field(name); generator.writeNumber(value); return this; } + public XContentBuilder field(XContentString name, int value) throws IOException { + field(name); + generator.writeNumber(value); + return this; + } + public XContentBuilder field(String name, Long value) throws IOException { return field(name, value.longValue()); } + public XContentBuilder field(XContentString name, Long value) throws IOException { + return field(name, value.longValue()); + } + public XContentBuilder field(String name, long value) throws IOException { field(name); generator.writeNumber(value); return this; } + public XContentBuilder field(XContentString name, long value) throws IOException { + field(name); + generator.writeNumber(value); + return this; + } + public XContentBuilder field(String name, Float value) throws IOException { return field(name, value.floatValue()); } + public XContentBuilder field(XContentString name, Float value) throws IOException { + return field(name, value.floatValue()); + } + public XContentBuilder field(String name, float value) throws IOException { field(name); generator.writeNumber(value); return this; } + public XContentBuilder field(XContentString name, float value) throws IOException { + field(name); + generator.writeNumber(value); + return this; + } public XContentBuilder field(String name, Double value) throws IOException { return field(name, value.doubleValue()); } + public XContentBuilder field(XContentString name, Double value) throws IOException { + return field(name, value.doubleValue()); + } + public XContentBuilder field(String name, double value) throws IOException { field(name); generator.writeNumber(value); return this; } + public XContentBuilder field(XContentString name, double value) throws IOException { + field(name); + generator.writeNumber(value); + return this; + } + public XContentBuilder field(String name, Map value) throws IOException { field(name); value(value); return this; } + public XContentBuilder field(XContentString name, Map value) throws IOException { + field(name); + value(value); + return this; + } + public XContentBuilder field(String name, List value) throws IOException { startArray(name); for (Object o : value) { @@ -239,6 +351,15 @@ public final class XContentBuilder { return this; } + public XContentBuilder field(XContentString name, List value) throws IOException { + startArray(name); + for (Object o : value) { + value(o); + } + endArray(); + return this; + } + public XContentBuilder field(String name, String... value) throws IOException { startArray(name); for (String o : value) { @@ -248,6 +369,15 @@ public final class XContentBuilder { return this; } + public XContentBuilder field(XContentString name, String... value) throws IOException { + startArray(name); + for (String o : value) { + value(o); + } + endArray(); + return this; + } + public XContentBuilder field(String name, Object... value) throws IOException { startArray(name); for (Object o : value) { @@ -257,6 +387,15 @@ public final class XContentBuilder { return this; } + public XContentBuilder field(XContentString name, Object... value) throws IOException { + startArray(name); + for (Object o : value) { + value(o); + } + endArray(); + return this; + } + public XContentBuilder field(String name, int... value) throws IOException { startArray(name); for (Object o : value) { @@ -266,6 +405,15 @@ public final class XContentBuilder { return this; } + public XContentBuilder field(XContentString name, int... value) throws IOException { + startArray(name); + for (Object o : value) { + value(o); + } + endArray(); + return this; + } + public XContentBuilder field(String name, long... value) throws IOException { startArray(name); for (Object o : value) { @@ -275,6 +423,15 @@ public final class XContentBuilder { return this; } + public XContentBuilder field(XContentString name, long... value) throws IOException { + startArray(name); + for (Object o : value) { + value(o); + } + endArray(); + return this; + } + public XContentBuilder field(String name, float... value) throws IOException { startArray(name); for (Object o : value) { @@ -284,6 +441,15 @@ public final class XContentBuilder { return this; } + public XContentBuilder field(XContentString name, float... value) throws IOException { + startArray(name); + for (Object o : value) { + value(o); + } + endArray(); + return this; + } + public XContentBuilder field(String name, double... value) throws IOException { startArray(name); for (Object o : value) { @@ -293,6 +459,15 @@ public final class XContentBuilder { return this; } + public XContentBuilder field(XContentString name, double... value) throws IOException { + startArray(name); + for (Object o : value) { + value(o); + } + endArray(); + return this; + } + public XContentBuilder field(String name, Object value) throws IOException { if (value == null) { nullField(name); @@ -337,43 +512,155 @@ public final class XContentBuilder { return this; } + public XContentBuilder field(XContentString name, Object value) throws IOException { + if (value == null) { + nullField(name); + return this; + } + Class type = value.getClass(); + if (type == String.class) { + field(name, (String) value); + } else if (type == Float.class) { + field(name, ((Float) value).floatValue()); + } else if (type == Double.class) { + field(name, ((Double) value).doubleValue()); + } else if (type == Integer.class) { + field(name, ((Integer) value).intValue()); + } else if (type == Long.class) { + field(name, ((Long) value).longValue()); + } else if (type == Boolean.class) { + field(name, ((Boolean) value).booleanValue()); + } else if (type == Date.class) { + field(name, (Date) value); + } else if (type == byte[].class) { + field(name, (byte[]) value); + } else if (value instanceof ReadableInstant) { + field(name, (ReadableInstant) value); + } else if (value instanceof Map) { + field(name, (Map) value); + } else if (value instanceof List) { + field(name, (List) value); + } else if (value instanceof Object[]) { + field(name, (Object[]) value); + } else if (value instanceof int[]) { + field(name, (int[]) value); + } else if (value instanceof long[]) { + field(name, (long[]) value); + } else if (value instanceof float[]) { + field(name, (float[]) value); + } else if (value instanceof double[]) { + field(name, (double[]) value); + } else { + field(name, value.toString()); + } + return this; + } + + public XContentBuilder value(Object value) throws IOException { + if (value == null) { + return nullValue(); + } + Class type = value.getClass(); + if (type == String.class) { + value((String) value); + } else if (type == Float.class) { + value(((Float) value).floatValue()); + } else if (type == Double.class) { + value(((Double) value).doubleValue()); + } else if (type == Integer.class) { + value(((Integer) value).intValue()); + } else if (type == Long.class) { + value(((Long) value).longValue()); + } else if (type == Boolean.class) { + value((Boolean) value); + } else if (type == byte[].class) { + value((byte[]) value); + } else if (type == Date.class) { + value((Date) value); + } else if (value instanceof ReadableInstant) { + value((ReadableInstant) value); + } else if (value instanceof Map) { + value((Map) value); + } else { + throw new IOException("Type not allowed [" + type + "]"); + } + return this; + } + public XContentBuilder field(String name, boolean value) throws IOException { field(name); generator.writeBoolean(value); return this; } + public XContentBuilder field(XContentString name, boolean value) throws IOException { + field(name); + generator.writeBoolean(value); + return this; + } + public XContentBuilder field(String name, byte[] value) throws IOException { field(name); generator.writeBinary(value); return this; } + public XContentBuilder field(XContentString name, byte[] value) throws IOException { + field(name); + generator.writeBinary(value); + return this; + } + public XContentBuilder field(String name, ReadableInstant date) throws IOException { field(name); return value(date); } + public XContentBuilder field(XContentString name, ReadableInstant date) throws IOException { + field(name); + return value(date); + } + public XContentBuilder field(String name, ReadableInstant date, DateTimeFormatter formatter) throws IOException { field(name); return value(date, formatter); } + public XContentBuilder field(XContentString name, ReadableInstant date, DateTimeFormatter formatter) throws IOException { + field(name); + return value(date, formatter); + } + public XContentBuilder field(String name, Date date) throws IOException { field(name); return value(date); } + public XContentBuilder field(XContentString name, Date date) throws IOException { + field(name); + return value(date); + } + public XContentBuilder field(String name, Date date, DateTimeFormatter formatter) throws IOException { field(name); return value(date, formatter); } + public XContentBuilder field(XContentString name, Date date, DateTimeFormatter formatter) throws IOException { + field(name); + return value(date, formatter); + } + public XContentBuilder nullField(String name) throws IOException { generator.writeNullField(name); return this; } + public XContentBuilder nullField(XContentString name) throws IOException { + generator.writeNullField(name); + return this; + } + public XContentBuilder nullValue() throws IOException { generator.writeNull(); return this; @@ -470,37 +757,6 @@ public final class XContentBuilder { return this; } - public XContentBuilder value(Object value) throws IOException { - if (value == null) { - return nullValue(); - } - Class type = value.getClass(); - if (type == String.class) { - value((String) value); - } else if (type == Float.class) { - value(((Float) value).floatValue()); - } else if (type == Double.class) { - value(((Double) value).doubleValue()); - } else if (type == Integer.class) { - value(((Integer) value).intValue()); - } else if (type == Long.class) { - value(((Long) value).longValue()); - } else if (type == Boolean.class) { - value((Boolean) value); - } else if (type == byte[].class) { - value((byte[]) value); - } else if (type == Date.class) { - value((Date) value); - } else if (value instanceof ReadableInstant) { - value((ReadableInstant) value); - } else if (value instanceof Map) { - value((Map) value); - } else { - throw new IOException("Type not allowed [" + type + "]"); - } - return this; - } - public XContentBuilder copyCurrentStructure(XContentParser parser) throws IOException { generator.copyCurrentStructure(parser); return this; diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentGenerator.java b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentGenerator.java index 34d51b9547b..18c400523e9 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentGenerator.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentGenerator.java @@ -43,6 +43,8 @@ public interface XContentGenerator { void writeFieldName(String name) throws IOException; + void writeFieldName(XContentString name) throws IOException; + void writeString(String text) throws IOException; void writeString(char[] text, int offset, int len) throws IOException; @@ -66,24 +68,44 @@ public interface XContentGenerator { void writeStringField(String fieldName, String value) throws IOException; + void writeStringField(XContentString fieldName, String value) throws IOException; + void writeBooleanField(String fieldName, boolean value) throws IOException; + void writeBooleanField(XContentString fieldName, boolean value) throws IOException; + void writeNullField(String fieldName) throws IOException; + void writeNullField(XContentString fieldName) throws IOException; + void writeNumberField(String fieldName, int value) throws IOException; + void writeNumberField(XContentString fieldName, int value) throws IOException; + void writeNumberField(String fieldName, long value) throws IOException; + void writeNumberField(XContentString fieldName, long value) throws IOException; + void writeNumberField(String fieldName, double value) throws IOException; + void writeNumberField(XContentString fieldName, double value) throws IOException; + void writeNumberField(String fieldName, float value) throws IOException; + void writeNumberField(XContentString fieldName, float value) throws IOException; + void writeBinaryField(String fieldName, byte[] data) throws IOException; + void writeBinaryField(XContentString fieldName, byte[] data) throws IOException; + void writeArrayFieldStart(String fieldName) throws IOException; + void writeArrayFieldStart(XContentString fieldName) throws IOException; + void writeObjectFieldStart(String fieldName) throws IOException; + void writeObjectFieldStart(XContentString fieldName) throws IOException; + void writeRawField(String fieldName, byte[] content, FastByteArrayOutputStream bos) throws IOException; void writeRawField(String fieldName, InputStream content, FastByteArrayOutputStream bos) throws IOException; diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentString.java b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentString.java new file mode 100644 index 00000000000..279b71b9cf0 --- /dev/null +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentString.java @@ -0,0 +1,32 @@ +/* + * Licensed to Elastic Search and Shay Banon under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Elastic Search 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.elasticsearch.common.xcontent; + +import org.elasticsearch.common.jackson.io.SerializedString; + +/** + * @author kimchy (shay.banon) + */ +public class XContentString extends SerializedString { + + public XContentString(String v) { + super(v); + } +} diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java index 64fced3f9cc..b2ee5292c6d 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java @@ -23,10 +23,7 @@ import org.elasticsearch.common.Bytes; import org.elasticsearch.common.io.FastByteArrayOutputStream; import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.jackson.JsonGenerator; -import org.elasticsearch.common.xcontent.XContentGenerator; -import org.elasticsearch.common.xcontent.XContentHelper; -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.common.xcontent.*; import java.io.IOException; import java.io.InputStream; @@ -70,6 +67,10 @@ public class JsonXContentGenerator implements XContentGenerator { generator.writeFieldName(name); } + @Override public void writeFieldName(XContentString name) throws IOException { + generator.writeFieldName(name); + } + @Override public void writeString(String text) throws IOException { generator.writeString(text); } @@ -114,42 +115,92 @@ public class JsonXContentGenerator implements XContentGenerator { generator.writeStringField(fieldName, value); } + @Override public void writeStringField(XContentString fieldName, String value) throws IOException { + generator.writeFieldName(fieldName); + generator.writeString(value); + } + @Override public void writeBooleanField(String fieldName, boolean value) throws IOException { generator.writeBooleanField(fieldName, value); } + @Override public void writeBooleanField(XContentString fieldName, boolean value) throws IOException { + generator.writeFieldName(fieldName); + generator.writeBoolean(value); + } + @Override public void writeNullField(String fieldName) throws IOException { generator.writeNullField(fieldName); } + @Override public void writeNullField(XContentString fieldName) throws IOException { + generator.writeFieldName(fieldName); + generator.writeNull(); + } + @Override public void writeNumberField(String fieldName, int value) throws IOException { generator.writeNumberField(fieldName, value); } + @Override public void writeNumberField(XContentString fieldName, int value) throws IOException { + generator.writeFieldName(fieldName); + generator.writeNumber(value); + } + @Override public void writeNumberField(String fieldName, long value) throws IOException { generator.writeNumberField(fieldName, value); } + @Override public void writeNumberField(XContentString fieldName, long value) throws IOException { + generator.writeFieldName(fieldName); + generator.writeNumber(value); + } + @Override public void writeNumberField(String fieldName, double value) throws IOException { generator.writeNumberField(fieldName, value); } + @Override public void writeNumberField(XContentString fieldName, double value) throws IOException { + generator.writeFieldName(fieldName); + generator.writeNumber(value); + } + @Override public void writeNumberField(String fieldName, float value) throws IOException { generator.writeNumberField(fieldName, value); } + @Override public void writeNumberField(XContentString fieldName, float value) throws IOException { + generator.writeFieldName(fieldName); + generator.writeNumber(value); + } + @Override public void writeBinaryField(String fieldName, byte[] data) throws IOException { generator.writeBinaryField(fieldName, data); } + @Override public void writeBinaryField(XContentString fieldName, byte[] value) throws IOException { + generator.writeFieldName(fieldName); + generator.writeBinary(value); + } + @Override public void writeArrayFieldStart(String fieldName) throws IOException { generator.writeArrayFieldStart(fieldName); } + @Override public void writeArrayFieldStart(XContentString fieldName) throws IOException { + generator.writeFieldName(fieldName); + generator.writeStartArray(); + } + @Override public void writeObjectFieldStart(String fieldName) throws IOException { generator.writeObjectFieldStart(fieldName); } + @Override public void writeObjectFieldStart(XContentString fieldName) throws IOException { + generator.writeFieldName(fieldName); + generator.writeStartObject(); + } + @Override public void writeRawField(String fieldName, byte[] content, FastByteArrayOutputStream bos) throws IOException { generator.writeRaw(", \""); generator.writeRaw(fieldName);