From 6cdfd1f136d9e705df90041315915de93009ad79 Mon Sep 17 00:00:00 2001 From: Russ Cam Date: Mon, 28 Nov 2016 13:27:02 +1100 Subject: [PATCH] Faster enum -> string resolution Specific enum GetStringValue extension methods for known enums Caching of generic method of resolving string values for enums based on enum type. Renamed KnownEnums.Resolve to GetStringValue and made an extension method. Added GetStringValue extension method for HttpMethod - this is a hot path, called on every request. Fixed casing issue in HttpConnection for setting ContentLength Closes #2400 --- .../ApiGenerator/Views/Enums.Generated.cshtml | 156 ++- .../Connection/HttpConnection.cs | 2 +- .../Connection/HttpMethod.cs | 2 +- .../Domain/Enums.Generated.cs | 1117 +++++++++-------- .../Elasticsearch.Net.csproj | 3 +- .../Extensions/EnumExtensions.cs | 25 + .../Extensions/Extensions.cs | 210 ++-- .../MovingAverageAggregationJsonConverter.cs | 3 +- .../Analysis/Analyzers/LanguageAnalyzer.cs | 1 + .../Extensions/Extensions.cs | 12 - .../Infer/Features/Features.cs | 6 +- .../Infer/Metrics/IndexMetrics.cs | 4 +- .../Infer/Metrics/Metrics.cs | 2 +- src/Nest/CommonOptions/DateMath/DateMath.cs | 1 + .../Geo/DistanceJsonConverter.cs | 1 + src/Nest/CommonOptions/TimeUnit/Time.cs | 1 + .../ElasticsearchCorePropertyAttributeBase.cs | 1 + .../Types/Core/Number/NumberAttribute.cs | 4 +- .../Types/Core/Number/NumberProperty.cs | 1 + .../Specialized/Script/ScriptQuery.cs | 1 + .../QueryDsl/Visitor/DslPrettyPrintVisitor.cs | 1 + src/Nest/Search/Search/Sort/SortDescriptor.cs | 5 +- src/Nest/XPack/Watcher/Action/ActionBase.cs | 1 + src/Nest/XPack/Watcher/Schedule/Interval.cs | 1 + 24 files changed, 860 insertions(+), 701 deletions(-) create mode 100644 src/Elasticsearch.Net/Extensions/EnumExtensions.cs diff --git a/src/CodeGeneration/ApiGenerator/Views/Enums.Generated.cshtml b/src/CodeGeneration/ApiGenerator/Views/Enums.Generated.cshtml index 5ec427bff10..fb0a2de8e2b 100644 --- a/src/CodeGeneration/ApiGenerator/Views/Enums.Generated.cshtml +++ b/src/CodeGeneration/ApiGenerator/Views/Enums.Generated.cshtml @@ -1,8 +1,8 @@ +@using System @using System.Collections.Generic @using System.Linq @using ApiGenerator.Domain @using ApiGenerator - @functions { private const string RawSize = "Raw"; private const string SizeEnum = "Size"; @@ -14,18 +14,33 @@ } private string CreateCase(string e, string o) { - var enumValue = (e == SizeEnum && o == string.Empty) ? RawSize : o.ToPascalCase(true); + var enumValue = GetEnumValue(e, o); return string.Format("case {0}.{1}: return \"{2}\";", e, enumValue, o); } private bool IsFlag(string name) { - return (name.EndsWith("Metric")) || name.EndsWith("Feature"); + return name.EndsWith("Metric") || name.EndsWith("Feature"); + } + + private string CreateEnumKeyValue(string enumName, string value, int index) + { + var enumValue = GetEnumValue(enumName, value); + return string.Format("{3}{{ {0}.{1}, \"{2}\" }},", enumName, enumValue, value, index == 0 ? "\t\t\t\t" : string.Empty); + } + + private string GetEnumValue(string enumName, string value) + { + return enumName == SizeEnum && value == string.Empty + ? RawSize + : value.ToPascalCase(true); } } using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Linq; using System.Text; +using System.Reflection; using System.Runtime.Serialization; ///This file contains all the typed enums that the client rest api spec exposes. @@ -33,56 +48,115 @@ using System.Runtime.Serialization; ///Generated of commit @Model.Commit namespace Elasticsearch.Net { - @foreach (EnumDescription e in Model.EnumsInTheSpec) - { - var isFlag = IsFlag(e.Name); +@foreach (EnumDescription e in Model.EnumsInTheSpec) +{ + var isFlag = IsFlag(e.Name); - @(isFlag ? "[Flags]" : string.Empty)public enum @e.Name + @(isFlag ? "[Flags]" : string.Empty)public enum @e.Name { - @Raw(string.Join(",\r\n\t\t", e.Options.OrderBy(s=>s == "_all" ? 1 : 0).Select((s, i) => CreateEnum(e.Name, s, isFlag ? (int?)i : null )))) - } - - } + @Raw(string.Join(",\r\n\t\t", e.Options.OrderBy(s => s == "_all" ? 1 : 0).Select((s, i) => CreateEnum(e.Name, s, isFlag ? (int?)i : null)))) + } +} public static class KnownEnums + { + private class EnumDictionary : @(Raw("Dictionary")) + { + public EnumDictionary(int capacity) : base(capacity) {} + public @(Raw("Func")) Resolver { get; set; } + } + + @foreach (EnumDescription e in Model.EnumsInTheSpec) { - public static string UnknownEnum { get; } = "_UNKNOWN_ENUM_"; - public static string Resolve(Enum e) + var isFlag = IsFlag(e.Name); + + public static string GetStringValue(this @(e.Name) enumValue) + { + + if (isFlag) + { + var allOption = e.Options.FirstOrDefault(o => o == "_all"); + if (allOption != null) + { + if ((enumValue & @(e.Name).All) != 0) return "_all"; + } + var list = new @(Raw("List()")); + foreach (var option in e.Options.Where(o => o != "_all")) + { + if ((enumValue & @(e.Name).@(GetEnumValue(e.Name, option))) != 0) list.Add("@(option)"); + } + return string.Join(",", list); + } + } + else + { + switch (enumValue) + { + @Raw(string.Join("\r\n\t\t\t\t", e.Options.Select(o => CreateCase(e.Name, o)))) + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum '@(e.Name)'"); + } + } + } + + private static readonly @(Raw("ConcurrentDictionary>")) EnumStringResolvers = + new @(Raw("ConcurrentDictionary>"))(); + + static KnownEnums() + { + @foreach (EnumDescription e in Model.EnumsInTheSpec) + { + EnumStringResolvers.TryAdd(typeof(@(e.Name)), (e) => GetStringValue((@(e.Name))e)); + } + } + + public static string GetStringValue(this Enum e) + { + var type = e.GetType(); + var resolver = EnumStringResolvers.GetOrAdd(type, GetEnumStringResolver); + return resolver(e); + } + + private static @Raw("Func") GetEnumStringResolver(Type type) { - @foreach (EnumDescription e in Model.EnumsInTheSpec) + var values = Enum.GetValues(type); + var dictionary = new EnumDictionary(values.Length); + + for (int index = 0; index < values.Length; index++) { - var isFlag = IsFlag(e.Name); - if (e is @e.Name) - { - if (isFlag) + var value = values.GetValue(index); +#if DOTNETCORE + var info = type.GetTypeInfo().GetDeclaredField(value.ToString()); +#else + var info = type.GetField(value.ToString()); +#endif + var da = (EnumMemberAttribute[])info.GetCustomAttributes(typeof(EnumMemberAttribute), false); + var stringValue = da.Length > 0 ? da[0].Value : Enum.GetName(type, value); + dictionary.Add((Enum)value, stringValue); + } + +#if DOTNETCORE + var isFlag = type.GetTypeInfo().GetCustomAttributes(typeof(FlagsAttribute), false).Any(); +#else + var isFlag = type.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0; +#endif + + return (e) => { - var list = new @(Raw("List()")); - foreach(var option in e.Options.OrderBy(s=>s == "_all" ? 1 : 0)) + if (isFlag) { - if (option != "_all") + var list = new @(Raw("List()")); + foreach(var kv in dictionary) { - if (e.HasFlag(@(e.Name).@(option.ToPascalCase(true)))) list.Add("@(option)"); - } - else - { - if (e.HasFlag(@(e.Name).@(option.ToPascalCase(true)))) return "@(option)"; + if (e.HasFlag(kv.Key)) list.Add(kv.Value); } + return string.Join(",", list); } - return string.Join(",", list); - } - else - { - switch((@e.Name)e) + else { - @Raw(string.Join("\r\n\t\t\t\t\t", e.Options.Select(o =>CreateCase(e.Name,o)))) - } - } - - } - - } - return UnknownEnum; + return dictionary[e]; + } + }; } } -} - \ No newline at end of file +} \ No newline at end of file diff --git a/src/Elasticsearch.Net/Connection/HttpConnection.cs b/src/Elasticsearch.Net/Connection/HttpConnection.cs index 0c7630a9f8f..8f7274c4506 100644 --- a/src/Elasticsearch.Net/Connection/HttpConnection.cs +++ b/src/Elasticsearch.Net/Connection/HttpConnection.cs @@ -66,7 +66,7 @@ protected virtual HttpWebRequest CreateWebRequest(RequestData requestData) //see: https://github.com/elasticsearch/elasticsearch-net/issues/562 var m = requestData.Method.GetStringValue(); request.Method = m; - if (m != "head" && m != "get" && (requestData.PostData == null)) + if (m != "HEAD" && m != "GET" && (requestData.PostData == null)) request.ContentLength = 0; return request; diff --git a/src/Elasticsearch.Net/Connection/HttpMethod.cs b/src/Elasticsearch.Net/Connection/HttpMethod.cs index db94cbbbc22..d13ee52a0c8 100644 --- a/src/Elasticsearch.Net/Connection/HttpMethod.cs +++ b/src/Elasticsearch.Net/Connection/HttpMethod.cs @@ -17,4 +17,4 @@ public enum HttpMethod [EnumMember(Value = "HEAD")] HEAD } -} \ No newline at end of file +} diff --git a/src/Elasticsearch.Net/Domain/Enums.Generated.cs b/src/Elasticsearch.Net/Domain/Enums.Generated.cs index fb1bf305964..e8726653d92 100644 --- a/src/Elasticsearch.Net/Domain/Enums.Generated.cs +++ b/src/Elasticsearch.Net/Domain/Enums.Generated.cs @@ -1,30 +1,30 @@ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Runtime.Serialization; - -///This file contains all the typed enums that the client rest api spec exposes. -///This file is automatically generated from https://github.com/elastic/elasticsearch/tree/v5.0.0/rest-api-spec -///Generated of commit v5.0.0 -namespace Elasticsearch.Net -{ - - public enum Refresh - { - [EnumMember(Value = "true")] +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq; +using System.Text; +using System.Reflection; +using System.Runtime.Serialization; + +///This file contains all the typed enums that the client rest api spec exposes. +///This file is automatically generated from https://github.com/elastic/elasticsearch/tree/v5.0.0/rest-api-spec +///Generated of commit v5.0.0 +namespace Elasticsearch.Net +{ + + public enum Refresh + { + [EnumMember(Value = "true")] True, [EnumMember(Value = "false")] False, [EnumMember(Value = "wait_for")] - WaitFor - } - - - public enum Bytes - { - [EnumMember(Value = "b")] + WaitFor + } + + public enum Bytes + { + [EnumMember(Value = "b")] B, [EnumMember(Value = "k")] K, @@ -45,24 +45,22 @@ public enum Bytes [EnumMember(Value = "p")] P, [EnumMember(Value = "pb")] - Pb - } - - - public enum Health - { - [EnumMember(Value = "green")] + Pb + } + + public enum Health + { + [EnumMember(Value = "green")] Green, [EnumMember(Value = "yellow")] Yellow, [EnumMember(Value = "red")] - Red - } - - - public enum Size - { - [EnumMember(Value = "")] + Red + } + + public enum Size + { + [EnumMember(Value = "")] Raw, [EnumMember(Value = "k")] K, @@ -73,24 +71,22 @@ public enum Size [EnumMember(Value = "t")] T, [EnumMember(Value = "p")] - P - } - - - public enum Level - { - [EnumMember(Value = "cluster")] + P + } + + public enum Level + { + [EnumMember(Value = "cluster")] Cluster, [EnumMember(Value = "indices")] Indices, [EnumMember(Value = "shards")] - Shards - } - - - public enum WaitForEvents - { - [EnumMember(Value = "immediate")] + Shards + } + + public enum WaitForEvents + { + [EnumMember(Value = "immediate")] Immediate, [EnumMember(Value = "urgent")] Urgent, @@ -101,133 +97,120 @@ public enum WaitForEvents [EnumMember(Value = "low")] Low, [EnumMember(Value = "languid")] - Languid - } - - - public enum WaitForStatus - { - [EnumMember(Value = "green")] + Languid + } + + public enum WaitForStatus + { + [EnumMember(Value = "green")] Green, [EnumMember(Value = "yellow")] Yellow, [EnumMember(Value = "red")] - Red - } - - - public enum ExpandWildcards - { - [EnumMember(Value = "open")] + Red + } + + public enum ExpandWildcards + { + [EnumMember(Value = "open")] Open, [EnumMember(Value = "closed")] Closed, [EnumMember(Value = "none")] None, [EnumMember(Value = "all")] - All - } - - - public enum DefaultOperator - { - [EnumMember(Value = "AND")] + All + } + + public enum DefaultOperator + { + [EnumMember(Value = "AND")] And, [EnumMember(Value = "OR")] - Or - } - - - public enum VersionType - { - [EnumMember(Value = "internal")] + Or + } + + public enum VersionType + { + [EnumMember(Value = "internal")] Internal, [EnumMember(Value = "external")] External, [EnumMember(Value = "external_gte")] ExternalGte, [EnumMember(Value = "force")] - Force - } - - - public enum Conflicts - { - [EnumMember(Value = "abort")] + Force + } + + public enum Conflicts + { + [EnumMember(Value = "abort")] Abort, [EnumMember(Value = "proceed")] - Proceed - } - - - public enum SearchType - { - [EnumMember(Value = "query_then_fetch")] + Proceed + } + + public enum SearchType + { + [EnumMember(Value = "query_then_fetch")] QueryThenFetch, [EnumMember(Value = "dfs_query_then_fetch")] - DfsQueryThenFetch - } - - - public enum SuggestMode - { - [EnumMember(Value = "missing")] + DfsQueryThenFetch + } + + public enum SuggestMode + { + [EnumMember(Value = "missing")] Missing, [EnumMember(Value = "popular")] Popular, [EnumMember(Value = "always")] - Always - } - - - public enum OpType - { - [EnumMember(Value = "index")] + Always + } + + public enum OpType + { + [EnumMember(Value = "index")] Index, [EnumMember(Value = "create")] - Create - } - - - public enum Format - { - [EnumMember(Value = "detailed")] + Create + } + + public enum Format + { + [EnumMember(Value = "detailed")] Detailed, [EnumMember(Value = "text")] - Text - } - - - public enum ThreadType - { - [EnumMember(Value = "cpu")] + Text + } + + public enum ThreadType + { + [EnumMember(Value = "cpu")] Cpu, [EnumMember(Value = "wait")] Wait, [EnumMember(Value = "block")] - Block - } - - - public enum PercolateFormat - { - [EnumMember(Value = "ids")] - Ids - } - - - public enum GroupBy - { - [EnumMember(Value = "nodes")] + Block + } + + public enum PercolateFormat + { + [EnumMember(Value = "ids")] + Ids + } + + public enum GroupBy + { + [EnumMember(Value = "nodes")] Nodes, [EnumMember(Value = "parents")] - Parents - } - - - [Flags]public enum ClusterStateMetric - { - [EnumMember(Value = "blocks")] + Parents + } + + [Flags]public enum ClusterStateMetric + { + [EnumMember(Value = "blocks")] Blocks = 1 << 0, [EnumMember(Value = "metadata")] Metadata = 1 << 1, @@ -242,24 +225,22 @@ [Flags]public enum ClusterStateMetric [EnumMember(Value = "version")] Version = 1 << 6, [EnumMember(Value = "_all")] - All = 1 << 7 - } - - - [Flags]public enum Feature - { - [EnumMember(Value = "_settings")] + All = 1 << 7 + } + + [Flags]public enum Feature + { + [EnumMember(Value = "_settings")] Settings = 1 << 0, [EnumMember(Value = "_mappings")] Mappings = 1 << 1, [EnumMember(Value = "_aliases")] - Aliases = 1 << 2 - } - - - [Flags]public enum IndicesStatsMetric - { - [EnumMember(Value = "completion")] + Aliases = 1 << 2 + } + + [Flags]public enum IndicesStatsMetric + { + [EnumMember(Value = "completion")] Completion = 1 << 0, [EnumMember(Value = "docs")] Docs = 1 << 1, @@ -292,13 +273,12 @@ [Flags]public enum IndicesStatsMetric [EnumMember(Value = "suggest")] Suggest = 1 << 15, [EnumMember(Value = "_all")] - All = 1 << 16 - } - - - [Flags]public enum NodesInfoMetric - { - [EnumMember(Value = "settings")] + All = 1 << 16 + } + + [Flags]public enum NodesInfoMetric + { + [EnumMember(Value = "settings")] Settings = 1 << 0, [EnumMember(Value = "os")] Os = 1 << 1, @@ -315,13 +295,12 @@ [Flags]public enum NodesInfoMetric [EnumMember(Value = "plugins")] Plugins = 1 << 7, [EnumMember(Value = "ingest")] - Ingest = 1 << 8 - } - - - [Flags]public enum NodesStatsMetric - { - [EnumMember(Value = "breaker")] + Ingest = 1 << 8 + } + + [Flags]public enum NodesStatsMetric + { + [EnumMember(Value = "breaker")] Breaker = 1 << 0, [EnumMember(Value = "fs")] Fs = 1 << 1, @@ -342,13 +321,12 @@ [Flags]public enum NodesStatsMetric [EnumMember(Value = "discovery")] Discovery = 1 << 9, [EnumMember(Value = "_all")] - All = 1 << 10 - } - - - [Flags]public enum NodesStatsIndexMetric - { - [EnumMember(Value = "completion")] + All = 1 << 10 + } + + [Flags]public enum NodesStatsIndexMetric + { + [EnumMember(Value = "completion")] Completion = 1 << 0, [EnumMember(Value = "docs")] Docs = 1 << 1, @@ -381,351 +359,448 @@ [Flags]public enum NodesStatsIndexMetric [EnumMember(Value = "suggest")] Suggest = 1 << 15, [EnumMember(Value = "_all")] - All = 1 << 16 - } - - - [Flags]public enum WatcherStatsMetric - { - [EnumMember(Value = "queued_watches")] + All = 1 << 16 + } + + [Flags]public enum WatcherStatsMetric + { + [EnumMember(Value = "queued_watches")] QueuedWatches = 1 << 0, [EnumMember(Value = "pending_watches")] PendingWatches = 1 << 1, [EnumMember(Value = "_all")] - All = 1 << 2 - } - - - public static class KnownEnums - { - public static string UnknownEnum { get; } = "_UNKNOWN_ENUM_"; - public static string Resolve(Enum e) - { - if (e is Refresh) - { - switch((Refresh)e) - { - case Refresh.True: return "true"; - case Refresh.False: return "false"; - case Refresh.WaitFor: return "wait_for"; - } - - } - - if (e is Bytes) - { - switch((Bytes)e) - { - case Bytes.B: return "b"; - case Bytes.K: return "k"; - case Bytes.Kb: return "kb"; - case Bytes.M: return "m"; - case Bytes.Mb: return "mb"; - case Bytes.G: return "g"; - case Bytes.Gb: return "gb"; - case Bytes.T: return "t"; - case Bytes.Tb: return "tb"; - case Bytes.P: return "p"; - case Bytes.Pb: return "pb"; - } - - } - - if (e is Health) - { - switch((Health)e) - { - case Health.Green: return "green"; - case Health.Yellow: return "yellow"; - case Health.Red: return "red"; - } - - } - - if (e is Size) - { - switch((Size)e) - { - case Size.Raw: return ""; - case Size.K: return "k"; - case Size.M: return "m"; - case Size.G: return "g"; - case Size.T: return "t"; - case Size.P: return "p"; - } - - } - - if (e is Level) - { - switch((Level)e) - { - case Level.Cluster: return "cluster"; - case Level.Indices: return "indices"; - case Level.Shards: return "shards"; - } - - } - - if (e is WaitForEvents) - { - switch((WaitForEvents)e) - { - case WaitForEvents.Immediate: return "immediate"; - case WaitForEvents.Urgent: return "urgent"; - case WaitForEvents.High: return "high"; - case WaitForEvents.Normal: return "normal"; - case WaitForEvents.Low: return "low"; - case WaitForEvents.Languid: return "languid"; - } - - } - - if (e is WaitForStatus) - { - switch((WaitForStatus)e) - { - case WaitForStatus.Green: return "green"; - case WaitForStatus.Yellow: return "yellow"; - case WaitForStatus.Red: return "red"; - } - - } - - if (e is ExpandWildcards) - { - switch((ExpandWildcards)e) - { - case ExpandWildcards.Open: return "open"; - case ExpandWildcards.Closed: return "closed"; - case ExpandWildcards.None: return "none"; - case ExpandWildcards.All: return "all"; - } - - } - - if (e is DefaultOperator) - { - switch((DefaultOperator)e) - { - case DefaultOperator.And: return "AND"; - case DefaultOperator.Or: return "OR"; - } - - } - - if (e is VersionType) - { - switch((VersionType)e) - { - case VersionType.Internal: return "internal"; - case VersionType.External: return "external"; - case VersionType.ExternalGte: return "external_gte"; - case VersionType.Force: return "force"; - } - - } - - if (e is Conflicts) - { - switch((Conflicts)e) - { - case Conflicts.Abort: return "abort"; - case Conflicts.Proceed: return "proceed"; - } - - } - - if (e is SearchType) - { - switch((SearchType)e) - { - case SearchType.QueryThenFetch: return "query_then_fetch"; - case SearchType.DfsQueryThenFetch: return "dfs_query_then_fetch"; - } - - } - - if (e is SuggestMode) - { - switch((SuggestMode)e) - { - case SuggestMode.Missing: return "missing"; - case SuggestMode.Popular: return "popular"; - case SuggestMode.Always: return "always"; - } - - } - - if (e is OpType) - { - switch((OpType)e) - { - case OpType.Index: return "index"; - case OpType.Create: return "create"; - } - - } - - if (e is Format) - { - switch((Format)e) - { - case Format.Detailed: return "detailed"; - case Format.Text: return "text"; - } - - } - - if (e is ThreadType) - { - switch((ThreadType)e) - { - case ThreadType.Cpu: return "cpu"; - case ThreadType.Wait: return "wait"; - case ThreadType.Block: return "block"; - } - - } - - if (e is PercolateFormat) - { - switch((PercolateFormat)e) - { - case PercolateFormat.Ids: return "ids"; - } - - } - - if (e is GroupBy) - { - switch((GroupBy)e) - { - case GroupBy.Nodes: return "nodes"; - case GroupBy.Parents: return "parents"; - } - - } - - if (e is ClusterStateMetric) - { - var list = new List(); - if (e.HasFlag(ClusterStateMetric.Blocks)) list.Add("blocks"); - if (e.HasFlag(ClusterStateMetric.Metadata)) list.Add("metadata"); - if (e.HasFlag(ClusterStateMetric.Nodes)) list.Add("nodes"); - if (e.HasFlag(ClusterStateMetric.RoutingTable)) list.Add("routing_table"); - if (e.HasFlag(ClusterStateMetric.RoutingNodes)) list.Add("routing_nodes"); - if (e.HasFlag(ClusterStateMetric.MasterNode)) list.Add("master_node"); - if (e.HasFlag(ClusterStateMetric.Version)) list.Add("version"); - if (e.HasFlag(ClusterStateMetric.All)) return "_all"; - return string.Join(",", list); - - } - - if (e is Feature) - { - var list = new List(); - if (e.HasFlag(Feature.Settings)) list.Add("_settings"); - if (e.HasFlag(Feature.Mappings)) list.Add("_mappings"); - if (e.HasFlag(Feature.Aliases)) list.Add("_aliases"); - return string.Join(",", list); - - } - - if (e is IndicesStatsMetric) - { - var list = new List(); - if (e.HasFlag(IndicesStatsMetric.Completion)) list.Add("completion"); - if (e.HasFlag(IndicesStatsMetric.Docs)) list.Add("docs"); - if (e.HasFlag(IndicesStatsMetric.Fielddata)) list.Add("fielddata"); - if (e.HasFlag(IndicesStatsMetric.QueryCache)) list.Add("query_cache"); - if (e.HasFlag(IndicesStatsMetric.Flush)) list.Add("flush"); - if (e.HasFlag(IndicesStatsMetric.Get)) list.Add("get"); - if (e.HasFlag(IndicesStatsMetric.Indexing)) list.Add("indexing"); - if (e.HasFlag(IndicesStatsMetric.Merge)) list.Add("merge"); - if (e.HasFlag(IndicesStatsMetric.Percolate)) list.Add("percolate"); - if (e.HasFlag(IndicesStatsMetric.RequestCache)) list.Add("request_cache"); - if (e.HasFlag(IndicesStatsMetric.Refresh)) list.Add("refresh"); - if (e.HasFlag(IndicesStatsMetric.Search)) list.Add("search"); - if (e.HasFlag(IndicesStatsMetric.Segments)) list.Add("segments"); - if (e.HasFlag(IndicesStatsMetric.Store)) list.Add("store"); - if (e.HasFlag(IndicesStatsMetric.Warmer)) list.Add("warmer"); - if (e.HasFlag(IndicesStatsMetric.Suggest)) list.Add("suggest"); - if (e.HasFlag(IndicesStatsMetric.All)) return "_all"; - return string.Join(",", list); - - } - - if (e is NodesInfoMetric) - { - var list = new List(); - if (e.HasFlag(NodesInfoMetric.Settings)) list.Add("settings"); - if (e.HasFlag(NodesInfoMetric.Os)) list.Add("os"); - if (e.HasFlag(NodesInfoMetric.Process)) list.Add("process"); - if (e.HasFlag(NodesInfoMetric.Jvm)) list.Add("jvm"); - if (e.HasFlag(NodesInfoMetric.ThreadPool)) list.Add("thread_pool"); - if (e.HasFlag(NodesInfoMetric.Transport)) list.Add("transport"); - if (e.HasFlag(NodesInfoMetric.Http)) list.Add("http"); - if (e.HasFlag(NodesInfoMetric.Plugins)) list.Add("plugins"); - if (e.HasFlag(NodesInfoMetric.Ingest)) list.Add("ingest"); - return string.Join(",", list); - - } - - if (e is NodesStatsMetric) - { - var list = new List(); - if (e.HasFlag(NodesStatsMetric.Breaker)) list.Add("breaker"); - if (e.HasFlag(NodesStatsMetric.Fs)) list.Add("fs"); - if (e.HasFlag(NodesStatsMetric.Http)) list.Add("http"); - if (e.HasFlag(NodesStatsMetric.Indices)) list.Add("indices"); - if (e.HasFlag(NodesStatsMetric.Jvm)) list.Add("jvm"); - if (e.HasFlag(NodesStatsMetric.Os)) list.Add("os"); - if (e.HasFlag(NodesStatsMetric.Process)) list.Add("process"); - if (e.HasFlag(NodesStatsMetric.ThreadPool)) list.Add("thread_pool"); - if (e.HasFlag(NodesStatsMetric.Transport)) list.Add("transport"); - if (e.HasFlag(NodesStatsMetric.Discovery)) list.Add("discovery"); - if (e.HasFlag(NodesStatsMetric.All)) return "_all"; - return string.Join(",", list); - - } - - if (e is NodesStatsIndexMetric) - { - var list = new List(); - if (e.HasFlag(NodesStatsIndexMetric.Completion)) list.Add("completion"); - if (e.HasFlag(NodesStatsIndexMetric.Docs)) list.Add("docs"); - if (e.HasFlag(NodesStatsIndexMetric.Fielddata)) list.Add("fielddata"); - if (e.HasFlag(NodesStatsIndexMetric.QueryCache)) list.Add("query_cache"); - if (e.HasFlag(NodesStatsIndexMetric.Flush)) list.Add("flush"); - if (e.HasFlag(NodesStatsIndexMetric.Get)) list.Add("get"); - if (e.HasFlag(NodesStatsIndexMetric.Indexing)) list.Add("indexing"); - if (e.HasFlag(NodesStatsIndexMetric.Merge)) list.Add("merge"); - if (e.HasFlag(NodesStatsIndexMetric.Percolate)) list.Add("percolate"); - if (e.HasFlag(NodesStatsIndexMetric.RequestCache)) list.Add("request_cache"); - if (e.HasFlag(NodesStatsIndexMetric.Refresh)) list.Add("refresh"); - if (e.HasFlag(NodesStatsIndexMetric.Search)) list.Add("search"); - if (e.HasFlag(NodesStatsIndexMetric.Segments)) list.Add("segments"); - if (e.HasFlag(NodesStatsIndexMetric.Store)) list.Add("store"); - if (e.HasFlag(NodesStatsIndexMetric.Warmer)) list.Add("warmer"); - if (e.HasFlag(NodesStatsIndexMetric.Suggest)) list.Add("suggest"); - if (e.HasFlag(NodesStatsIndexMetric.All)) return "_all"; - return string.Join(",", list); - - } - - if (e is WatcherStatsMetric) - { - var list = new List(); - if (e.HasFlag(WatcherStatsMetric.QueuedWatches)) list.Add("queued_watches"); - if (e.HasFlag(WatcherStatsMetric.PendingWatches)) list.Add("pending_watches"); - if (e.HasFlag(WatcherStatsMetric.All)) return "_all"; - return string.Join(",", list); - - } - - return UnknownEnum; - } - } -} - \ No newline at end of file + All = 1 << 2 + } + + public static class KnownEnums + { + private class EnumDictionary : Dictionary + { + public EnumDictionary(int capacity) : base(capacity) {} + public Func Resolver { get; set; } + } + + + public static string GetStringValue(this Refresh enumValue) + { + + switch (enumValue) + { + case Refresh.True: return "true"; + case Refresh.False: return "false"; + case Refresh.WaitFor: return "wait_for"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'Refresh'"); + } + + public static string GetStringValue(this Bytes enumValue) + { + + switch (enumValue) + { + case Bytes.B: return "b"; + case Bytes.K: return "k"; + case Bytes.Kb: return "kb"; + case Bytes.M: return "m"; + case Bytes.Mb: return "mb"; + case Bytes.G: return "g"; + case Bytes.Gb: return "gb"; + case Bytes.T: return "t"; + case Bytes.Tb: return "tb"; + case Bytes.P: return "p"; + case Bytes.Pb: return "pb"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'Bytes'"); + } + + public static string GetStringValue(this Health enumValue) + { + + switch (enumValue) + { + case Health.Green: return "green"; + case Health.Yellow: return "yellow"; + case Health.Red: return "red"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'Health'"); + } + + public static string GetStringValue(this Size enumValue) + { + + switch (enumValue) + { + case Size.Raw: return ""; + case Size.K: return "k"; + case Size.M: return "m"; + case Size.G: return "g"; + case Size.T: return "t"; + case Size.P: return "p"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'Size'"); + } + + public static string GetStringValue(this Level enumValue) + { + + switch (enumValue) + { + case Level.Cluster: return "cluster"; + case Level.Indices: return "indices"; + case Level.Shards: return "shards"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'Level'"); + } + + public static string GetStringValue(this WaitForEvents enumValue) + { + + switch (enumValue) + { + case WaitForEvents.Immediate: return "immediate"; + case WaitForEvents.Urgent: return "urgent"; + case WaitForEvents.High: return "high"; + case WaitForEvents.Normal: return "normal"; + case WaitForEvents.Low: return "low"; + case WaitForEvents.Languid: return "languid"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'WaitForEvents'"); + } + + public static string GetStringValue(this WaitForStatus enumValue) + { + + switch (enumValue) + { + case WaitForStatus.Green: return "green"; + case WaitForStatus.Yellow: return "yellow"; + case WaitForStatus.Red: return "red"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'WaitForStatus'"); + } + + public static string GetStringValue(this ExpandWildcards enumValue) + { + + switch (enumValue) + { + case ExpandWildcards.Open: return "open"; + case ExpandWildcards.Closed: return "closed"; + case ExpandWildcards.None: return "none"; + case ExpandWildcards.All: return "all"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'ExpandWildcards'"); + } + + public static string GetStringValue(this DefaultOperator enumValue) + { + + switch (enumValue) + { + case DefaultOperator.And: return "AND"; + case DefaultOperator.Or: return "OR"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'DefaultOperator'"); + } + + public static string GetStringValue(this VersionType enumValue) + { + + switch (enumValue) + { + case VersionType.Internal: return "internal"; + case VersionType.External: return "external"; + case VersionType.ExternalGte: return "external_gte"; + case VersionType.Force: return "force"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'VersionType'"); + } + + public static string GetStringValue(this Conflicts enumValue) + { + + switch (enumValue) + { + case Conflicts.Abort: return "abort"; + case Conflicts.Proceed: return "proceed"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'Conflicts'"); + } + + public static string GetStringValue(this SearchType enumValue) + { + + switch (enumValue) + { + case SearchType.QueryThenFetch: return "query_then_fetch"; + case SearchType.DfsQueryThenFetch: return "dfs_query_then_fetch"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'SearchType'"); + } + + public static string GetStringValue(this SuggestMode enumValue) + { + + switch (enumValue) + { + case SuggestMode.Missing: return "missing"; + case SuggestMode.Popular: return "popular"; + case SuggestMode.Always: return "always"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'SuggestMode'"); + } + + public static string GetStringValue(this OpType enumValue) + { + + switch (enumValue) + { + case OpType.Index: return "index"; + case OpType.Create: return "create"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'OpType'"); + } + + public static string GetStringValue(this Format enumValue) + { + + switch (enumValue) + { + case Format.Detailed: return "detailed"; + case Format.Text: return "text"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'Format'"); + } + + public static string GetStringValue(this ThreadType enumValue) + { + + switch (enumValue) + { + case ThreadType.Cpu: return "cpu"; + case ThreadType.Wait: return "wait"; + case ThreadType.Block: return "block"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'ThreadType'"); + } + + public static string GetStringValue(this PercolateFormat enumValue) + { + + switch (enumValue) + { + case PercolateFormat.Ids: return "ids"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'PercolateFormat'"); + } + + public static string GetStringValue(this GroupBy enumValue) + { + + switch (enumValue) + { + case GroupBy.Nodes: return "nodes"; + case GroupBy.Parents: return "parents"; + } + throw new ArgumentException($"'{enumValue.ToString()}' is not a valid value for enum 'GroupBy'"); + } + + public static string GetStringValue(this ClusterStateMetric enumValue) + { + + if ((enumValue & ClusterStateMetric.All) != 0) return "_all"; + var list = new List(); + if ((enumValue & ClusterStateMetric.Blocks) != 0) list.Add("blocks"); + if ((enumValue & ClusterStateMetric.Metadata) != 0) list.Add("metadata"); + if ((enumValue & ClusterStateMetric.Nodes) != 0) list.Add("nodes"); + if ((enumValue & ClusterStateMetric.RoutingTable) != 0) list.Add("routing_table"); + if ((enumValue & ClusterStateMetric.RoutingNodes) != 0) list.Add("routing_nodes"); + if ((enumValue & ClusterStateMetric.MasterNode) != 0) list.Add("master_node"); + if ((enumValue & ClusterStateMetric.Version) != 0) list.Add("version"); + return string.Join(",", list); + } + + public static string GetStringValue(this Feature enumValue) + { + + var list = new List(); + if ((enumValue & Feature.Settings) != 0) list.Add("_settings"); + if ((enumValue & Feature.Mappings) != 0) list.Add("_mappings"); + if ((enumValue & Feature.Aliases) != 0) list.Add("_aliases"); + return string.Join(",", list); + } + + public static string GetStringValue(this IndicesStatsMetric enumValue) + { + + if ((enumValue & IndicesStatsMetric.All) != 0) return "_all"; + var list = new List(); + if ((enumValue & IndicesStatsMetric.Completion) != 0) list.Add("completion"); + if ((enumValue & IndicesStatsMetric.Docs) != 0) list.Add("docs"); + if ((enumValue & IndicesStatsMetric.Fielddata) != 0) list.Add("fielddata"); + if ((enumValue & IndicesStatsMetric.QueryCache) != 0) list.Add("query_cache"); + if ((enumValue & IndicesStatsMetric.Flush) != 0) list.Add("flush"); + if ((enumValue & IndicesStatsMetric.Get) != 0) list.Add("get"); + if ((enumValue & IndicesStatsMetric.Indexing) != 0) list.Add("indexing"); + if ((enumValue & IndicesStatsMetric.Merge) != 0) list.Add("merge"); + if ((enumValue & IndicesStatsMetric.Percolate) != 0) list.Add("percolate"); + if ((enumValue & IndicesStatsMetric.RequestCache) != 0) list.Add("request_cache"); + if ((enumValue & IndicesStatsMetric.Refresh) != 0) list.Add("refresh"); + if ((enumValue & IndicesStatsMetric.Search) != 0) list.Add("search"); + if ((enumValue & IndicesStatsMetric.Segments) != 0) list.Add("segments"); + if ((enumValue & IndicesStatsMetric.Store) != 0) list.Add("store"); + if ((enumValue & IndicesStatsMetric.Warmer) != 0) list.Add("warmer"); + if ((enumValue & IndicesStatsMetric.Suggest) != 0) list.Add("suggest"); + return string.Join(",", list); + } + + public static string GetStringValue(this NodesInfoMetric enumValue) + { + + var list = new List(); + if ((enumValue & NodesInfoMetric.Settings) != 0) list.Add("settings"); + if ((enumValue & NodesInfoMetric.Os) != 0) list.Add("os"); + if ((enumValue & NodesInfoMetric.Process) != 0) list.Add("process"); + if ((enumValue & NodesInfoMetric.Jvm) != 0) list.Add("jvm"); + if ((enumValue & NodesInfoMetric.ThreadPool) != 0) list.Add("thread_pool"); + if ((enumValue & NodesInfoMetric.Transport) != 0) list.Add("transport"); + if ((enumValue & NodesInfoMetric.Http) != 0) list.Add("http"); + if ((enumValue & NodesInfoMetric.Plugins) != 0) list.Add("plugins"); + if ((enumValue & NodesInfoMetric.Ingest) != 0) list.Add("ingest"); + return string.Join(",", list); + } + + public static string GetStringValue(this NodesStatsMetric enumValue) + { + + if ((enumValue & NodesStatsMetric.All) != 0) return "_all"; + var list = new List(); + if ((enumValue & NodesStatsMetric.Breaker) != 0) list.Add("breaker"); + if ((enumValue & NodesStatsMetric.Fs) != 0) list.Add("fs"); + if ((enumValue & NodesStatsMetric.Http) != 0) list.Add("http"); + if ((enumValue & NodesStatsMetric.Indices) != 0) list.Add("indices"); + if ((enumValue & NodesStatsMetric.Jvm) != 0) list.Add("jvm"); + if ((enumValue & NodesStatsMetric.Os) != 0) list.Add("os"); + if ((enumValue & NodesStatsMetric.Process) != 0) list.Add("process"); + if ((enumValue & NodesStatsMetric.ThreadPool) != 0) list.Add("thread_pool"); + if ((enumValue & NodesStatsMetric.Transport) != 0) list.Add("transport"); + if ((enumValue & NodesStatsMetric.Discovery) != 0) list.Add("discovery"); + return string.Join(",", list); + } + + public static string GetStringValue(this NodesStatsIndexMetric enumValue) + { + + if ((enumValue & NodesStatsIndexMetric.All) != 0) return "_all"; + var list = new List(); + if ((enumValue & NodesStatsIndexMetric.Completion) != 0) list.Add("completion"); + if ((enumValue & NodesStatsIndexMetric.Docs) != 0) list.Add("docs"); + if ((enumValue & NodesStatsIndexMetric.Fielddata) != 0) list.Add("fielddata"); + if ((enumValue & NodesStatsIndexMetric.QueryCache) != 0) list.Add("query_cache"); + if ((enumValue & NodesStatsIndexMetric.Flush) != 0) list.Add("flush"); + if ((enumValue & NodesStatsIndexMetric.Get) != 0) list.Add("get"); + if ((enumValue & NodesStatsIndexMetric.Indexing) != 0) list.Add("indexing"); + if ((enumValue & NodesStatsIndexMetric.Merge) != 0) list.Add("merge"); + if ((enumValue & NodesStatsIndexMetric.Percolate) != 0) list.Add("percolate"); + if ((enumValue & NodesStatsIndexMetric.RequestCache) != 0) list.Add("request_cache"); + if ((enumValue & NodesStatsIndexMetric.Refresh) != 0) list.Add("refresh"); + if ((enumValue & NodesStatsIndexMetric.Search) != 0) list.Add("search"); + if ((enumValue & NodesStatsIndexMetric.Segments) != 0) list.Add("segments"); + if ((enumValue & NodesStatsIndexMetric.Store) != 0) list.Add("store"); + if ((enumValue & NodesStatsIndexMetric.Warmer) != 0) list.Add("warmer"); + if ((enumValue & NodesStatsIndexMetric.Suggest) != 0) list.Add("suggest"); + return string.Join(",", list); + } + + public static string GetStringValue(this WatcherStatsMetric enumValue) + { + + if ((enumValue & WatcherStatsMetric.All) != 0) return "_all"; + var list = new List(); + if ((enumValue & WatcherStatsMetric.QueuedWatches) != 0) list.Add("queued_watches"); + if ((enumValue & WatcherStatsMetric.PendingWatches) != 0) list.Add("pending_watches"); + return string.Join(",", list); + } + + private static readonly ConcurrentDictionary> EnumStringResolvers = + new ConcurrentDictionary>(); + + static KnownEnums() + { + EnumStringResolvers.TryAdd(typeof(Refresh), (e) => GetStringValue((Refresh)e)); + EnumStringResolvers.TryAdd(typeof(Bytes), (e) => GetStringValue((Bytes)e)); + EnumStringResolvers.TryAdd(typeof(Health), (e) => GetStringValue((Health)e)); + EnumStringResolvers.TryAdd(typeof(Size), (e) => GetStringValue((Size)e)); + EnumStringResolvers.TryAdd(typeof(Level), (e) => GetStringValue((Level)e)); + EnumStringResolvers.TryAdd(typeof(WaitForEvents), (e) => GetStringValue((WaitForEvents)e)); + EnumStringResolvers.TryAdd(typeof(WaitForStatus), (e) => GetStringValue((WaitForStatus)e)); + EnumStringResolvers.TryAdd(typeof(ExpandWildcards), (e) => GetStringValue((ExpandWildcards)e)); + EnumStringResolvers.TryAdd(typeof(DefaultOperator), (e) => GetStringValue((DefaultOperator)e)); + EnumStringResolvers.TryAdd(typeof(VersionType), (e) => GetStringValue((VersionType)e)); + EnumStringResolvers.TryAdd(typeof(Conflicts), (e) => GetStringValue((Conflicts)e)); + EnumStringResolvers.TryAdd(typeof(SearchType), (e) => GetStringValue((SearchType)e)); + EnumStringResolvers.TryAdd(typeof(SuggestMode), (e) => GetStringValue((SuggestMode)e)); + EnumStringResolvers.TryAdd(typeof(OpType), (e) => GetStringValue((OpType)e)); + EnumStringResolvers.TryAdd(typeof(Format), (e) => GetStringValue((Format)e)); + EnumStringResolvers.TryAdd(typeof(ThreadType), (e) => GetStringValue((ThreadType)e)); + EnumStringResolvers.TryAdd(typeof(PercolateFormat), (e) => GetStringValue((PercolateFormat)e)); + EnumStringResolvers.TryAdd(typeof(GroupBy), (e) => GetStringValue((GroupBy)e)); + EnumStringResolvers.TryAdd(typeof(ClusterStateMetric), (e) => GetStringValue((ClusterStateMetric)e)); + EnumStringResolvers.TryAdd(typeof(Feature), (e) => GetStringValue((Feature)e)); + EnumStringResolvers.TryAdd(typeof(IndicesStatsMetric), (e) => GetStringValue((IndicesStatsMetric)e)); + EnumStringResolvers.TryAdd(typeof(NodesInfoMetric), (e) => GetStringValue((NodesInfoMetric)e)); + EnumStringResolvers.TryAdd(typeof(NodesStatsMetric), (e) => GetStringValue((NodesStatsMetric)e)); + EnumStringResolvers.TryAdd(typeof(NodesStatsIndexMetric), (e) => GetStringValue((NodesStatsIndexMetric)e)); + EnumStringResolvers.TryAdd(typeof(WatcherStatsMetric), (e) => GetStringValue((WatcherStatsMetric)e)); + } + + public static string GetStringValue(this Enum e) + { + var type = e.GetType(); + var resolver = EnumStringResolvers.GetOrAdd(type, GetEnumStringResolver); + return resolver(e); + } + + private static Func GetEnumStringResolver(Type type) + { + var values = Enum.GetValues(type); + var dictionary = new EnumDictionary(values.Length); + + for (int index = 0; index < values.Length; index++) + { + var value = values.GetValue(index); +#if DOTNETCORE + var info = type.GetTypeInfo().GetDeclaredField(value.ToString()); +#else + var info = type.GetField(value.ToString()); +#endif + var da = (EnumMemberAttribute[])info.GetCustomAttributes(typeof(EnumMemberAttribute), false); + var stringValue = da.Length > 0 ? da[0].Value : Enum.GetName(type, value); + dictionary.Add((Enum)value, stringValue); + } + +#if DOTNETCORE + var isFlag = type.GetTypeInfo().GetCustomAttributes(typeof(FlagsAttribute), false).Any(); +#else + var isFlag = type.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0; +#endif + + return (e) => + { + if (isFlag) + { + var list = new List(); + foreach(var kv in dictionary) + { + if (e.HasFlag(kv.Key)) list.Add(kv.Value); + } + return string.Join(",", list); + } + else + { + return dictionary[e]; + } + }; + } + } +} \ No newline at end of file diff --git a/src/Elasticsearch.Net/Elasticsearch.Net.csproj b/src/Elasticsearch.Net/Elasticsearch.Net.csproj index 67e6418ea54..a9ab0cb6201 100644 --- a/src/Elasticsearch.Net/Elasticsearch.Net.csproj +++ b/src/Elasticsearch.Net/Elasticsearch.Net.csproj @@ -84,6 +84,7 @@ + @@ -129,4 +130,4 @@ - + \ No newline at end of file diff --git a/src/Elasticsearch.Net/Extensions/EnumExtensions.cs b/src/Elasticsearch.Net/Extensions/EnumExtensions.cs new file mode 100644 index 00000000000..58cb4dec1aa --- /dev/null +++ b/src/Elasticsearch.Net/Extensions/EnumExtensions.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Elasticsearch.Net +{ + public static class EnumExtensions + { + public static string GetStringValue(this HttpMethod enumValue) + { + switch (enumValue) + { + case HttpMethod.GET: return "GET"; + case HttpMethod.POST: return "POST"; + case HttpMethod.PUT: return "PUT"; + case HttpMethod.DELETE: return "DELETE"; + case HttpMethod.HEAD: return "HEAD"; + default: + throw new ArgumentOutOfRangeException(nameof(enumValue), enumValue, null); + } + } + } +} diff --git a/src/Elasticsearch.Net/Extensions/Extensions.cs b/src/Elasticsearch.Net/Extensions/Extensions.cs index 9a585724d44..63ba3d02294 100644 --- a/src/Elasticsearch.Net/Extensions/Extensions.cs +++ b/src/Elasticsearch.Net/Extensions/Extensions.cs @@ -1,45 +1,27 @@ -using System; -using System.Collections.Generic; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.Globalization; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -#if DOTNETCORE -using System.Reflection; -#endif - -namespace Elasticsearch.Net -{ - internal static class Extensions - { - internal static string GetStringValue(this Enum enumValue) - { - var knownEnum = KnownEnums.Resolve(enumValue); - if (knownEnum != KnownEnums.UnknownEnum) return knownEnum; - - //TODO measure performance and cache - var type = enumValue.GetType(); -#if DOTNETCORE - var info = type.GetTypeInfo().GetDeclaredField(enumValue.ToString()); -#else - var info = type.GetField(enumValue.ToString()); -#endif - var da = (EnumMemberAttribute[])(info.GetCustomAttributes(typeof(EnumMemberAttribute), false)); - - return da.Length > 0 ? da[0].Value : Enum.GetName(enumValue.GetType(), enumValue); - } - -#if !DOTNETCORE +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization; +using System.Text; + +namespace Elasticsearch.Net +{ + internal static class Extensions + { +#if !DOTNETCORE internal static string Utf8String(this byte[] bytes) => bytes == null ? null : Encoding.UTF8.GetString(bytes); -#else - internal static string Utf8String(this byte[] bytes) => bytes == null ? null : Encoding.UTF8.GetString(bytes, 0, bytes.Length); -#endif +#else + internal static string Utf8String(this byte[] bytes) => bytes == null ? null : Encoding.UTF8.GetString(bytes, 0, bytes.Length); +#endif internal static byte[] Utf8Bytes(this string s) { return s.IsNullOrEmpty() ? null : Encoding.UTF8.GetBytes(s); } - + internal static string ToCamelCase(this string s) { if (string.IsNullOrEmpty(s)) @@ -55,90 +37,90 @@ internal static string ToCamelCase(this string s) return camelCase; } - internal static string NotNull(this string @object, string parameterName) - { - @object.ThrowIfNull(parameterName); - if (string.IsNullOrWhiteSpace(@object)) - throw new ArgumentException("String argument is empty", parameterName); - return @object; - } - + internal static string NotNull(this string @object, string parameterName) + { + @object.ThrowIfNull(parameterName); + if (string.IsNullOrWhiteSpace(@object)) + throw new ArgumentException("String argument is empty", parameterName); + return @object; + } + internal static string NotNull(this Enum @object, string parameterName) { @object.ThrowIfNull(parameterName); return @object.GetStringValue(); } - internal static void ThrowIfEmpty(this IEnumerable @object, string parameterName) - { - @object.ThrowIfNull(parameterName); - if (!@object.Any()) - throw new ArgumentException("Argument can not be an empty collection", parameterName); - } - internal static bool HasAny(this IEnumerable list) - { - return list != null && list.Any(); - } - - internal static void ThrowIfNull(this T value, string name) - { - if (value == null) - throw new ArgumentNullException(name); - } - internal static bool IsNullOrEmpty(this string value) - { - return string.IsNullOrEmpty(value); - } - - internal static IEnumerable DistinctBy(this IEnumerable items, Func property) - { - return items.GroupBy(property).Select(x => x.First()); - } - - private static readonly long _week = (long)TimeSpan.FromDays(7).TotalMilliseconds; - private static readonly long _day = (long)TimeSpan.FromDays(1).TotalMilliseconds; - private static readonly long _hour = (long)TimeSpan.FromHours(1).TotalMilliseconds; - private static readonly long _minute = (long)TimeSpan.FromMinutes(1).TotalMilliseconds; + internal static void ThrowIfEmpty(this IEnumerable @object, string parameterName) + { + @object.ThrowIfNull(parameterName); + if (!@object.Any()) + throw new ArgumentException("Argument can not be an empty collection", parameterName); + } + internal static bool HasAny(this IEnumerable list) + { + return list != null && list.Any(); + } + + internal static void ThrowIfNull(this T value, string name) + { + if (value == null) + throw new ArgumentNullException(name); + } + internal static bool IsNullOrEmpty(this string value) + { + return string.IsNullOrEmpty(value); + } + + internal static IEnumerable DistinctBy(this IEnumerable items, Func property) + { + return items.GroupBy(property).Select(x => x.First()); + } + + private static readonly long _week = (long)TimeSpan.FromDays(7).TotalMilliseconds; + private static readonly long _day = (long)TimeSpan.FromDays(1).TotalMilliseconds; + private static readonly long _hour = (long)TimeSpan.FromHours(1).TotalMilliseconds; + private static readonly long _minute = (long)TimeSpan.FromMinutes(1).TotalMilliseconds; private static readonly long _second = (long)TimeSpan.FromSeconds(1).TotalMilliseconds; - internal static string ToTimeUnit(this TimeSpan timeSpan) - { - var ms = timeSpan.TotalMilliseconds; - string interval; - double factor = 0; - - if (ms >= _week) - { - factor = ms / _week; - interval = "w"; - } - else if (ms >= _day) - { - factor = ms / _day; - interval = "d"; - } - else if (ms >= _hour) - { - factor = ms / _hour; - interval = "h"; - } - else if (ms >= _minute) - { - factor = ms / _minute; - interval = "m"; - } - else if (ms >= _second) - { - factor = ms / _second; - interval = "s"; - } - else - { - factor = ms; - interval = "ms"; - } - - return factor.ToString("0.##", CultureInfo.InvariantCulture) + interval; - } - } -} + internal static string ToTimeUnit(this TimeSpan timeSpan) + { + var ms = timeSpan.TotalMilliseconds; + string interval; + double factor = 0; + + if (ms >= _week) + { + factor = ms / _week; + interval = "w"; + } + else if (ms >= _day) + { + factor = ms / _day; + interval = "d"; + } + else if (ms >= _hour) + { + factor = ms / _hour; + interval = "h"; + } + else if (ms >= _minute) + { + factor = ms / _minute; + interval = "m"; + } + else if (ms >= _second) + { + factor = ms / _second; + interval = "s"; + } + else + { + factor = ms; + interval = "ms"; + } + + return factor.ToString("0.##", CultureInfo.InvariantCulture) + interval; + } + } +} diff --git a/src/Nest/Aggregations/Pipeline/MovingAverage/MovingAverageAggregationJsonConverter.cs b/src/Nest/Aggregations/Pipeline/MovingAverage/MovingAverageAggregationJsonConverter.cs index ba89e563a66..a588b1f0737 100644 --- a/src/Nest/Aggregations/Pipeline/MovingAverage/MovingAverageAggregationJsonConverter.cs +++ b/src/Nest/Aggregations/Pipeline/MovingAverage/MovingAverageAggregationJsonConverter.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Elasticsearch.Net; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -34,7 +35,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist { aggregation.BucketsPath = default(SingleBucketsPath); } - + #else aggregation.BucketsPath = GetOrDefault("buckets_path", ps); #endif diff --git a/src/Nest/Analysis/Analyzers/LanguageAnalyzer.cs b/src/Nest/Analysis/Analyzers/LanguageAnalyzer.cs index 390e172e214..0e1323e00a2 100644 --- a/src/Nest/Analysis/Analyzers/LanguageAnalyzer.cs +++ b/src/Nest/Analysis/Analyzers/LanguageAnalyzer.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Elasticsearch.Net; using Newtonsoft.Json; namespace Nest diff --git a/src/Nest/CommonAbstractions/Extensions/Extensions.cs b/src/Nest/CommonAbstractions/Extensions/Extensions.cs index b152962ab1d..b3100e6b13b 100644 --- a/src/Nest/CommonAbstractions/Extensions/Extensions.cs +++ b/src/Nest/CommonAbstractions/Extensions/Extensions.cs @@ -37,18 +37,6 @@ internal static TReturn InvokeOrDefault(this Func func?.Invoke(@default, param2) ?? @default; - internal static string GetStringValue(this Enum enumValue) - { - var knownEnum = KnownEnums.Resolve(enumValue); - if (knownEnum != KnownEnums.UnknownEnum) return knownEnum; - - var type = enumValue.GetType(); - var info = type.GetField(enumValue.ToString()); - var da = info.GetCustomAttribute(); - - return da != null ? da.Value : Enum.GetName(enumValue.GetType(), enumValue); - } - internal static readonly JsonConverter dateConverter = new IsoDateTimeConverter { Culture = CultureInfo.InvariantCulture }; internal static readonly JsonSerializer serializer = new JsonSerializer(); internal static string ToJsonNetString(this DateTime date) diff --git a/src/Nest/CommonAbstractions/Infer/Features/Features.cs b/src/Nest/CommonAbstractions/Infer/Features/Features.cs index 4093c1eea89..ad5b5e822b1 100644 --- a/src/Nest/CommonAbstractions/Infer/Features/Features.cs +++ b/src/Nest/CommonAbstractions/Infer/Features/Features.cs @@ -7,15 +7,15 @@ namespace Nest [JsonConverter(typeof(FeaturesJsonConverter))] public class Features : IUrlParameter { - string IUrlParameter.GetString(IConnectionConfigurationValues settings) => KnownEnums.Resolve(_enumValue); + string IUrlParameter.GetString(IConnectionConfigurationValues settings) => _enumValue.GetStringValue(); - private readonly Enum _enumValue; + private readonly Feature _enumValue; internal Features(Feature feature) { _enumValue = feature; } public static implicit operator Features(Feature feature) => new Features(feature); public static implicit operator Features(string features) => FromString(features); - + public static Features FromString(string features) { var parts = features.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); diff --git a/src/Nest/CommonAbstractions/Infer/Metrics/IndexMetrics.cs b/src/Nest/CommonAbstractions/Infer/Metrics/IndexMetrics.cs index 7715ef8a073..3d4dc0262d6 100644 --- a/src/Nest/CommonAbstractions/Infer/Metrics/IndexMetrics.cs +++ b/src/Nest/CommonAbstractions/Infer/Metrics/IndexMetrics.cs @@ -5,9 +5,9 @@ namespace Nest { public class IndexMetrics : IUrlParameter { - private readonly Enum _enumValue; + private readonly NodesStatsIndexMetric _enumValue; - public string GetString(IConnectionConfigurationValues settings) => KnownEnums.Resolve(this._enumValue); + public string GetString(IConnectionConfigurationValues settings) => this._enumValue.GetStringValue(); internal IndexMetrics(NodesStatsIndexMetric metric) { _enumValue = metric; } public static implicit operator IndexMetrics(NodesStatsIndexMetric metric) => new IndexMetrics(metric); diff --git a/src/Nest/CommonAbstractions/Infer/Metrics/Metrics.cs b/src/Nest/CommonAbstractions/Infer/Metrics/Metrics.cs index a1d2b483e0a..3d0690de1cb 100644 --- a/src/Nest/CommonAbstractions/Infer/Metrics/Metrics.cs +++ b/src/Nest/CommonAbstractions/Infer/Metrics/Metrics.cs @@ -7,7 +7,7 @@ public class Metrics : IUrlParameter { private readonly Enum _enumValue; - public string GetString(IConnectionConfigurationValues settings) => KnownEnums.Resolve(this._enumValue); + public string GetString(IConnectionConfigurationValues settings) => this._enumValue.GetStringValue(); internal Metrics(IndicesStatsMetric metric) { _enumValue = metric; } internal Metrics(NodesStatsMetric metric){ _enumValue = metric; } internal Metrics(NodesInfoMetric metric){ _enumValue = metric; } diff --git a/src/Nest/CommonOptions/DateMath/DateMath.cs b/src/Nest/CommonOptions/DateMath/DateMath.cs index fa405047c98..bd42c3daef7 100644 --- a/src/Nest/CommonOptions/DateMath/DateMath.cs +++ b/src/Nest/CommonOptions/DateMath/DateMath.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; +using Elasticsearch.Net; using Newtonsoft.Json; namespace Nest diff --git a/src/Nest/CommonOptions/Geo/DistanceJsonConverter.cs b/src/Nest/CommonOptions/Geo/DistanceJsonConverter.cs index 5f320b21cf6..9aa43bb19e3 100644 --- a/src/Nest/CommonOptions/Geo/DistanceJsonConverter.cs +++ b/src/Nest/CommonOptions/Geo/DistanceJsonConverter.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using Elasticsearch.Net; using Newtonsoft.Json; namespace Nest diff --git a/src/Nest/CommonOptions/TimeUnit/Time.cs b/src/Nest/CommonOptions/TimeUnit/Time.cs index ae6d4d30c3c..6ec12b359eb 100644 --- a/src/Nest/CommonOptions/TimeUnit/Time.cs +++ b/src/Nest/CommonOptions/TimeUnit/Time.cs @@ -1,6 +1,7 @@ using System; using System.Globalization; using System.Text.RegularExpressions; +using Elasticsearch.Net; using Newtonsoft.Json; namespace Nest diff --git a/src/Nest/Mapping/AttributeBased/ElasticsearchCorePropertyAttributeBase.cs b/src/Nest/Mapping/AttributeBased/ElasticsearchCorePropertyAttributeBase.cs index 1937a6eb42f..df73c11462d 100644 --- a/src/Nest/Mapping/AttributeBased/ElasticsearchCorePropertyAttributeBase.cs +++ b/src/Nest/Mapping/AttributeBased/ElasticsearchCorePropertyAttributeBase.cs @@ -1,5 +1,6 @@ using System; using System.Reflection; +using Elasticsearch.Net; using Newtonsoft.Json; namespace Nest diff --git a/src/Nest/Mapping/Types/Core/Number/NumberAttribute.cs b/src/Nest/Mapping/Types/Core/Number/NumberAttribute.cs index 6ef1480dd77..822d3e47932 100644 --- a/src/Nest/Mapping/Types/Core/Number/NumberAttribute.cs +++ b/src/Nest/Mapping/Types/Core/Number/NumberAttribute.cs @@ -1,4 +1,6 @@ -namespace Nest +using Elasticsearch.Net; + +namespace Nest { /// /// Maps a property as a number type. If no type is specified, diff --git a/src/Nest/Mapping/Types/Core/Number/NumberProperty.cs b/src/Nest/Mapping/Types/Core/Number/NumberProperty.cs index 13e35870922..801cc94cce4 100644 --- a/src/Nest/Mapping/Types/Core/Number/NumberProperty.cs +++ b/src/Nest/Mapping/Types/Core/Number/NumberProperty.cs @@ -1,4 +1,5 @@ using System; +using Elasticsearch.Net; using Newtonsoft.Json; namespace Nest diff --git a/src/Nest/QueryDsl/Specialized/Script/ScriptQuery.cs b/src/Nest/QueryDsl/Specialized/Script/ScriptQuery.cs index 3c2d9ea5a66..b896f9163cb 100644 --- a/src/Nest/QueryDsl/Specialized/Script/ScriptQuery.cs +++ b/src/Nest/QueryDsl/Specialized/Script/ScriptQuery.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Elasticsearch.Net; using Newtonsoft.Json; namespace Nest diff --git a/src/Nest/QueryDsl/Visitor/DslPrettyPrintVisitor.cs b/src/Nest/QueryDsl/Visitor/DslPrettyPrintVisitor.cs index 0754e99c915..d9db738638b 100644 --- a/src/Nest/QueryDsl/Visitor/DslPrettyPrintVisitor.cs +++ b/src/Nest/QueryDsl/Visitor/DslPrettyPrintVisitor.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using Elasticsearch.Net; namespace Nest { diff --git a/src/Nest/Search/Search/Sort/SortDescriptor.cs b/src/Nest/Search/Search/Sort/SortDescriptor.cs index 540408c38b8..7c6ee45e5f6 100644 --- a/src/Nest/Search/Search/Sort/SortDescriptor.cs +++ b/src/Nest/Search/Search/Sort/SortDescriptor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq.Expressions; +using Elasticsearch.Net; namespace Nest { @@ -25,7 +26,7 @@ public SortDescriptor() : base(new List()) { } public SortDescriptor Field(Field field, SortOrder order) => AddSort(new SortField { Field = field, Order = order }); - public SortDescriptor Field(Expression> field, SortOrder order) => + public SortDescriptor Field(Expression> field, SortOrder order) => AddSort(new SortField { Field = field, Order = order }); public SortDescriptor GeoDistance(Func, IGeoDistanceSort> sortSelector) => AddSort(sortSelector?.Invoke(new SortGeoDistanceDescriptor())); @@ -34,4 +35,4 @@ public SortDescriptor Field(Expression> field, SortOrder orde private SortDescriptor AddSort(ISort sort) => sort == null ? this : this.Assign(a => a.Add(sort)); } -} \ No newline at end of file +} diff --git a/src/Nest/XPack/Watcher/Action/ActionBase.cs b/src/Nest/XPack/Watcher/Action/ActionBase.cs index 0c7599cbcd4..9612cf17fea 100644 --- a/src/Nest/XPack/Watcher/Action/ActionBase.cs +++ b/src/Nest/XPack/Watcher/Action/ActionBase.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Elasticsearch.Net; using Newtonsoft.Json; using Newtonsoft.Json.Linq; diff --git a/src/Nest/XPack/Watcher/Schedule/Interval.cs b/src/Nest/XPack/Watcher/Schedule/Interval.cs index b51d5a736cd..ec459189cd3 100644 --- a/src/Nest/XPack/Watcher/Schedule/Interval.cs +++ b/src/Nest/XPack/Watcher/Schedule/Interval.cs @@ -2,6 +2,7 @@ using System.Globalization; using System.Runtime.Serialization; using System.Text.RegularExpressions; +using Elasticsearch.Net; using Newtonsoft.Json; using Newtonsoft.Json.Converters;