Skip to content

Commit 5063091

Browse files
authored
Simplify Indices type and API (#6455)
1 parent 584edb8 commit 5063091

File tree

11 files changed

+275
-106
lines changed

11 files changed

+275
-106
lines changed

src/Elastic.Clients.Elasticsearch/Common/Infer/Indices/Indices.cs

Lines changed: 116 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Collections;
67
using System.Collections.Generic;
78
using System.Diagnostics;
89
using System.Linq;
@@ -14,132 +15,178 @@ namespace Elastic.Clients.Elasticsearch;
1415

1516
[DebuggerDisplay("{DebugDisplay,nq}")]
1617
[JsonConverter(typeof(IndicesJsonConverter))]
17-
public sealed class Indices : Union<Indices.AllIndicesMarker, Indices.ManyIndices>, IUrlParameter
18+
public sealed class Indices : IUrlParameter, IEnumerable<IndexName>, IEquatable<Indices>
1819
{
19-
internal Indices(AllIndicesMarker all) : base(all) { }
20+
private static readonly HashSet<IndexName> AllIndexList = new() { AllValue };
2021

21-
internal Indices(ManyIndices indices) : base(indices) { }
22+
internal const string AllValue = "_all";
23+
internal const string WildcardValue = "*";
2224

23-
internal Indices(IEnumerable<IndexName> indices) : base(new ManyIndices(indices)) { }
25+
private readonly HashSet<IndexName>? _indices;
26+
private readonly bool _isAllIndices;
2427

25-
internal Indices(IEnumerable<string> indices) : base(new ManyIndices(indices)) { }
28+
internal Indices(IndexName indexName)
29+
{
30+
if (indexName.Equals(AllValue) || indexName.Equals(WildcardValue))
31+
{
32+
_isAllIndices = true;
33+
_indices = AllIndexList;
34+
return;
35+
}
2636

27-
/// <summary>All indices. Represents _all</summary>
28-
public static Indices All { get; } = new Indices(new AllIndicesMarker());
37+
_indices = new HashSet<IndexName>
38+
{
39+
indexName
40+
};
41+
}
2942

30-
/// <inheritdoc cref="All" />
31-
public static Indices AllIndices { get; } = All;
43+
internal Indices(IEnumerable<IndexName> indices)
44+
{
45+
var enumerated = indices.NotEmpty(nameof(indices));
3246

33-
private string DebugDisplay => Match(
34-
all => "_all",
35-
types => $"Count: {types.Indices.Count} [" + string.Join(",", types.Indices.Select((t, i) => $"({i + 1}: {t.DebugDisplay})")) + "]"
36-
);
47+
foreach (var index in enumerated)
48+
{
49+
if (index.Equals(AllValue) || index.Equals(WildcardValue))
50+
{
51+
_isAllIndices = true;
52+
_indices = AllIndexList;
53+
return;
54+
}
55+
}
3756

38-
public override string ToString() => DebugDisplay;
57+
_indices = new HashSet<IndexName>(enumerated);
58+
}
3959

40-
string IUrlParameter.GetString(ITransportConfiguration? settings) => Match(
41-
all => "_all",
42-
many =>
43-
{
44-
if (settings is not IElasticsearchClientSettings clientSettings)
45-
throw new Exception(
46-
"Tried to pass index names on querysting but it could not be resolved because no nest settings are available");
60+
internal Indices(IEnumerable<string> indices)
61+
{
62+
var enumerated = indices.NotEmpty(nameof(indices));
4763

48-
var infer = clientSettings.Inferrer;
49-
var indices = many.Indices.Select(i => infer.IndexName(i)).Distinct();
50-
return string.Join(",", indices);
64+
foreach (var index in enumerated)
65+
{
66+
if (index.Equals(AllValue) || index.Equals(WildcardValue))
67+
{
68+
_isAllIndices = true;
69+
_indices = AllIndexList;
70+
return;
71+
}
5172
}
52-
);
5373

54-
public static IndexName Index(string index) => index;
74+
_indices = new HashSet<IndexName>(enumerated.Select(s => (IndexName)s));
75+
}
5576

56-
public static IndexName Index(IndexName index) => index;
77+
public Indices And<T>()
78+
{
79+
if (_isAllIndices)
80+
return this;
5781

58-
public static IndexName Index<T>() => typeof(T);
82+
_indices.Add(typeof(T));
83+
84+
return this;
85+
}
86+
87+
internal HashSet<IndexName> IndexNames => _indices;
88+
89+
public static Indices All { get; } = new Indices(AllValue);
90+
91+
private string DebugDisplay => _isAllIndices ? "_all" : $"Count: {_indices.Count} [" + string.Join(",", _indices.Select((t, i) => $"({i + 1}: {t.DebugDisplay})")) + "]";
5992

60-
public static ManyIndices Index(IEnumerable<IndexName> indices) => new(indices);
93+
public override string ToString() => DebugDisplay;
94+
95+
string IUrlParameter.GetString(ITransportConfiguration? settings)
96+
{
97+
if (settings is not IElasticsearchClientSettings clientSettings)
98+
throw new Exception(
99+
"Tried to pass index names on querysting but it could not be resolved because no nest settings are available.");
100+
101+
if (_isAllIndices)
102+
return "_all";
61103

62-
public static ManyIndices Index(params IndexName[] indices) => new(indices);
104+
var inferrer = clientSettings.Inferrer;
63105

64-
public static ManyIndices Index(IEnumerable<string> indices) => new(indices);
106+
if (_indices.Count == 1)
107+
{
108+
var value = inferrer.IndexName(_indices.First());
109+
return value;
110+
}
111+
112+
var indices = _indices.Select(i => inferrer.IndexName(i));
113+
return string.Join(",", indices);
114+
}
65115

66-
public static ManyIndices Index(params string[] indices) => new(indices);
116+
public static IndexName Index(string index) => index;
117+
118+
public static IndexName Index(IndexName index) => index;
119+
120+
public static IndexName Index<T>() => typeof(T);
67121

68122
public static Indices Parse(string indicesString)
69123
{
70124
if (indicesString.IsNullOrEmptyCommaSeparatedList(out var indices))
71125
return null;
72126

73-
return indices.Contains("_all") ? All : Index(indices.Select(i => (IndexName)i));
127+
return indices.Contains(AllValue) || indices.Contains(WildcardValue) ? All : new Indices(indices);
74128
}
75129

76130
public static implicit operator Indices(string indicesString) => Parse(indicesString);
77131

78-
public static implicit operator Indices(ManyIndices many) => many == null ? null : new Indices(many);
132+
public static implicit operator Indices(string[] indices) => indices.IsEmpty() ? null : new Indices(indices);
79133

80-
public static implicit operator Indices(string[] many) => many.IsEmpty() ? null : new ManyIndices(many);
134+
public static implicit operator Indices(IndexName[] indices) => indices.IsEmpty() ? null : new Indices(indices);
81135

82-
public static implicit operator Indices(IndexName[] many) => many.IsEmpty() ? null : new ManyIndices(many);
136+
public static implicit operator Indices(IndexName index) => index == null ? null : new Indices(new[] { index });
83137

84-
public static implicit operator Indices(IndexName index) => index == null ? null : new ManyIndices(new[] { index });
85-
86-
public static implicit operator Indices(Type type) => type == null ? null : new ManyIndices(new IndexName[] { type });
138+
public static implicit operator Indices(Type type) => type == null ? null : new Indices(new IndexName[] { type });
87139

88140
public static bool operator ==(Indices left, Indices right) => Equals(left, right);
89141

90142
public static bool operator !=(Indices left, Indices right) => !Equals(left, right);
91143

144+
public bool Equals(Indices other) => EqualsAllIndices(IndexNames, other.IndexNames);
145+
92146
public override bool Equals(object obj)
93147
{
94-
if (!(obj is Indices other))
148+
if (obj is not Indices other)
95149
return false;
96150

97-
return Match(
98-
all => other.Match(a => true, m => false),
99-
many => other.Match(
100-
a => false,
101-
m => EqualsAllIndices(m.Indices, many.Indices)
102-
)
103-
);
151+
return EqualsAllIndices(IndexNames, other.IndexNames);
104152
}
105153

106-
private static bool EqualsAllIndices(IReadOnlyList<IndexName> thisIndices, IReadOnlyList<IndexName> otherIndices)
154+
private static bool EqualsAllIndices(HashSet<IndexName> thisIndices, HashSet<IndexName> otherIndices)
107155
{
108156
if (thisIndices == null && otherIndices == null)
109157
return true;
158+
110159
if (thisIndices == null || otherIndices == null)
111160
return false;
112161

113162
return thisIndices.Count == otherIndices.Count && !thisIndices.Except(otherIndices).Any();
114163
}
115164

116-
public override int GetHashCode() => Match(
117-
all => "_all".GetHashCode(),
118-
many => string.Concat(many.Indices.OrderBy(i => i.ToString())).GetHashCode()
119-
);
120-
121-
public class AllIndicesMarker
122-
{
123-
internal AllIndicesMarker() { }
124-
}
125-
126-
public class ManyIndices
165+
public override int GetHashCode()
127166
{
128-
private readonly List<IndexName> _indices = new();
167+
var hashCodes = new List<int>(IndexNames.Count);
129168

130-
internal ManyIndices(IEnumerable<IndexName> indices) => _indices.AddRange(indices.NotEmpty(nameof(indices)));
131-
132-
internal ManyIndices(IEnumerable<string> indices) =>
133-
_indices.AddRange(indices.NotEmpty(nameof(indices)).Select(s => (IndexName)s));
169+
foreach (var item in IndexNames.OrderBy(s => s))
170+
{
171+
hashCodes.Add(item.GetHashCode());
172+
}
134173

135-
public IReadOnlyList<IndexName> Indices => _indices;
174+
hashCodes.Sort();
136175

137-
public ManyIndices And<T>()
176+
unchecked
138177
{
139-
_indices.Add(typeof(T));
140-
return this;
178+
var hash = 17;
179+
foreach (var hashCode in hashCodes)
180+
{
181+
hash = hash * 23 + hashCode;
182+
}
183+
return typeof(IndexName).GetHashCode() ^ hash;
141184
}
142185
}
186+
187+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
188+
189+
public IEnumerator<IndexName> GetEnumerator() => IndexNames.GetEnumerator();
143190
}
144191

145192
internal sealed class IndicesJsonConverter : JsonConverter<Indices>
@@ -178,14 +225,6 @@ public override void Write(Utf8JsonWriter writer, Indices value, JsonSerializerO
178225
return;
179226
}
180227

181-
switch (value.Tag)
182-
{
183-
case 0:
184-
writer.WriteStringValue("_all");
185-
break;
186-
case 1:
187-
writer.WriteStringValue(((IUrlParameter)value).GetString(_settings));
188-
break;
189-
}
228+
writer.WriteStringValue(((IUrlParameter)value).GetString(_settings));
190229
}
191230
}

src/Elastic.Clients.Elasticsearch/Common/Infer/Indices/IndicesExtensions.cs

Lines changed: 0 additions & 15 deletions
This file was deleted.

tests/Tests.Configuration/tests.default.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# tracked by git).
66

77
# mode either u (unit test), i (integration test) or m (mixed mode)
8-
mode: i
8+
mode: u
99
# the elasticsearch version that should be started
1010
# Can be a snapshot version of sonatype or "latest" to get the latest snapshot of sonatype
1111
elasticsearch_version: latest-8

tests/Tests/ClientConcepts/HighLevel/Inference/Equality/IndicesEqualityTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ [U] public void Eq()
1818
foreach (var t in equal)
1919
{
2020
(t == types).ShouldBeTrue(t);
21-
t.Should().Be(types);
21+
t.Should().BeEquivalentTo(types);
2222
}
2323

2424
(Indices.All == "_all").Should().BeTrue();
@@ -32,7 +32,7 @@ [U] public void NotEq()
3232
foreach (var t in notEqual)
3333
{
3434
(t != types).ShouldBeTrue(t);
35-
t.Should().NotBe(types);
35+
t.Should().NotBeEquivalentTo(types);
3636
}
3737
}
3838

tests/Tests/ClientConcepts/HighLevel/Inference/ImplicitConversionTests.cs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ [U] public void Fields()
5555
Implicit<Fields>((Field[])null).Should().BeNull();
5656
Implicit<Fields>("").Should().BeNull();
5757
Implicit<Fields>(" ").Should().BeNull();
58-
Implicit<Fields>(new string[] { }).Should().BeNull();
59-
Implicit<Fields>(new Expression[] { }).Should().BeNull();
60-
Implicit<Fields>(new PropertyInfo[] { }).Should().BeNull();
61-
Implicit<Fields>(new Field[] { }).Should().BeNull();
58+
Implicit<Fields>(Array.Empty<string>()).Should().BeNull();
59+
Implicit<Fields>(Array.Empty<Expression>()).Should().BeNull();
60+
Implicit<Fields>(Array.Empty<PropertyInfo>()).Should().BeNull();
61+
Implicit<Fields>(Array.Empty<Field>()).Should().BeNull();
6262
Implicit<Fields>(new Expression[] { null, null }).Should().BeNull();
6363
Implicit<Fields>(new PropertyInfo[] { null, null }).Should().BeNull();
6464
Implicit<Fields>(new Field[] { null, null }).Should().BeNull();
@@ -82,16 +82,15 @@ [U] public void IndexName()
8282
[U] public void Indices()
8383
{
8484
Implicit<Indices>((string)null).Should().BeNull();
85-
Implicit<Indices>((Indices.ManyIndices)null).Should().BeNull();
8685
Implicit<Indices>((string[])null).Should().BeNull();
8786
Implicit<Indices>((IndexName)null).Should().BeNull();
8887
Implicit<Indices>((IndexName[])null).Should().BeNull();
8988
Implicit<Indices>((IndexName)null).Should().BeNull();
9089
Implicit<Indices>("").Should().BeNull();
9190
Implicit<Indices>(" ").Should().BeNull();
9291
Implicit<Indices>(",, ,, ").Should().BeNull();
93-
Implicit<Indices>(new string[] { }).Should().BeNull();
94-
Implicit<Indices>(new IndexName[] { }).Should().BeNull();
92+
Implicit<Indices>(Array.Empty<string>()).Should().BeNull();
93+
Implicit<Indices>(Array.Empty<IndexName>()).Should().BeNull();
9594
Implicit<Indices>(new string[] { null, null }).Should().BeNull();
9695
Implicit<Indices>(new IndexName[] { null, null }).Should().BeNull();
9796
}
@@ -104,7 +103,7 @@ [U] public void Names()
104103
Implicit<Names>(",,").Should().BeNull();
105104
Implicit<Names>(", ,").Should().BeNull();
106105
Implicit<Names>(" ").Should().BeNull();
107-
Implicit<Names>(new string[] { }).Should().BeNull();
106+
Implicit<Names>(Array.Empty<string>()).Should().BeNull();
108107
Implicit<Names>(new string[] { null, null }).Should().BeNull();
109108
}
110109

@@ -116,7 +115,7 @@ [U] public void Routing()
116115
Implicit<Routing>(",,").Should().BeNull();
117116
Implicit<Routing>(", ,").Should().BeNull();
118117
Implicit<Routing>(" ").Should().BeNull();
119-
Implicit<Routing>(new string[] { }).Should().BeNull();
118+
Implicit<Routing>(Array.Empty<string>()).Should().BeNull();
120119
Implicit<Routing>(new string[] { null, null }).Should().BeNull();
121120
}
122121

@@ -138,7 +137,7 @@ [U] public void NodeId()
138137
Implicit<NodeIds>("").Should().BeNull();
139138
Implicit<NodeIds>(" ").Should().BeNull();
140139
Implicit<NodeIds>(" ,, , ,,").Should().BeNull();
141-
Implicit<NodeIds>(new string[] { }).Should().BeNull();
140+
Implicit<NodeIds>(Array.Empty<string>()).Should().BeNull();
142141
Implicit<NodeIds>(new string[] { null, null }).Should().BeNull();
143142
}
144143

tests/Tests/ClientConcepts/HighLevel/Inference/IndexNameInference.doc.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ [U] public void EqualsValidation()
260260

261261
Indices indices1 = "foo,bar";
262262
Indices indices2 = "bar,foo";
263-
indices1.Should().Be(indices2);
263+
indices1.Should().BeEquivalentTo(indices2);
264264
(indices1 == indices2).Should().BeTrue();
265265
}
266266

0 commit comments

Comments
 (0)