Skip to content

Commit c310c6a

Browse files
committed
ensure integration tests use the VectorData API
1 parent 62a5ee7 commit c310c6a

File tree

3 files changed

+18
-14
lines changed

3 files changed

+18
-14
lines changed

src/NRedisStack/PublicAPI/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
NRedisStack.Search.Parameters
22
static NRedisStack.Search.Parameters.From<T>(T obj) -> System.Collections.Generic.IReadOnlyDictionary<string!, object!>!
3+
[NRS001]abstract NRedisStack.Search.VectorData.AsRedisValue() -> StackExchange.Redis.RedisValue
34
[NRS001]abstract NRedisStack.Search.VectorData<T>.Dispose() -> void
45
[NRS001]abstract NRedisStack.Search.VectorData<T>.Span.get -> System.Span<T>
56
[NRS001]const NRedisStack.Search.HybridSearchQuery.Fields.Key = "@__key" -> string!

src/NRedisStack/Search/VectorData.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ internal sealed class VectorBytesData(int byteLength) : VectorData<T>
1818
{
1919
private byte[]? _oversized = ArrayPool<byte>.Shared.Rent(byteLength);
2020
public override Span<T> Span => MemoryMarshal.Cast<byte, T>(Array.AsSpan(0, byteLength));
21-
internal override object GetSingleArg() => (RedisValue)new ReadOnlyMemory<byte>(Array, 0, byteLength);
2221

2322
private byte[] Array => _oversized ?? ThrowDisposed();
2423
static byte[] ThrowDisposed() => throw new ObjectDisposedException(nameof(VectorData));
@@ -28,6 +27,7 @@ public override void Dispose()
2827
_oversized = null;
2928
if (tmp is not null) ArrayPool<byte>.Shared.Return(tmp);
3029
}
30+
public override RedisValue AsRedisValue() => (RedisValue)new ReadOnlyMemory<byte>(Array, 0, byteLength);
3131
}
3232

3333
public abstract void Dispose();
@@ -38,7 +38,8 @@ public abstract class VectorData
3838
{
3939
/// <summary>
4040
/// Lease a vector that can hold values of <typeparamref name="T"/>.
41-
/// No quantization occurs - the data is transmitted as the raw bytes of the corresponding size.
41+
/// No quantization occurs - the data is transmitted as the raw bytes of the corresponding size; for
42+
/// example, to use FLOAT16 encoding, the <c>Half</c> type might be used.
4243
/// </summary>
4344
/// <param name="dimension">The number of values to be held.</param>
4445
/// <typeparam name="T">The data type to be represented</typeparam>
@@ -65,6 +66,11 @@ private protected VectorData()
6566
{
6667
}
6768

69+
/// <summary>
70+
/// Gets the underlying payload of this vector as a <see cref="RedisValue"/>.
71+
/// </summary>
72+
public abstract RedisValue AsRedisValue();
73+
6874
/// <summary>
6975
/// A raw vector payload.
7076
/// </summary>
@@ -88,14 +94,14 @@ private protected VectorData()
8894
/// <inheritdoc cref="Parameter"/>
8995
public static implicit operator VectorData(string name) => new VectorParameter(name);
9096

91-
internal abstract object GetSingleArg();
97+
internal virtual object GetSingleArg() => AsRedisValue();
9298

9399
/// <inheritdoc/>
94100
public override string ToString() => GetType().Name;
95101

96102
private sealed class VectorDataRaw(ReadOnlyMemory<byte> bytes) : VectorData
97103
{
98-
internal override object GetSingleArg() => (RedisValue)bytes;
104+
public override RedisValue AsRedisValue() => (RedisValue)bytes;
99105
}
100106

101107
private sealed class VectorParameter : VectorData
@@ -110,7 +116,8 @@ public VectorParameter(string name)
110116
}
111117

112118
public override string ToString() => name;
113-
internal override object GetSingleArg() => name;
119+
internal override object GetSingleArg() => name; // note type is string, not RedisValue
120+
public override RedisValue AsRedisValue() => name;
114121
}
115122

116123
private protected static void ThrowBigEndian() =>

tests/NRedisStack.Tests/Search/HybridSearchIntegrationTests.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,29 +54,25 @@ private async Task<Api> CreateIndexAsync(string endpointId, [CallerMemberName] s
5454
if (populate)
5555
{
5656
#if NET
57-
Task last = Task.CompletedTask;
5857
var rand = new Random(12345);
5958
string[] tags = ["foo", "bar", "blap"];
59+
using var vectorData = VectorData.Lease<Half>(V1DIM);
6060
for (int i = 0; i < 16; i++)
6161
{
62-
byte[] vec = new byte[V1DIM * sizeof(ushort)];
63-
var halves = MemoryMarshal.Cast<byte, Half>(vec);
64-
for (int j = 1; j < V1DIM; j++)
62+
foreach (ref Half val in vectorData.Span)
6563
{
66-
halves[j] = (Half)rand.NextDouble();
64+
val = (Half)rand.NextDouble();
6765
}
6866

6967
HashEntry[] entry =
7068
[
7169
new("text1", $"Search entry {i}"),
7270
new("tag1", tags[rand.Next(tags.Length)]),
7371
new("numeric1", rand.Next(0, 32)),
74-
new("vector1", vec)
72+
new("vector1", vectorData.AsRedisValue())
7573
];
76-
last = db.HashSetAsync($"{index}_entry{i}", entry);
74+
await db.HashSetAsync($"{index}_entry{i}", entry);
7775
}
78-
79-
await last;
8076
#else
8177
// throw SkipException.ForSkip("FP16 not supported");
8278
return default;

0 commit comments

Comments
 (0)