Commit 6b351b86 authored by Marc Gravell's avatar Marc Gravell

improve TypedRedisValue.MultiBulk API - doesn't require a ToArray() now

parent 4de58246
...@@ -359,7 +359,7 @@ protected virtual TypedRedisValue Keys(RedisClient client, RedisRequest request) ...@@ -359,7 +359,7 @@ protected virtual TypedRedisValue Keys(RedisClient client, RedisRequest request)
found.Add(TypedRedisValue.BulkString(key.AsRedisValue())); found.Add(TypedRedisValue.BulkString(key.AsRedisValue()));
} }
if (found == null) return TypedRedisValue.EmptyArray; if (found == null) return TypedRedisValue.EmptyArray;
return TypedRedisValue.MultiBulk(found.ToArray()); return TypedRedisValue.MultiBulk(found);
} }
protected virtual IEnumerable<RedisKey> Keys(int database, RedisKey pattern) => throw new NotSupportedException(); protected virtual IEnumerable<RedisKey> Keys(int database, RedisKey pattern) => throw new NotSupportedException();
......
using System; using System;
using System.Buffers; using System.Buffers;
using System.Collections.Generic;
namespace StackExchange.Redis namespace StackExchange.Redis
{ {
...@@ -8,8 +9,15 @@ namespace StackExchange.Redis ...@@ -8,8 +9,15 @@ namespace StackExchange.Redis
/// </summary> /// </summary>
public readonly struct TypedRedisValue public readonly struct TypedRedisValue
{ {
// note: if this ever becomes exposed on the public API, it should be made so that it clears;
// can't trust external callers to clear the space, and using recycle without that is dangerous
internal static TypedRedisValue Rent(int count, out Span<TypedRedisValue> span) internal static TypedRedisValue Rent(int count, out Span<TypedRedisValue> span)
{ {
if (count == 0)
{
span = default;
return EmptyArray;
}
var arr = ArrayPool<TypedRedisValue>.Shared.Rent(count); var arr = ArrayPool<TypedRedisValue>.Shared.Rent(count);
span = new Span<TypedRedisValue>(arr, 0, count); span = new Span<TypedRedisValue>(arr, 0, count);
return new TypedRedisValue(arr, count); return new TypedRedisValue(arr, count);
...@@ -63,8 +71,8 @@ public static TypedRedisValue SimpleString(string value) ...@@ -63,8 +71,8 @@ public static TypedRedisValue SimpleString(string value)
public static TypedRedisValue OK { get; } = SimpleString("OK"); public static TypedRedisValue OK { get; } = SimpleString("OK");
internal static TypedRedisValue Zero { get; } = Integer(0); internal static TypedRedisValue Zero { get; } = Integer(0);
internal static TypedRedisValue One { get; } = Integer(1); internal static TypedRedisValue One { get; } = Integer(1);
internal static TypedRedisValue NullArray { get; } = MultiBulk(null); internal static TypedRedisValue NullArray { get; } = new TypedRedisValue((TypedRedisValue[])null, 0);
internal static TypedRedisValue EmptyArray { get; } = MultiBulk(Array.Empty<TypedRedisValue>()); internal static TypedRedisValue EmptyArray { get; } = new TypedRedisValue(Array.Empty<TypedRedisValue>(), 0);
/// <summary> /// <summary>
/// Gets the array elements as a span /// Gets the array elements as a span
...@@ -99,16 +107,27 @@ public static TypedRedisValue Integer(long value) ...@@ -99,16 +107,27 @@ public static TypedRedisValue Integer(long value)
=> new TypedRedisValue(value, ResultType.Integer); => new TypedRedisValue(value, ResultType.Integer);
/// <summary> /// <summary>
/// Initialize a TypedRedisValue from an array /// Initialize a TypedRedisValue from a span
/// </summary> /// </summary>
public static TypedRedisValue MultiBulk(TypedRedisValue[] items) public static TypedRedisValue MultiBulk(ReadOnlySpan<TypedRedisValue> items)
=> new TypedRedisValue(items, items == null ? 0 : items.Length); {
if (items.IsEmpty) return EmptyArray;
var result = Rent(items.Length, out var span);
items.CopyTo(span);
return result;
}
/// <summary> /// <summary>
/// Initialize a TypedRedisValue from an oversized array /// Initialize a TypedRedisValue from a collection
/// </summary> /// </summary>
public static TypedRedisValue MultiBulk(TypedRedisValue[] oversizedItems, int count) public static TypedRedisValue MultiBulk(ICollection<TypedRedisValue> items)
=> new TypedRedisValue(oversizedItems, count); {
if (items == null) return NullArray;
int count = items.Count;
if (count == 0) return EmptyArray;
var arr = ArrayPool<TypedRedisValue>.Shared.Rent(count);
items.CopyTo(arr, 0);
return new TypedRedisValue(arr, count);
}
/// <summary> /// <summary>
/// Initialize a TypedRedisValue that represents a bulk string /// Initialize a TypedRedisValue that represents a bulk string
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment