Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions Enyim.Caching.Tests/MemcachedClientGetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,35 @@ public void When_Getting_SByte_Result_Is_Successful()
public async Task GetValueOrCreateAsyncTest()
{
var key = "GetValueOrCreateAsyncTest_" + Guid.NewGuid();
await _client.GetValueOrCreateAsync(key, 10, () => GenerateValue());
var cacheValue = await _client.GetValueAsync<string>(key);
Assert.Equal(nameof(GetValueOrCreateAsyncTest), cacheValue);
var posts1 = await _client.GetValueOrCreateAsync(
key,
10,
async () => await GenerateValue());
Assert.NotNull(posts1);

var posts2 = await _client.GetValueAsync<IEnumerable<BlogPost>>(key);
Assert.NotNull(posts2);

Assert.Equal(posts1.First().Title, posts2.First().Title);
}

private Task<string> GenerateValue()
private Task<IEnumerable<BlogPost>> GenerateValue()
{
return Task.FromResult(nameof(GetValueOrCreateAsyncTest));
var posts = new List<BlogPost>()
{
new BlogPost{ Title = "test title 1", Body = "test body 1" },
new BlogPost{ Title = "test title 2", Body = "test body 2" }
};

return Task.FromResult(posts.AsEnumerable());
}
}

internal class BlogPost
{
public string Title { get; set; }
public string Body { get; set; }
}
}

#region [ License information ]
Expand Down
1 change: 0 additions & 1 deletion Enyim.Caching.Tests/MemcachedClientTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ protected string GetUniqueKey(string prefix = null)

protected IEnumerable<string> GetUniqueKeys(string prefix = null, int max = 5)
{

var keys = new List<string>(max);
for (int i = 0; i < max; i++)
{
Expand Down
12 changes: 6 additions & 6 deletions Enyim.Caching/Memcached/MemcachedNode.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
using Enyim.Caching.Configuration;
using Enyim.Caching.Memcached.Protocol.Binary;
using Enyim.Caching.Memcached.Results;
using Enyim.Caching.Memcached.Results.Extensions;
using Enyim.Collections;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
Expand All @@ -7,12 +13,6 @@
using System.Security;
using System.Threading;
using System.Threading.Tasks;
using Enyim.Caching.Configuration;
using Enyim.Caching.Memcached.Protocol.Binary;
using Enyim.Caching.Memcached.Results;
using Enyim.Caching.Memcached.Results.Extensions;
using Enyim.Collections;
using Microsoft.Extensions.Logging;

namespace Enyim.Caching.Memcached
{
Expand Down
108 changes: 80 additions & 28 deletions Enyim.Caching/Memcached/Protocol/Binary/BinaryConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,58 +5,110 @@ namespace Enyim.Caching.Memcached.Protocol.Binary
{
public static class BinaryConverter
{
public static ushort DecodeUInt16(Span<byte> buffer, int offset)
public static unsafe ushort DecodeUInt16(byte[] buffer, int offset)
{
return (ushort)((buffer[offset] << 8) + buffer[offset + 1]);
}

public static int DecodeInt32(Span<byte> buffer, int offset)
public static unsafe ushort DecodeUInt16(byte* buffer, int offset)
{
var slice = buffer.Slice(offset);
return (ushort)((buffer[offset] << 8) + buffer[offset + 1]);
}

public static unsafe int DecodeInt32(ArraySegment<byte> segment, int offset)
{
fixed (byte* buffer = segment.Array)
{
byte* ptr = buffer + segment.Offset + offset;

return DecodeInt32(buffer, 0);
}
}

public static unsafe int DecodeInt32(byte* buffer, int offset)
{
buffer += offset;

return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
}

public static unsafe int DecodeInt32(byte[] buffer, int offset)
{
return (buffer[offset] << 24) | (buffer[offset + 1] << 16) | (buffer[offset + 2] << 8) | buffer[offset + 3];
}

return (slice[0] << 24) | (slice[1] << 16) | (slice[2] << 8) | slice[3];
public static unsafe ulong DecodeUInt64(byte[] buffer, int offset)
{
fixed (byte* ptr = buffer)
{
return DecodeUInt64(ptr, offset);
}
}

public static unsafe ulong DecodeUInt64(Span<byte> buffer, int offset)
public static unsafe ulong DecodeUInt64(byte* buffer, int offset)
{
var slice = buffer.Slice(offset);
buffer += offset;

var part1 = (uint)((slice[0] << 24) | (slice[1] << 16) | (slice[2] << 8) | slice[3]);
var part2 = (uint)((slice[4] << 24) | (slice[5] << 16) | (slice[6] << 8) | slice[7]);
var part1 = (uint)((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]);
var part2 = (uint)((buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]);

return ((ulong)part1 << 32) | part2;
}

public static unsafe void EncodeUInt16(uint value, Span<byte> buffer, int offset)
public static unsafe void EncodeUInt16(uint value, byte[] buffer, int offset)
{
fixed (byte* bufferPtr = buffer)
{
EncodeUInt16(value, bufferPtr, offset);
}
}

public static unsafe void EncodeUInt16(uint value, byte* buffer, int offset)
{
var slice = buffer.Slice(offset);
byte* ptr = buffer + offset;

slice[0] = (byte)(value >> 8);
slice[1] = (byte)(value & 255);
ptr[0] = (byte)(value >> 8);
ptr[1] = (byte)(value & 255);
}

public static unsafe void EncodeUInt32(uint value, Span<byte> buffer, int offset)
public static unsafe void EncodeUInt32(uint value, byte[] buffer, int offset)
{
var slice = buffer.Slice(offset);
fixed (byte* bufferPtr = buffer)
{
EncodeUInt32(value, bufferPtr, offset);
}
}

public static unsafe void EncodeUInt32(uint value, byte* buffer, int offset)
{
byte* ptr = buffer + offset;

slice[0] = (byte)(value >> 24);
slice[1] = (byte)(value >> 16);
slice[2] = (byte)(value >> 8);
slice[3] = (byte)(value & 255);
ptr[0] = (byte)(value >> 24);
ptr[1] = (byte)(value >> 16);
ptr[2] = (byte)(value >> 8);
ptr[3] = (byte)(value & 255);
}

public static unsafe void EncodeUInt64(ulong value, Span<byte> buffer, int offset)
public static unsafe void EncodeUInt64(ulong value, byte[] buffer, int offset)
{
var slice = buffer.Slice(offset);
fixed (byte* bufferPtr = buffer)
{
EncodeUInt64(value, bufferPtr, offset);
}
}

slice[0] = (byte)(value >> 56);
slice[1] = (byte)(value >> 48);
slice[2] = (byte)(value >> 40);
slice[3] = (byte)(value >> 32);
slice[4] = (byte)(value >> 24);
slice[5] = (byte)(value >> 16);
slice[6] = (byte)(value >> 8);
slice[7] = (byte)(value & 255);
public static unsafe void EncodeUInt64(ulong value, byte* buffer, int offset)
{
byte* ptr = buffer + offset;

ptr[0] = (byte)(value >> 56);
ptr[1] = (byte)(value >> 48);
ptr[2] = (byte)(value >> 40);
ptr[3] = (byte)(value >> 32);
ptr[4] = (byte)(value >> 24);
ptr[5] = (byte)(value >> 16);
ptr[6] = (byte)(value >> 8);
ptr[7] = (byte)(value & 255);
}

public static byte[] EncodeKey(string key)
Expand Down
30 changes: 16 additions & 14 deletions Enyim.Caching/Memcached/Protocol/Binary/BinaryResponse.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.Diagnostics;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;

namespace Enyim.Caching.Memcached.Protocol.Binary
Expand Down Expand Up @@ -64,7 +64,7 @@ public unsafe bool Read(PooledSocket socket)
if (dataLength > 0)
{
var data = new byte[dataLength];
socket.Read(data, 0, dataLength);
socket.Read(data, 0, dataLength);

this.Extra = new ArraySegment<byte>(data, 0, extraLength);
this.Data = new ArraySegment<byte>(data, extraLength, data.Length - extraLength);
Expand Down Expand Up @@ -207,22 +207,24 @@ private void DoDecodeBody(AsyncIOArgs asyncEvent)
if (this.shouldCallNext) this.next(true);
}


private void DeserializeHeader(Span<byte> header, out int dataLength, out int extraLength)
private unsafe void DeserializeHeader(byte[] header, out int dataLength, out int extraLength)
{
if (header[0] != MAGIC_VALUE)
throw new InvalidOperationException("Expected magic value " + MAGIC_VALUE + ", received: " + header[0]);
fixed (byte* buffer = header)
{
if (buffer[0] != MAGIC_VALUE)
throw new InvalidOperationException("Expected magic value " + MAGIC_VALUE + ", received: " + buffer[0]);

this.DataType = header[HEADER_DATATYPE];
this.Opcode = header[HEADER_OPCODE];
this.StatusCode = BinaryConverter.DecodeUInt16(header, HEADER_STATUS);
this.DataType = buffer[HEADER_DATATYPE];
this.Opcode = buffer[HEADER_OPCODE];
this.StatusCode = BinaryConverter.DecodeUInt16(buffer, HEADER_STATUS);

this.KeyLength = BinaryConverter.DecodeUInt16(header, HEADER_KEY);
this.CorrelationId = BinaryConverter.DecodeInt32(header, HEADER_OPAQUE);
this.CAS = BinaryConverter.DecodeUInt64(header, HEADER_CAS);
this.KeyLength = BinaryConverter.DecodeUInt16(buffer, HEADER_KEY);
this.CorrelationId = BinaryConverter.DecodeInt32(buffer, HEADER_OPAQUE);
this.CAS = BinaryConverter.DecodeUInt64(buffer, HEADER_CAS);

dataLength = BinaryConverter.DecodeInt32(header, HEADER_BODY);
extraLength = header[HEADER_EXTRA];
dataLength = BinaryConverter.DecodeInt32(buffer, HEADER_BODY);
extraLength = buffer[HEADER_EXTRA];
}
}

private void LogExecutionTime(string title, DateTime startTime, int thresholdMs)
Expand Down
3 changes: 1 addition & 2 deletions Enyim.Caching/Memcached/Protocol/Binary/GetOperation.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Text;
using Enyim.Caching.Memcached.Results;
Expand Down Expand Up @@ -38,7 +37,7 @@ protected override IOperationResult ProcessResponse(BinaryResponse response)

if (status == 0)
{
int flags = BinaryConverter.DecodeInt32(response.Extra.AsSpan(), 0);
int flags = BinaryConverter.DecodeInt32(response.Extra, 0);
this.result = new CacheItem((ushort)flags, response.Data);
this.Cas = response.CAS;

Expand Down
Loading