Skip to content

Commit de62914

Browse files
committed
Adds more write overloads to Utf8Json
Either memory stream or to serialize on the writer. This consolidates and funnels places that need to write bytes/streams/objects directly
1 parent 9511871 commit de62914

File tree

13 files changed

+65
-68
lines changed

13 files changed

+65
-68
lines changed

src/Elasticsearch.Net/Utf8Json/IJsonFormatterResolver.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,10 @@ public static IJsonFormatter<T> GetFormatterWithVerify<T>(this IJsonFormatterRes
6060
return formatter;
6161
}
6262

63+
private static readonly MethodInfo _getFormatterMethod = typeof(IJsonFormatterResolver).GetRuntimeMethod("GetFormatter", Type.EmptyTypes);
6364
public static object GetFormatterDynamic(this IJsonFormatterResolver resolver, Type type)
6465
{
65-
var methodInfo = typeof(IJsonFormatterResolver).GetRuntimeMethod("GetFormatter", Type.EmptyTypes);
66-
67-
var formatter = methodInfo.MakeGenericMethod(type).Invoke(resolver, null);
66+
var formatter = _getFormatterMethod.MakeGenericMethod(type).Invoke(resolver, null);
6867
return formatter;
6968
}
7069
}

src/Elasticsearch.Net/Utf8Json/Internal/UnsafeMemory.Low.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ internal static class UnsafeMemory
3535
{
3636
public static readonly bool Is32Bit = (IntPtr.Size == 4);
3737

38-
public static void WriteRaw(ref JsonWriter writer, byte[] src)
38+
public static void WriteRaw(ref JsonWriter writer, byte[] src) => WriteRaw(ref writer, src, src.Length);
39+
public static void WriteRaw(ref JsonWriter writer, byte[] src, int length)
3940
{
40-
switch (src.Length)
41+
switch (length)
4142
{
4243
case 0: break;
4344
case 1: if (Is32Bit) { UnsafeMemory32.WriteRaw1(ref writer, src); } else { UnsafeMemory64.WriteRaw1(ref writer, src); } break;
@@ -77,19 +78,20 @@ public static void WriteRaw(ref JsonWriter writer, byte[] src)
7778
}
7879
}
7980

80-
public static unsafe void MemoryCopy(ref JsonWriter writer, byte[] src)
81+
public static void MemoryCopy(ref JsonWriter writer, byte[] src) => MemoryCopy(ref writer, src, src.Length);
82+
public static unsafe void MemoryCopy(ref JsonWriter writer, byte[] src, int length)
8183
{
82-
BinaryUtil.EnsureCapacity(ref writer.buffer, writer.offset, src.Length);
84+
BinaryUtil.EnsureCapacity(ref writer.buffer, writer.offset, length);
8385
#if !NET45
8486
fixed (void* dstP = &writer.buffer[writer.offset])
8587
fixed (void* srcP = &src[0])
8688
{
87-
Buffer.MemoryCopy(srcP, dstP, writer.buffer.Length - writer.offset, src.Length);
89+
Buffer.MemoryCopy(srcP, dstP, writer.buffer.Length - writer.offset, length);
8890
}
8991
#else
90-
Buffer.BlockCopy(src, 0, writer.buffer, writer.offset, src.Length);
92+
Buffer.BlockCopy(src, 0, writer.buffer, writer.offset, length);
9193
#endif
92-
writer.offset += src.Length;
94+
writer.offset += length;
9395
}
9496
}
9597

src/Elasticsearch.Net/Utf8Json/JsonWriter.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#endregion
2424

2525
using System;
26+
using System.IO;
2627
using System.Runtime.CompilerServices;
2728
using System.Text;
2829
using Elasticsearch.Net.Extensions;
@@ -147,6 +148,27 @@ public void WriteRaw(byte[] rawValue)
147148
offset += rawValue.Length;
148149
#endif
149150
}
151+
public void WriteRaw(byte[] rawValue, int length)
152+
{
153+
UnsafeMemory.WriteRaw(ref this, rawValue, length);
154+
}
155+
public void WriteRaw(MemoryStream ms)
156+
{
157+
if (ms.TryGetBuffer(out var b) && !(b.Array is null) && b.Offset == 0)
158+
WriteRaw(b.Array, b.Count);
159+
else
160+
{
161+
var bytes = ms.ToArray();
162+
this.WriteRaw(bytes);
163+
}
164+
}
165+
166+
public void WriteSerialized<T>(T value, IElasticsearchSerializer serializer, IConnectionConfigurationValues settings, SerializationFormatting formatting = SerializationFormatting.None)
167+
{
168+
using var ms = settings.MemoryStreamFactory.Create();
169+
serializer.Serialize(value, ms, formatting);
170+
WriteRaw(ms);
171+
}
150172

151173
#if NETSTANDARD
152174
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -483,5 +505,6 @@ private static void ToUnicode(char c, ref int offset, byte[] buffer)
483505
buffer[offset++] = (byte)CharUtils.HexDigit((c >> 4) & '\x000f');
484506
buffer[offset++] = (byte)CharUtils.HexDigit(c & '\x000f');
485507
}
508+
486509
}
487510
}

src/Elasticsearch.Net/Utf8Json/Resolvers/CompositeResolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ internal abstract class DynamicCompositeResolver : IJsonFormatterResolver
157157
{
158158
private static readonly string ModuleName = $"{ResolverConfig.Namespace}.DynamicCompositeResolver";
159159

160-
static readonly DynamicAssembly assembly;
160+
static readonly DynamicAssembly assembly;
161161

162162
static DynamicCompositeResolver()
163163
{

src/Nest/CommonAbstractions/Extensions/TypeExtensions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq.Expressions;
66
using System.Reflection;
77
using System.Text;
8+
using Elasticsearch.Net.CrossPlatform;
89

910
namespace Nest
1011
{
@@ -150,5 +151,9 @@ private static bool IsHidingMember(PropertyInfo propertyInfo)
150151
}
151152

152153
internal delegate T ObjectActivator<out T>(params object[] args);
154+
155+
private static readonly Assembly NestAssembly = typeof(TypeExtensions).Assembly();
156+
157+
public static bool IsNestType(this Type type) => type.Assembly() == NestAssembly;
153158
}
154159
}

src/Nest/CommonAbstractions/SerializationBehavior/DefaultHighLevelSerializer.cs

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,17 @@ internal class DefaultHighLevelSerializer : IElasticsearchSerializer, IInternalS
1414

1515
public IJsonFormatterResolver FormatterResolver { get; }
1616

17-
public T Deserialize<T>(Stream stream)
18-
{
19-
return JsonSerializer.Deserialize<T>(stream, FormatterResolver);
20-
}
21-
22-
public object Deserialize(Type type, Stream stream)
23-
{
24-
return JsonSerializer.NonGeneric.Deserialize(type, stream, FormatterResolver);
25-
}
26-
27-
public Task<T> DeserializeAsync<T>(Stream stream, CancellationToken cancellationToken = default)
28-
{
29-
return JsonSerializer.DeserializeAsync<T>(stream, FormatterResolver);
30-
}
31-
32-
public Task<object> DeserializeAsync(Type type, Stream stream, CancellationToken cancellationToken = default)
33-
{
34-
return JsonSerializer.NonGeneric.DeserializeAsync(type, stream, FormatterResolver);
35-
}
17+
public T Deserialize<T>(Stream stream) =>
18+
JsonSerializer.Deserialize<T>(stream, FormatterResolver);
19+
20+
public object Deserialize(Type type, Stream stream) =>
21+
JsonSerializer.NonGeneric.Deserialize(type, stream, FormatterResolver);
22+
23+
public Task<T> DeserializeAsync<T>(Stream stream, CancellationToken cancellationToken = default) =>
24+
JsonSerializer.DeserializeAsync<T>(stream, FormatterResolver);
25+
26+
public Task<object> DeserializeAsync(Type type, Stream stream, CancellationToken cancellationToken = default) =>
27+
JsonSerializer.NonGeneric.DeserializeAsync(type, stream, FormatterResolver);
3628

3729
public virtual void Serialize<T>(T data, Stream writableStream, SerializationFormatting formatting = SerializationFormatting.None) =>
3830
JsonSerializer.Serialize(writableStream, data, FormatterResolver);

src/Nest/CommonAbstractions/SerializationBehavior/JsonFormatters/ProxyRequestFormatterBase.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ public void Serialize(ref JsonWriter writer, TRequestInterface value, IJsonForma
3737
using (var ms = settings.MemoryStreamFactory.Create())
3838
{
3939
untypedDocumentRequest.WriteJson(serializer, ms, SerializationFormatting.None);
40-
var v = ms.ToArray();
41-
writer.WriteRaw(v);
40+
writer.WriteRaw(ms);
4241
}
4342
}
4443
}

src/Nest/CommonAbstractions/SerializationBehavior/JsonFormatters/SourceFormatter.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,17 @@ public virtual void Serialize(ref JsonWriter writer, T value, IJsonFormatterReso
3030
var settings = formatterResolver.GetConnectionSettings();
3131

3232
// avoid serialization to bytes when not using custom source serializer
33-
if (ReferenceEquals(settings.SourceSerializer, settings.RequestResponseSerializer))
33+
if (ReferenceEquals(settings.SourceSerializer, settings.RequestResponseSerializer)
34+
|| settings.SourceSerializer is IInternalSerializerWithFormatter s && s.FormatterResolver != null)
3435
{
3536
formatterResolver.GetFormatter<T>().Serialize(ref writer, value, formatterResolver);
3637
return;
3738
}
3839

3940
var sourceSerializer = settings.SourceSerializer;
4041
var f = ForceFormatting ?? SerializationFormatting.None;
41-
byte[] bytes;
42-
using (var ms = settings.MemoryStreamFactory.Create())
43-
{
44-
sourceSerializer.Serialize(value, ms, f);
45-
// TODO: read each byte instead of creating and allocating an array
46-
bytes = ms.ToArray();
47-
}
4842

49-
writer.WriteRaw(bytes);
43+
writer.WriteSerialized(value, sourceSerializer, settings, f);
5044
}
5145
}
5246
}

src/Nest/CommonAbstractions/SerializationBehavior/SourceValueWriteConverter.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using Elasticsearch.Net.CrossPlatform;
21
using Elasticsearch.Net.Utf8Json;
32

43
namespace Nest
@@ -13,8 +12,7 @@ public override void Serialize(ref JsonWriter writer, T value, IJsonFormatterRes
1312
return;
1413
}
1514

16-
var nestType = value.GetType().Assembly() == typeof(SourceWriteFormatter<>).Assembly();
17-
if (nestType)
15+
if (value.GetType().IsNestType())
1816
formatterResolver.GetFormatter<T>().Serialize(ref writer, value, formatterResolver);
1917
else
2018
base.Serialize(ref writer, value, formatterResolver);

src/Nest/Document/Multiple/Bulk/BulkRequestFormatter.cs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ internal class BulkRequestFormatter : IJsonFormatter<IBulkRequest>
88
{
99
private const byte Newline = (byte)'\n';
1010

11+
private static SourceWriteFormatter<object> SourceWriter { get; } = new SourceWriteFormatter<object>();
12+
1113
public IBulkRequest Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver) =>
1214
throw new NotSupportedException();
1315

@@ -17,16 +19,13 @@ public void Serialize(ref JsonWriter writer, IBulkRequest value, IJsonFormatterR
1719
return;
1820

1921
var settings = formatterResolver.GetConnectionSettings();
20-
var memoryStreamFactory = settings.MemoryStreamFactory;
21-
var requestResponseSerializer = settings.RequestResponseSerializer;
22-
var sourceSerializer = settings.SourceSerializer;
2322
var inferrer = settings.Inferrer;
2423
var formatter = formatterResolver.GetFormatter<object>();
2524

2625
for (var index = 0; index < value.Operations.Count; index++)
2726
{
2827
var op = value.Operations[index];
29-
op.Index = op.Index ?? value.Index ?? op.ClrType;
28+
op.Index ??= value.Index ?? op.ClrType;
3029
if (op.Index.Equals(value.Index)) op.Index = null;
3130
op.Id = op.GetIdForOperation(inferrer);
3231
op.Routing = op.GetRoutingForOperation(inferrer);
@@ -42,12 +41,7 @@ public void Serialize(ref JsonWriter writer, IBulkRequest value, IJsonFormatterR
4241
if (body == null)
4342
continue;
4443

45-
var bodySerializer = op.Operation == "update" || body is ILazyDocument
46-
? requestResponseSerializer
47-
: sourceSerializer;
48-
49-
var bodyBytes = bodySerializer.SerializeToBytes(body, memoryStreamFactory, SerializationFormatting.None);
50-
writer.WriteRaw(bodyBytes);
44+
SourceWriter.Serialize(ref writer, body, formatterResolver);
5145
writer.WriteRaw(Newline);
5246
}
5347
}

src/Nest/Search/MultiSearch/MultiSearchFormatter.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,9 @@ public void Serialize(ref JsonWriter writer, IMultiSearchRequest value, IJsonFor
4444
ignore_unavailable = GetString("ignore_unavailable")
4545
};
4646

47-
var headerBytes = serializer.SerializeToBytes(header, memoryStreamFactory, SerializationFormatting.None);
48-
writer.WriteRaw(headerBytes);
47+
writer.WriteSerialized(header, serializer, settings, SerializationFormatting.None);
4948
writer.WriteRaw(Newline);
50-
var bodyBytes = serializer.SerializeToBytes(operation, memoryStreamFactory, SerializationFormatting.None);
51-
writer.WriteRaw(bodyBytes);
49+
writer.WriteSerialized(operation, serializer, settings, SerializationFormatting.None);
5250
writer.WriteRaw(Newline);
5351
}
5452
}

src/Nest/Search/MultiSearchTemplate/MultiSearchTemplateJsonConverter.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,9 @@ string GetString(string key)
4444
ignore_unavailable = GetString("ignore_unavailable")
4545
};
4646

47-
var headerBytes = serializer.SerializeToBytes(header, memoryStreamFactory, SerializationFormatting.None);
48-
writer.WriteRaw(headerBytes);
47+
writer.WriteSerialized(header, serializer, settings, SerializationFormatting.None);
4948
writer.WriteRaw(Newline);
50-
var bodyBytes = serializer.SerializeToBytes(operation, memoryStreamFactory, SerializationFormatting.None);
51-
writer.WriteRaw(bodyBytes);
49+
writer.WriteSerialized(operation, serializer, settings, SerializationFormatting.None);
5250
writer.WriteRaw(Newline);
5351
}
5452
}

src/Nest/XPack/MachineLearning/PostJobData/PostJobDataRequest.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,9 @@ public void Serialize(ref JsonWriter writer, IPostJobDataRequest value, IJsonFor
6363

6464
var settings = formatterResolver.GetConnectionSettings();
6565
var sourceSerializer = settings.SourceSerializer;
66-
var memoryStreamFactory = settings.MemoryStreamFactory;
6766

6867
foreach (var data in value.Data)
69-
{
70-
var bodyJson = sourceSerializer.SerializeToBytes(data, memoryStreamFactory, SerializationFormatting.None);
71-
writer.WriteRaw(bodyJson);
72-
writer.WriteRaw(Newline);
73-
}
68+
writer.WriteSerialized(data, sourceSerializer, settings, SerializationFormatting.None);
7469
}
7570
}
7671
}

0 commit comments

Comments
 (0)