Skip to content

Commit 5721c22

Browse files
committed
move repetitive logic to ExpiryToken type (potentially also useful from other use-cases)
1 parent ae9e389 commit 5721c22

3 files changed

Lines changed: 299 additions & 143 deletions

File tree

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System;
2+
3+
namespace StackExchange.Redis;
4+
5+
internal partial class RedisDatabase
6+
{
7+
/// <summary>
8+
/// Parses, validates and represents, for example: "EX 10", "KEEPTTL" or "".
9+
/// </summary>
10+
internal readonly struct ExpiryToken
11+
{
12+
private static readonly ExpiryToken s_Persist = new(RedisLiterals.PERSIST), s_KeepTtl = new(RedisLiterals.KEEPTTL), s_Null = new(RedisValue.Null);
13+
14+
public RedisValue Operand { get; }
15+
public long Value { get; }
16+
public int Tokens => Value == long.MinValue ? (Operand.IsNull ? 0 : 1) : 2;
17+
public bool HasValue => Value != long.MinValue;
18+
public bool HasOperand => !Operand.IsNull;
19+
20+
public static ExpiryToken Persist(TimeSpan? expiry, bool persist)
21+
{
22+
if (expiry.HasValue)
23+
{
24+
if (persist) throw new ArgumentException("Cannot specify both expiry and persist", nameof(persist));
25+
return new(expiry.GetValueOrDefault()); // EX 10
26+
}
27+
28+
return persist ? s_Persist : s_Null; // PERSIST (or nothing)
29+
}
30+
31+
public static ExpiryToken KeepTtl(TimeSpan? expiry, bool keepTtl)
32+
{
33+
if (expiry.HasValue)
34+
{
35+
if (keepTtl) throw new ArgumentException("Cannot specify both expiry and keepTtl", nameof(keepTtl));
36+
return new(expiry.GetValueOrDefault()); // EX 10
37+
}
38+
39+
return keepTtl ? s_KeepTtl : s_Null; // KEEPTTL (or nothing)
40+
}
41+
42+
private ExpiryToken(RedisValue operand, long value = long.MinValue)
43+
{
44+
Operand = operand;
45+
Value = value;
46+
}
47+
48+
public ExpiryToken(TimeSpan expiry)
49+
{
50+
long milliseconds = expiry.Ticks / TimeSpan.TicksPerMillisecond;
51+
var useSeconds = milliseconds % 1000 == 0;
52+
53+
Operand = useSeconds ? RedisLiterals.EX : RedisLiterals.PX;
54+
Value = useSeconds ? (milliseconds / 1000) : milliseconds;
55+
}
56+
57+
public ExpiryToken(DateTime expiry)
58+
{
59+
long milliseconds = GetUnixTimeMilliseconds(expiry);
60+
var useSeconds = milliseconds % 1000 == 0;
61+
62+
Operand = useSeconds ? RedisLiterals.EXAT : RedisLiterals.PXAT;
63+
Value = useSeconds ? (milliseconds / 1000) : milliseconds;
64+
}
65+
66+
public override string ToString() => Tokens switch
67+
{
68+
2 => $"{Operand} {Value}",
69+
1 => Operand.ToString(),
70+
_ => "",
71+
};
72+
73+
public override int GetHashCode() => throw new NotSupportedException();
74+
public override bool Equals(object? obj) => throw new NotSupportedException();
75+
}
76+
}

0 commit comments

Comments
 (0)