33// See the LICENSE file in the project root for more information.
44
55using System ;
6+ using System . Collections ;
67using System . Collections . Generic ;
78using System . Diagnostics ;
89using 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
145192internal 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}
0 commit comments