From 541e514e4508719e85ba33abbb344b6f9415e417 Mon Sep 17 00:00:00 2001 From: Steve Gordon Date: Tue, 2 Feb 2021 12:19:41 +0000 Subject: [PATCH] Optimise RouteValues (#5293) (cherry picked from commit 46caff6d1b5a7cdecb39a962df0fcfdfbd132a41) --- .../CommonAbstractions/Request/RouteValues.cs | 30 ++++++++++++------- .../Document/Single/Index/IndexRequest.cs | 2 +- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Nest/CommonAbstractions/Request/RouteValues.cs b/src/Nest/CommonAbstractions/Request/RouteValues.cs index 16dc28bcf34..2f42f61fb09 100644 --- a/src/Nest/CommonAbstractions/Request/RouteValues.cs +++ b/src/Nest/CommonAbstractions/Request/RouteValues.cs @@ -8,23 +8,32 @@ namespace Nest { - internal class ResolvedRouteValues : Dictionary { } + internal class ResolvedRouteValues : Dictionary + { + internal static ResolvedRouteValues Empty = new(0); + + public ResolvedRouteValues(int size) : base(size) { } + } public class RouteValues : Dictionary { - // Not too happy with this, only exists because IndexRequest needs a resolved - // id to know if it has to send a PUT or POST. - internal ResolvedRouteValues Resolved { get; private set; } + /// + /// Used specifically by index requests to determine whether to use PUT or POST. + /// + internal bool ContainsId { get; private set;} internal ResolvedRouteValues Resolve(IConnectionSettingsValues configurationValues) { - var resolved = new ResolvedRouteValues(); + if (Count == 0) return ResolvedRouteValues.Empty; + + var resolved = new ResolvedRouteValues(Count); foreach (var kv in this) { var value = this[kv.Key].GetString(configurationValues); - if (!value.IsNullOrEmpty()) resolved[kv.Key] = value; + if (value.IsNullOrEmpty()) continue; + resolved[kv.Key] = value; + if (IsId(kv.Key)) ContainsId = true; } - Resolved = resolved; return resolved; } @@ -33,19 +42,20 @@ private RouteValues Route(string name, IUrlParameter routeValue, bool required = switch (routeValue) { case null when !required: { if (!ContainsKey(name)) return this; - Remove(name); - Resolved = null; //invalidate cache + if (IsId(name)) ContainsId = false; // invalidate cache return this; } case null: throw new ArgumentNullException(name, $"{name} is required to build a url to this API"); default: this[name] = routeValue; - Resolved = null; //invalidate cache + if (IsId(name)) ContainsId = false; // invalidate cache return this; } } + private static bool IsId(string key) => key.Equals("id", StringComparison.OrdinalIgnoreCase); + internal RouteValues Required(string route, IUrlParameter value) => Route(route, value); internal RouteValues Optional(string route, IUrlParameter value) => Route(route, value, false); diff --git a/src/Nest/Document/Single/Index/IndexRequest.cs b/src/Nest/Document/Single/Index/IndexRequest.cs index b2554c398ca..857b715cdc0 100644 --- a/src/Nest/Document/Single/Index/IndexRequest.cs +++ b/src/Nest/Document/Single/Index/IndexRequest.cs @@ -26,7 +26,7 @@ void IProxyRequest.WriteJson(ITransportSerializer sourceSerializer, Stream strea sourceSerializer.Serialize(Document, stream, formatting); internal static HttpMethod GetHttpMethod(IIndexRequest request) => - request.Id?.StringOrLongValue != null || (request.RouteValues.Resolved?.ContainsKey("id") ?? false) ? HttpMethod.PUT : HttpMethod.POST; + request.Id?.StringOrLongValue != null || request.RouteValues.ContainsId ? HttpMethod.PUT : HttpMethod.POST; partial void DocumentFromPath(TDocument document) => Document = document; }