Skip to content

Commit 579133b

Browse files
committed
ack experimental
1 parent ebce7eb commit 579133b

File tree

7 files changed

+129
-73
lines changed

7 files changed

+129
-73
lines changed

docs/exp/SER001.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
At the current time, [Redis documents that](https://redis.io/docs/latest/commands/vadd/):
2+
3+
> Vector set is a new data type that is currently in preview and may be subject to change.
4+
5+
As such, the corresponding library feature must also be considered subject to change:
6+
7+
1. Existing bindings may cease working correctly if the underlying server API changes.
8+
2. Changes to the server API may require changes to the library API, manifesting in either/both of build-time
9+
or run-time breaks.
10+
11+
While this seems *unlikely*, it must be considered a possibility. If you acknowledge this, you can suppress
12+
this warning by adding the following to your `csproj` file:
13+
14+
```xml
15+
<NoWarn>$(NoWarn);SER001</NoWarn>
16+
```
17+
18+
or more granularly / locally in C#:
19+
20+
``` c#
21+
#pragma warning disable SER001
22+
```

src/StackExchange.Redis/ResultProcessor.cs

Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ public static readonly ResultProcessor<Lease<byte>>
102102

103103
public static readonly ResultProcessor<RedisValue[]>
104104
RedisValueArray = new RedisValueArrayProcessor();
105+
public static readonly ResultProcessor<Lease<RedisValue>?>
106+
RedisValueLease = new RedisValueLeaseProcessor();
105107

106108
public static readonly ResultProcessor<long[]>
107109
Int64Array = new Int64ArrayProcessor();
@@ -1707,6 +1709,64 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
17071709
}
17081710
}
17091711

1712+
private abstract class LeaseProcessor<T> : ResultProcessor<Lease<T>?>
1713+
{
1714+
protected sealed override bool SetResultCore(PhysicalConnection connection, Message message, in RawResult result)
1715+
{
1716+
if (result.Resp2TypeArray != ResultType.Array)
1717+
{
1718+
return false; // not an array
1719+
}
1720+
1721+
// deal with null
1722+
if (result.IsNull)
1723+
{
1724+
SetResult(message, Lease<T>.Empty);
1725+
return true;
1726+
}
1727+
1728+
// lease and fill
1729+
var items = result.GetItems();
1730+
var length = checked((int)items.Length);
1731+
var lease = Lease<T>.Create(length, clear: false); // note this handles zero nicely
1732+
var target = lease.Span;
1733+
int index = 0;
1734+
foreach (ref RawResult item in items)
1735+
{
1736+
if (!TryParse(item, out target[index++]))
1737+
{
1738+
// something went wrong; recycle and quit
1739+
lease.Dispose();
1740+
return false;
1741+
}
1742+
}
1743+
Debug.Assert(index == length, "length mismatch");
1744+
SetResult(message, lease);
1745+
return true;
1746+
}
1747+
1748+
protected abstract bool TryParse(in RawResult raw, out T parsed);
1749+
}
1750+
1751+
private sealed class RedisValueLeaseProcessor : LeaseProcessor<RedisValue>
1752+
{
1753+
protected override bool TryParse(in RawResult raw, out RedisValue parsed)
1754+
{
1755+
parsed = raw.AsRedisValue();
1756+
return true;
1757+
}
1758+
}
1759+
1760+
private sealed class LeaseFloat32Processor : LeaseProcessor<float>
1761+
{
1762+
protected override bool TryParse(in RawResult raw, out float parsed)
1763+
{
1764+
var result = raw.TryGetDouble(out double val);
1765+
parsed = (float)val;
1766+
return result;
1767+
}
1768+
}
1769+
17101770
private sealed class Int64ArrayProcessor : ResultProcessor<long[]>
17111771
{
17121772
protected override bool SetResultCore(PhysicalConnection connection, Message message, in RawResult result)
@@ -2116,47 +2176,6 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
21162176
}
21172177
}
21182178

2119-
private sealed class LeaseFloat32Processor : ResultProcessor<Lease<float>?>
2120-
{
2121-
protected override bool SetResultCore(PhysicalConnection connection, Message message, in RawResult result)
2122-
{
2123-
switch (result.Resp2TypeArray)
2124-
{
2125-
case ResultType.Array:
2126-
if (result.IsNull)
2127-
{
2128-
SetResult(message, null);
2129-
return true;
2130-
}
2131-
2132-
var items = result.GetItems();
2133-
if (items.IsEmpty)
2134-
{
2135-
SetResult(message, Lease<float>.Empty);
2136-
return true;
2137-
}
2138-
2139-
var length = checked((int)items.Length);
2140-
var lease = Lease<float>.Create(length, clear: false);
2141-
var target = lease.Span;
2142-
int index = 0;
2143-
foreach (ref RawResult item in items)
2144-
{
2145-
if (!item.TryGetDouble(out double val)) break;
2146-
target[index++] = (float)val;
2147-
}
2148-
if (index == length)
2149-
{
2150-
SetResult(message, lease);
2151-
return true;
2152-
}
2153-
lease.Dispose(); // something went wrong; recycle
2154-
break;
2155-
}
2156-
return false;
2157-
}
2158-
}
2159-
21602179
private sealed class ScriptResultProcessor : ResultProcessor<RedisResult>
21612180
{
21622181
public override bool SetResult(PhysicalConnection connection, Message message, in RawResult result)

src/StackExchange.Redis/VectorQuantizationType.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
13
namespace StackExchange.Redis;
24

35
/// <summary>
46
/// Specifies the quantization type for vectors in a vectorset.
57
/// </summary>
8+
[Experimental(Experiments.VectorSets, UrlFormat = Experiments.UrlFormat)]
69
public enum VectorQuantizationType
710
{
811
/// <summary>

src/StackExchange.Redis/VectorSetAddMessage.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Runtime.CompilerServices;
32
using System.Runtime.InteropServices;
43
using System.Threading;
54

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,47 @@
11
using System;
2+
using System.Diagnostics.CodeAnalysis;
23

3-
namespace StackExchange.Redis
4+
namespace StackExchange.Redis;
5+
6+
/// <summary>
7+
/// Contains metadata information about a vectorset returned by VINFO command.
8+
/// </summary>
9+
[Experimental(Experiments.VectorSets, UrlFormat = Experiments.UrlFormat)]
10+
public readonly struct VectorSetInfo(
11+
VectorQuantizationType quantizationType,
12+
int dimension,
13+
long length,
14+
int maxLevel,
15+
long vectorSetUid,
16+
long hnswMaxNodeUid)
417
{
518
/// <summary>
6-
/// Contains metadata information about a vectorset returned by VINFO command.
19+
/// The quantization type used for vectors in this vectorset.
720
/// </summary>
8-
public readonly struct VectorSetInfo(VectorQuantizationType quantizationType, int dimension, long length, int maxLevel, long vectorSetUid, long hnswMaxNodeUid)
9-
{
10-
/// <summary>
11-
/// The quantization type used for vectors in this vectorset.
12-
/// </summary>
13-
public VectorQuantizationType QuantizationType { get; } = quantizationType;
21+
public VectorQuantizationType QuantizationType { get; } = quantizationType;
1422

15-
/// <summary>
16-
/// The number of dimensions in each vector.
17-
/// </summary>
18-
public int Dimension { get; } = dimension;
23+
/// <summary>
24+
/// The number of dimensions in each vector.
25+
/// </summary>
26+
public int Dimension { get; } = dimension;
1927

20-
/// <summary>
21-
/// The number of elements (cardinality) in the vectorset.
22-
/// </summary>
23-
public long Length { get; } = length;
28+
/// <summary>
29+
/// The number of elements (cardinality) in the vectorset.
30+
/// </summary>
31+
public long Length { get; } = length;
2432

25-
/// <summary>
26-
/// The maximum level in the HNSW graph structure.
27-
/// </summary>
28-
public int MaxLevel { get; } = maxLevel;
33+
/// <summary>
34+
/// The maximum level in the HNSW graph structure.
35+
/// </summary>
36+
public int MaxLevel { get; } = maxLevel;
2937

30-
/// <summary>
31-
/// The unique identifier for this vectorset.
32-
/// </summary>
33-
public long VectorSetUid { get; } = vectorSetUid;
38+
/// <summary>
39+
/// The unique identifier for this vectorset.
40+
/// </summary>
41+
public long VectorSetUid { get; } = vectorSetUid;
3442

35-
/// <summary>
36-
/// The maximum node unique identifier in the HNSW graph.
37-
/// </summary>
38-
public long HnswMaxNodeUid { get; } = hnswMaxNodeUid;
39-
}
43+
/// <summary>
44+
/// The maximum node unique identifier in the HNSW graph.
45+
/// </summary>
46+
public long HnswMaxNodeUid { get; } = hnswMaxNodeUid;
4047
}

src/StackExchange.Redis/VectorSetLink.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
namespace StackExchange.Redis;
1+
using System.Diagnostics.CodeAnalysis;
2+
3+
namespace StackExchange.Redis;
24

35
/// <summary>
46
/// Represents a link/connection between members in a vectorset with similarity score.
57
/// Used by VLINKS command with WITHSCORES option.
68
/// </summary>
9+
[Experimental(Experiments.VectorSets, UrlFormat = Experiments.UrlFormat)]
710
public readonly struct VectorSetLink(RedisValue member, double score)
811
{
912
/// <summary>

src/StackExchange.Redis/VectorSimilarityResult.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
namespace StackExchange.Redis;
1+
using System.Diagnostics.CodeAnalysis;
2+
3+
namespace StackExchange.Redis;
24

35
/// <summary>
46
/// Represents a result from vector similarity search operations.
57
/// </summary>
8+
[Experimental(Experiments.VectorSets, UrlFormat = Experiments.UrlFormat)]
69
public readonly struct VectorSimilarityResult(RedisValue member, double score = double.NaN, string? attributesJson = null)
710
{
811
/// <summary>

0 commit comments

Comments
 (0)